Kubernetes v1.34:更精细地控制容器重启
随着 Kubernetes 1.34 的发布,引入了一个新的 Alpha 功能,使你能够更精细地控制 Pod 内的容器重启。此功能名为 容器重启策略与规则(Container Restart Policy and Rules),允许你为每个容器单独指定重启策略,从而覆盖 Pod 的全局重启策略。此外,它还允许你根据容器的退出码有条件地重启单个容器。此功能在 Alpha 特性门控 ContainerRestartRules
之后可用。
这是一个被长期请求的功能。让我们深入了解它的工作原理以及如何使用它。
单一重启策略的问题
在此功能之前,restartPolicy
是在 Pod 级别设置的。这意味着 Pod 中的所有容器共享相同的重启策略(Always
、OnFailure
或 Never
)。虽然这适用于许多用例,但在其他情况下可能会受到限制。
例如,考虑一个包含主应用容器和一个执行某些初始设置的 Init 容器的 Pod。你可能希望主容器在失败时总是重启,但 Init 容器应该只运行一次并且永不重启。使用单一的 Pod 级重启策略,这是不可能的。
引入按容器重启策略
通过新的 ContainerRestartRules
特性门控,你现在可以为 Pod 规约中的每个容器指定一个 restartPolicy
。你还可以定义 restartPolicyRules
以根据退出码控制重启。这为你提供了处理复杂场景所需的精细控制。
使用场景
让我们看一些现实生活中的使用场景,在这些场景中,按容器重启策略可能是有益的。
训练作业的就地重启
在机器学习研究中,编排大量长期运行的 AI/ML 训练工作负载是很常见的。在这些场景中,工作负载故障是不可避免的。当工作负载因可重试的退出码而失败时,你希望容器能够快速重启,而无需重新调度整个 Pod,这会消耗大量的时间和资源。对失败的容器进行“就地”重启对于更好地利用计算资源至关重要。容器只应在因可重试错误失败时才“就地”重启;否则,容器和 Pod 应终止并可能被重新调度。
现在,这可以通过容器级的 restartPolicyRules
来实现。工作负载可以以不同的代码退出,以表示可重试和不可重试的错误。有了 restartPolicyRules
,工作负载可以快速就地重启,但仅限于错误是可重试的情况。
一次性尝试的 Init 容器
Init 容器通常用于为主容器执行初始化工作,例如设置环境和凭据。有时,你希望主容器总是被重启,但如果初始化失败,你不想重试。
通过容器级的 restartPolicy
,这现在成为可能。Init 容器可以只执行一次,其失败将被视为 Pod 失败。如果初始化成功,主容器可以总是被重启。
具有多个容器的 Pod
对于运行多个容器的 Pod,你可能对每个容器有不同的重启要求。一些容器可能有明确的成功定义,并且只应在失败时重启。其他容器可能需要总是被重启。
现在,通过容器级的 restartPolicy
,这成为可能,允许单个容器具有不同的重启策略。
如何使用它
要使用此新功能,你需要在运行 Kubernetes 1.34+ 的 Kubernetes 集群控制平面和工作节点上启用 ContainerRestartRules
特性门控。启用后,你可以在容器定义中指定 restartPolicy
和 restartPolicyRules
字段。
以下是一些示例
示例 1:根据特定退出码重启
在此示例中,仅当容器因可重试错误(由退出码 42 表示)而失败时,容器才应重启。
为实现此目的,该容器的 restartPolicy
为 Never
,并有一条重启策略规则,告诉 Kubernetes 如果容器以退出码 42 退出,则就地重启该容器。
apiVersion: v1
kind: Pod
metadata:
name: restart-on-exit-codes
annotations:
kubernetes.io/description: "This Pod only restart the container only when it exits with code 42."
spec:
restartPolicy: Never
containers:
- name: restart-on-exit-codes
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'sleep 60 && exit 0']
restartPolicy: Never # Container restart policy must be specified if rules are specified
restartPolicyRules: # Only restart the container if it exits with code 42
- action: Restart
exitCodes:
operator: In
values: [42]
示例 2:一个只尝试一次的 Init 容器
在此示例中,一个 Pod 在初始化成功后应该总是被重启。但是,初始化应该只尝试一次。
为实现此目的,Pod 的重启策略为 Always
。init-once
这个 Init 容器将只尝试一次。如果它失败,Pod 将会失败。这使得 Pod 在初始化失败时会失败,但在初始化成功后也能保持运行。
apiVersion: v1
kind: Pod
metadata:
name: fail-pod-if-init-fails
annotations:
kubernetes.io/description: "This Pod has an init container that runs only once. After initialization succeeds, the main container will always be restarted."
spec:
restartPolicy: Always
initContainers:
- name: init-once # This init container will only try once. If it fails, the Pod will fail.
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Failing initialization" && sleep 10 && exit 1']
restartPolicy: Never
containers:
- name: main-container # This container will always be restarted once initialization succeeds.
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'sleep 1800 && exit 0']
示例 3:具有不同重启策略的容器
在此示例中,有两个具有不同重启要求的容器。一个应该总是被重启,而另一个只应在失败时重启。
这是通过在两个容器上使用不同的容器级 restartPolicy
来实现的。
apiVersion: v1
kind: Pod
metadata:
name: on-failure-pod
annotations:
kubernetes.io/description: "This Pod has two containers with different restart policies."
spec:
containers:
- name: restart-on-failure
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Not restarting after success" && sleep 10 && exit 0']
restartPolicy: OnFailure
- name: restart-always
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Always restarting" && sleep 1800 && exit 0']
restartPolicy: Always
了解更多
路线图
更多用于重启 Pod 和容器的动作和信号即将到来!值得注意的是,有计划增加对重启整个 Pod 的支持。关于这些功能的规划和讨论正在进行中。欢迎与 SIG Node 社区分享反馈或请求!
欢迎你的反馈!
这是一个 Alpha 功能,Kubernetes 项目希望听到你的反馈。请试用它。此功能由 SIG Node 推动。如果你有兴趣帮助开发此功能、分享反馈或参与任何其他正在进行的 SIG Node 项目,请与 SIG Node 社区联系!
你可以通过多种方式联系 SIG Node
- Slack: #sig-node
- 邮件列表
- 开放的社区问题/PR