为容器管理资源
当你定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存(RAM)大小;此外还有其他类型的资源。
当你为 Pod 中的 Container 指定了资源 请求 时,调度器就利用该信息决定将 Pod 调度到哪个节点上。 当你还为 Container 指定了资源 约束 时,kubelet 就可以确保运行的容器不会使用超出所设约束的资源。 kubelet 还会为容器预留所 请求 数量的系统资源,供其使用。
请求和约束
如果 Pod 运行所在的节点具有足够的可用资源,容器可能(且可以)使用超出对应资源 request
属性所设置的资源量。不过,容器不可以使用超出其资源 limit
属性所设置的资源量。
例如,如果你将容器的 memory
的请求量设置为 256 MiB,而该容器所处的 Pod 被调度到一个具有 8 GiB 内存的节点上,并且该节点上没有其他 Pods 运行,那么该容器就可以尝试使用更多的内存。
如果你将某容器的 memory
约束设置为 4 GiB,kubelet 就会确保该约束生效。 容器运行时会禁止容器使用超出所设置资源约束的资源。 例如:当容器中进程尝试使用超出所允许内存量的资源时,系统内核会将尝试申请内存的进程终止, 并引发内存不足(OOM)错误。
约束值可以以被动方式来实现(系统会在发现违例时进行干预),或者通过强制生效的方式实现 (系统会避免容器用量超出约束值)。不同的容器运行时采用不同方式来实现相同的限制。
说明:
如果某 Container 设置了自己的内存限制但未设置内存请求,Kubernetes 自动为其设置与内存限制相匹配的请求值。类似的,如果某 Container 设置了 CPU 限制值但未设置 CPU 请求值,则 Kubernetes 自动为其设置 CPU 请求 并使之与 CPU 限制值匹配。
Pod 和 容器的资源请求和约束
Pod 中的每个容器都可以指定以下的一个或者多个值:
-
spec.containers[].resources.limits.cpu
-
spec.containers[].resources.limits.memory
-
spec.containers[].resources.limits.hugepages-<size>
-
spec.containers[].resources.requests.cpu
-
spec.containers[].resources.requests.memory
-
spec.containers[].resources.requests.hugepages-<size>
尽管请求和限制值只能在单个容器上指定,我们仍可方便地计算出 Pod 的资源请求和约束。 Pod 对特定资源类型的请求/约束值是 Pod 中各容器对该类型资源的请求/约束值的总和。
Kubernetes 中的资源单位
CPU 的含义
CPU 资源的约束和请求以 cpu 为单位。
Kubernetes 中的一个 cpu 等于云平台上的 1 个 vCPU/核和裸机 Intel 处理器上的 **1 个超线程 **。
你也可以表达带小数 CPU 的请求。spec.containers[].resources.requests.cpu
为 0.5 的 Container 肯定能够获得请求 1 CPU 的容器的一半 CPU 资源。表达式 0.1
等价于表达式 100m
, 可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。 具有小数点(如 0.1
)的请求由 API 转换为 100m
;最大精度是 1m
。 因此,或许你应该优先考虑使用 100m
的形式。
CPU 总是按绝对数量来请求的,不可以使用相对数量; 0.1 的 CPU 在单核、双核、48 核的机器上的意义是一样的。
内存的含义
内存的约束和请求以字节为单位。你可以使用以下后缀之一以一般整数或定点数字形式来表示内存: E、P、T、G、M、K。你也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。 例如,以下表达式所代表的是大致相同的值:
创建一个Pod的工作流程
Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。其他组件监控自己负责的资源,当这些资源发生变化时,kube apiserver会通知这些组件,这个过程类似于发布与订阅。
Pod中影响调度的主要属性
在集群当中创建pod的时候,哪些属性会影响pod的调度呢,有哪些熟悉可以指定pod分布在指定的节点上呢?
这里就能够看到一部分调度策略了,比如使用调度器的名称为default-scheduler
Pod中影响调度的主要属性
上面这些红框最终都是会影响pod的调度
资源限制对Pod调度的影响
如果pod不限制的资源的使用,如果其中一个容器出现异常,那么会消耗该宿主机上面的所有资源,因为容器之间是没有任何限制的。这样可能会导致其他容器没有可用的资源去运行,从而无法正常提供服务。
为了防止该事情的发生就会对容器资源做限制。为了实现配置k8s做了两方面的配置
容器资源限制:
容器最大资源限制
• resources.limits.cpu
• resources.limits.memory
容器使用的最小资源需求,作为容器调度时资源分配的依据:(容器最小使用的资源是多少)
• resources.requests.cpu
• resources.requests.memory
其实在调度的时候只有requests会影响调度,而limit只是一个实际的限制。只不过都在resource字段下完成的。
下面是一个成功调度的例子
查看k8s-node2节点详细信息
下面是一个调度失败的例子
可以看到资源限制会对pod调度产生影响,K8s会根据Request的值去查找有足够资源的Node来调度此Pod。
资源的配额request只会影响这个Pod请求的最小资源,在节点当中有没有资源可以满足它。如果要将pod调度到某个节点上,这样是满足不了的.
当你创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。 每个节点对每种资源类型都有一个容量上限:可为 Pod 提供的 CPU 和内存量。 调度程序确保对于每种资源类型,所调度的容器的资源请求的总和小于节点的容量。 请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,如果容量检查失败, 调度程序仍会拒绝在该节点上放置 Pod。