pod优雅关闭+无宕机+eureka注册摘取

通过eureka测试pod生命周期:

两种情况

一:

1
2
3
4
5
前提:
守护进程pid为1
无lifecycle.preStop
测试结果:
容器可以正常关闭,eureka可以正常摘除

1
2
3
4
5
6
7
8
9
10
11
12
13
前提:
守护进程pid为1
有lifecycle.preStop
lifecycle:
preStop:
exec:
command:
- "sh"
- "-c"
- |
sleep 30
测试结果:
容器无法正常关闭,eureka无法正常摘除

结论:preStop会覆盖pod第一次发送 SIGTERM -15 的信号,需在sleep后kill 1 #存疑:测试过程中会有sleep后SIGTERM 无法关闭应用的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
lifecycle:
preStop:
exec:
command:
- bash
- -c
- 'curl -X POST --data DOWN http://127.0.0.1:8080/service-registry/instance-status -H
"Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8";sleep 30'

####### 参数解释
127.0.0.1:8080 #代表eureka地址
service-registry #代表注册中心
DOWN #执行down请求
sleep #等待30秒

curl -v -X DELETE http://192.168.3.34:20001/eureka/apps/MEMBER-SERVER/192.168.3.34:member-server:20021

参考https://kubernetes.io/zh/docs/tasks/inject-data-application/define-command-argument-container/

中文官网:

image-20200916102726464

简单的说Kubernetes终止Pod生命周期的每一步

  • Pod 设置为Terminating状态,并从所有服务的Endpoints列表中删除
  • 此时,Pod停止,但是Pod中运行的容器不受影响
  • PreStop Hook被执行
  • preStop Hook发送容器特殊命令或者Http请求到Pod中
  • 此时,Kubernetes将向Pod中的容器发送SIGTERM信号,这个信号即通知容器他们很快将进行关闭。
  • Kubernetes等待优雅的终止
  • 此时,Kubernetes等待指定的时间称为优雅终止宽限期。默认情况下,这是30秒(可以修改),值得注意的是,PreStop Hook和SIGTREM信息是属于并行执行,Kubernetes不会等待PreStop Hook完成。

如果Pod在terminationGracePeriod完成之前推出,Kubernetes将进入释放阶段,如果容器在优雅终止宽限期(terminationGracePeriod限定时间),则会发送SIGKILL信号并强制删除。与此同时,所有的Kubernetes对象也会被清除。

终止生命周期

1 – 将 pod 设置为“正在终止”状态,并将其从所有服务的端点列表中移除

此时,pod 停止获取新流量,Pod 中运行的容器不受影响。

2 – 执行 preStop 钩子

preStop 钩子是向 pod 中的容器发送的特殊命令或 http 请求。

如果您的应用程序在收到 SIGTERM 后未正常关闭,可使用此钩子触发正常关闭。大多数程序在收到 SIGTERM 后都会正常关闭,但如果您使用的是第三方代码或管理的系统不受您控制,preStop 钩子将是一个不错的方案,可帮您在不修改应用程序的情况下触发正常关闭。

3 – 向 pod 发送 SIGTERM -15 信号

此时,Kubernetes 将向 pod 中的容器发送 SIGTERM 信号。此信号通知容器它们即将被关闭。

您的代码应侦听此事件,并在此时开始“干净地”关闭。这可能包括停止所有长时间连接(如数据库连接或 WebSocket 流)、保存当前状态或类似任务。

即使您现在已经在使用 preStop 钩子,也有必要测试一下应用程序在您向它发送 SIGTERM 信号后的反应,以免在实际使用时对实际情况感到惊讶!

4 – Kubernetes 等待片刻(宽限期)

此时,Kubernetes 将等待片刻,此时间称为终止宽限期,具体值可指定。默认值为 30 秒。需要注意的是,这与 preStop 钩子和 SIGTERM 信号并行发生。Kubernetes 不会等待 preStop 钩子完成。

如果您的应用在 terminationGracePeriod 完成之前完成关闭并退出,Kubernetes 将立即转到下一步。

如果您的 pod 通常需要 30 秒以上的时间才能关闭,请务必延长宽限期。您可以通过在 Pod YAML 中设置 terminationGracePeriodSeconds 选项来实现此目的。例如,可将该值改为 60 秒:

5 – 向 pod 发送 SIGKILL -9 信号,pod 随即被移除

如果宽限期结束后容器仍在运行,将向容器发送 SIGKILL 信号并强制将它们移除。此时,所有 Kubernetes 对象将被一同清理。