如何在 Kubernetes 中以特定顺序配置 Pod 初始化?

How to Configure Pod initialization in a specific order in Kubernetes?

我想知道如何按特定顺序开始部署。我知道 initContainers 但这对我不起作用。我有一个巨大的平台,有大约 20 个部署和 5 个状态集,每个都有自己的服务、环境变量、卷、水平自动缩放器等。所以不可能(或者我不知道如何)在另一个中定义它们yaml 部署为 initContainers.

是否有其他选项可以按特定顺序启动部署?

k8s 中没有 "depends_on-like" 选项,我认为它没有实现只是因为在云原生(= 微服务)环境中,应用程序应该是无状态的。无状态还意味着任何应用程序都不应知道另一个应用程序的状态:每个应用程序都应该能够在任何时刻启动、终止、恢复而不影响其他应用程序,当然平台服务可能会出现质量下降!

如果你有这种限制(如果你部署了一个消息代理并且每个消费者都必须等待它启动并且 运行 在建立连接之前这是合理的)你必须在一个"stateless fashion":例如,您可以阻止启动过程,直到未建立代理连接,然后定期重试。使用 kubernetes healthcecks,您甚至可以在 window 或 "not healthy" 期间声明您的服务 "not ready" 如果多次重试失败

你可以在其他上下文中翻译这个模式,试着举例说明你想要实现的目标

可以在 Pod 或属于同一 StatefulSet 的 Pods 中命令启动 initContainer。但是,这些解决方案不适用于您的情况。

这是因为排序初始化不是解决问题的标准方法。在微服务架构中,更具体地说是 Kubernetes,你会编写你的容器,这样它们就会尝试调用它们所依赖的服务(无论它们是否启动),如果它们不可用,你就会让你的容器崩溃。这是可行的,因为 Kubernetes 提供了一个 self-healing mechanism 可以在容器失败时自动重启容器。这样,您的容器将尝试连接到它们所依赖的服务,如果后者不可用,容器将崩溃并稍后使用指数 back-off.

重试

通过删除服务之间不必要的依赖关系,您可以简化应用程序的部署并减少不同服务之间的耦合。

正如许多其他答案所概述的那样,如果 pod/服务不可用,micro-service 架构中的应用程序不应 中断

然而,即使发生了,Kubernetes 也应该足够聪明,可以自动尝试从故障中恢复并重新启动 pod。这应该重复直到应用程序的依赖项已经完成。

Kubernetes 本身并不是一个 release-manager,而是一个平台。如果您需要按顺序或以特定顺序部署 pods 或服务,您可能需要查看实际的 release-manager,例如 Helm, using particular deployment/design-patterns such as an umbrella-chart pattern (Whosebug example)。这可能包括一些额外的工作,但可能正是您正在寻找的。

我真的希望至少能帮到你一点点。 :)

正如其他答案中已经回答的那样,您无法在部署之外定义 PODs 之间的初始化顺序。

每个部署 (POD) 都应该是一个独立的单元,应该有自己的生命周期,如果一个 POD 依赖于其他 PODs 要 运行ning 进行初始化,您可能需要检查您的设计。

  • 如果 POD 在启动时启动并在另一个 POD 启动后失败,会发生什么情况?
  • 如果 POD B 正在更新,而 POD A 在之后更新?

您在设计系统时应考虑到它们总是会失败,如果服务 B 在服务 A 之前启动,则 POD 的行为方式与它们以正确的顺序和服务 A(即依赖项)启动时的行为相同在 B) 之后失败了。

您的应用程序应该处理这些而不是将其卸载到协调器。

.

如果您确实需要实施排序并且更改应用程序是不可能的,您可以使用 init containers 以相同的方式向其他容器中的健康(就绪)端点发出请求K8s 确实会检查你的容器是否准备好,当他们回答成功时,你然后完成 init 执行并让 POD 运行 其他容器。

只需同时启动它们,然后让它们崩溃。 Kubernetes 将在一些延迟后重新启动失败的。

假设您有服务 A,它依赖于 B,而 B 又依赖于 C。A 首先启动,并且作为其启动序列的一部分尝试调用 B。失败(因为 B 未启动)并且pod 更改为错误状态。它可能会重试一次或两次,然后进入 CrashLoopBackOff 状态。 Kubernetes 会暂停几秒钟,然后再次重试。 B也会发生同样的事情。

最终服务 C(位于堆栈底部)将启动,一段时间后自动重启将启动 B(紧靠其上方)。这次B就启动成功了。一段时间后自动重启将启动 A,这次将成功启动。

您需要注意的一件事是,如果 Pod 最终进入 CrashLoopBackOff 状态,可能是因为代码错误或配置错误,或者仅仅是因为它所依赖的服务不是起来了。您需要查看 kubectl logs(并确保您的服务代码写出可用的诊断信息)以了解您所处的情况。

我希望您的容器已 liveness probe 定义。在依赖部署中使用它们来创建一个 initContainer 来检查应用程序是否准备就绪。 initContainer验证其他容器就绪后,启动依赖容器

您在使用 initContainer 时遇到的问题到底是什么?使用 initContainer 启动依赖容器的示例 link 是 here.

另一种方法是编写 shell 包装器,然后创建初始部署。然后使用 until 循环等待初始部署状态就绪。然后触发依赖初始部署的部署。

要在部署之间创建依赖关系,需要有一系列特定条件为真。

例如,等待 pod“busybox1”包含“Ready”类型的状态条件。

kubectl wait --for=condition=Ready pod/busybox1

之后,您可以展开下一个部署。

有关详细信息,请参阅 kubectl-wait

这是来自@Michael Hausenblas job-dependencies 的另一个示例,在作业对象之间具有依赖性。

如果您想在工人完成后开始另一份工作?给你:

$ kubectl -n waitplayground \
             wait --for=condition=complete --timeout=32s \     
             job/worker
job.batch/worker condition met