前言:
学习参考kubernetes官方文档,以kubernetes为准
pod是容器的集合,容器中的隐患(cpu、IO、MEM),在k8s中依然存在
官方文档:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
云计算 两大块虚拟化
OpenStack ——创建虚拟硬件资源池——创建虚拟机实例
比如:vdisk 虚拟磁盘
容器—》容器编排—容器群集管理 例如:docker—docker-compose-----kubernetes虚拟硬件 ---- 资源限制
文章目录
一:pod和container的资源请求和限制
spec.containers[].resources.limits.cpu //cpu上限
spec.containers[].resources.limits.memory //内存上限
spec.containers[].resources.requests.cpu //创建时分配的基本CPU资源
spec.containers[].resources.requests.memory //创建时分配的基本内存资源
一种是最大上限,一种是基本分配
尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。
1.1 cpu的含义
CPU 资源的限制和请求以 cpu 为单位。
Kubernetes 中的一个 cpu 等于:
- 1 AWS vCPU
- 1 GCP Core
- 1 Azure vCore
- 1 Hyperthread 在带有超线程的裸机 Intel 处理器上
允许浮点数请求。具有 spec.containers[].resources.requests.cpu
为 0.5 的容器保证了一半 CPU 要求 1 CPU的一半。表达式 0.1
等价于表达式 100m
,可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。具有小数点(如 0.1
)的请求由 API 转换为100m
,精度不超过 1m
。因此,可能会优先选择 100m
的形式。
CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。
1.2 内存的含义
内存的限制和请求以字节为单位。您可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。您还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。例如,以下代表大致相同的值:
128974848, 129e6, 129M, 123Mi
1.3 举例验证
以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
1.4 具有资源请求的pod如何调度
当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。
每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。
调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。
注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。
当资源使用量稍后增加时,例如在请求率的每日峰值期间,这便可以防止节点上的资源短缺。
1.5 具有资源限制的pod如何运行
当 kubelet 启动一个 Pod 的容器时,它会将 CPU 和内存限制传递到容器运行时。
当使用 Docker 时:
spec.containers[].resources.requests.cpu
的值将转换成 millicore 值,这是个浮点数,并乘以 1024,这个数字中的较大者或 2 用作docker run
命令中的--cpu-shares
标志的值。spec.containers[].resources.limits.cpu
被转换成 millicore 值。被乘以 100000 然后 除以 1000。这个数字用作docker run
命令中的--cpu-quota
标志的值。[--cpu-quota
] 标志被设置成了 100000,表示测量配额使用的默认100ms 周期。如果 [--cpu-cfs-quota
] 标志设置为 true,则 kubelet 会强制执行 cpu 限制。从 Kubernetes 1.2 版本起,此标志默认为 true。
注意: 默认配额限制为 100 毫秒。 CPU配额的最小单位为 1 毫秒。
如果容器超过其内存限制,则可能会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。
如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。
容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。
1.6 pod处于pending状态且时间显示failedscheduling
如果调度器找不到任何该 Pod 可以匹配的节点,则该 Pod 将保持不可调度状态,直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,会产生一个事件,如下所示:
kubectl describe pod frontend | grep -A 3 Events
Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,可以尝试如下几件事情:
- 向集群添加更多节点。
- 终止不需要的 Pod,为待处理的 Pod 腾出空间。
- 检查 Pod 所需的资源是否大于所有节点的资源。 例如,如果全部节点的容量为
cpu:1
,那么一个请求为cpu:1.1
的 Pod 永远不会被调度。
1.7 kubectl describe nodes 检查节点容量分配和分配的数量
kubectl describe nodes e2e-test-node-pool-4lw4
Name: e2e-test-node-pool-4lw4
[ ... lines removed for clarity ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... lines removed for clarity ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
在上面的输出中,您可以看到如果 Pod 请求超过 1120m CPU 或者 6.23Gi 内存,节点将无法满足。
通过查看 Pods
部分,您将看到哪些 Pod 占用的节点上的资源。
Pod 可用的资源量小于节点容量,因为系统守护程序使用一部分可用资源。 NodeStatus 的 allocatable
字段给出了可用于 Pod 的资源量。 有关更多信息,请参阅官方文档 节点可分配资源。
可以将 资源配额 功能配置为限制可以使用的资源总量。如果与 namespace 配合一起使用,就可以防止一个团队占用所有资源
1.8 容器被终止
容器可能因为资源枯竭而被终止了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用 kubectl describe pod
:
kubectl describe pod simmemleak-hra99
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers:
simmemleak:
Image: saadali/simmemleak
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700
Last Termination State: Terminated
Exit Code: 1
Started: Fri, 07 Jul 2015 12:54:30 -0700
Finished: Fri, 07 Jul 2015 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
Restart Count: 5
意味着 Pod 中的 simmemleak
容器被终止并重启了五次。
可以使用 kubectl get pod
命令加上 -o go-template=...
选项来获取之前终止容器的状态。
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
可以看到容器因为 reason:OOM killed
被终止,OOM
表示 Out Of Memory。
二:演示
2.1 编写yaml文件
[root@master1 ~]# vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
#两个容器,分别是名为db的mysql,名为wp的wordpress
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
#资源管理
requests:
#请求资源
memory: "64Mi"
cpu: "250m"
limits:
#限制资源
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
2.2 创建资源
[root@master1 ~]# kubectl apply -f pod2.yaml
pod/frontend created
2.3 查看pod具体事件
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend 0/2 ContainerCreating 0 45s
[root@master1 ~]# kubectl describe pod frontend #这里只截取事件
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 79s default-scheduler Successfully assigned default/frontend to 192.168.247.143
Normal Pulling 58s kubelet, 192.168.247.143 pulling image "wordpress"
Normal Pulled 26s kubelet, 192.168.247.143 Successfully pulled image "wordpress"
Normal Pulling 25s (x2 over 78s) kubelet, 192.168.247.143 pulling image "mysql"
Normal Started 25s kubelet, 192.168.247.143 Started container
Normal Created 25s kubelet, 192.168.247.143 Created container
Normal Pulled 24s (x2 over 58s) kubelet, 192.168.247.143 Successfully pulled image "mysql"
Normal Created 23s (x2 over 58s) kubelet, 192.168.247.143 Created container
Normal Started 23s (x2 over 58s) kubelet, 192.168.247.143 Started container
Warning BackOff 6s kubelet, 192.168.247.143 Back-off restarting failed container
yaml文件有误,但不影响验证
2.4 查看node节点的docker
[root@node01 ~]# docker ps -a | grep wp
a99b989fb2a7 wordpress "docker-entrypoint.s…" 2 minutes ago Up 2 minutes k8s_wp_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_0
[root@node01 ~]# docker ps -a | grep mysql
a5f2dccad7cb mysql "docker-entrypoint.s…" 5 seconds ago Up 4 seconds k8s_db_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_4
a2bad2be413f mysql "docker-entrypoint.s…" About a minute ago Exited (1) 56 seconds ago k8s_db_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_3
2.5 回到master,发现已经重启四次
[root@master1 ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
frontend 1/2 CrashLoopBackOff 4 4m9s
frontend 2/2 Running 5 4m47s
frontend 1/2 OOMKilled 5 4m55s
frontend 1/2 CrashLoopBackOff 5 5m10s
2.6 查看pod所在node节点的描述信息
备注:从pod事件中可以知道pod在192.168.247.143node01上
[root@master1 ~]# kubectl describe node 192.168.247.143
Name: 192.168.247.143
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=192.168.247.143
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 30 Apr 2020 11:40:08 +0800
Taints: <none>
Unschedulable: false
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
OutOfDisk False Wed, 13 May 2020 08:55:30 +0800 Fri, 08 May 2020 13:03:43 +0800 KubeletHasSufficientDisk kubelet has sufficient disk space available
MemoryPressure False Wed, 13 May 2020 08:55:30 +0800 Fri, 08 May 2020 13:03:43 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Wed, 13 May 2020 08:55:30 +0800 Fri, 08 May 2020 13:03:43 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Wed, 13 May 2020 08:55:30 +0800 Thu, 30 Apr 2020 11:40:08 +0800 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Wed, 13 May 2020 08:55:30 +0800 Tue, 12 May 2020 08:40:28 +0800 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 192.168.247.143
Hostname: 192.168.247.143
Capacity:
cpu: 2
ephemeral-storage: 309307844Ki
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 3861364Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 285058108559
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 3758964Ki
pods: 110
System Info:
Machine ID: e7c72a193a404cf587718e10bd4e5533
System UUID: 13744D56-2BA1-6509-242B-ED05BBAA67FF
Boot ID: 54684508-2c2f-4e1f-81c7-427c94c4c16b
Kernel Version: 3.10.0-1062.el7.x86_64
OS Image: CentOS Linux 7 (Core)
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://19.3.8
Kubelet Version: v1.12.3
Kube-Proxy Version: v1.12.3
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
default frontend 500m (25%) 1 (50%) 128Mi (3%) 256Mi (6%)
default my-tomcat-6cbc7c4d65-hdmhc 0 (0%) 0 (0%) 0 (0%) 0 (0%)
default nginx-deployment-78cdb5b557-f2hx2 0 (0%) 0 (0%) 0 (0%) 0 (0%)
default pod1 0 (0%) 0 (0%) 0 (0%) 0 (0%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 500m (25%) 1 (50%)
memory 128Mi (3%) 256Mi (6%)
Events: <none>
[root@master1 ~]#
2.7 node的限额信息
百分比是占用当前硬件的百分比,pod是k8s的最小执行单位
对pod的资源限制参数是pod内容器的限制之和
命名空间在不指定的情况下默认命名空间
[root@master1 ~]# kubectl get ns
NAME STATUS AGE
default Active 12d
kube-public Active 12d
kube-system Active 12d