前言
本篇主要分享一些處理故障和問題絕招,比如聽診三闆斧:
1)檢視日志
2)檢視資源詳情和事件
3)檢視資源配置(YAML)
如果還是不太好分析,那就祭出神器——kubectl-debug。
最後,僅需根據問題對症下藥即可。
目錄
- 進一步診斷分析——聽診三闆斧
- 容器調測
- 對症下藥
在初診階段,我們往往隻能獲得一些表面的資訊,比如節點挂了,Pod崩潰了,網絡不通等等,這時,我們需要根據我們初診的方向和範圍使用一些工具以及結合日志進行具體的診斷。
這裡筆者推崇聽診三闆斧:
- 檢視日志
- 檢視資源詳情和事件
- 檢視資源配置
大部分情況下,想要獲得具體的病因,檢視日志是最為直接的方式,是以,我們需要學會如何檢視日志。
1.使用journalctl檢視服務日志
主流的Linux系統基本上都采用Systemd來集中管理和配置系統,如果使用的是Systemd機制,我們可以使用journalctl指令來檢視服務日志:
比如docker:
journalctl -u docker
檢視并追蹤kubelet的日志:
journalctl -u kubelet -f
2.使用“kubectl logs”檢視容器日志
我們的應用運作在Pod之中,以及k8s的一些元件,例如kube-apiserver、coredns、etcd、kube-controller-manager、kube-proxy、kube-scheduler等,也都運作在Pod之中(靜态Pod),那麼如何檢視這些元件以及應用的日志呢?這裡就要用到前面提到的“kubectl logs”指令。
文法如下所示:
kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] [options]
主要的參數說明如下表所示:
參數 | 說明 |
-f, --follow | 是否持續追蹤日志,預設為false,指定了之後會持續輸出日志。 |
-p, --previous | 輸出Pod中曾經運作過,但目前已終止的容器的日志。 |
-c, --container | 容器名稱。 |
--since | 僅傳回相對時間範圍(如5s、2m或3h)内的日志。預設傳回所有日志。 |
--since-time | 僅傳回指定時間之後的日志,預設傳回所有。隻能同時使用since和since-time中的一種。 |
--tail | 要顯示的最新的日志條數,預設為-1,顯示所有。 |
--timestamps | 輸出的日志中包含時間戳。 |
-l, --selector | 使用Label選擇器過濾 |
了解了主要的參數和說明,我們檢視幾個示例:
- 檢視Pod“mssql-58b6bff865-xdxx8”的日志
kubectl logs mssql-58b6bff865-xdxx8
- 檢視24小時内的日志
kubectl logs mssql-58b6bff865-xdxx8 --since 24h
- 根據Pod标簽檢視日志
kubectl logs -lapp=mssql
- 檢視指定命名空間下的Pod日志(注意系統元件的命名空間為“kube-system”)
kubectl logs kube-apiserver-k8s-master -f -n kube-system
檢視資源執行個體詳情
除了檢視日志之外,有時候我們需要檢視資源執行個體詳情以幫助我們解決問題。這就需要用到我們上面提到過的“kubectl describe”指令。
“kubectl describe”指令用于檢視一個或多個資源的詳細情況,包括相關資源和事件。文法如下所示:
kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)
-A,--all-namespaces | 檢視所有命名空間下的資源 |
-f, --filename | 根據資源描述檔案、目錄、Url來檢視 |
-R, --recursive | 以遞歸方式檢視-f指定的所有資源 |
--show-events | 顯示事件 |
了解了主要的參數和說明,我們通過示例來進行解說:
1.檢視節點
檢視指定節點:
kubectl describe nodes k8s-node1
檢視所有節點:
kubectl describe nodes
檢視指定節點以及事件:
kubectl describe nodes k8s-node1--show-events
注意,如果Node狀态為NotReady,通過檢視節點事件可以有助于我們排查問題。
2.檢視Pod
檢視指定Pod:
kubectl describe pods gitlab-84754bd77f-7tqcb
檢視指定檔案描述的所有資源
kubectl describe -f teamcity.yaml
檢視資源以及配置
很多應用的出錯往往都是我們的配置導緻的,那麼如何檢視已部署資源的配置呢?這就需要用到強大的“kubectl get”指令了。
“kubectl get”指令我們經常使用,在這之前我們經常用其來查詢資源,那麼如何使用它來檢視資源配置呢?我們先來看其文法:
kubectl get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags] [options]
如上述文法所示,“kubectl get”擁有強大的格式化輸出能力,支援“json”、“yaml”等,在上面的kubectl一節中我們已經講解過了,這裡我們就主要用到“-o”來檢視資源配置,具體如以下執行個體所示:
- 檢視指定Pod配置
kubectl get pods mssql-58b6bff865-xdxx8 -o yaml
- yaml奴家看不慣,想看JSON版的:
- 想看所有的:
kubectl get pods -o json
- 檢視服務配置
kubectl get svc mssql -o yaml
- 檢視部署(deployment)配置
kubectl get deployments mssql -o yaml
注意:“-o”用得好,再也不用擔心yaml不會寫了。
容器調測
有時候光看日志還沒發給出具體診斷,可能得動刀子或者進行進一步檢查調測才能論證我們的猜想。筆者推薦使用以下方案:
使用“kubectl exec”進入運作中的容器進行調測
我們可以使用“kubectl exec”進入運作中的容器進行調測。這個指令和“docker exec”很類似,具體文法如下所示:
kubectl exec (POD | TYPE/NAME) [-c CONTAINER] [flags] -- COMMAND [args...] [options]
指定容器名稱 | |
-i, --stdin | 啟用标準輸入 |
--tty , -t | 配置設定僞TTY(終端裝置) |
接下來我們結合示例說明:
- 進入容器檢視配置
kubectl exec mssql-58b6bff865-xdxx8 -- cat /etc/resolv.conf
- 進入容器配置設定終端并将标準輸入流轉到bash
kubectl exec mssql-58b6bff865-xdxx8 -it bash
如上圖所示,我們進入MSSQL資料庫的容器之後,使用sqlcmd工具執行了一個查詢。這塊操作如有疑問,請參閱資料庫容器化一節。
使用kubectl-debug工具調測容器
kubectl-debug 是一個簡單的開源的kubectl 插件, 可以幫助我們便捷地進行 Kubernetes 上的 Pod 排障診斷,背後做的事情很簡單: 在運作中的 Pod 上額外起一個新容器, 并将新容器加入到目标容器的 pid, network, user以及 ipc namespace中, 這時我們就可以在新容器中直接用 netstat, tcpdump 這些熟悉的工具來診斷和解決問題了, 而舊容器可以保持最小化, 不需要預裝任何額外的排障工具.
GitHub位址:https://github.com/aylei/kubectl-debug
安裝腳本如下(CentOS 7):
export PLUGIN_VERSION=0.1.1
# linux x86_64,下載下傳檔案
curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_linux_amd64.tar.gz
#解壓
tar -zxvf kubectl-debug.tar.gz kubectl-debug
#移動到使用者的可執行檔案目錄
sudo mv kubectl-debug /usr/local/bin/
為了調試更快更友善,我們還需安裝debug-agent DaemonSet,安裝指令如下:
kubectl apply -f https://raw.githubusercontent.com/aylei/kubectl-debug/master/scripts/agent_daemonset.yml
使用起來非常簡單,以下是常用的使用示例:
# 輸出幫助指令
kubectl debug -h
# 啟動Debug
kubectl debug (POD | NAME)
# 假如 Pod 處于 CrashLookBackoff 狀态無法連接配接, 可以複制一個完全相同的 Pod 來進行診斷
kubectl debug (POD | NAME) --fork
# 假如 Node 沒有公網 IP 或無法直接通路(防火牆等原因), 請使用 port-forward 模式
kubectl debug (POD | NAME) --port-forward --daemonset-ns=kube-system --daemonset-name=debug-agent
接下來,我們使用該工具調試一個已有Pod,如下所示:
kubectl debug teamcity-5997d4fc7f-ldt8w
執行該指令後,會自動拉取相關鏡像并建立容器開啟tty并進入容器内部,并且自帶一些常用工具。這裡我們使用nslookup指令來測試Pod内的外網域名(比如xin-lai.com)解析:
如上圖所示,這樣就不用每次為了調測網絡問題、應用問題而且安裝各種工具了,費時費力不說,有時候網絡不通就比較傷了。
對症下藥
根據“聽診”步驟,我們需要獲得具體的情報才能對症下藥。比如Pod為啥沒有排程,是資源(CPU、記憶體等)不足,還是所有節點均不滿足排程要求(比如指定了“nodeName”要求Pod強制排程到某個節點,而該節點當機)。隻有知道了具體原因,我們才能針對情況進行調整和處理,直到解決問題。
一般來說,大家遇到的Pod問題比較多,這裡筆者做個經驗總結。
- Pod一直處于Pending狀态,經診斷為資源不足
Pending一般情況下表示這個pod沒有被排程到一個節點上。通常這是因為資源不足引起的。
解決方案有:
- 添加工作節點
- 移除部分Pod以釋放資源
- 降低目前Pod的資源限制
- Pod一直處于Waiting狀态,經診斷為鏡像拉取失敗
如果一個pod卡在Waiting狀态,則表示這個pod已經調試到節點上,但是沒有運作起來。
- 檢查網絡問題,如果是網絡問題,則保障網絡通暢,可以考慮使用代理或國際網絡(部分域名在國内網絡無法通路,比如“k8s.gcr.io”)
- 如果是拉取逾時,可以考慮使用鏡像加速器(比如使用阿裡雲或騰訊雲提供的鏡像加速位址),也可以考慮适當調整逾時時間
- 嘗試使用docker pull <image>來驗證鏡像是否可以正常拉取
- Pod一直處于CrashLoopBackOff狀态,經檢查為健康檢查啟動逾時而退出
CrashLoopBackOff 狀态說明容器曾經啟動了,但又異常退出了。通常此Pod的重新開機次數是大于0的。
- 重試設定合适的健康檢查門檻值
- 優化容器性能,提高啟動速度
- 關閉健康檢查
往期内容連結
Docker+ Kubernetes已成為雲計算的主流(二十五)
容器化之後如何節省雲端成本?(二十六)
了解Kubernetes主體架構(二十七)
使用Minikube部署本地Kubernetes叢集(二十八)
使用kubectl管理k8s叢集(二十九)
使用Kubeadm建立k8s叢集之部署規劃(三十)
使用Kubeadm建立k8s叢集之節點部署(三十一)
叢集故障處理之處理思路以及健康狀态檢查(三十二)
作者:雪雁
出處:http://www.cnblogs.com/codelove/
溝通管道:程式設計交流群<85318032> 産品交流群<897857351>
如果喜歡作者的文章,請關注【麥扣聊技術】訂閱号以便第一時間獲得最新内容。本文版權歸作者和湖南心萊資訊科技有限公司共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
靜聽鳥語花香,漫賞雲卷雲舒。