背景
某環境客戶部署了一個kubernetes集群,發現flannel的pod一直重啟,始終處於CrashLoopBackOff狀態。
排查
-
對於始終CrashLoopBackOff的pod,一般是應用本身的問題,需要查看具體pod的日志,通過
kubectl logs -f --tail -n kube-system flannel-xxx
顯示,“pod cidr not assigned”,然后flannel退出 -
檢查日志顯示的節點10.0.0.17的cidr,發現確實為空,而正常的環境卻是正常的。
- 檢查flannel的啟動參數,發現為
--kube-subnet-mgr
,–kube-subnet-mgr代表其使用kube類型的subnet-manager。該類型有別於使用etcd的local-subnet-mgr類型,使用kube類型后,flannel上各Node的IP子網分配均基於K8S Node的spec.podCIDR屬性—"contact the Kubernetes API for subnet assignment instead of etcd.
",而在第2步,我們已經發現節點的podcidr為空。
- node節點分配podCIDR,需要kube-controller-manager開啟
allocate-node-cidrs
為true,它和cluster-cidr
參數共同使用的時候,controller-manager
會為所有的Node資源分配容器IP段, 並將結果寫入到PodCIDR
字段.檢查環境kube-controller-manager的配置文件,發現問題所在。如下圖,環境設置了cluster-cidr
為192.168.2.0/24
,同時設置了node-cidr-mask-size
為24
,node-cidr-mask-size
參數,用來表示kubernetes管理集群中節點的cidr掩碼長度,默認是24位,需要從cluster-cidr
里面分配地址段,而設置的cluster-cidr
顯然無法滿足這個掩碼要求,導致kube-controller-manager為節點分配地址失敗。
后記
綜上,可以修改node-cidr-mask-size
參數為24以上的數解決node沒法分配podcidr問題,但是同時發現環境部署使用的kubernetes自動化工具分配集群的service-cluster-ip-range
也是從cluster-cidr
里面取一段,分配不滿足竟然使用了和cluster-cidr一樣的地址,造成網段沖突。最終,讓客戶重新規划了網段,修改cluster-cidr
掩碼從24位改為16位,后續flannel均啟動正常。