Kubernetes 资源限制对Pod调度的影响

网友投稿 783 2022-11-29

Kubernetes 资源限制对Pod调度的影响

Kubernetes 资源限制对Pod调度的影响

为容器管理资源

当你定义 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-​​​​spec.containers[].resources.requests.cpu​​​​spec.containers[].resources.requests.memory​​​​spec.containers[].resources.requests.hugepages-​​

尽管请求和限制值只能在单个容器上指定,我们仍可方便地计算出 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。 例如,以下表达式所代表的是大致相同的值:

128974848、129e6、129M、123Mi

创建一个Pod的工作流程

Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。其他组件监控自己负责的资源,当这些资源发生变化时,kube apiserver会通知这些组件,这个过程类似于发布与订阅。

Pod中影响调度的主要属性

在集群当中创建pod的时候,哪些属性会影响pod的调度呢,有哪些熟悉可以指定pod分布在指定的节点上呢?

[root@k8s-master ~]# kubectl create deployment nginx --image=nginx[root@k8s-master ~]# kubectl expose deployment nginx --port=80 --type=NodePort[root@k8s-master ~]# kubectl get deploy nginx -o yamldnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30

这里就能够看到一部分调度策略了,比如使用调度器的名称为default-scheduler

Pod中影响调度的主要属性

上面这些红框最终都是会影响pod的调度

资源限制对Pod调度的影响

2核就2*1000=2000m2c=2000m1c=1000m0.5c=500m

如果pod不限制的资源的使用,如果其中一个容器出现异常,那么会消耗该宿主机上面的所有资源,因为容器之间是没有任何限制的。这样可能会导致其他容器没有可用的资源去运行,从而无法正常提供服务。

为了防止该事情的发生就会对容器资源做限制。为了实现配置k8s做了两方面的配置

容器资源限制:

容器最大资源限制

• resources.limits.cpu

• resources.limits.memory

容器使用的最小资源需求,作为容器调度时资源分配的依据:(容器最小使用的资源是多少)

• resources.requests.cpu

• resources.requests.memory

其实在调度的时候只有requests会影响调度,而limit只是一个实际的限制。只不过都在resource字段下完成的。

下面是一个成功调度的例子

[root@k8s-master ~]# cat pod-resource.yaml apiVersion: v1kind: Podmetadata: name: pod-resource spec: containers: - name: web image: nginx resources: requests: # 容器最小资源配额 memory: "64Mi" cpu: "250m" limits: # 容器最大资源上限 memory: "128Mi" cpu: "500m"# Limits一定要比request高[root@k8s-master ~]# kubectl apply -f pod-resource.yaml pod/pod-resource created[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod-resource 1/1 Running 0 75s 10.244.169.143 k8s-node2 [root@k8s-master ~]# kubectl describe pod pod-resource Limits: cpu: 500m memory: 128Mi Requests: cpu: 250m memory: 64Mi

查看k8s-node2节点详细信息

[root@k8s-master ~]# kubectl describe node k8s-node2Non-terminated Pods: (8 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE --------- ---- ------------ ---------- --------------- ------------- --- default pod-resource 250m (25%) 500m (50%) 64Mi (4%) 128Mi (9%) 3m56s# 标识该节点为pod分配的配额Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 500m (50%) 500m (50%) memory 64Mi (4%) 128Mi (9%) ephemeral-storage 0 (0%) 0 (0%) hugepages-1Gi 0 (0%) 0 (0%) hugepages-2Mi 0 (0%) 0 (0%)# 这部分为可分配的Allocatable: cpu: 1 ephemeral-storage: 7717729063 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 1319260Ki pods: 110

下面是一个调度失败的例子

[root@k8s-master ~]# cat pod-resource2.yml apiVersion: v1kind: Podmetadata: name: pod-resource2 spec: containers: - name: web image: nginx resources: requests: memory: "4Gi" cpu: "2000m"[root@k8s-master ~]# kubectl apply -f pod-resource2.yml pod/pod-resource2 created[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod-resource2 0/1 Pending 0 78s [root@k8s-master ~]# kubectl describe pod pod-resource2Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 113s 0/3 nodes are available: 3 Insufficient cpu, 3 Insufficient memory. Warning FailedScheduling 113s 0/3 nodes are available: 3 Insufficient cpu, 3 Insufficient memory.# 可以看出给了三个节点,每个节点的CPU和内存都不足,所以处于pending状态,如果要运行起来到等到有节点的资源可以满足

可以看到资源限制会对pod调度产生影响,K8s会根据Request的值去查找有足够资源的Node来调度此Pod。

资源的配额request只会影响这个Pod请求的最小资源,在节点当中有没有资源可以满足它。如果要将pod调度到某个节点上,这样是满足不了的.

当你创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。 每个节点对每种资源类型都有一个容量上限:可为 Pod 提供的 CPU 和内存量。 调度程序确保对于每种资源类型,所调度的容器的资源请求的总和小于节点的容量。 请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,如果容量检查失败, 调度程序仍会拒绝在该节点上放置 Pod。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Keepalived+Lvs 原来如此简单,so easy
下一篇:Kubernetes 工作负载控制器Deployment和Replicaset
相关文章

 发表评论

暂时没有评论,来抢沙发吧~