前言:
學習參考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