云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod
Posted 云原生兴趣小组
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod相关的知识,希望对你有一定的参考价值。
一、故障演练目的
UAT 和 Sandox 环境,出于成本考虑,集群资源一直比较缺乏,导致UAT和sandbox环境多次节点不可用,产生了节点的应用驱逐行为,对于驱逐后是是否多实例应用可用性是否受影响不确定,查阅相关资料,发现官网没有明确说明,比如在 Eviction Pod 时,是否触发ProStop 钩子,所以这里我们模拟演练,观测下相关结果和状态
如果节点处于资源压力,那么kubelet就会执行驱逐策略。驱逐会考虑Pod的优先级,资源使用和资源申请。当优先级相同时,资源使用/资源申请最大的Pod会被首先驱逐。
kube-controller-manager的eviction机制是粗粒度的,即驱赶一个节点上的所有pod,而kubelet则是细粒度的,它驱赶的是节点上的某些Pod,驱赶哪些Pod与Pod的Qos机制有关。该Eviction会周期性检查本节点内存、磁盘等资源,当资源不足时,按照优先级驱逐部分pod。
驱逐阈值分为软驱逐阈值(Soft Eviction Thresholds)和强制驱逐(Hard Eviction Thresholds)两种机制,如下:
软驱逐阈值:当node的内存/磁盘空间达到一定的阈值后,kubelet不会马上回收资源,如果改善到低于阈值就不进行驱逐,若这段时间一直高于阈值就进行驱逐。
强制驱逐:强制驱逐机制则简单的多,一旦达到阈值,直接把pod从本地驱逐。
kubelet提供了以下参数控制eviction:
eviction-soft:软驱逐阈值设置,具有一系列阈值,比如memory.available<1.5Gi时,它不会立即执行pod eviction,而会等待eviction-soft-grace-period时间,假如该时间过后,依然还是达到了eviction-soft,则触发一次pod eviction。
eviction-soft-grace-period:默认为90秒,当eviction-soft时,终止Pod的grace的时间,即软驱逐宽限期,软驱逐信号与驱逐处理之间的时间差。
eviction-max-pod-grace-period:最大驱逐pod宽限期,停止信号与kill之间的时间差。
eviction-pressure-transition-period:默认为5分钟,脱离pressure condition的时间,超过阈值时,节点会被设置为memory pressure或者disk pressure,然后开启pod eviction。
eviction-minimum-reclaim:表示每一次eviction必须至少回收多少资源。
eviction-hard**:**强制驱逐设置,也具有一系列的阈值,比如memory.available<1Gi,即当节点可用内存低于1Gi时,会立即触发一次pod eviction。
二、故障演练实施
准备两个节点如下:
相应应用在两个节点,都有分布
我们计划模拟节点内存耗尽到驱逐的临界值,导致节点 node202 发生应用驱逐。
驱逐前,Node202 的资源消耗如下:
查看 Node202 驱逐条件的配置信息:systemctl status kubelet -l
● kubelet.service - kubelet
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2021-04-19 10:14:32 CST; 3 weeks 3 days ago
Process: 1787639 ExecStartPost=/bin/bash /etc/kubernetes/deny-tcp-port-10250.sh (code=exited, status=0/SUCCESS)
Main PID: 1787638 (kubelet)
Tasks: 56
Memory: 229.6M
CGroup: /system.slice/kubelet.service
└─1787638 /usr/bin/kubelet --serialize-image-pulls=false --register-schedulable=true --v=2 --cloud-provider=qcloud --fail-swap-on=false --authorization-mode=Webhook --cloud-config=/etc/kubernetes/qcloud.conf --cluster-dns=10.61.253.50 --image-pull-progress-deadline=10m0s --hostname-override=*.*.1.202 --eviction-hard=nodefs.available<10%,nodefs.inodesFree<5%,memory.available<100Mi --client-ca-file=/etc/kubernetes/cluster-ca.crt --non-masquerade-cidr=0.0.0.0/0 --kube-reserved=cpu=90m,memory=3436Mi --max-pods=253 --authentication-token-webhook=true --pod-infra-container-image=ccr.ccs.tencentyun.com/library/pause:latest --anonymous-auth=false --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --network-plugin=cni --cluster-domain=cluster.local
其中,当内存 `--eviction-hard=nodefs.available<10%,nodefs.inodesFree<5%,memory.available<100Mi` 小于100Mi时会产生驱逐操作。
我们希望验证在驱逐时:
1、是否会优雅停止容器
terminationGracePeriodSeconds: 60
,
2、是否会调用preStop脚本(比如:反向注册eureka服务)
image: xxx/smsproxy:V2.0
imagePullPolicy: Always
lifecycle:
preStop:
exec:
command:
/bin/sh
-c
' APPLICATION=SMSPROXY2; APPLICATION_PORT=9057; curl -X PUT http://eureka01-svc:9000/eureka/apps/${APPLICATION}/${MY_POD_IP}:${APPLICATION_PORT}/status?value=OUT_OF_SERVICE;
sleep 60;'
name: smsproxy
ports:
containerPort: 9057
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
mountPath: /pinpoint-agent/pinpoint.config
name: ppconfig-volume
subPath: pinpoint.config
mountPath: /pinpoint-agent/profiles/release/pinpoint-env.config
name: ppenvconfig-volume
subPath: pinpoint-env.config
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-rp5d5
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
imagePullSecrets:
name: harbor-secret
nodeName: *.*.1.202
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 60
tolerations:
反注册到Eureka上不容易精准观测,为便于观测是否preStop在驱逐时是否被触发了,我们修改proStop中的URL请求到一个可观测的日志上去如下:
curl -X PUT http://eureka01-svc:9000/eureka/apps/${APPLICATION}/${MY_POD_IP}:${APPLICATION_PORT}/status?value=OUT_OF_SERVICE; \
curl -X GET https://xxxx.com/gw/hello?prestop=itworking \
如果观测到,相应时间的日志如下,即可证明驱逐时也会触发preStop钩子。
使用chaosBlade 模拟内存耗尽:
blade c mem load --mode ram --mem-percent 100
# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
172.19.1.202 2162m 27% 61496Mi 101%
172.19.133.177 7375m 93% 60356Mi 99%
# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
172.19.1.202 272m 3% 693Mi 1%
172.19.133.177 7995m 101% 60704Mi 100%
三、结论
1、”Kubelet的eviction Pod 时,会触发proStop钩子“
2、Hard Eviction 没有 grace period, Soft Eviction 会等待 Grace Period.
以上是关于云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod的主要内容,如果未能解决你的问题,请参考以下文章
云原生背景下故障演练体系建设的思考与实践—云原生混沌工程系列之指南篇