【问题标题】:How can I have replicated pods with an init container that is run only once?如何使用只运行一次的 init 容器复制 pod?
【发布时间】:2019-08-30 22:25:44
【问题描述】:

如果我想运行需要一次性初始化任务的某个容器的多个副本,是否有标准或推荐的做法?

可能性:

  • 即使在初始化后不需要 StatefulSet,也要使用 StatefulSet,并让 init 容器检查它们是否位于集合中的第一个 pod 上,否则什么也不做。 (如果出于其他原因需要 StatefulSet,这几乎可以肯定是最简单的答案。)
  • 使用使用领导选举或类似方法的初始化容器只选择其中一个进行初始化。
  • 使用初始化容器,并确保多个副本可以安全地并行运行。可能是理想的,但安排起来并不总是那么简单。 (特别是在滚动更新期间 Pod 随机失败的情况下,并且替换的旧 Pod 在启动新 Pod 的同时运行其 init。)
  • 对单个副本使用单独的作业(或单独的部署)。可能会使初始化变得容易,但会使管理它与 CI/CD 管道中的主容器之间的依赖关系变得更加困难(我们没有使用 Helm,但这与安装后/升级后的钩子大致相当) .

【问题讨论】:

标签: kubernetes


【解决方案1】:

“某个容器的副本”依赖于“一次性初始化任务”这一事实意味着应用程序架构不适合 Kubernetes 范式。这就是为什么必须考虑像 Helm 这样的 k8s 之上的第三方管理器的参与(正如 Eduardo Baitello 和 Matt 所建议的那样)。

为了保持纯粹的 Kubernetes 方法,最好重新设计您的应用程序,使其组件作为独立或松散耦合的微服务(包括初始化任务)工作。 最近在这里讨论了similar question。

至于问题中列出的可能性,也许InitContainers 和StatefulSets 的第一个选项在纯Kubernetes 中是可行的。

【讨论】:

  • 重新设计应用程序以不使用任何第三方数据库或具有相同模式的其他组件不是一个选项:-) 我目前正在考虑一个纯 Kubernetes 解决方案,其中工作在 Job 中完成,所有的 init 容器都试图创建它,但其中最多有一个会成功,有效地将 Kubernetes API 用作互斥锁。因为已经存在而不创建 Job 的 init 容器将阻塞,直到现有的容器完成(并且什么也不做)。
  • 根据 Kubernetes 的良好实践,您应该重新设计您的应用程序,以便每个应用程序副本都与自己的数据库副本一起工作。这样,您将获得独立的 pod,每个 pod 都可以使用自己的 InitContainer 轻松初始化。
  • 这反而错过了拥有数据库的意义。确实,Kubernetes 曾经被认为只适用于无状态应用程序,但事情已经发生了变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
相关资源
最近更新 更多