在使用kuboard學習k8s的時候,突然發現資源不能調度。如下所示:
出現了這個問題真是百思不得其解。
按照問題解決辦法。逐步檢查可能的問題:
確認 metrics-server 是否正常運行
Metrics server 是 Kubernetes 中的一個重要組件,但是卻不是內置組件。Kubernetes 許多特性都依賴於 metrics server,
kubectl top nodes / kubectl top pods 指令,查看節點/容器組的資源利用率;
Kuboard 集羣概覽頁顯示節點資源利用率;
HPA 水平自動伸縮,依據節點/容器組資源利用率情況自動執行水平伸縮;
當 metrcis-server 出現異常時,相關依賴組件都會受到影響,例如:
在安裝了kubectl的客戶端或者master節點上檢查:
# kubectl top nodes
Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io)
進入容器檢查metrics-server狀態
狀態顯示無異常。進入日誌查看
也無異常輸出
基本斷定 metrics-server無異常
確認 ApiService 是否正常
出現這個錯誤,是因爲的 Kubernetes ApiServer 不能訪問到 metrics-server,通常可能是因爲如下幾類原因:
使用二進制安裝方式安裝 Kubernetes 集羣,但是未在 Master 節點上啓用 kube-proxy 組件;
master 節點與 metrics-server 所在的 worker 節點之間有防火牆,或者不在同一個安全組;
具體 URL 請從您自己實際得到的消息提示中獲得
curl -ik https://10.96.106.114:443/apis/metrics.k8s.io/v1beta1
首選確認kube-proxy節點狀態
發現kube-proxy都是正常的,但是calico-node有一個沒有處於ready狀態
說明calico一個容器可能存在問題,由此導致網絡不通。
Calico是Kubernetes生態系統中另一種流行的網絡選擇。雖然Flannel被公認爲是最簡單的選擇,但Calico以其性能、靈活性而聞名。Calico的功能更爲全面,不僅提供主機和pod之間的網絡連接,還涉及網絡安全和管理。Calico CNI插件在CNI框架內封裝了Calico的功能。
儘管部署Calico所需的操作看起來相當簡單,但它創建的網絡環境同時具有簡單和複雜的屬性。與Flannel不同,Calico不使用overlay網絡。相反,Calico配置第3層網絡,該網絡使用BGP路由協議在主機之間路由數據包。這意味着在主機之間移動時,不需要將數據包包裝在額外的封裝層中。BGP路由機制可以本地引導數據包,而無需額外在流量層中打包流量。
檢查caclico
在kubeboard中,可以看到cailco-node少部署了一個副本
下面可以看到日誌
說明calico存在問題
檢查各個節點的iptables,防火牆等,發現一個節點selinux處於enable狀態
關閉selinux後,重啓該節點
caico組件故障排查
在關閉節點selinux並重啓後,也嘗試多次將容器重啓,但是故障依舊。
進入容器後,可以看到pod報錯信息
Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 172.18.0.1
然後開始通過kubectl logs -f pod calico-node-fg6bn及kubectl describe pod calico-node-fg6bn進行查看日誌輸出,發現信息如下:
Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 172.18.0.1
然後再github上找到相關描述信息https://github.com/projectcalico/calico/issues/2561
計是calico綁定網卡時,沒有綁定到主機上用於羣集通信的網卡(ens33),而是綁定到了lo、virbr*等這樣的網卡上。
解決辦法的話,就是調整calicao 網絡插件的網卡發現機制,修改 IP_AUTODETECTION_METHOD 對應的value值。官方提供的yaml文件中,ip識別策略(IPDETECTMETHOD)沒有配置,即默認爲first-found,這可能會導致一個網絡異常的ip作爲nodeIP被註冊,從而影響 node-to-node mesh 。我們可以修改成 can-reach 或者 interface 的策略,嘗試連接某一個Ready的node的IP,以此選擇出正確的IP。
修改calico配置文件
kubectl get daemonset -n kube-system #獲取daemonset資源名稱
$ kubectl edit daemonset calico-node -n kube-system # 編輯calico資源對象
進入後在末行模式下搜索:name: CLUSTER_TYPE
,定位到name: CLUSTER_TYPE位置後,添加以下兩行配置:
- name: IP_AUTODETECTION_METHOD
value: "interface=ens192" # 指定用於k8s集羣中節點之間通信的網卡名稱,我這裏是ens192
#上面的value值,支持通配符,可以寫成ens*,但不建議這麼寫,尤其是多網卡主機,最好只寫用於羣集通信的就行
#修改後的部分配置如下:
............... # 省略部分內容
- name: CLUSTER_TYPE
value: k8s,bgp
- name: IP_AUTODETECTION_METHOD
value: "interface=ens33"
- name: IP
value: autodetect
- name: CALICO_IPV4POOL_IPIP
value: Always
- name: FELIX_IPINIPMTU
............... # 省略部分內容
修改後保存退出,執行指令watch kubectl get pods -A -o wide即可動態觀察calico相關的pod重啓過程,直至所有pod全部Running,並且READY列爲1/1,如下:
至此問題解決
關於calico的wiki詳細見:
https://docs.projectcalico.org/about/about-networking
關於kuboard見:
https://kuboard.cn/install/install-dashboard.html
問題解決參考: