用Kubernetes部署零停机轨道

在行动中卷展栏

如果您练习持续部署,则在没有停机时间的情况下部署很重要。否则,您没有持续交付;你有连续的停机时间。

如果您正在将应用程序部署到Kubernetes,您已经拥有所有所需的所有作品,以确保您的部署无需停机时间。但是,弄清楚如何为轨道应用程序组合在一起,这可能是一个挑战的东西!

这篇文章将通过主要步骤来获取在没有停机时间的Kubernetes中运行的Rails应用程序。

容器

Kubernetes使用根据根据的图像运行容器oci.集装箱格式。这些图像最常用使用Docker.,但其他工具喜欢生成包帕德曼也可以提供。

要将Rails应用程序部署到Kubernetes集群,您需要的第一件事是应用程序的一个容器图像。应用程序的图像将居住在具有URL的容器图像存储库中,如:

docker.io/mycompany/myapplication :tag.

每次为应用程序构建图像时,您都可以给它一个新的标签。我建议将图像标记以匹配Git提交图像是从中构建的,因此您将最终包含如下所示的图像URL:

docker.io/mycompany/myapplication:aabcd123

要使用Docker构建容器图像,您需要一个dockerfile.。之后,您可以构建,标记和推动您的图像:

Docker Build。--tag myApplication:最新的docker标记myapplication:最新docker.io/mycompany/myapplication :abcd123 docker push docker.io/mycompany/myapplication :abcd123

大多数团队都希望在持续集成期间自动构建这些图像。

部署

构建图像后,您可以告诉kubernetes您要使用该图像运行Pods:

#deployment.yaml.apiersionapps / v1种类部署元数据姓名轨道#...规格#...模板#...规格容器-姓名主要的图片docker.io/mycompany/myapplication:aabcd123
kubectl应用-f deployment.yaml

无论何时要部署新版本的应用程序,您都可以更新清单以使用容器图像的最新标记,并且Kubernetes将执行新版本的卷展栏。

推出

Kubernetes将通过创建和缩放副本集来为您推出发布。卷展栏策略是可定制的,但Kubernetes将默认使用滚动释放。简单的滚动版本如下所示:

  1. Kubernetes创建一个匹配更新的部署的新副本集。
  2. Kubernetes将推出一个匹配新副本集的新POD。
  3. 一旦POD标记为准备就绪,POD将开始接收生产流量。
  4. Kubernetes将从旧副本集终止吊舱。
  5. 重复步骤2-4,直到新的副本集运行所需数量的POD,并且完全按下旧副本集。

此过程意味着新的容器慢慢地联机,流量逐渐转移到最新版本。这避免了在部署期间的一个时期,其中吊舱不可用于服务流量,所有流量移动一次以使用冷库或许多额外的容器靴子同时启动,压倒数据库具有新的连接。这是零停机部署的一个好的,默认配方。

但是,您需要提供Kubernetes一些额外信息,以确保此过程为您的Rails迁移顺利运行。

准备探针

Kubernetes需要知道何时您的POD准备好开始接收生产流量。在加载应用程序代码时启动新容器后会有一段时间,连接到数据库,否则准备提供交通。Kubernetes知道何时结束,避免在部署中过早地前进。

对于Rails应用程序,制作HTTP请求是一个很好的安全赌注:

规格容器-姓名主要的图片docker.io/mycompany/myapplication:aabcd123ReadinessProbe.httpget.小路/robots.txt.港口3000.方案http.

更新您的课后部署.Yaml.文件,您可以重新应用它以更新:

kubectl应用-f deployment.yaml

将此添加到部署告诉Kubernetes等待请求/robots.txt.在标记POD之前,请响应200次数。这将暂停部署,直到您的应用程序服务器(例如PUMA)加载您的应用程序并准备回复用户请求。

如果某些内容阻止您的应用程序到达它可以满足此准备探测的点,则卷展栏不会向前移动,旧版本将继续运行不间断。这意味着您不会通过忘记添加新环境变量来降低生产。卷展栏将继续尝试重新启动和探测容器,直到它成功响应。

迁移工作

大多数Rails应用程序将利用Postgres等数据库,这意味着保持数据库模式与应用程序同步。这与Rails迁移很容易,但您需要一种方法来告诉Kubernetes运行迁移。这样做的一个好方法是使用工作:

apiersion批量/ v1种类工作元数据generateName.db-migrate-规格模板规格容器-姓名主要的命令-轨道-DB:迁移图片docker.io/mycompany/myapplication:aabcd123

一份工作就像部署一样,而不是保持一定数量的豆荚始终运行,它运行您的POD,直到它成功完成然后停止。您可以为CD管道中的每个新版本创建新的迁移作业。

init容器

您可以在更新部署时同时启动迁移作业以使用新的图像标记,但您需要确保在尝试启动Rails应用程序之前成功完成迁移。否则,新代码将尝试使用尚不存在的数据库列,这将导致应用程序错误。

您可以确保您的容器等待迁移通过向部署清单添加initcontainer来完成:

规格容器-姓名主要的图片docker.io/mycompany/myapplication:aabcd123initcontainers.-姓名迁移图片docker.io/mycompany/myapplication:aabcd123命令--db:abort_if_pending_migrations.

Kubernetes将运行迁移在尝试启动之前的容器主要的容器。如果迁移正在审理,则此内置Rake任务将退出错误。如果initcontainer.失败,Kubernetes将重新启动它,直到它成功完成。这意味着在迁移成功完成之前,您的主容器将无法启动,并且Pod将在其需要到位之前将其标记为准备就绪。

迁移Gotchas.

使用滚动发布的一个缺点是您的应用程序的多个版本将在卷展栏期间同时运行。如果在运行旧版本的旧版本运行时运行迁移,这意味着您的迁移必须向后兼容至少一个部署。大多数迁移都可以正常工作,但这意味着用小心处理一些变化:

  • 如果添加新的非空数据列,则必须提供默认值。
  • 删除仍在使用的列将导致应用程序错误。释放首先使用列的版本,然后将其删除在后续版本中。
  • 重命名表或列可能会导致问题。您可能希望部署首先使用别名的代码,然后将其重命名为后续版本。

这需要一点额外的警惕,但它使得轻松的零停机时间部署。作为一个奖励,如果出现问题,它更容易回滚释放。

把它整合在一起

通过所有这些部分到位,您可以在没有中断或错误的情况下连续部署,自动运行数据库迁移。

如果您正在寻找一组清单作为自己部署的基础,我将汇总了要旨包含更全面的例子。