如果 docker 镜像更新,强制 Kubernetes 重新部署部署 YAML?

时间:2021-03-09 21:50:29

标签: docker kubernetes gitlab gitlab-ci

我在此工作流中编写了一些代码,并在 latest 下部署了一个 docker 映像。目前,它部署到我的容器注册表,然后我在容器部署后运行此 kubectl apply file.yaml,但 K8s 似乎没有意识到它需要使用新拉取的映像重新拉取和推出新部署。< /p>

我怎样才能基本上输入我的部署的 YAML 规范,然后只是推出重新启动部署?

或者,有没有更好的方法?我无条件地以这种方式在我的所有部署中重新启动部署。

1 个答案:

答案 0 :(得分:1)

@daniel-mann 不鼓励使用 :latest 是正确的。

当您看到 latest 标签时,请勿阅读“最新”一词。这是一个默认标签,它破坏了确定图像内容是否已更改的能力。

更好的机制是通过一些不变的值来标记您的图像……例如,您的代码的哈希值。这就是 Docker 对其图像哈希所做的事情,这是识别图像的最佳(但不是最简单的)方法:[[image]]@sha256:....

您可以使用一些 SemVer 值。另一种常见机制是使用代码的 git commit 作为其标签:git rev-parse HEAD 或类似的。

那么,假设您现在通过标签唯一标识图像,如何更新部署?文档提供了各种方法:

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment

但是这些不利于稳健的部署(小写 D)。您还应该做的是在每次更改映像时创建唯一的部署清单。然后,如果你犯了一个错误并无意中部署了一些不合适的东西,你有一份你所做的事情的副本,你可以纠正它(制作另一个清单)并应用它。这是不可变基础架构背后的原则。

所以...

TAG=$(git rev-parse HEAD)

docker build \
--tag=${REPO}/${IMAGE}:${TAG} \
...

docker push ${REPO}/${IMAGE}:${TAG}

然后更改清单(并将更改提交到源代码管理):

sed --in-place "s|image: IMAGE|image: ${REPO}/${IMAGE}:${TAG}|g" path/to/manifest.yaml

git add /path/to/manifest.yaml
git commit --message=...

然后将修改后的(但唯一的!)清单应用到集群:

kubectl apply \
--filename=/path/to/manifest.yaml \
--namespace=${NAMESPACE}