提问人:Andriy Kopachevskyy 提问时间:11/2/2016 更新时间:4/29/2021 访问量:331008
Kubernetes 如何进行部署以更新映像
Kubernetes how to make Deployment to update image
问:
我确实部署了单个 pod,我的自定义 docker 映像如下:
containers:
- name: mycontainer
image: myimage:latest
在开发过程中,我想推送新的最新版本并更新部署。 找不到如何做到这一点,而没有明确定义标签/版本并为每个构建递增它,然后执行
kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1
答:
您可以为 Pod 配置宽限期(例如 30 秒或更长时间,具体取决于容器启动时间和映像大小)并设置 .并使用 .
将创建一个新容器并自动下载最新映像,然后终止旧容器。"imagePullPolicy: "Always"
kubectl delete pod pod_name
例:
spec:
terminationGracePeriodSeconds: 30
containers:
- name: my_container
image: my_image:latest
imagePullPolicy: "Always"
我目前正在使用 Jenkins 进行自动构建和图像标记,它看起来像这样:
kubectl --user="kube-user" --server="https://kubemaster.example.com" --token=$ACCESS_TOKEN set image deployment/my-deployment mycontainer=myimage:"$BUILD_NUMBER-$SHORT_GIT_COMMIT"
另一个诀窍是先后运行:
kubectl set image deployment/my-deployment mycontainer=myimage:latest
然后:
kubectl set image deployment/my-deployment mycontainer=myimage
它实际上会触发滚动更新,但请确保您也设置了。imagePullPolicy: "Always"
更新:
我发现的另一个技巧是,您不必更改图像名称,而是更改将触发滚动更新的字段的值,例如 .您可以使用或使用如下补丁来执行此操作:terminationGracePeriodSeconds
kubectl edit deployment your_deployment
kubectl apply -f your_deployment.yaml
kubectl patch deployment your_deployment -p \
'{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'
只需确保始终更改数字值即可。
评论
kubectl set image
kubectl set image deployment/my-deployment mycontainer=myimage:v0.2
更新 2019-06-24
根据@Jodiug注释,如果您有版本,则可以使用以下命令:1.15
kubectl rollout restart deployment/demo
阅读有关该问题的更多信息:
https://github.com/kubernetes/kubernetes/issues/13488
好吧,在 kubernetes GitHub 项目上有一个有趣的关于这个主题的讨论。请参阅问题:https://github.com/kubernetes/kubernetes/issues/33664
从那里描述的解决方案中,我建议两种之一。
第一
1.准备部署
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: demo
spec:
replicas: 1
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: registry.example.com/apps/demo:master
imagePullPolicy: Always
env:
- name: FOR_GODS_SAKE_PLEASE_REDEPLOY
value: 'THIS_STRING_IS_REPLACED_DURING_BUILD'
2.部署
sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(date)/g" deployment.yml
kubectl apply -f deployment.yml
第二(一班):
kubectl patch deployment web -p \
"{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
当然,这两种情况都是必需的。imagePullPolicy: Always
评论
docker build --no-cache
\"
似乎 k8s 希望我们为每个部署提供不同的映像标签。我的默认策略是让 CI 系统生成并推送 docker 映像,并用内部版本号标记它们:.xpmatteo/foobar:456
对于本地开发,使用脚本或 makefile 可以很方便,如下所示:
# create a unique tag
VERSION:=$(shell date +%Y%m%d%H%M%S)
TAG=xpmatteo/foobar:$(VERSION)
deploy:
npm run-script build
docker build -t $(TAG) .
docker push $(TAG)
sed s%IMAGE_TAG_PLACEHOLDER%$(TAG)% foobar-deployment.yaml | kubectl apply -f - --record
该命令将部署文档中的占位符替换为实际生成的映像标记。sed
评论
我使用 Gitlab-CI 构建映像,然后将其直接部署到 GCK。如果使用一个巧妙的小技巧来实现滚动更新,而无需更改容器的任何实际设置,即将标签更改为当前的 commit-short-sha。
我的命令如下所示:
kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"
您可以在其中使用任何名称和任何值作为标签,只要它随每次生成而更改即可。
玩得愉快!
kubectl rollout restart deployment myapp
这是触发滚动更新的当前方法,并将旧副本集保留在原位,以便进行类似回滚提供的其他操作。kubectl rollout
评论
undo
我正在使用Azure DevOps来部署容器化应用程序,通过使用生成ID,我可以轻松地克服此问题
每次构建并生成新的构建 ID 时,我都会使用此构建 ID 作为 docker 映像的标签,这里是示例
imagename:buildID
成功构建映像 (CI) 后,在部署 yml 文件中的 CD 管道中,我将映像名称指定为
imagename:env:buildID
此处 evn:buildid 是 Azure DevOps 变量,其值为 build ID。
所以现在每次我对 build(CI) 和 deploy(CD) 都有新的更改。
如果您需要 CI/CD 的构建定义,请发表评论。
评论
另一个更适合调试但值得一提的选项是检查推出的修订历史记录:
$ kubectl rollout history deployment my-dep
deployment.apps/my-dep
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
若要查看每个修订的详细信息,请运行:
kubectl rollout history deployment my-dep --revision=2
然后通过运行以下命令返回到上一个修订版本:
$kubectl rollout undo deployment my-dep --to-revision=2
然后回到新的。
就像跑步一样(:ctrl+z -> ctrl+y
(*)CHANGE-CAUSE 是因为您应该使用以下标志运行更新 - 如下所述:<none>
--record
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
(**)有一个关于弃用此标志的讨论。
我们可以使用以下命令更新它:
kubectl set image deployment/<<deployment-name>> -n=<<namespace>> <<container_name>>=<<your_dockerhub_username>>/<<image_name you want to set now>>:<<tag_of_the_image_you_want>>
例如
kubectl set image deployment/my-deployment -n=sample-namespace my-container=alex/my-sample-image-from-dockerhub:1.1
哪里:
kubectl set image deployment/my-deployment
- 我们想将名为my-deployment
-n=sample-namespace
- 此部署属于名为 的命名空间。如果您的部署属于默认命名空间,则无需在命令中提及此部分。sample-namespace
my-container
是之前在部署配置的 YAML 文件中提到的容器名称。alex/my-sample-image-from-dockerhub:1.1
是要为部署设置并运行容器的新映像。这里是 dockerhub 镜像的用户名(如果适用)、要使用的镜像和标签。alex
my-sample-image-from-dockerhub:1.1
评论