背景
今天发现好多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
$kubectlgetpo-A-owide|grep-v"Running" NAMESPACENAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATES nsopaccount-service-pre-master-6db67f5cc-5nrgf0/1Evicted0103m<none>node2.pre.ayunw.cn<none><none> nsopaccount-service-pre-master-6db67f5cc-7zbrf0/1Evicted0103m<none>node2.pre.ayunw.cn<none><none> nsopaccount-service-pre-master-6db67f5cc-h78hv0/1Evicted0103m<none>node2.pre.ayunw.cn<none><none> nsopaccount-service-pre-master-6db67f5cc-jj4xx0/1Evicted0103m<none>node2.pre.ayunw.cn<none><none> nsopaccount-service-pre-master-6db67f5cc-jz4cs0/1Evicted0103m<none>node2.pre.ayunw.cn<none><none> nsopaccount-service-pre-master-6db67f5cc-km2cz0/1Evicted0103m<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,表示磁盘存在压力了。
$kubectldescribepoaccount-service-pre-master-6db67f5cc-5nrgf-nnsop ... QoSClass:Burstable Node-Selectors:<none> Tolerations:node.kubernetes.io/not-ready:NoExecuteop=Existsfor300s node.kubernetes.io/unreachable:NoExecuteop=Existsfor300s topology.kubernetes.io/env=pre:NoSchedule topology.kubernetes.io/region=bce-gz:NoSchedule topology.kubernetes.io/type=appserver:NoSchedule topology.kubernetes.io/zone:NoScheduleop=Exists Events: TypeReasonAgeFromMessage ------------------------- NormalScheduled100mdefault-schedulerSuccessfullyassignednsop/account-service-pre-master-6db67f5cc-5nrgftonode2.pre.ayunw.cn WarningEvicted100mkubelet,node2.pre.ayunw.cnThenodehadcondition:[DiskPressure].
登录node2.pre.ayunw.cn查看
[root@node2-pre-ayunw.cn~]#df-Th|egrep-v"overlay2|kubernetes|docker" FilesystemTypeSizeUsedAvailUse%Mountedon devtmpfsdevtmpfs32G032G0%/dev tmpfstmpfs32G032G0%/dev/shm tmpfstmpfs32G5.9M32G1%/run tmpfstmpfs32G032G0%/sys/fs/cgroup /dev/vda1ext450G7.9G39G17%/ /dev/vdb1xfs200G138G63G69%/data tmpfstmpfs6.3G06.3G0%/run/user/0
发现还有69%的磁盘空间,似乎也没有什么问题啊,应该磁盘空间也还很充足的。
iostat命令查看磁盘IO
[root@node2-pre-ayunw.cn~]#iostat-xk13 Linux5.10.8-1.el8.elrepo.x86_64(node2-pre-ayunw.cn)08/31/2021_x86_64_(32CPU) avg-cpu:%user%nice%system%iowait%steal%idle 1.860.001.770.030.0096.34 Devicer/sw/srkB/swkB/srrqm/swrqm/s%rrqm%wrqmr_awaitw_awaitaqu-szrareq-szwareq-szsvctm%util vda0.022.770.4022.430.002.144.5743.581.510.750.0024.118.090.380.11 vdb0.08126.813.31519.350.000.540.310.433.200.560.0740.294.100.476.01 avg-cpu:%user%nice%system%iowait%steal%idle 3.090.003.340.030.0093.54 Devicer/sw/srkB/swkB/srrqm/swrqm/s%rrqm%wrqmr_awaitw_awaitaqu-szrareq-szwareq-szsvctm%util vda0.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00 vdb0.0051.000.00168.500.000.000.000.000.000.450.020.003.300.552.80 avg-cpu:%user%nice%system%iowait%steal%idle 2.740.002.810.000.0094.45 Devicer/sw/srkB/swkB/srrqm/swrqm/s%rrqm%wrqmr_awaitw_awaitaqu-szrareq-szwareq-szsvctm%util vda0.003.000.0040.000.007.000.0070.000.000.670.000.0013.331.000.30 vdb0.0062.000.00619.500.007.000.0010.140.000.580.040.009.990.503.10
目前似乎也看不到有什么IO压力 。但是由于我手上没有监控权限,估计也是直接就没有对pod做监控。然后describe的时候看到问题发生也是7个小时之前的事情了,所以的话这边猜测可能是当时已经触发了kubelet的eviction-hard,然后磁盘已经有部分空间被回收了,而且压力可能也已经下去了。
查看node上的日志
查看节点上kubelet日志和message日志,并没有任何Evicted的日志被发现。
$tail-500kubelet.log|grep"Evicted" $tail-500/var/log/messages|grep"Evicted"
那当前情况下就只能临时先处理掉这个Evicted状态的pod了
$kubectlgetpo-nnsop--field-selector'status.phase!=Running'-ojson|kubectldelete-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.cnvol-apm-empty]#cdlogs/ [root@node2-pre-ayunw.cnlogs]#ll total4327672 -rw-r--r--1rootroot260328481Aug3109:43skywalking-api.log -rw-r--r--1rootroot314573222Aug1202:56skywalking-api.log.2021_08_12_02_56_35 -rw-r--r--1rootroot314573394Aug1315:01skywalking-api.log.2021_08_13_15_01_56 -rw-r--r--1rootroot314574277Aug1503:12skywalking-api.log.2021_08_15_03_12_26 -rw-r--r--1rootroot314574161Aug1615:21skywalking-api.log.2021_08_16_15_21_13 -rw-r--r--1rootroot314574334Aug1803:31skywalking-api.log.2021_08_18_03_31_18 -rw-r--r--1rootroot314572887Aug1915:40skywalking-api.log.2021_08_19_15_40_22 -rw-r--r--1rootroot314574238Aug2103:44skywalking-api.log.2021_08_21_03_44_28 -rw-r--r--1rootroot314574144Aug2215:49skywalking-api.log.2021_08_22_15_49_08 -rw-r--r--1rootroot314573963Aug2403:51skywalking-api.log.2021_08_24_03_51_28 -rw-r--r--1rootroot314572991Aug2515:54skywalking-api.log.2021_08_25_15_54_21 -rw-r--r--1rootroot314573321Aug2703:57skywalking-api.log.2021_08_27_03_57_11 -rw-r--r--1rootroot314572890Aug2816:01skywalking-api.log.2021_08_28_16_01_26 -rw-r--r--1rootroot314573311Aug3004:05skywalking-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./*|grepG 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
$dockerps-a|grep"321baae6-1efe-4535-8a20-0fdfa6cc3117" a69b2635ba98registry.ayunw.cn/tsp/msmessagecenter"/startApp.sh"5weeksagoUp5weeksk8s_msmessagecenter-perf-dev-v1-0-0_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0 c8f2cc0a2737874552b27b34"sh-c'set-ex;mkdi…"5weeksagoExited(0)5weeksagok8s_init-skywalking-agent_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0 c415f52e7489registry.ayunw.cn/library/k8s.gcr.io/pause:3.2"/pause"5weeksagoUp5weeksk8s_POD_msmessagecenter-perf-dev-v1-0-0-7f746b84bf-wb4g5_tsp_321baae6-1efe-4535-8a20-0fdfa6cc3117_0
等pod被完全删除后查看这个目录已经消失
$du-sh./*|grepG 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进去了
$catDockerfile FROMregistry.ayunw.cn/library/alpine:3.12.0 ENVLANG=C.UTF-8\ SKYWLKING_AGENT_VERSION=8.6.0 RUNset-eux&&mkdir-p/opt/skywalking/agent\ &&apkaddwget\ &&wgethttps://downloads.apache.org/skywalking/${SKYWLKING_AGENT_VERSION}/apache-skywalking-apm-es7-${SKYWLKING_AGENT_VERSION}.tar.gz-P/tmp/\ &&cd/tmp&&tarzxfapache-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/\ &&unsetexport\ &&rm-rf/tmp/*/opt/skywalking/agent/config/agent.config COPYagent.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中引用即可。
$catdeployment.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这种问题的方法,也欢迎后台回复,一起交流。
转载请注明:IT运维空间 » 运维技术 » 一文弄懂pod Evicted的状态究竟是何人所为
发表评论