1: 高版本docker與老版本Linux內核不兼容,導致內存泄漏
詳細描述:
高版本docker與老版本Linux內核不兼容,導致內存泄漏
容器集羣中某個計算節點ICMP ping失敗,上線查看機器已經宕機,重啓後查看內核日誌
出現:SLUB: Unable to allocate memory on node -1
重啓後機器不斷打出改log。但free查看內存,發現內存有空閒
解題思路:
無
原因分析:
參見網址:https://github.com/moby/moby/issues/27576
新版docker啓用Linux CGroup memory這個feature,但這個feature在kernel 4.0以下版本中是非穩定版本(經過實踐,即使是kernel 4.2也不靠譜),會導致內存泄露。
解決步驟:
將升級內核到4.9,問題即可解決
2: 默認容器文件系統採用device mapper,導致硬盤空間頻繁被佔滿
詳細描述:
默認容器文件系統採用device mapper,導致硬盤空間頻繁被佔滿
現象:磁盤空間告警,提示根目 錄/、/var/lib/docker、/var/lib/kubelet、/var/lib/docker/devicemapper的磁盤空間已經超過80%
解題思路:
無
原因分析:
由於內核升級等原因,docker默認採用的文件系統由aufs變成了devicemapper,而devicemapper所佔用的空間比較多。
查看 #cat /proc/filesysytems | grep aufs # cat /proc/filesystems | grep overlay
顯示輸出 overlay
而且devicemapper的優先級高於overlay,因此docker最終選擇devicemapper作爲文件系統
解決步驟:
將docker文件系統改爲佔用硬盤空間較少的overlay2
修改docker啓動配置/etc/default/docker,修改docker配置文件中DOCKER_OPTS增加:
-s overlay2
刪除docker文件,並重啓docker和kubelet
service docker stop
service kubelet stop
rm /var/lib/docker -rf
service docker start
/opt/paas-deploy/script/node-start.sh
備註: 若不清除舊文件,則docker daemon啓動後將無響應
3: Eviction Policy 逐出kube-proxy,導致服務無法訪問; 發現節點上kube-proxy進程全部沒有
詳細描述:
Eviction Policy 逐出kube-proxy,導致服務無法訪問; 發現節點上kube-proxy進程全部沒有
解題思路:
無
原因分析:
由於節點kube-proxy是以static pod的方式部署,因此出問題後首現查看kubelet的日誌:
eviction manager: must evict pod(s) to reclaim imagefs
顯然問題發生時,imagefs滿了,爲了回收硬盤空間,kubelet的Eviction Policy將kube-proxy逐出,導致無法通過service的external IP/port訪問容器
爲了提高運維自動化程度,kubelet配置了Eviction Policy,當硬盤空閒率低於一定百分比則自動開始逐出容器,並清理容器和鏡像所佔存儲空間。如下:
--eviction-hard=memory.available<5%,nodefs.available<25%,imagefs.available<25% --eviction-minimum- reclaim=memory.available=0Mi,nodefs.available=5%,imagefs.available=5% --system-reserved=memory=768Mi
解決步驟:
臨時解決方案,暫時關閉節點的Eviction Policy
備註: eviction是無法逐出daemonset所啓動的pod。所以也可以只需將kube-proxy部署方式由static pod改爲daemonset方式部署即可 。
4: 節點open file 數消耗完,導致節點的容器網絡失效
詳細描述:
節點open file 數消耗完,導致節點的容器網絡失效;
具體表現服務域名監控返回502,用戶無法訪問服務
解題思路:
排查發現容器系統服務正常,DNS服務正常,問題不出現在容器服務的系統上
排查calico網絡,發現3個節點的calico-node處於start狀態(正常狀態是up),而這三個異常節點正是項目externallPs所綁定的節點。
查看calico-node的log發現如下信息:
Active Socket: Connection reset by peer
顯然,這三個節點的calico-node處於異常狀態。嘗試重啓calico-node,但問題並未得到解決。
原因分析:
查看節點的網絡連接,發現大量連接處於TIME_WAIT狀態。查看nofile限制,發現上限是1024(Ubuntu默認配置):
# ulimit -n
1024
解決步驟:
修改節點/etc/sercurity/limits.conf,將root 用戶的open file 數量增加到102400
root soft nofile 102400
root hard nofile 102400
* soft nofile 102400
* hard nofile 102400
* hard nproc 8192
* soft nproc 8192
5:節點hostname改動,導致節點calico網絡故障
詳細描述:
節點hostname改動,導致節點calico網絡故障;
容器啓動失敗,發現對應節點上新啓動的容器無法進行通信
檢查容器集羣網絡狀態,發現出現4個沒有見過的新的節點
# calicoctl node status
# 4個節點的hostname
AMZ-IAD12-OpsResPool-xxx-xx
AMZ-IAD12-OpsResPool-xxx-xx
AMZ-IAD12-OpsResPool-xxx-xx
AMZ-IAD12-OpsResPool-xxx-xx
.... ....
# 4個未見過的hostname
ip-xx-xx-xxx-xx.ec2.internal
ip-xx-xx-xxx-xx.ec2.internal
ip-xx-xx-xxx-xx.ec2.internal
ip-xx-xx-xxx-xx.ec2.internal
解題思路:
無
原因分析:
修改過對應節點的hostname,從AMZ-IAD12-OpsResPool-xxx-xx改成了ip-xx-xx-xxx- xx.ec2.internal格式 。至此,問題的原因明確了:
容器集羣的網絡方案是calico網絡。calico將節點的網絡信息保存於etcd數據庫(key-value)中,並使用節點的hostname作爲數據的key。當節點的hostname發生變化時,calico會將其識別爲一個新的節點。etcd中會同時存儲一個節點的兩份不同的配置,導致節點的calico網絡出現故障。
解決步驟:
當節點hostname發生變化後,集羣管理員需要重置該節點的calico網絡,步驟如下:
首先:通過calicoctl命令刪除舊的calico節點,清除etcd中該節點的信息
其次,通過kubectl 命令重啓該節點上的calico-node容器,讓節點calico網絡重置
最後,通過kubectl命令重啓該節點上所有采用容器網絡的pod
6:kubernetes node資源耗盡等方面
詳細描述:
kubernetes node資源耗盡等方面
現象: 創建Pod的時候,有個節點上一直不能分配到Pod,並且該節點上的pod有處於pengding的狀態
解題思路:
服務器系統資源不足
原因分析:
查詢該節點的狀態
kubectl describe node xxxx
從狀態可以看到以下異常信息:
status is now: NodeHasSufficientDisk
status is now: NodeHasSufficientMemory
status is now: NodeHasNoDiskPressure
status is now: NodeReady
解決步驟:
進入對應的故障node,檢查/var/lib/docker的分區資源