如何 运行 将脚本发送到 CI/CD 中的 pod?

How to run a script to a pod in CI/CD?

我在 Kubernetes 上部署了一个 PostgreSQL,也在 NodeJS 中部署了一个微服务。我将 CircleCI 用作 CI/CD.

我正在使用 Prisma ORM,每次构建我的 NodeJS 容器的新映像时,我都需要 运行 针对我的 PostgreSQL 数据库的脚本。数据库 运行 位于与我的 NodeJS 应用程序不同的 pod 中,并且它只能在 Kubernetes 环境中访问(它不会暴露给网络)。

最初我想在我的 CI/CD 管道中创建一个到 运行 脚本的步骤,但是,Circleci 将无法连接到我的 PostgreSQL pod,因为它无法从外部访问.

此外,我不想在每次部署新 pod 时都运行 脚本,只有在我构建新的 Docker 映像时才这样做。

我需要 运行 的命令是 prisma migrate deploy,它将检查我的 NodeJS 架构中的数据库迁移。

我应该怎么做?

如果您想在 NodeJS 代码中执行此操作,您可以使用 npm @c6o/kubeclient 并使用 exec 命令在 运行 pod 中执行命令。

const cluster = new Cluster(options) // can be {} if KUBECONFIG is set

const runningPod = {kind: 'Pod', apiVersion, metadata } // Your Pod name/namspace 

 await cluster.
            begin('Copy authorization_keys')
            .exec(runningPod, ['mkdir', '-p', '/data/.ssh'])
            .exec(runningPod, ['cp', '/data/keys/authorized_keys', '/data/.ssh'])
            .end()

或者,您可以使用 kubectl exec 在 Pod 中执行命令。

最后,您还可以使用 CodeZero PostgreSQL 配置器 (bash/NodeJS) 来安装和设置您的 ProstgreSQL https://github.com/c6o/provisioners

所以在回答中提出我的意见。

您想要在构建 docker 映像时 运行 数据库迁移。 运行 在 kubernetes 集群中迁移的最佳方法是借助 init 容器。

什么是初始化容器?

Init 容器是在与“主”容器相同的 pod 中启动的容器,但它在任何其他容器之前启动。在初始化容器中,你应该有一些初始化逻辑。您可以像 class 构造函数一样查看 init 容器。他们负责初始化。

如上图所示,初始化容器正在对未初始化的数据库执行一些操作(种子),主应用程序正在使用已初始化的数据库。

与构造函数一样,初始化容器也有一些“缺点”。如果构造函数抛出异常会怎样?您将无法使用该对象,因为它尚未初始化。初始化容器也一样。如果 init 容器没有以成功代码退出,主容器将不会启动。如果 init 容器失败,那么它将执行您在 restartPolicy 中定义的任何操作。

但是当你将 restartPolicy 设置为 always 并且 init container 失败时会发生什么?好吧,它会再试一次。然后再次......所以你需要确保你的代码是 idempotent.

我可以有多个初始化容器吗?

当然可以,为什么不呢?但它们会按顺序执行。而且,如果一个 init 容器失败,则在失败的容器之后的所有其他容器都不会被执行。

我也对 Kubernetes Patterns: The Init Containers

做了一些回顾