使用场景
如果我们直接将Pod杀死,那这部分流量就无法得到正确处理,会影响部分用户,通常来说网关或者注册中心会将我们的服务保持一个心跳,过了心跳超时之后会自动摘除我们的服务,但是有一个问题就是超时时间可能是30秒也可能是60秒,虽然不会影响我们的系统,但是会产生用户轻微抖动。
如果我们在停止前执行一条命令,通知网关或者注册中心这台主机进行下线,那么注册中心就会标记这台主机已经下线,不进行流量转发,用户就不会有任何影响,这就是优雅停止,将滚动更新影响最小化
Pod Hook
Pod Hook是由kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中
我们可以同时为Pod中的所有容器都配置hook
在k8s中,理想的状态是pod优雅释放,并产生新的Pod。但是并不是每一个Pod都会这么顺利
Pod卡死,处理不了优雅退出的命令或者操作
优雅退出的逻辑有BUG,陷入死循环
代码问题,导致执行的命令没有效果
对于以上问题,k8s的Pod终止流程中还有一个”最多可以容忍的时间”,即grace period (在pod的.spec.terminationGracePeriodSeconds字段定义),这个值默认是30秒,当我们执行kubectl delete的时候也可以通过--grace-period参数显示指定一个优雅退出时间来覆盖Pod中的配置,如果我们配置的grace period超过时间之后,k8s就只能选择强制kill Pod
1. `Kubernetes等待指定的时间称为优雅终止宽限期。默认情况下,这是30秒。`
2. `值得注意的是,这与preStop Hook和SIGTERM信号并行发生。Kubernetes不会等待preStop Hook完成。`
3. `如果你的应用程序完成关闭并在terminationGracePeriod完成之前退出,Kubernetes会立即进入下一步。`
5. `如果您的Pod通常需要超过30秒才能关闭,请确保增加优雅终止宽限期(通过terminationGracePeriodSeconds来实现)`
POD终止原理
用户发送命令删除Pod,Pod进入Terminating状态
service摘除Pod节点
当kubelet看到Pod已被标记终止,开始执行preStop钩子,
假如preStop hook的运行时间超过了grace period,
kubelet会发送SIGTERM并等2秒
示例
```yaml
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Always
ports:
- containerPort: 80
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: CONFIG_ENV
value: "DEV"
- name: ARGS
value: "-Dapp.id=nginx -Dapollo.meta=http://apollo-config-svc:8060 -Denv=dev -Dapollo.bootstrap.namespaces=application,eureka-client-common,TEST1.redis,TEST1.swagger"
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- " \
APPLICATION=SERVICE-NGINX; \
APPLICATION_PORT=80; \
curl -X PUT http://eureka01-svc:9000/eureka/apps/${APPLICATION}/${MY_POD_IP}:${APPLICATION_PORT}/status?value=OUT_OF_SERVICE; \
sleep 60;"
terminationGracePeriodSeconds: 60
网友评论