运行 Kubernetes 中的 pod/container 将维护应用于数据库

Running a pod/container in Kubernetes that applies maintenance to a DB

我发现有几个人询问如何启动一个容器 运行 一个数据库,然后 运行 一个不同的容器 运行s maintenance/migration 在数据库上然后退出。以下是我检查过的所有解决方案以及我认为每个解决方案存在的问题:

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

上述解决方案中是否有我忽略的选项或遗漏的内容?谢谢。

一种选择是使用 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. 由于 sleep hack.
  2. ,数据库和 sidecar 容器具有相同的 restartPolicy 效果很好
  3. 只有当两个容器都准备就绪时,您的 Pod 才会准备就绪。在 sidecar 容器的情况下,当 startupProbe 成功时会发生这种情况。

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