核心 第一原因是 df -hT 磁盘空间超过85%

起因

1 有个node节点异常(tke集群里面一台机器 pod数量超标导致)

kubectl get pod -n ilog 
NAME                                      READY   STATUS    RESTARTS   AGE
ilogdc-deployment-75757cc87d-msfzl        1/1     Running   0          2d19h
ilogres-deployment-77b4646786-gh2w5       1/1     Running   0          26d
ilogrescxlp-deployment-9b95d4bc7-6rxhr    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-6s6gp    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-f987s    1/1     Running   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-fclgn    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-h5264    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-lgcfd    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-pqq7g    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-qbgpf    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-tfq96    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-vmqx2    0/1     Evicted   0          8d
ilogrescxlp-deployment-9b95d4bc7-x6mtp    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-zcs5g    0/1     Evicted   0          2d21h
ilogrescxlp-deployment-9b95d4bc7-zt9nx    0/1     Evicted   0          2d21h
ilogrestxcb-deployment-6868959878-657lt   1/1     Running   0          41d
ilogrestxlp-deployment-77bdbff895-j9hnv   1/1     Running   0          2d19h

发现很多pod的状态为evicted。
原因

eviction,即驱赶的意思,意思是当节点出现异常时,kubernetes将有相应的机制驱赶该节点上的Pod。
多见于资源不足时导致的驱赶。

更多详情参考
kubernetes的eviction机制
解决方案

排查资源和异常原因,防止新的驱赶产生。
使用如下命令删除旧驱赶的遗留

移除了node节点 删除了所有 驱逐状态pod

kubectl get pod -n ilog | grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n ilog

清理脚本 所有命名空间 Evicted 的容器

#!/bin/bash
for ns in `kubectl get ns | awk 'NR>1{print $1}'`
do
      kubectl get pods -n ${ns} | grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n ${ns}
done

定时任务

*/5 * * * * flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &'
0 0 * * * docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2) # 每晚00:00执行
30 0 * * * docker rm `docker ps -a -q` # 每晚00:30执行
0 1 * * * docker image prune -a -f --filter "until=72h" # 每晚01:00执行
0 2 * * * ansible node -m shell -a "docker image prune -a -f --filter 'until=72h'"
0 3 * * * ansible traefik -m shell -a "cat /dev/null > /data/logs/traefik/traefik-access.log"

附图

在这里插入图片描述

查看命令

cat /proc/net/sockstat  

分析参考文章1:http://blog.chinaunix.net/uid-26971437-id-3944966.html
下面的一些参数的解释来自于网络上的两篇博文,关于博文的内容也罗列在下面:
cat /proc/net/sockstat
sockets: used:已使用的所有协议套接字总量
TCP: inuse:正在使用的TCP套接字数量。
TCP: orphan:无主,即socket fd不属于任何进程的数量;当执行close之后,引用计数为0,则socket fd属于orphan;处于Fin-wait1, fin-wait2等状态都是这种情况;但处于time-wait状态的数量(下面的tw),又不属于这个orphan的计数里面。太多的orhpan会消耗过多的资源(单个orphan为64k),为了防止ddos攻击,当内核当前的orphan数量超过了tcp_max_orphan值之后,就这个socket直接置为reset,进入closed状态。
TCP: tw:等待关闭的TCP连接数。
TCP:alloc(allocated):已分配的TCP套接字数量。
TCP:mem:当前tcp协议栈用到的内存数量,以page为单位

文章2:
http://www.linyaohong.com/blog/list/303.html

cat >tcp_alloc.sh <<-'EOF'
#!/bin/sh
for i in  /proc/* ;
do
  if [ -d $i/fd ];then
    echo $i   $(ls $i/fd -l | grep socket: |wc -l)
  fi
done
EOF

二 Evicted 深度分析

https://baijiahao.baidu.com/s?id=1712924840994472463&wfr=spider&for=pc

源码中对于 Statefulset 和 DaemonSet 会自动删除 Evicted 实例,但是对于 Deployment 不会自动删除。阅读了部分官方文档以及 issue,暂未找到官方对 Deployment Evicted 实例未删除原因给出解释。
Evicted 实例判断逻辑:

const ( podEvictedStatus = “Evicted”)// 判断如果为 Evicted 状态的实例且 Pod 中容器数为 0 时直接删除 podif strings.ToLower(status) == strings.ToLower(podEvictedStatus) && len(pod.Status.ContainerStatuses) == 0 {}2、社区有人提供通过在 kube-controller-manager 中配置 podgc controller –terminated-pod-gc-threshold 参数来自动清理:

Podgc controller flags: --terminated-pod-gc-threshold int32 Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled. (default12500)该参数配置的是保留的异常实例数,默认值为 12500,但 podgc controller 回收 pod 时使用强杀模式不支持实例的优雅退出,因此暂不考虑使用。

总结

由于在之前的公司中对于稳定性的高度重视,线上节点并未开启驱逐实例的功能,因此也不会存在 Evicted 状态的实例,当节点资源严重不足时会有告警人工介入处理,以及还会有二次调度、故障自愈等一些辅助处理措施。本次针对 Evicted 相关实例的分析,发现 k8s 与操作系统之间存在了很多联系,如果要彻底搞清楚某些机制需要对操作系统的一些原理有一定的了解。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