首页 > 解决方案 > 在 Kubernetes 中运行对数据库进行维护的 pod/容器

问题描述

我发现有几个人询问如何启动运行数据库的容器,然后运行另一个容器,该容器在数据库上运行维护/迁移,然后退出。以下是我研究过的所有解决方案以及我认为每个解决方案的问题:

  1. Init Containers - 这不起作用,因为它们在主容器启动之前运行,并且它们会阻止主容器的启动,直到它们成功完成。
  2. Post Start Hook - 如果postStart hook 可以启动容器而不是简单地在容器内执行命令,那么这将起作用。不幸的是,带有数据库的容器不(也不应该)包含以这种方式运行它所需的相当大的维护应用程序。这将违反每个组件应该做一件事并做好的原则。
  3. Sidecar Pattern - 如果restartPolicy在容器级别而不是 pod 级别是可分配或可覆盖的,这将起作用。在我的情况下,维护容器应该在 pod 被认为正在运行之前成功终止(就像postStart挂钩可以运行容器的情况一样),而数据库容器应该始终重新启动。
  4. 单独的 Pod - 作为单独的 pod 运行维护可以工作,但在维护运行之前不应考虑数据库。这意味着管理运行状态必须完全独立于 Kubernetes 来完成。系统中的每个其他容器/pod 都必须进行自定义检查以确保维护已运行,而不是简单地检查数据库是否已启动。
  5. 使用作业- 除非我误解了这些工作原理,否则这将等同于上述(“单独的 Pod”)。
  6. 带有 Sidecar 的OnFailure重启策略 - 这意味着对 POD 使用OnFailure的restartPolicy,然后破解数据库容器,使其始终退出并出现错误。这是可行的,但显然只是一个被黑的解决方法。编辑:这也会导致 POD 状态出现问题。当维护运行并保持启动并且两个容器都在运行时,POD 的状态为Ready,但一旦维护容器退出,即使使用 SUCCESS(0 退出代码),POD 的状态也会变为NotReady 1/2

是否有我忽略的选项或我在上述解决方案中遗漏了什么?谢谢。

标签: kuberneteskubernetes-pod

解决方案


一种选择是对Sidecar pattern您描述的方法进行 2 处细微更改:

  1. 执行维护命令后,您可以使用while : ; do sleep 86400; done命令或类似命令保持容器运行。
  2. 您设置了一个适当startupProbe的地方,只有当您的维护命令成功执行时才能成功解决。例如,您可以创建一个文件/maintenance-done并使用这样的 startupProbe:
startupProbe:
  exec:
    command:
    - cat
    - /maintenance-done
  initialDelaySeconds: 5
  periodSeconds: 5

使用这种方法,您将获得以下结果:

  1. 由于. restartPolicy_sleep hack
  2. 只有当两个容器都准备好时,Pod 才会准备好。在 sidecar 容器的情况下,这会在 startupProbe 成功时发生。

此外,您的 pod 中不会有明显的开销:即使 sidecar 容器继续运行,它也会消耗接近于零的资源,因为它只运行 sleep 命令。


推荐阅读