云原生故障演练 - 实例驱逐异常下 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。


二、故障演练实施


准备两个节点如下:

云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod


相应应用在两个节点,都有分布


云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod


我们计划模拟节点内存耗尽到驱逐的临界值,导致节点 node202 发生应用驱逐。

驱逐前,Node202 的资源消耗如下:

云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod


查看 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钩子。

云原生故障演练 - 实例驱逐异常下 preStop&GracePeriod



使用chaosBlade 模拟内存耗尽:

blade c mem load --mode ram --mem-percent 100


# kubectl top nodeNAME CPU(cores) CPU% MEMORY(bytes) MEMORY%172.19.1.202 2162m 27% 61496Mi 101%172.19.133.177 7375m 93% 60356Mi 99%


# kubectl top nodeNAME 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的主要内容,如果未能解决你的问题,请参考以下文章

云原生背景下故障演练体系建设的思考与实践—云原生混沌工程系列之指南篇

打造云原生时代高可用验证能力-混沌工程实践

异常测试-中间件故障演练

云原生|SpringCloud 在Kubernetes 上的最佳实践

云原生下的混沌工程 - Chaos Mesh

云原生大趋势下的容器化技术现状与发展