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的分区资源