Kubernetes如何使部署更新图像

时间:2016-11-01 18:20:17

标签: docker kubernetes

我确实使用单个pod进行部署,使用我的自定义docker镜像:

containers:
  - name: mycontainer
    image: myimage:latest

在开发期间,我想推送新的最新版本并更新部署。 无法明确定义标记/版本并为每个构建增加它,并且无法找到如何做到这一点,并且

kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1

8 个答案:

答案 0 :(得分:86)

您可以使用宽限期(例如30秒或更长时间,根据容器启动时间和图像大小)配置您的pod,并设置"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_deploymentkubectl apply -f your_deployment.yaml或使用此类补丁执行此操作:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

请确保始终更改数字值。

答案 1 :(得分:19)

在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.Deploy

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

答案 2 :(得分:5)

kubectl rollout restart deployment myapp

这是当前触发滚动更新并将旧副本集留在原处的方法,以供kubectl rollout提供的其他操作,如回滚。

答案 3 :(得分:2)

似乎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命令用实际生成的图像标记替换部署文档中的占位符。

答案 4 :(得分:1)

我使用Gitlab-CI构建映像,然后将其直接部署到GCK。如果使用整洁的小技巧在不更改容器实际设置的情况下实现滚动更新,则将标签更改为当前的commit-short-sha。

我的命令如下:

kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"

您可以在其中使用标签的任何名称和值,只要标签随每次构建而变化即可。

玩得开心!

答案 5 :(得分:1)

我正在使用Azure DevOps部署容器化应用程序,我可以通过使用内部版本ID来轻松解决该问题

每次构建并生成新的Build ID时,我都将此构建ID用作docker image的标签,此处为示例

imagename:buildID

一旦映像成功构建(CI),在部署yml文件的CD管道中,我将映像名称命名为

imagename:env:buildID

此处evn:buildid是天蓝色的devops变量,其值具有构建ID。

所以现在每次我对build(CI)和deploy(CD)进行新更改时。

如果需要CI / CD的构建定义,请发表评论。

答案 6 :(得分:1)

我们可以使用以下命令更新它:

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 是您要为部署设置并为其运行容器的新映像。此处,alex 是 dockerhub 映像的用户名(如果适用),my-sample-image-from-dockerhub:1.1 是您要使用的映像和标签。

答案 7 :(得分:0)

另一个更适合调试但值得一提的选项是签入首次展示的修订历史记录:

$ kubectl rollout history deployment my-dep
deployment.apps/my-dep
 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

然后运行以下命令返回上一个修订版本:

 $kubectl rollout unto deployment my-dep --to-revision=2

然后返回到新的。
就像运行ctrl+z -> ctrl+y(:

(*)CHANGE-CAUSE为<none>,因为您应该使用--record标志运行更新-就像提到的here

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record

(**)关于弃用该标志的问题discussion