前言
按照筆者的教程,大家應該都能夠比較順暢的完成k8s叢集的部署,不過由於環境、配置以及對Linux、k8s的不瞭解會導致很多問題、異常和故障,這裡筆者分享一些處理技巧和思路,以及部分常見的問題,以供大家參考和學習。
總之,出現問題不要慌,先根據異常、故障症狀初步推敲問題的所在,然後結合相關命令、工具、日誌推敲出具體問題。其中,具體的日誌內容是關鍵,請務必獲得相關異常的詳細日誌進行診斷,而不是被表象所迷惑,或者根據表象問題(比如“XXXX”pod崩潰了)去猜、搜尋或者請教他人。總體上,思路如下圖所示:
如果問題實在無法解決或者無法確定是哪裡的配置以及操作不當引起的,可以試著重置節點以及重置叢集。
如果出現問題,我們應該怎麼去分析和解決問題呢?下面,筆者將分享一些思路和經驗:
目錄
健康狀態檢查——初診
-
元件、外掛健康狀態檢查
-
Kubernetes 元件異常分析
-
節點健康狀態檢查
-
Pod健康狀態檢查
健康狀態檢查——初診
首先,我們需要根據表象進行初步診斷,以便沿著線索按圖索驥。
元件、外掛健康狀態檢查
使用命令:
kubectl get componentstatus
或
kubectl get cs
健康情況下如下圖所示:
Kubernetes元件(外掛)部分預設基於systemd執行,比如kubelet、docker等,我們需要使用以下命令確保其處於活動(active)狀態:
systemctl status kubelet docker
而大部分的Kubernetes的元件則執行在名稱空間為“kube-system”的靜態Pod 之中(參見“kubeadm init”一節),我們可以使用以下命令來檢視這些Pod 的狀態:
kubectl get pods -o wide -n kube-system
Kubernetes 元件異常分析
k8s元件主要分為Master元件和節點元件,Master元件對叢集做出全域性性決策(比如排程), 以及檢測和響應叢集事件。如果Master元件出現問題,可能會導致叢集不可訪問,Kubernetes API 訪問出錯,各種控制器無法工作等等。而節點元件在每個節點上執行,維護執行的Pod並提供 Kubernetes執行時環境。如果節點元件出現問題,可能會導致該節點異常並且該節點Pod無法正常執行和結束。
因此,根據不同的元件,可能會出現不同的異常。
kube-apiserver對外暴露了Kubernetes API,如果kube-apiserver出現異常可能會導致:
-
叢集無法訪問,無法註冊新的節點
-
資源(Deployment、Service等)無法建立、更新和刪除
-
現有的不依賴Kubernetes API的pods和services可以繼續正常工作
etcd用於Kubernetes的後端儲存,所有的叢集資料都存在這裡。保持穩定的etcd叢集對於Kubernetes叢集的穩定性至關重要。因此,我們需要在專用計算機或隔離環境上執行etcd叢集以確保資源需求。當etcd出現異常時可能會導致:
-
kube-apiserver無法讀寫叢集狀態,apiserver無法啟動
-
Kubernetes API訪問出錯
-
kubectl操作異常
-
kubelet無法訪問apiserver,僅能繼續執行已有的Pod
kube-controller-manager和kube-scheduler分別用於控制器管理和Pod 的排程,如果他們出現問題,則可能導致:
-
相關控制器無法工作
-
資源(Deployment、Service等)無法正常工作
-
無法註冊新的節點
-
Pod無法排程,一直處於Pending狀態
kubelet是主要的節點代理,如果節點當機(VM關機)或者kubelet出現異常(比如無法啟動),那麼可能會導致:
-
該節點上的Pod無法正常執行,如果節點關機,則當前節點上所有Pod都將停止執行
-
已執行的Pod無法伸縮,也無法正常終止
-
無法啟動新的Pod
-
節點會標識為不健康狀態
-
副本控制器會在其它的節點上啟動新的Pod
-
Kubelet有可能會刪掉當前執行的Pod
CoreDNS(在1.11以及以上版本的Kubernetes中,CoreDNS是預設的DNS伺服器)是k8s叢集預設的DNS伺服器,如果其出現問題則可能導致:
-
無法註冊新的節點
-
叢集網路出現問題
-
Pod無法解析域名
kube-proxy是Kubernetes在每個節點上執行網路代理。如果它出現了異常,則可能導致:
-
該節點Pod通訊異常
節點健康狀態檢查
我們可以使用以下命令來檢查節點狀態:
kubectl get nodes
其中,“Ready”表示節點已就緒,為正常狀態,反之則該節點出現異常。節點出現問題,則Pod無法無法排程到該節點。
Pod健康狀態檢查
如果是叢集應用出現異常,我們需要檢查相關Pod是否執行正常,可以使用以下命令:
kubectl get pods -o wide
如果存在名稱空間,需要使用-n引數指定名稱空間。如上圖所示,Pod為“Running”狀態才是正常。
如果Pod執行正常,但是又無法訪問(叢集內部、外部),這時,我們需要檢查Service是否正常,可使用以下命令:
kubectl get svc -o wide