pod Evicted的状态究竟是何人所为

pod Evicted的状态究竟是何人所为微信公众号:运维开发故事,作者:姜总背景今天发现好多pod的状态都是Evicted,然后我没有监控的权限,本来想看看grafana上监控图是否出现了特殊情况,无奈没权限看。因为我发现pod出现大量的Evicted状态的时候,查看pod所在的node节点,距离当时发生Evicted的时间已经是7小时之久了。因此可能会存在一种原因:发生了Evicted的时候的确磁盘已经超过默认的kubelet的资源预留参数了。但是问题发生后,触发了阈值,已经回收了磁盘空间,导致我看的时候磁盘空间已经恢复。在每个K.

大家好,又见面了,我是你们的朋友全栈君。

微信公众号:运维开发故事,作者:姜总

背景

今天发现好多pod的状态都是Evicted,然后我没有监控的权限,本来想看看grafana上监控图是否出现了特殊情况,无奈没权限看。

因为我发现pod出现大量的Evicted状态的时候,查看pod所在的node节点,距离当时发生Evicted的时间已经是7小时之久了。因此可能会存在一种原因:发生了Evicted的时候的确磁盘已经超过默认的kubelet的资源预留参数了。但是问题发生后,触发了阈值,已经回收了磁盘空间,导致我看的时候磁盘空间已经恢复。

在每个 Kubernetes Node节点 上,kubelet 默认根目录是 /var/lib/kubelet 和 日志目录 /var/log 保存在节点的系统分区上,这个分区同时也会被Pod的 EmptyDir 类型的 volume、容器日志、镜像层、容器的可写层所占用。ephemeral-storage 便是对系统分区进行管理。

大量的Evicted状态的pod

$ kubectl get po -A -o wide | grep -v "Running"
NAMESPACE              NAME                                                              READY   STATUS             RESTARTS   AGE     IP              NODE                           NOMINATED NODE   READINESS GATES
nsop                   account-service-pre-master-6db67f5cc-5nrgf                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>
nsop                   account-service-pre-master-6db67f5cc-7zbrf                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>
nsop                   account-service-pre-master-6db67f5cc-h78hv                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>
nsop                   account-service-pre-master-6db67f5cc-jj4xx                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>
nsop                   account-service-pre-master-6db67f5cc-jz4cs                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>
nsop                   account-service-pre-master-6db67f5cc-km2cz                        0/1     Evicted            0          103m    <none>          node2.pre.ayunw.cn           <none>           <none>

当我们的集群中有太多被驱逐的 pod 时,这会导致网络负载。因为每个 pod 即使被驱逐是连接到网络的,并且在云 Kubernetes 集群的情况下,也会阻塞一个 IP 地址,这可能导致如果您的集群有固定的 IP 地址池,也会耗尽 IP 地址。此外,当我们有太多处于 Evicted 状态的 Pod 时,通过运行kubectl get pod命令来监控 Pod 会变得很困难,因为会存在非常多的 Evicted Pod。当然你可以通过grep等手段过滤掉Evicted状态的pod。

查看Evicted的pod的任意一个node

describe任意一个pod查看,发现Warning提示DiskPressure,表示磁盘存在压力了。

$ kubectl describe po account-service-pre-master-6db67f5cc-5nrgf -n nsop
...
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
                 topology.kubernetes.io/env=pre:NoSchedule
                 topology.kubernetes.io/region=bce-gz:NoSchedule
                 topology.kubernetes.io/type=appserver:NoSchedule
                 topology.kubernetes.io/zone:NoSchedule op=Exists
Events:
  Type     Reason     Age   From                               Message
  ----     ------     ----  ----                               -------
  Normal   Scheduled  100m  default-scheduler                  Successfully assigned nsop/account-service-pre-master-6db67f5cc-5nrgf to node2.pre.ayunw.cn
  Warning  Evicted    100m  kubelet, node2.pre.ayunw.cn        The node had condition: [DiskPressure].

登录node2.pre.ayunw.cn查看

[root@node2-pre-ayunw.cn ~]# df -Th | egrep -v "overlay2|kubernetes|docker"
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs   32G     0   32G   0% /dev
tmpfs          tmpfs      32G     0   32G   0% /dev/shm
tmpfs          tmpfs      32G  5.9M   32G   1% /run
tmpfs          tmpfs      32G     0   32G   0% /sys/fs/cgroup
/dev/vda1      ext4       50G  7.9G   39G  17% /
/dev/vdb1      xfs       200G  138G   63G  69% /data
tmpfs          tmpfs     6.3G     0  6.3G   0% /run/user/0

发现还有69%的磁盘空间,似乎也没有什么问题啊,应该磁盘空间也还很充足的。

