排錯指南 - Pod
本文檔介紹 Pod 的異常狀態,可能原因和解決辦法。
排查 Pod 異常的常用命令如下:
- 查看 Pod 狀態:
kubectl get pods <pod-name> -n <namespace> -o wide
- 查看 Pod 的 yaml 配置:
kubectl get pods <pod-name> -n <namespace> -o yaml
- 查看 Pod 的事件:
kubectl describe pods <pod-name> -n <namespace>
- 查看 Pod 容器日志:
kubectl logs -n <namespace> <pod-name> [-c <container-name>]
Pod 一直處于 Pending 狀態
Pending 狀態說明 Pod 還沒有調度到某個 Node 上面??梢酝ㄟ^ kubectl describe pods <pod-name> -n <namespace>
命令查看到 Pod 的事件,進而判斷為什么沒有調度。如:
``` bash
$ kubectl describe pod mypod
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 12s (x6 over 27s) default-scheduler 0/4 nodes are available: 2 Insufficient cpu.
```
可能的原因和解決方案:
-
集群的 kube-scheduler 服務都掛掉了:
可以在各節點運行
ps -elf | grep kube-scheduler
命令來驗證。如果掛掉,可以使用systectl start kube-scheduler
命令啟動服務; -
節點沒有打標簽或打的標簽值不匹配:
如 Pod 指定了 nodeSelector、nodeAffinity、podAffinity 或 AntiAffinity 等標簽選擇器,但沒有節點打對應的標簽或打的標值不匹配。
可以使用
kubectl describe pods
查看 Pod 的定義,使用kubectl get node --show-labels
查看各 Node 的 lables 列表,使用kubectl label node lable_name=lable_value
給 Node 打標簽; -
節點資源不足:
集群內所有的 Node 都不滿足該 Pod request 的 CPU、Memory、GPU 或者臨時存儲空間等資源,或者 Node 上的 Pod 數量達到了上限(kubelet 的 --max-pods 參數指定)。
可以通過
kubectl describe node
來查看各節點資源分配情況。然后通過刪除不用的 Pod 來釋放資源,或增加新的 Node 來增加資源。案例:
- 創建的 Pod 一直處于 Pending 狀態,kubectl describe pods 顯示
No nodes are available that match all of the predicates: Insufficient pods (3).
原因:
-
kubelet 默認最多能運行 110 個 Pods:
$ kubectl describe node m7-devops-128071|grep -A 7 'Capacity' Capacity: cpu: 40 memory: 264040352Ki pods: 110 Allocatable: cpu: 40 memory: 263937952Ki pods: 110
當所有 kubelet 運行的 Pods 數達到 110 后,新創建的 Pod 就會因為資源不足而無法調度,提示 Insufficient pods;
解決方案:
- kubelet 的 --max-pods 選項可以指定運行的最大 Pod 數目,通過調大該參數,如 110 → 240, 可以解決該問題。
- 注意:因為 flanneld 配置的本節點 Pod 網段是 /24,所以一個 Node 最多運行 254 個 Pod(flannel、docker0 占用 2 個),--max-pods 不能超過該值;
- 創建的 Pod 一直處于 Pending 狀態,kubectl describe pods 顯示
-
創建 Pod 基礎容器 (sanbox) 失?。?/p>
現象:
-
創建的 Pod 一直處于 Pending 狀態;
[root@scriptk8c ~]# k get pods NAME READY STATUS RESTARTS AGE dnsuutils-ds-7q6dr 0/1 Pending 0 3s
-
kubectl describe pod 顯示創建 sandbox pod 失敗:
[root@scriptk8c ~]# k describe pods dnsuutils-ds-7q6dr|tail Tolerations: node.alpha.kubernetes.io/notReady:NoExecute node.alpha.kubernetes.io/unreachable:NoExecute node.kubernetes.io/disk-pressure:NoSchedule node.kubernetes.io/memory-pressure:NoSchedule Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulMountVolume 2m kubelet, 172.27.129.237 MountVolume.SetUp succeeded for volume "default-token-jhdrm" Warning FailedCreatePodSandBox 25s (x8 over 2m) kubelet, 172.27.129.237 Failed create pod sandbox. Warning FailedSync 25s (x8 over 2m) kubelet, 172.27.129.237 Error syncing pod
原因:
- kubelet 基礎容器配置參數:--pod-infra-container-image=docker02:35000/rhel7/pod-infrastructure:latest
- 節點本地不存在這個 image,所以 kubelet 去 registry docker02:35000 拉取該鏡像;
- registry 需要登錄認證,而 kubelet 沒有提供認證信息,所以獲取 pod-infra-container-image 失敗,進而導致創建 sandbox 失??;
解決方案:
-
從其他節點導出 pod-infra-container-image ,再導入到該節點,這樣 kubelet 就不會去 registry 拉取鏡像了;
$ docker save registry.access.redhat.com/rhel7/pod-infrastructure -o rhel.tar $ docker load -i rhel.tar
-
或者讓 kublet 使用節點的 docker 認證信息去 registry 拉取鏡像:
在節點 root 賬戶下,執行 docker login docker02:35000 命令,輸入賬號、密碼登錄;
-
修改 kubelet 配置文件,添加環境變量: HOME=root,重啟 kubelet:
[root@scriptk8c ~]# grep HOME /mnt/disk01/opt/k8s/etc/kubernetes/kubelet HOME=/root [root@scriptk8c ~]# systemctl restart kubelet [root@scriptk8c ~]#
注意:方案 2 適用于 k8s 1.8 版本,1.11 支持更多的認證方式;
參考:
-
-
Pod 使用 HostNetwork,對應的端口(HostPort)在節點上已被占用:
案例:
-
集群中已經部署一個 node_exporter 的 Daemonset,它使用了 hostNetwork 和 hostPID ,端口為 9100。則再部署一個使用相同端口的 daemonset 時,一直不創建 pod(describe 時所有 field 均為 0):
[root@m7-devops-128123 log]# kubectl get ds |grep -E "NAME|node-exporter" NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE my-prom-prometheus-node-exporter 0 0 0 0 0 <none> 17m
查看所有 kube-xxx 組件的日志,均沒有相關的異常日志。
原因:
- Daemonset 由 DaemonSet Controller (非 scheduler )負責調度。如果 DS Controller 發現沒有 Node 滿足調度條件,如 Node 資源不足、** HostPort 端口沖突**等,就不會為 Node 創建 POD;
- 本問題原因在于 Node_Exporter 使用了 hostNewtork,部署監聽相同端口的 Daemonset 時出現 HostPort 端口沖突,故 K8S 不再創建 POD;
解決方案:
- 換個 HostPort (Service 端口也需要更新) 或通常使用 Service 對外開放服務端口;
-
Pod 一直處于 Waiting 或 ContainerCreating 狀態
可能的原因和解決方案:
-
創建 Pod 的基礎容器 (sandbox) 失敗,例如節點本地沒有 pod-infrastructure 鏡像,但是從 kubelet 拉取失?。ㄈ缯J證問題):
使用命令
docker images |grep pod-infra
確認節點 kubelet 參數--pod-infra-container-image
對應的鏡像,如registry.access.redhat.com/rhel7/pod-infrastructure:latest
是否存在。如果不存在則手動拉取到節點(可能需要先登錄 registry)。 -
Pod yaml 定義中請求的 CPU、Memory 太小,不足以成功運行 Sandbox。
常見的錯誤是:Pod yaml 定義 request 或 limit Memory 值是不帶單位(如 Gi, Mi, Ki 等)的數值,如 4,這時只分配和限制使用 4 bytes。
kubectl descirbe pod
顯示:
Pod sandbox changed, it will be killed and re-created。kubelet 日志報錯:
to start sandbox container for pod ... Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:301: running exec setns process for init caused "signal: killed"": unknown -
拉取鏡像失敗:
- 配置了錯誤的鏡像;
- Kubelet 無法訪問鏡像倉庫(國內環境訪問 gcr.io 需要特殊處理);
- 拉取私有鏡像的 imagePullSecret 沒有配置或配置有誤;
- 鏡像太大,拉取超時(可以適當調整 kubelet 的 --image-pull-progress-deadline 和 --runtime-request-timeout 選項);
Pod 一直處于 ImagePullBackOff 狀態
可能的原因和解決方案:
-
http 類型的 registry,但是沒有添加到 dockerd 的 insecure-registry=172.27.129.211:35000 配置參數中:
dockerd 默認從 https 類型的 registry 拉取鏡像,如果使用 https 類型的 registry,則必須將它添加到 insecure-registry 參數中,然后重啟或 reload dockerd 生效。
-
https 類型的 registry,但是使用自簽名的 ca 證書,dockerd 不識別:
將 registry 加入到 insecure-registry 參數中,然后重啟或 reload dockerd 生效?;蛘邔⑺?ca 證書放置到
/etc/docker/certs.d/<registry:port>/ca.crt
位置; -
registry 需要認證,但是 Pod 沒有配置 imagePullSecret,配置的 Secret 不存在或有誤:
首先創建一個 docker-registry 類型的 Secret:
$ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
然后在容器中引用這個 Secret:
spec: containers: - name: private-reg-container image: <your-private-image> imagePullSecrets: - name: my-secret
-
鏡像文件損壞,需要重新 push 鏡像文件
kubectl describe pod 報錯:
Failed to pull image "docker02:35000/env/release/3.2.0/prophet/app/executor-service-kube.tar:release-3.2.0-8": rpc error: code = Unknown desc = error pulling image configuration: unknown blob
-
kubelet 的 --registry-qps、--registry-burst 值太?。J分別為 5,10),并發拉取鏡像時被限制:
被并發限制時,kubectl describe pod 報錯:
Failed to pull image "172.27.129.211:35000/metricbeat-prophet:6.0.1": pull QPS exceeded,這時,可以調大這兩個參數,然后重啟 kubelet 解決。
--registry-qps 太小導致的并發限制案例:
[root@m7-power-k8s01 ~]# kubectl get pods -n env30 -o wide alert-engine-alert-engine-54fd454f64-clbd7 NAME READY STATUS RESTARTS AGE IP NODE alert-engine-alert-engine-54fd454f64-clbd7 0/3 ImagePullBackOff 0 59m 172.30.208.111 m7-power-k8s03 [root@m7-power-k8s01 ~]# kubectl describe pods -n env30 alert-engine-alert-engine-54fd454f64-clbd7 | tail -3 Warning Failed 44m (x2 over 46m) kubelet, m7-power-k8s03 Failed to pull image "172.27.129.211:35000/filebeat-with-module:6.0.0": pull QPS exceeded. Normal BackOff 5m (x83 over 51m) kubelet, m7-power-k8s03 Back-off pulling image "172.27.129.211:35000/filebeat-with-module:6.0.0" Normal Pulling 36s (x13 over 51m) kubelet, m7-power-k8s03 pulling image "172.27.129.211:35000/filebeat-with-module:6.0.0"
Pod 一直處于 ImageInspectError 狀態
現象:
-
啟動 Pod 失敗,kubectl get pods 顯示的 STATUS 為 "ImageInspectError"
[root@m7-devops-128071 gitlab]# kubectl get pods --all-namespaces|grep Inspect fangrong pms-558b58dfbd-fpjzl 0/1 ImageInspectError 0 13h prophet-resource-automl pas-08a7e677-5c4e-4e2d-992f-7d93cd0f05d5-automl-544ff774b7xgh88 0/1 ImageInspectError 0 13h prophet-resource-automl pas-1ccab6a2-0415-4542-8ccf-348dd28451c4-automl-6c6bd6f4644sqpw 0/1 ImageInspectError 0 13h qatest312 pms-b97bc97fc-5djfl 0/1 ImageInspectError 0 6h
-
kubectl describe pod 顯示,ImageInspectError 的原因為 readlink /mnt/disk0/docker/data/overlay2: invalid argument:
[root@m7-devops-128071 gitlab]# kubectl describe pods -n fangrong pms-558b58dfbd-fpjzl|tail -2 Warning FailedSync 1h (x522 over 13h) kubelet, m7-devops-128107 Error syncing pod Warning InspectFailed 3m (x590 over 13h) kubelet, m7-devops-128107 Failed to inspect image "docker02:35000/env/develop/prophet/app/pms.tar:develop-175": rpc error: code = Unknown desc = Error response from daemon: readlink /mnt/disk0/docker/data/overlay2: invalid argument
-
打開 dockerd 的 debug 日志級別,查看對應的日志顯示 在 readlink /mnt/disk0/docker/data/overlay2 出現了 os.PathError 錯誤:
13 06:00:04 m7-devops-128107 dockerd[34157]: time="2018-08-13T06:00:04.061634901+08:00" level=debug msg="FIXME: Got an API for which error does not match any expected type!!!: readlink /mnt/disk0/docker/data/overlay2: invalid argument" error_type="*os.PathError" module=api 8月 13 06:00:04 m7-devops-128107 dockerd[34157]: time="2018-08-13T06:00:04.061670830+08:00" level=error msg="Handler for GET /v1.31/images/docker02:35000/grafana/grafana-enhanced:5.2.0/json returned error: readlink /mnt/disk0/docker/data/overlay2: invalid argument" 8月 13 06:00:04 m7-devops-128107 dockerd[34157]: time="2018-08-13T06:00:04.061704408+08:00" level=debug msg="FIXME: Got an API for which error does not match any expected type!!!: readlink /mnt/disk0/docker/data/overlay2: invalid argument" error_type="*os.PathError" module=api
原因:
- 節點上 docker 鏡像文件損壞,當使用它啟動容器后,容器文件系統錯誤,進而導致系統調用 readlink() 返回 os.PathError 錯誤;
- dockerd 不能正確處理這個 Error https://github.com/allencloud/docker/blob/master/api/server/httputils/errors.go#L65,所以提示 FIXME: Got an API for which error does not match any expected type!!!
- image 文件損壞可能與重啟服務器導致的文件系統不完整有關,可以使用 fsck 命令修復文件系統;
驗證節點上鏡像文件損壞的步驟:
-
在該節點上使用 image 起容器,結果啟動失?。?/p>
[root@m7-devops-128107 ~]# docker run -it docker02:35000/env/develop/prophet/app/pms.tar:develop-175 sh docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown. [root@m7-devops-128107 ~]#
-
或者,導出 image 鏡像失敗,提示文件完整性校驗出錯:
[root@m7-devops-128107 ~]# docker save docker02:35000/env/develop/prophet/app/pms.tar:develop-175 -o pms.img Error response from daemon: file integrity checksum failed for "etc/anacrontab"
解決方案:
-
刪除節點上所有使用損壞 image 的容器,否則不能刪除 image:
[root@m7-devops-128107 ~]# docker ps -a|grep pms.tar ecdad07d835b docker02:35000/env/develop/prophet/app/pms.tar:develop-175 "/bin/bash /opt/work…" About a minute ago Created competent_meninsky f9c805e91ac7 docker02:35000/env/develop/prophet/app/pms.tar:develop-175 "/bin/bash /opt/work…" 2 minutes ago Created hopeful_stonebraker 63b6a12efc3e docker02:35000/env/develop/prophet/app/pms.tar:develop-175 "/bin/bash /opt/work…" 8 minutes ago Created confident_wright [root@m7-devops-128107 ~]# docker rm ecdad07d835b # 刪除所有使用損壞的 pms.tar 鏡像的容器 ecdad07d835b [root@m7-devops-128107 ~]# docker rm f9c805e91ac7 f9c805e91ac7 [root@m7-devops-128107 ~]# docker rm 63b6a12efc3e 63b6a12efc3
-
刪除節點上損壞的 image (必須要有 Deleted: sha256 開頭的輸出結果,才表明實際刪除了 image layer 文件,否則需要刪除使用它的容器后再刪除 image):
[root@m7-devops-128107 ~]# docker rmi docker02:35000/env/develop/prophet/app/pms.tar:develop-175
-
重新拉取 image 文件:
[root@m7-devops-128107 ~]# docker pull docker02:35000/env/develop/prophet/app/pms.tar:develop-175
參考:
- https://github.com/allencloud/docker/blob/master/api/server/httputils/errors.go#L65
- https://github.com/kubernetes/kubernetes/issues/63612
Pod 一直處于 CrashLoopBackOff 狀態
CrashLoopBackOff 狀態說明容器曾經啟動了,但又異常退出了。此時 Pod 的 RestartCounts 通常是大于 0 的,可以先查看一下容器的日志:
kubectl describe pod <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> [-c container_name]
kubectl logs --previous <pod-name> -n <namespace> [-c container_name]
從 describe pod 的 State、Last State 里,以及容器日志可以發現一些容器退出的原因,比如:
- 容器進程退出,如域名解析失敗、連接數據庫失?。?/li>
- 健康檢查失敗退出
- OOMKilled
- 鏡像文件損壞
$ kubectl describe pod mypod
...
Containers:
sh:
Container ID: docker://3f7a2ee0e7e0e16c22090a25f9b6e42b5c06ec049405bc34d3aa183060eb4906
Image: alpine
Image ID: docker-pullable://alpine@sha256:7b848083f93822dd21b0a2f14a110bd99f6efb4b838d499df6d04a49d0debf8b
Port: <none>
Host Port: <none>
State: Terminated
Reason: OOMKilled
Exit Code: 2
Last State: Terminated
Reason: OOMKilled
Exit Code: 2
Ready: False
Restart Count: 3
Limits:
cpu: 1
memory: 1G
Requests:
cpu: 100m
memory: 500M
...
如果此時如果還未發現線索,還可以到容器內執行命令來進一步查看退出原因:
$ kubectl exec cassandra -- cat /var/log/cassandra/system.log
如果還是沒有線索,那就需要 SSH 登錄該 Pod 所在的 Node 上,查看 Kubelet 或者 Docker 的日志進一步排查了:
# Query Node
kubectl get pod <pod-name> -o wide
# SSH to Node
ssh <username>@<node-name>
# Query kubelet log
journalctl -u kubelet
# Query docker log
journalctl -u docker
案例:
- Pod 啟動失敗,kubectl get pods 顯示狀態為 CrashLoopBackOff,kubectl describe pods 顯示錯誤信息:read-only file system error
現象:
-
Pod 啟動失敗,kubectl get pods 顯示狀態為 CrashLoopBackOff:
[root@m7-devops-128071 gitlab]# kubectl get pods --all-namespaces -o wide|grep 128123|grep -v Running|grep pas prophet-resource-qa312 pas-7e9f06b0-6f42-4c40-b9a9-eb3471ee824b-predictor-7789d7bjqzdw 0/2 CrashLoopBackOff 5 3m 172.30.37.27 m7-devops-128123 prophet-resource-qa312 pas-c7917262-fd06-4f98-86bf-96bf3813e5ec-predictor-765c577zp6jl 0/2 CrashLoopBackOff 4 3m 172.30.37.16 m7-devops-128123 prophet-resource-qa312 pas-d12af6cb-3659-48b3-b2d7-f34fc9536c23-online-dataload-7455d7 0/1 ImagePullBackOff 0 14m 172.30.37.29 m7-devops-128123
-
kubectl describe pods 顯示 mkdir 時返回 read-only file system error:
E0813 14:55:53.024865 3777 remote_runtime.go:209] StartContainer "d41d314a85af6eb8c7e5e" from runtime service failed: rpc error: code = Unknown desc = failed to start container "d41d314a85af6eb8c7e5ec38ff89": Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"rootfs_linux.go:58: mounting \\\"/mnt/disk0/k8s/kubelet/pods/ea9035f3-9ec5-11e8-af9c-0cc47adb93d8/volumes/kubernetes.io~empty-dir/log-entry--predictor--1\\\" to rootfs \\\"/mnt/disk0/docker/data/overlay2/962a78785442dc45bdf95e/merged\\\" at \\\"/mnt/disk0/docker/data/overlay2/962a78785442dc45b0f5/merged/collect/predictor/root/predictor/logs/predictor\\\" caused \\\"mkdir /mnt/disk0/docker/data/overlay2/962a78785442dc495e/merged/collect/predictor/root/predictor/logs/predictor: read-only file system\\\"\"": unknown
原因:
- 節點本地 docker image 文件損壞,當使用它啟動容器后,容器文件系統錯誤,進而導致被只讀掛載(ro);
- 或者,docker pull image 時出錯(提示 error pulling image configuration: unknown blob),導致掛載時文件系統錯誤;
解決方案:
- 刪除節點上所有使用損壞 image 的容器,然后刪除 image,再重新 pull image;
- 確認 registry 中的 image 文件是否完整,不完整時重新 push image;
Pod 一直處于 Error 狀態
通常處于 Error 狀態說明 Pod 啟動過程中發生了錯誤。常見的原因包括:
- 依賴的 ConfigMap、Secret 或者 PV 等不存在
- 請求的資源超過了管理員設置的限制,比如超過了 LimitRange 等
- 違反集群的安全策略,比如違反了 PodSecurityPolicy 等
- 容器無權操作集群內的資源,比如開啟 RBAC 后,需要為 ServiceAccount 配置角色綁定
Pod 一直處于 Terminating 或 Unknown 狀態
正常情況下,如果刪除了 Pod,經過一個 grace period(默認 30s)后,如果 Pod 還在 Running,則 kublet 會向 docker 發送 kill 命令,進而 docker 向 Pod 中的所有進程發送 SIGKILL 信號,強行刪除 Pod。所以,如果節點工作正常,一般一個 grace period 后,Pod 會被清除。
如果節點失聯 NotReady,默認 5min 后,node controller 開始驅逐它上面的 Pods,即將該 Node 上的 Pod 標記為 Terminating 狀態,然后在其它節點上再起 Pod。從 v1.5 開始,node controller 不再從 etcd 中強行刪除(force delete)失聯 Node 上的 Pod 信息,而是等待節點恢復連接后,確認驅逐的 Pod 都已經 Terminating 后才刪除這些 Pods。所以,這一段時間內,Pod 可能有多副本運行的情況。想要刪除 NotReady 節點上的 Terminating 或 Unknown 狀態 Pod 的方法:
- 從集群中刪除該 Node:kubectl delete node <node-name>
- Node 恢復正常。Kubelet 會重新跟 kube-apiserver 通信確認這些 Pod 的期待狀態,進而再刪除這些 Pod。
- 用戶強制刪除。用戶可以執行 kubectl delete pods <pod> --grace-period=0 --force 強制刪除 Pod。除非明確知道 Pod 的確處于停止狀態(比如 Node 所在 VM 或物理機已經關機),否則不建議使用該方法。特別是 StatefulSet 管理的 Pod,強制刪除容易導致腦裂或者數據丟失等問題。
處于 Terminating 狀態的 Pod 在 Kubelet 恢復正常運行后一般會自動刪除。但有時也會出現無法刪除的情況,并且通過 kubectl delete pods <pod> --grace-period=0 --force 也無法強制刪除。此時一般是由于 finalizers 導致的,通過 kubectl edit 將 finalizers 刪除即可解決。
``` bash
"finalizers": [
"foregroundDeletion"
]
```
另一種導致刪除的 Pod 一直處于 Terminating 狀態的原因:Pod 業務容器和 Sandbox 都被正常刪除,但是 kubelet 在 umount Pod 掛載的目錄時一直失敗,提示 device or resource busy,進而導致 Pod 的狀態一直是 Terminating:
9月 22 20:04:07 ee-test kubelet[3583]: E0922 20:04:07.711666 3583 nestedpendingoperations.go:264] Operation for "\"kubernetes.io/configmap/c74b89dd-be53-11e8-a1f4-525400f721a0-filebeat-config\" (\"c74b89dd-be53-11e8-a1f4-525400f721a0\")" failed. No retries permitted until 2018-09-22 20:04:08.711632504 +0800 CST (durationBeforeRetry 1s). Error: error cleaning subPath mounts for volume "filebeat-config" (UniqueName: "kubernetes.io/configmap/c74b89dd-be53-11e8-a1f4-525400f721a0-filebeat-config") pod "c74b89dd-be53-11e8-a1f4-525400f721a0" (UID: "c74b89dd-be53-11e8-a1f4-525400f721a0") : error deleting /mnt/disk01/k8s/lib/kubelet/pods/c74b89dd-be53-11e8-a1f4-525400f721a0/volume-subpaths/filebeat-config/filebeat/1: remove /mnt/disk01/k8s/lib/kubelet/pods/c74b89dd-be53-11e8-a1f4-525400f721a0/volume-subpaths/filebeat-config/filebeat/1: device or resource busy
原因:
- CentOS 3.10 內核以及 17.12.1 以前版本的 docker 在 umount 時可能會出現 device busy 情況;
解決方案:
- 升級 docker-ce 到 17.12.1 及以上版本;
- 升級操作系統內核到 4.4.x;
參考:
Pod 狀態長時間(小時級別)不更新,一直處于 Creating、Terminating 狀態
現象:
- 創建、刪除或重建 Pod 后,等待很長時間(小時級別),kubectl get pods 顯示 Pod 的 Status 一直是 Creating、Terminating 狀態,進而導致 Service 長時間不可用;
- 在 Pod 調度到的節點上,執行 docker ps |grep xxx 命令,可以看到 Creating 的 Pod 容器已實際 Running 一段時間了;
原因:
- kubelet 周期(1s)向 docker 查詢各容器的狀態、配置參數、image 是否存在、image 版本等信息;
- kubelet 將查詢的結果發給 kube-apiserver,以更新 Pod 的狀態,這個發送過程受多個 QPS 參數控制;
- kubelet 的 QPS 配置參數: --event-qps 、--kube-api-qps、--event-burst、--kube-api-burst 默認值分別為 5、5、10、10 ;
- 當節點 Pod 數目過多(200+),Pod 狀態更新時間非常頻繁時,kubelet 的默認 QPS 值成為瓶頸,導致 Pod 狀態不能及時更新到 kube-apiserver。查看 Pod 的 Status時, 一直處于 Creating、Terminating 狀態,進而導致 Service 長時間不可用;
解決辦法:
-
調大 kubelet 的 QPS 配置參數:
--event-qps=0 --kube-api-qps=2000 --kube-api-burst=4000 --registry-qps=0
參考:
Pod 行為異常
這里所說的行為異常是指 Pod 沒有按預期的行為執行,比如沒有運行 podSpec 里面設置的命令行參數。這一般是 podSpec yaml 文件內容有誤,可以嘗試使用 --validate 參數重建容器,比如:
kubectl delete pod mypod
kubectl create --validate -f mypod.yaml
也可以查看創建后的 podSpec 是否是對的,比如
kubectl get pod mypod -o yaml
修改靜態 Pod 的 Manifest 后未自動重建
Kubelet 使用 inotify 機制檢測 /etc/kubernetes/manifests 目錄(可通過 Kubelet 的 --pod-manifest-path 選項指定)中靜態 Pod 的變化,并在文件發生變化后重新創建相應的 Pod。但有時也會發生修改靜態 Pod 的 Manifest 后未自動創建新 Pod 的情景,此時一個簡單的修復方法是重啟 Kubelet。