在Kubernetes中,我如何等待在群集中部署更新的代码?

时间:2017-11-17 14:54:24

标签: kubernetes

我在Google Kubernetes引擎中托管了一个有效的Kubernetes集群。我可以通过使用新代码构建Docker镜像,将图像(使用新标签)推送到Google容器注册表,然后kubectl apply更新清单(使用新标签),将新代码应用于群集)到集群。

我有一个手动步骤(具体来说,rails db:migrate将新的迁移应用到数据库),我想在部署新代码后发生这种步骤。我可以像kubectl exec命令一样执行此命令。但是存在一个问题:我需要针对新图像运行它,而不是旧图像。在退出代码为0的情况下,对旧图像运行它将成功,但它不会应用新的迁移,这些迁移仅出现在新图像中。

我的问题:在针对它运行kubectl exec命令之前,如何等待新代码在群集中生效?

请注意,我无法使用新图片kubectl run,因为容器本身无法访问数据库;它需要" sidecar" CloudSQL代理容器在同一个pod中运行。

还有一个约束:我需要在脚本环境(例如bash)中执行此操作,因此重复运行命令并手动检查输出不是一个选项。在满足某些条件之前执行自动脚本循环确实算作解决方案,但我真的更喜欢在我的脚本中不要求我进行轮询的内容。

持续时间sleep可以解决这个问题,但这种方法存在问题:

  • 睡眠时间可能不足以完成所有事情(而且所需时间多变且难以预测)。
  • 如果我的睡眠时间比我需要的时间长,Rails应用程序将拒绝工作,因为它会识别出尚未应用的数据库迁移 - 这应该被视为应用程序的停机时间。

1 个答案:

答案 0 :(得分:0)

如果我已正确理解问题,那么我认为init containers可以很好地解决您的问题。 Init容器允许您在启动pod之前执行某些任务。

因此,在您的情况下,以下内容的调整将达到目的(从上面的链接复制的代码):

apiVersion: v1 kind: Pod metadata: name: rails-app labels: app: myapp annotations: pod.beta.kubernetes.io/init-containers: '[ { "name": "init-myservice", "image": "new-image", "command": ["sh", "-c", "rails db:migrate"] } ]' spec: containers: - name: myapp-rails-app image: new-image

让我们了解一下这将如何运作:

  • 您将构建应用程序的新图像并将其推送到注册表。当然,您必须修改pod定义以拥有init容器。
  • 您将通过kubectl将新版本应用于部署
  • init容器使用与应用程序使用的映像相同的映像,但仅用于执行rails DB迁移。
  • 在该实际应用程序启动之后。

即使您拥有带有deploymentreplication controller对象的广告连播的N个副​​本 - 然后迁移可能会运行N次(每个广告连播一次)。它不是目的或最佳路径,但不会有任何问题,因为出现的第一个pod无论如何都会完成迁移。