kavin

一文弄懂pod Evicted的状态究竟是何人所为

kavin 运维技术 2022-11-16 496浏览 0

一文弄懂pod Evicted的状态究竟是何人所为

背景

今天发现好多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这种问题的方法,也欢迎后台回复,一起交流。

继续浏览有关 系统运维 的文章
发表评论