iostat命令查看磁盘IO

[root@node2-pre-ayunw.cn ~]# iostat -xk 1 3
Linux 5.10.8-1.el8.elrepo.x86_64 (node2-pre-ayunw.cn)  08/31/2021  _x86_64_ (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.86    0.00    1.77    0.03    0.00   96.34

Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
vda              0.02    2.77      0.40     22.43     0.00     2.14   4.57  43.58    1.51    0.75   0.00    24.11     8.09   0.38   0.11
vdb              0.08  126.81      3.31    519.35     0.00     0.54   0.31   0.43    3.20    0.56   0.07    40.29     4.10   0.47   6.01

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           3.09    0.00    3.34    0.03    0.00   93.54

Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
vda              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
vdb              0.00   51.00      0.00    168.50     0.00     0.00   0.00   0.00    0.00    0.45   0.02     0.00     3.30   0.55   2.80

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           2.74    0.00    2.81    0.00    0.00   94.45

Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
vda              0.00    3.00      0.00     40.00     0.00     7.00   0.00  70.00    0.00    0.67   0.00     0.00    13.33   1.00   0.30
vdb              0.00   62.00      0.00    619.50     0.00     7.00   0.00  10.14    0.00    0.58   0.04     0.00     9.99   0.50   3.10

目前似乎也看不到有什么IO压力 。但是由于我手上没有监控权限,估计也是直接就没有对pod做监控。然后describe的时候看到问题发生也是7个小时之前的事情了,所以的话这边猜测可能是当时已经触发了kubelet的eviction-hard,然后磁盘已经有部分空间被回收了,而且压力可能也已经下去了。

查看node上的日志

查看节点上kubelet日志和message日志,并没有任何Evicted的日志被发现。

$ tail -500 kubelet.log  | grep "Evicted"
$ tail -500 /var/log/messages  | grep "Evicted"

那当前情况下就只能临时先处理掉这个Evicted状态的pod了

$ kubectl get po -n nsop  --field-selector 'status.phase!=Running' -o json| kubectl delete -f -

因为是磁盘空间的问题,所以想到去检查一下是否有持续增长的目录。最后排查发现,所有出现Evicted状态的pod所处的节点似乎都有一个共性:那就是都启用了skywalking,并且以emptyDir的形式写日志到本地临时存储中。

目前公司将默认的docker目录和kubelet目录都改到了/data目录下,上pod所在的node,到/data/目录下通过du -sh ./* | grep G命令去查看了一下有好多/data/kubernetes/kubelet/pods/xxx/volumes/kubernetes.io~empty-dir/vol-apm-empty/logs的目录下存在skywalking-api.log的日志,而且都是轮转的日志,默认没有设置日志保留时间。

skywalking-agent的配置文件中默认开启了以下几个参数:

$ egrep -v "^$|^#" agent.config
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
logging.level=${SW_LOGGING_LEVEL:INFO}
plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations}

skywalking-agent在emptyDir下的日志

[root@node2-pre-ayunw.cn vol-apm-empty]# cd logs/
[root@node2-pre-ayunw.cn logs]# ll
total 4327672
-rw-r--r-- 1 root root 260328481 Aug 31 09:43 skywalking-api.log
-rw-r--r-- 1 root root 314573222 Aug 12 02:56 skywalking-api.log.2021_08_12_02_56_35
-rw-r--r-- 1 root root 314573394 Aug 13 15:01 skywalking-api.log.2021_08_13_15_01_56
-rw-r--r-- 1 root root 314574277 Aug 15 03:12 skywalking-api.log.2021_08_15_03_12_26
-rw-r--r-- 1 root root 314574161 Aug 16 15:21 skywalking-api.log.2021_08_16_15_21_13
-rw-r--r-- 1 root root 314574334 Aug 18 03:31 skywalking-api.log.2021_08_18_03_31_18
-rw-r--r-- 1 root root 314572887 Aug 19 15:40 skywalking-api.log.2021_08_19_15_40_22
-rw-r--r-- 1 root root 314574238 Aug 21 03:44 skywalking-api.log.2021_08_21_03_44_28
-rw-r--r-- 1 root root 314574144 Aug 22 15:49 skywalking-api.log.2021_08_22_15_49_08
-rw-r--r-- 1 root root 314573963 Aug 24 03:51 skywalking-api.log.2021_08_24_03_51_28
-rw-r--r-- 1 root root 314572991 Aug 25 15:54 skywalking-api.log.2021_08_25_15_54_21
-rw-r--r-- 1 root root 314573321 Aug 27 03:57 skywalking-api.log.2021_08_27_03_57_11
-rw-r--r-- 1 root root 314572890 Aug 28 16:01 skywalking-api.log.2021_08_28_16_01_26
-rw-r--r-- 1 root root 314573311 Aug 30 04:05 skywalking-api.log.2021_08_30_04_05_34

我的docker根目录被更改过,不是默认的/var/lib/docker,而是/data/docker。我的k8s的kubelet目录也是被更改过的,在/data/kubernetes/kubelet

临时解决日志爆满的两种方法

  • 在K8s-master节点查看Evicted的pod调度在哪个节点,然后到/data/kubernetes/kubelet/pods目录下去通过du -sh 命令找到目录占用量大的pod,然后将截图指出的轮转后(就是带上时间2021_08_17这一类)的日志文件删除

  • 直接重新删除pod,其实只要是pod重启后,EmptyDir目录就会被删除掉。

操作步骤

$ cd /data/kubernetes/kubelet/pods

$ du -sh ./* | grep G
1.3G ./02c9511d-0787-49f1-8c59-0db239baee79
1.3G ./079f3ca0-810d-468d-9136-75f3d3235b2d
4.8G ./07fc67f7-d46d-4d0c-8f6c-401e14705ae1
3.0G ./091594a0-b5ac-45c2-8ad9-7dcfc91c9e55
1.8G ./130a1b35-b447-43e1-8802-eb74aefa566c
1.2G ./1b257c27-cbaf-49f8-bca3-ceadc467aad6
2.8G ./2ec50216-f81e-4e83-922d-14316762dee2
7.0G ./321baae6-1efe-4535-8a20-0fdfa6cc3117
8.0G ./46680114-11f7-47af-9ee2-347f56592924
...

我这里找到了占用7.0G大小的pod,根据目录名称找到pod名字,然后触发了这个pod的cicd,也就相当于更新了这个pod的deployment.yaml,然后apply -f重新生成了一遍这个pod

$ docker ps -a | grep "321baae6-1efe-4535-8a20-0fdfa6cc3117"
a69b2635ba98        registry.ayunw.cn/tsp/msmessagecenter                     "/startApp.sh"           5 weeks ago          Up 5 weeks                                          k8s_msmessagecenter-perf-dev-v1-0-0_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0
c8f2cc0a2737        874552b27b34                                                        "sh -c 'set -ex;mkdi…"   5 weeks ago          Exited (0) 5 weeks ago                              k8s_init-skywalking-agent_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0
c415f52e7489        registry.ayunw.cn/library/k8s.gcr.io/pause:3.2            "/pause"                 5 weeks ago          Up 5 weeks                                          k8s_POD_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0

等pod被完全删除后查看这个目录已经消失

$ du -sh ./* | grep G
1.3G ./02c9511d-0787-49f1-8c59-0db239baee79
1.3G ./079f3ca0-810d-468d-9136-75f3d3235b2d
4.8G ./07fc67f7-d46d-4d0c-8f6c-401e14705ae1
3.0G ./091594a0-b5ac-45c2-8ad9-7dcfc91c9e55
1.8G ./130a1b35-b447-43e1-8802-eb74aefa566c
1.2G ./1b257c27-cbaf-49f8-bca3-ceadc467aad6
2.8G ./2ec50216-f81e-4e83-922d-14316762dee2
8.0G ./46680114-11f7-47af-9ee2-347f56592924
...

永久解决日志保留个数方法

  • 直接在Dockerfile打镜像的时候更改参数或者提前写好配置文件然后构建镜像的时候COPY进去

我这里直接改好agent.config参数然后Dockerfile中COPY进去了

$ cat Dockerfile
FROM registry.ayunw.cn/library/alpine:3.12.0
ENV LANG=C.UTF-8 \
    SKYWLKING_AGENT_VERSION=8.6.0
RUN set -eux && mkdir -p /opt/skywalking/agent \
    && apk add wget \
    && wget https://downloads.apache.org/skywalking/${SKYWLKING_AGENT_VERSION}/apache-skywalking-apm-es7-${SKYWLKING_AGENT_VERSION}.tar.gz -P /tmp/ \
    && cd /tmp && tar zxf apache-skywalking-apm-es7-${SKYWLKING_AGENT_VERSION}.tar.gz \
    && mv /tmp/apache-skywalking-apm-bin-es7/agent/* /opt/skywalking/agent \
    && rm -f /opt/skywalking/agent/optional-plugins/apm-spring-annotation-plugin-8.6.0.jar /opt/skywalking/agent/plugins/thrift-plugin-8.6.0.jar \
    && mv /opt/skywalking/agent/plugins/thrift-plugin-8.6.0.jar /tmp/thrift-plugin-8.6.0.jar \
    && cp -r /opt/skywalking/agent/optional-plugins/* /opt/skywalking/agent/plugins/ \
    && unset export \
    && rm -rf /tmp/* /opt/skywalking/agent/config/agent.config

COPY agent.config /opt/skywalking/agent/config/

WORKDIR /

$ egrep -v "^$|^#" agent.config
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
logging.level=${SW_LOGGING_LEVEL:INFO}
plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations}
# 以下参数是我更改后的,表示日志保留个数为3个
logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:3}

其实agent.config文件中是有logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1}这一行的,但是默认被注释掉了。我这里将它打开,然后将-1改成了3。这行配置是JAVA中的写法,意思是默认是-1表示”最大历史日志文件保留个数”,而-1则表示不设置最大历史日志文件保留,也就是一直轮转,不会做日志清理。参数意思可以参考skywalking官网。

然后重新构建这个skywalking-agent镜像,在deployment中引用即可。

$ cat deployment.yaml

apiVersion: apps/v1
kind: Deployment

  dnsPolicy: ClusterFirst
  terminationGracePeriodSeconds: 10
  serviceAccountName: default
  imagePullSecrets:
    - name: registry-auth-ayunw-cn
  initContainers:
    - name: init-skywalking-agent
      image: "registry.ayunw.cn/library/skywalking-agent:33-ac402d20"
      command:
        - 'sh'
        - '-c'
        - 'set -ex;mkdir -p /skywalking/agent;cp -r /opt/skywalking/agent/* /skywalking/agent;'
      volumeMounts:
        - name: vol-apm-empty
          mountPath: /skywalking/agent
  containers:
    - name: demo-hello-pre-master
      image: "registry.ayunw.cn/paas/demo-hello:537-c87b6177"
      ...
      volumeMounts:
        - name: vol-apm-empty
          mountPath: /skywalking/agent
  volumes:
    - name: vol-apm-empty
      emptyDir: {}

其实这里的磁盘DiskPressure目前只能大概排查到skywalking导致,但没有监控的情况下并不能百分百确认就是skywalking引起,因此如果需要更精准的定位这个问题,还需要通过监控等手段去排查。如果各位有更好的解决Evicted状态的pod这种问题的方法,也欢迎后台回复,一起交流。

  

  

  

  



![图片](https://img-blog.csdnimg.cn/img_convert/11f745991f27a83222e6fc84d1c4de4a.png)


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/145319.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • contextConfigLocation 配置

    contextConfigLocation 配置web.xml通过contextConfigLocation配置spring的方式SSI框架配置文件路径问题:struts2的1个+N个路径:src+src(可配置)名称:struts.xml+Nspring的1个路径:src名称:applicationContex…

    2022年6月15日
    33
  • android加密设备,用于Android手机的加密设备和加密外部SD卡

    android加密设备,用于Android手机的加密设备和加密外部SD卡电话被盗或丢失后,隐私将被泄露.Android手机具有“加密设备”和“加密外部SD卡”功能.那么这两个功能有什么区别?加密设备加密设备后,内置SD卡上的所有数据将被加密.此部分主要用于保护和SMS的隐私.加密设备后,即使将设备重置为出厂设置也无法解密数据.加密的外部SD卡加密外部SD卡可以保护SD卡上的所有数据.这部分数据主要用于保护用户的某些图片和私人文件,并防止照片.如果未解密加…

    2022年5月16日
    41
  • Lua使用心得(2)

    在lua脚本调用中,如果我们碰到一种不好的脚本,例如:while1dodoend那我们的程序主线程也会被阻塞住。那我们如何防止这种问题呢?下面就给出一个解决的办法。首先为了不阻塞主线程,

    2021年12月25日
    53
  • BZOJ 1052 HAOI2007 覆盖问题 二分法答案+DFS

    BZOJ 1052 HAOI2007 覆盖问题 二分法答案+DFS

    2022年1月3日
    39
  • 数据库的表空间_默认表空间

    数据库的表空间_默认表空间表空间的概述数据库的表空间,简而言之就是数据库存储数据的存储结构,是一种用来存储数据的逻辑空间,是数据库用来存储数据的最大逻辑单元,其下还有段、区、数据块等逻辑数据类型。表空间的存在就是为了用来存储数据库的数据对象,一个数据库可以由多个数据表空间组成,可以通过表空间来实现对数据库的调参。表空间的分类永久性表空间:在存储过程中需要永久化存储的对象,比如二维表,视图,存储过程,索引。临时表空间:临时表…

    2025年5月26日
    0
  • 数据库优化 – SQL优化[通俗易懂]

    数据库优化 – SQL优化[通俗易懂]以实际SQL入手,带你一步一步走上SQL优化之路!

    2022年9月8日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号