在 Kubernetes 中进行滚动更新时,我们通常希望新的 Pod 能够迅速生效,同时允许旧的 Pod 完成它们可能正在执行的任务。为了实现这一目标,我们可以借助 preStop
生命周期钩子和 terminationGracePeriodSeconds
字段。通过合理配置这两个参数,我们可以确保在进行滚动更新时,新的 Pod 能够尽快生效,同时允许旧的 Pod 完成可能正在执行的任务。
滚动更新中的 Pod 过程
在 Kubernetes 中进行滚动更新时,新的 Pod 启动并逐渐接收流量,而旧的 Pod 开始进入终止阶段。这个过程包含以下关键步骤:
- 新 Pod 启动: 随着新的 Pod 的启动,它逐渐准备好接收传入的流量。这确保了在滚动更新期间应用程序的高可用性。
- 旧 Pod 进入 Terminating 状态: 一旦新的 Pod 开始接收流量,Kubernetes 将旧的 Pod 标记为
Terminating
状态。这表示它即将被终止。 - preStop 钩子执行: 进入
Terminating
状态后,旧的 Pod 开始执行preStop
生命周期钩子。这个钩子提供了在容器终止之前执行清理任务的机会,确保应用程序有机会完成正在进行的任务。 - terminationGracePeriodSeconds 等待: 在
preStop
钩子执行完成后,Kubernetes 将等待配置的terminationGracePeriodSeconds
时间,以确保旧的 Pod 有足够的时间来完成清理工作或处理正在进行的任务。 - Pod 正常终止: 在等待的时间结束后,Kubernetes 正式终止旧的 Pod,确保应用程序的平滑更新。此时,新的 Pod 已经完全接管流量。
1. 什么是preStop?
preStop
是Kubernetes容器生命周期钩子之一,用于在容器终止之前执行一些操作。在容器终止期间,Kubernetes首先会执行preStop
钩子,然后才会真正终止容器。这为我们提供了在容器即将终止之前执行一些清理任务的机会。
2. 什么是terminationGracePeriodSeconds?
terminationGracePeriodSeconds
是Pod规范中的一个字段,它指定在Kubernetes终止Pod之前等待的时间。在这段时间内,Kubernetes会等待容器执行preStop
钩子以及完成任何其他清理工作。这使得我们可以有更多的控制权,确保Pod能够优雅地终止。
3. 利用preStop和terminationGracePeriodSeconds实现滚动更新
假设我们有一个名为my-app
的Deployment,我们希望在进行更新时确保新的Pod能够迅速生效,同时允许旧的Pod完成任务。以下是如何配置Deployment来实现这个目标的示例
yamlapiVersion:
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
terminationGracePeriodSeconds: 600
containers:
- name: my-app-container
image: my-app:latest
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "/app/prestop-script.sh"]
我们配置了preStop
生命周期钩子,使其执行/app/prestop-script.sh
脚本。该脚本将负责检查应用程序是否有运行中的任务。如果有,脚本将等待任务完成;否则,它将退出,容器将继续正常终止。
此外,我们可以通过调整terminationGracePeriodSeconds
字段来控制Pod终止的等待时间
当
preStop
钩子执行完成后,Kubernetes 会等待terminationGracePeriodSeconds
时间,以确保容器有足够的时间来完成清理工作或处理正在进行的任务。如果prestop-script.sh
提前完成,Kubernetes 会等待剩余的terminationGracePeriodSeconds
时间,然后正常终止 Pod。
4. Service 的 Endpoint 自动更新
Kubernetes 中的 Service 通常由控制器自动管理和更新其 Endpoint。在进行滚动更新时,Kubernetes 会自动检测并更新 Service 的 Endpoint,以包含新的 Pod 地址。这确保了 Ingress 控制器或负载均衡器能够正确地将流量引导到新的 Pod。