<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用 K8s 部署我們的服務之後,為了觀察 Pod 是否成功,我們都會使用下面這個命令查詢 Pod 的狀態。
kubectl get pods NAME READY STATUS RESTARTS AGE my-app-5d7d978fb9-2fj5m 0/1 ContainerCreating 0 10s my-app-5d7d978fb9-dbt89 0/1 ContainerCreating 0 10s
這裡的 STATUS 代表了 Pod 的狀態,可能會遇到的狀態有下面幾個:
下面我們來看一下 Pod 的幾個錯誤狀態的原因,以及怎麼排查解決它們。
映象拉取失敗後 Pod 的狀態列位表示為 ImagePullBackOff,這個發生的情況還是很多的,原因除了我們不小心寫錯映象名字之外,還有就是常用軟體的一些官方映象都在國外,比如在docker.io 或者 quay.io 的映象倉庫上,有的時候存取速度會很慢。
下面我們自己故意製造一個映象名字寫錯的場景,看怎麼使用 kubectl 命令進行排查。比如我在 K8s 教學裡一直用的 Deployment 定義:
apiVersion: apps/v1 kind: Deployment metadata: name: my-go-app spec: replicas: 2 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app-container image: kevinyan001/kube-go-app:v0.3 resources: limits: memory: "200Mi" cpu: "50m" ports: - containerPort: 3000 volumeMounts: - name: app-storage mountPath: /tmp volumes: - name: app-storage emptyDir: {}
我們把映象的名字故意改錯,改成 v0.5,這個映象是我自己打的,確實還沒有 0.5 版本。執行kubectl apply 後,來觀察一下 Pod 的狀態。
➜ kubectl apply -f deployment.yaml deployment.apps/my-go-app configured ➜ kubectl get pods NAME READY STATUS RESTARTS AGE my-go-app-5d7d978fb9-2fj5m 1/1 Running 0 3h58m my-go-app-5d7d978fb9-dbt89 1/1 Running 0 3h58m my-go-app-6b77dbbcc5-jpgbw 0/1 ContainerCreating 0 7s ➜ kubectl get pods NAME READY STATUS RESTARTS AGE my-go-app-5d7d978fb9-2fj5m 1/1 Running 0 3h58m my-go-app-5d7d978fb9-dbt89 1/1 Running 0 3h58m my-go-app-6b77dbbcc5-jpgbw 0/1 ErrImagePull 0 14s .....// 停頓1分鐘,再檢視Pod 的狀態 ➜ kubectl get pods NAME READY STATUS RESTARTS AGE my-go-app-5d7d978fb9-2fj5m 1/1 Running 0 4h1m my-go-app-5d7d978fb9-dbt89 1/1 Running 0 4h1m my-go-app-6b77dbbcc5-jpgbw 0/1 ImagePullBackOff 0 3m11s
上面我們更新了 deployment 之後,觀察到 Pod 的狀態變化過程是:
ContainerCreating ===> ErrImagePull ===> ImagePullBackOff
首先 deployment 更新 Pod 時是捲動更新,要先把新 Pod 建立出來後能對舊版本 Pod 完成替換。接下來由於映象拉取錯誤會反饋一箇中間狀態 ErrImagePull,此時會再次嘗試拉取,如果確定映象拉取不下來後,最後反饋一個失敗的終態 ImagePullBackOff。
怎麼排查是什麼導致的拉取失敗呢?通過 kubectl describe pod {pod-name} 檢視它的事件記錄
➜ kubectl describe pod my-go-app-6b77dbbcc5-jpgbw Name: my-go-app-6b77dbbcc5-jpgbw Namespace: default Priority: 0 ... Controlled By: ReplicaSet/my-go-app-6b77dbbcc5 Containers: go-app-container: Container ID: Image: kevinyan001/kube-go-app:v0.5 Image ID: Port: 3000/TCP Host Port: 0/TCP State: Waiting Reason: ErrImagePull Ready: False ... Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m12s default-scheduler Successfully assigned default/my-go-app-6b77dbbcc5-jpgbw to docker-desktop Normal Pulling 27s (x4 over 2m12s) kubelet Pulling image "kevinyan001/kube-go-app:v0.5" Warning Failed 20s (x4 over 2m4s) kubelet Failed to pull image "kevinyan001/kube-go-app:v0.5": rpc error: code = Unknown desc = Error response from daemon: manifest for kevinyan001/kube-go-app:v0.5 not found: manifest unknown: manifest unknown Warning Failed 20s (x4 over 2m4s) kubelet Error: ErrImagePull Normal BackOff 4s (x5 over 2m4s) kubelet Back-off pulling image "kevinyan001/kube-go-app:v0.5" Warning Failed 4s (x5 over 2m4s) kubelet Error: ImagePullBackOff
Pod 事件記錄裡,清楚記錄了 Pod 從開始到最後經歷的狀態變化,以及是什麼導致狀態變化的,其中失敗事件裡清楚的給出了我們原因,就是映象找不到。
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Failed 20s (x4 over 2m4s) kubelet Failed to pull image "kevinyan001/kube-go-app:v0.5": rpc error: code = Unknown desc = Error response from daemon: manifest for kevinyan001/kube-go-app:v0.5 not found: manifest unknown: manifest unknown Warning Failed 20s (x4 over 2m4s) kubelet Error: ErrImagePull Normal BackOff 4s (x5 over 2m4s) kubelet Back-off pulling image "kevinyan001/kube-go-app:v0.5" Warning Failed 4s (x5 over 2m4s) kubelet Error: ImagePullBackOff
還有一種是網路原因,或者映象倉庫沒有許可權拒絕拉取請求,導致無法拉取成功。因為我這裡網路環境、加速器之類的好不容易都配好了,就不給大家演示這兩種情況了。
不過排查方式也是一樣,使用kubectl describe 命令檢視 Pod 的事件,並且使用 docker pull 嘗試主動的拉取一下映象試試,如果確實網路問題拉取不下來的,可以考慮翻牆,或者使用國內的加速節點。
設定加速器,可以考慮使用阿里雲的免費加速器,設定檔案在下面,需要註冊阿里雲賬號才能使用加速器
https://help.aliyun.com/product/60716.html
再來看這種錯誤,這種一般是容器裡執行的程式內部出問題導致的容器連續崩潰出現的問題。最後反饋到 Pod 狀態上是 CrashLoopBackOff 狀態。
演示容器執行中崩潰的情況有點難,不過好在我之前介紹 Go 服務自動取樣的時候,做過一個映象
以下內容參照我之前的文章:Go 服務進行自動取樣效能分析的方案設計與實現
我做了個docker 映象方便進行試驗,映象已經上傳到了Docker Hub上,大家感興趣的可以Down下來自己在電腦上快速試驗一下。
通過以下命令即可快速體驗。
docker run --name go-profile-demo -v /tmp:/tmp -p 10030:80 --rm -d kevinyan001/go-profiling
容器裡Go服務提供的路由如下
所以我們把上面的 deployment Pod 模版裡的映象換成這個 kevinyan001/go-profiling,再通過提供的路由手動製造 OOM,來故意製造容器崩潰的情況。
修改Pod 使用的容器映象
#執行 kubectl apply -f deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-go-app spec: replicas: 2 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app-container image: kevinyan001/go-profiling:latest resources: limits: memory: "200Mi" cpu: "50m"
建立個 SVC 讓Pod能接受外部流量
#執行 kubectl apply -f service.yaml apiVersion: v1 kind: Service metadata: name: app-service spec: type: NodePort selector: app: go-app ports: - name: http protocol: TCP nodePort: 30080 port: 80 targetPort: 80
程式中提供的路由如下:
存取 http://127.0.0.1:30080/1gb-slice 讓容器記憶體溢位,因為 Deployment 會重啟崩潰的 Pod,所以這裡非常考驗手速:) 估計狂點一分鐘,Deployment 就放棄治療休息會兒再重啟 Pod,這時 Pod 的狀態成功變成了:
➜ kubectl get pods NAME READY STATUS RESTARTS AGE my-go-app-598f697676-f5jfp 0/1 CrashLoopBackOff 2 (18s ago) 5m37s my-go-app-598f697676-tps7n 0/1 CrashLoopBackOff 2 (23s ago) 5m35s
這個時候我們使用 kubectl describe pod 看崩潰 Pod 的詳細資訊,會看到容器內程式返回的錯誤碼
➜ kubectl describe pod my-go-app-598f697676-tps7n Name: my-go-app-598f697676-tps7n Namespace: default Port: 3000/TCP Host Port: 0/TCP State: Running Started: Sun, 20 Mar 2022 16:09:29 +0800 Last State: Terminated Reason: Error Exit Code: 137 Started: Sun, 20 Mar 2022 16:08:56 +0800 Finished: Sun, 20 Mar 2022 16:09:05 +0800
不過要深入排查 Pod 內容器的問題,需要另一個命令 kubectl logs {pod-name} 的協助。
kubectl logs my-go-app-598f697676-tps7n
如果恰巧這個 Pod 被重啟了,查不出來任何東西,可以通過增加 — previous 引數選項,檢視之前容器的紀錄檔。
kubectl logs my-go-app-598f697676-tps7n --previous
首先宣告,這個問題研發解決不了,但是你發揮一下自己YY的能力:當群裡報警、運維@你趕緊看的時候,你來個反殺,告訴他資源不夠了趕緊擴容,是不是能裝到^_^…
扯遠了,現在回正題。叢集裡資源緊張的時候,K8s 會優先驅逐優先順序低的 Pod,被驅逐的 Pod 的狀態會是 Evicted,這個情況沒辦法在本地模擬,貼一個在公司K8s叢集遇到這種情況的截圖。
kubectl get pod 檢視Pod狀態
上圖可以看到有一個Pod 的狀態變成了 Evicted。
再來用describe 看下詳細資訊
kubectl describe pod 檢視Pod 的詳細資訊和事件記錄
不好意思,歷史久遠,上面的圖太模糊了,圖中的Message 一欄裡有給出如下資訊:
Status: Faild Reason: Evicted Message: The node wan low on resource: xxx-storage. Container xxx using xxxKi, which exceeds its request of ....
一般來說,大多數常見的部署失敗都可以使用這些命令進行排查和偵錯:
kubectl get pods
kubectl describe pod <podname>
kubectl logs <podname>
kubectl logs <podname> --previous
當然,有的時候想看 Pod 的設定資訊,還可以使用
kubectl get pod <podname> -o=yaml
驗證一下Pod的設定是不是跟我們提交上去的一樣,以及一些其他的額外資訊。
get 和 describe 這兩個命令除了能看 Pod 的狀態和資訊記錄外,也能看其他資源的狀態和資訊。
kubectl get pod|svc|deploy|sts|configmap <xxx-name> kubectl describe pod|svc|deploy|sts|configmap <xxx-name>
這些就留給大家後面自己體驗吧。為了方便大家在本地試驗,在公眾號「網管叨bi叨」回覆【k8s】能找到今天用的各種YAML的模版,感興趣的可以動手實踐起來。
以上就是kubernetes k8s常用問題排查方法的詳細內容,更多關於kubernetes k8s問題排查方法的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45