Kubernetes如何使部署更新图像

abo*_*sun 90 docker kubernetes

我有单个pod部署,我的自定义docker镜像如下:

containers:
  - name: mycontainer
    image: myimage:latest
Run Code Online (Sandbox Code Playgroud)

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

kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1
Run Code Online (Sandbox Code Playgroud)

Cam*_*mil 116

您可以使用宽限期(例如30秒或更长时间,具体取决于容器启动时间和图像大小)配置您的pod并进行设置"imagePullPolicy: "Always".并使用kubectl delete pod pod_name.将创建一个新容器并自动下载最新映像,然后终止旧容器.

例:

spec:
  terminationGracePeriodSeconds: 30
  containers:
  - name: my_container
    image: my_image:latest
    imagePullPolicy: "Always"
Run Code Online (Sandbox Code Playgroud)

我目前正在使用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"
Run Code Online (Sandbox Code Playgroud)

另一个技巧是最初运行:

kubectl set image deployment/my-deployment mycontainer=myimage:latest
Run Code Online (Sandbox Code Playgroud)

然后:

kubectl set image deployment/my-deployment mycontainer=myimage
Run Code Online (Sandbox Code Playgroud)

它实际上会触发滚动更新,但请确保您已imagePullPolicy: "Always"设置.

更新:

我找到的另一个技巧是,你不必更改图像名称,就是改变一个触发滚动更新的字段的值,比如terminationGracePeriodSeconds.您可以使用kubectl edit deployment your_deploymentkubectl apply -f your_deployment.yaml使用这样的补丁来执行此操作:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'
Run Code Online (Sandbox Code Playgroud)

只需确保始终更改数值.

  • 每次更改标签并运行`kubectl set image`命令时,kubernetes都会执行滚动更新.例如,假设您部署了"repo/myimage:latest".与此同时,您的图像被更改并推送到带有"v0.2"标签的仓库.您可以通过运行`kubectl set image deployment/my-deployment mycontainer = myimage:v0.2`来执行更新.此图像也将具有"最新"标记. (11认同)
  • 这个技巧看起来更像是一个错误,不知道为什么我们需要指定两次。 (2认同)
  • 如果您希望kubernetes部署使用相同的映像启动新的pod(并且此技巧仅适用于"latest"标记),则必须在没有标记的情况下指定它.下次添加"最新"标签,它将触发更新.订单可以撤销,没关系.您从不在生产中使用"最新"标签,但出于开发目的,您有时可以从中受益. (2认同)
  • 它仅适用于最新版本。默认情况下,至少在docker hub中,通过不标记图像,它将采用“最新”标记。但是没有它也可以工作。这个示例在生产环境中不是您想要的,并且没有很多用例可以在开发中从中受益。有更好的方法,可以使用CI / CD工具自动更新映像。 (2认同)

Prz*_*wak 40

在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'
Run Code Online (Sandbox Code Playgroud)

2.Deploy

sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(date)/g" deployment.yml
kubectl apply -f deployment.yml
Run Code Online (Sandbox Code Playgroud)

第二个(一个班轮):

kubectl patch deployment web -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
Run Code Online (Sandbox Code Playgroud)

当然1.15,这两种情况都是必需的.

  • 现在,您可以使用“ kubectl”卷展栏重新启动部署/演示来执行相同的操作而无需任何技巧!确保您具有kubectl版本“ 1.15”。 (3认同)
  • 发现了另一个相关的技巧。如果您只是执行“kubectl rollout restart deployment”而不指定任何特定的部署名称,则 ity 将执行“所有”操作。 (2认同)

Mar*_*ter 33

kubectl rollout restart deployment myapp
Run Code Online (Sandbox Code Playgroud)

这是当前触发滚动更新并将旧副本集保留在原位以供kubectl rollout类似回滚提供的其他操作的方式。


小智 17

我使用 Gitlab-CI 构建镜像,然后将其直接部署到 GCK。如果使用一个巧妙的小技巧来实现滚动更新而不更改容器的任何实际设置,这就是将标签更改为当前的 commit-short-sha。

我的命令如下所示:

kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"
Run Code Online (Sandbox Code Playgroud)

只要标签随每次构建而变化,您就可以使用任何名称和任何值作为标签。

玩得开心!


vag*_*i k 12

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

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>>
Run Code Online (Sandbox Code Playgroud)

例如,

kubectl set image deployment/my-deployment -n=sample-namespace my-container=alex/my-sample-image-from-dockerhub:1.1
Run Code Online (Sandbox Code Playgroud)

在哪里:

  • kubectl set image 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您要使用的镜像和标签


xpm*_*teo 8

k8s 似乎希望我们为每个部署提供不同的镜像标签。我默认的策略是使CI系统生成并推动泊坞窗图像,用版本号标记它们: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
Run Code Online (Sandbox Code Playgroud)

sed命令将部署文档中的占位符替换为实际生成的图像标记。

  • kubernetes 不要求您使用新标签更新部署即可拉取任何映像的最新版本,“最新”是最常见的示例。 (2认同)

Rtm*_*tmY 5

另一个更适合调试但值得一提的选项是检查推出的修订历史记录:

$ kubectl rollout history deployment my-dep
deployment.apps/my-dep
 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>
Run Code Online (Sandbox Code Playgroud)

要查看每个修订的详细信息,请运行:

 kubectl rollout history deployment my-dep --revision=2
Run Code Online (Sandbox Code Playgroud)

然后通过运行返回到以前的版本:

 $kubectl rollout undo deployment my-dep --to-revision=2
Run Code Online (Sandbox Code Playgroud)

然后又回到新的。
就像跑步一样ctrl+z -> ctrl+y(:

(*) 更改原因是<none>因为您应该使用标志运行更新--record- 就像这里提到的那样:

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
Run Code Online (Sandbox Code Playgroud)

(**) 有关于弃用此标志的讨论。