如何强制Kubernetes重新拉动图像?


161

我在GKE上的Kubernetes中具有以下复制控制器:

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    app: myapp
    deployment: initial
  template:
    metadata:
      labels:
        app: myapp
        deployment: initial
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:5c3dda6b
        ports:
        - containerPort: 80
      imagePullPolicy: Always
      imagePullSecrets:
        - name: myregistry.com-registry-key

现在,如果我说

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b

执行滚动更新,但不重新拉动。为什么?


12
我给了另一个图像,只是带有相同的标签。如果有必要提供其他标签,那么我在该imagePullPolicy字段中看不到任何意义。
Torsten Bronger 2015年

4
我想使用特定的标签,但使用最新版本。
Torsten Bronger '18

3
@TorstenBronger我认为这是Kubernetes / Docker理论的重大突破。您可以在两个不同的时间提取image:tag(不是最新的)并获得两个不同的图像的想法是有问题的。标签类似于版本号。最好在图像更改时始终更改标签。
–duct_tape_coder,

2
这取决于。有些软件的API非常稳定,但是安全性有所更新。然后,我想要最新的版本而不必这么明确地说。
Torsten Bronger

1
@TorstenBronger关于使用latest,请不要这样做。最新将拉动带有最新标签的最新图像。您想要的是SemVer系列。例如〜1.2.3。这将拉出带有> = 1.2.3和<1.3.0范围内的标签的图像。只要图像供应商遵循SemVer,您就会知道(这是重要的部分),没有(故意)添加向后突破性更改,也没有添加任何新功能(可能存在安全隐患)。请,请不要latest在生产系统中使用。
David J Eddy

Answers:


140

Kubernetes将在创建Pod的任何一种情况下使用Pod(请参见update -images doc):

  • 使用标记的图像 :latest
  • imagePullPolicy: Always 被指定

如果您想一直拉,那就太好了。但是,如果您想按需执行该操作怎么办:例如,如果您要使用,some-public-image:latest但只想在请求时手动提取一个新版本。您目前可以:

  • 设置imagePullPolicyIfNotPresentNever预拉:在每个群集节点上手动拉图像,以便缓存最新的图像,然后执行kubectl rolling-update或类似操作以重新启动Pods(难看的容易损坏的hack!)
  • 临时更改imagePullPolicy,执行a kubectl apply,重新启动广告连播(例如kubectl rolling-update),还原imagePullPolicy,重做a kubectl apply(难看!)
  • 拉并推 some-public-image:latest送到您的私有存储库并执行kubectl rolling-update(繁重!)

没有按需拉动的好的解决方案。如果发生变化,请发表评论;我将更新此答案。


你说当使用kubernetes将拉动荚创作:latest-怎么样patchING?它也总是拉最新/最新的图像吗?似乎不为我工作:(
pkyeck '16

这取决于您的补丁是否强制重新创建Pod。最有可能的是,它不会再拉。您可以手动杀死Pod,也可以标记一些独特的东西并使用更新后的标记进行修补。
周六

这是对另一个问题的答案。我要求强制重新拉动。
Torsten Bronger '16

这使我能够从GCR强制撤资。我有一个:latest指向新图像的标签,并kubectl rolling-update努力更新了豆荚。
兰迪L

谢谢。适用于“推拉”方法。使用bash脚本将其尽可能多地自动化,但是同意,它很重:)
arcseldon

76

必须imagePullPolicy将容器数据分组而不是规范数据分组。但是,我对此提出了一个问题,因为我觉得很奇怪。此外,没有错误消息。

因此,此规范代码片段有效:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key

3
imagePullPolicy(或标记:latest)是一个很好的选择,如果您想一直拉,却不能解决按需拉的问题。
2016年

1
是的,正如问题中所述,我想一直拉。
Torsten Bronger '16

1
使用imagePullPolicy: Always容器定义中都会有kubernetes获取标签的图像:latest,只要他们的新版本推到注册表?
pkaramol

1
@pkaramol号imagePullPolicy: Always只是告诉Kubernetes总是从注册表中提取映像。它将通过image属性配置什么图像。如果将其配置为image: your-image:latest,则它将始终your-image使用latest标记拉取图像。
朱斯

25

在开发过程中,我的技巧是更改我的Deployment清单以添加最新标签,并始终像这样拉

image: etoews/my-image:latest
imagePullPolicy: Always

然后我手动删除吊舱

kubectl delete pod my-app-3498980157-2zxhd

因为是部署,所以Kubernetes会自动重新创建容器并提取最新映像。


我喜欢利用“部署”对象的“理想状态”前提...谢谢您的建议!
Marcello de Sales

2
值得注意的是,该策略仅在服务故障和停机时间可以容忍的情况下才可行。对于开发来说,这似乎是合理的,但我绝不会将这一策略用于生产部署。
digitaldreamer

正如Everett建议的那样,编辑部署,将imagePullPolicy更改为always并删除pod对我来说就足够了。这是一个开发环境。kubernetes.io/docs/concepts/containers/images
Jos Roberto

17

一种流行的解决方法是使用虚拟注释(或标签)修补部署:

kubectl patch deployment <name> -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

假设您的部署满足这些要求,这将导致K8拉动任何新映像并重新部署。


2
是的,为此使用注释。
Torsten Bronger

什么注释?
杰里尔·库克

1
另一个复杂的解决方案是将两者结合起来。添加一个注释并将其设置ImagePullPolicyAlways。注释喜欢deployment.kubernetes.io/revision: "v-someversion"kubernetes.io/change-cause: the reason可以对一成不变的部署非常有帮助和头上。
chandan


7

显然现在,当您使用与--image现有容器映像相同的参数运行滚动更新时,还必须指定一个--image-pull-policy。当与容器图像相同时,以下命令应强制拉出图像:

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b --image-pull-policy Always


6
# Linux

kubectl patch deployment <name> -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

# windows

kubectl patch deployment <name> -p (-join("{\""spec\"":{\""template\"":{\""metadata\"":{\""annotations\"":{\""date\"":\""" , $(Get-Date -Format o).replace(':','-').replace('+','_') , "\""}}}}}"))

3

现在,将命令kubectl rollout restart deploy YOUR-DEPLOYMENTimagePullPolicy: Always策略结合使用将使您可以使用映像的最新版本重新启动所有Pod。


3

当提供图像参数时,滚动更新命令假定该图像与复制控制器中当前存在的图像不同


这是否意味着图像标签(又名)必须不同?
Torsten Bronger

是的,如果您通过--image标志,则图像名称必须不同。
罗伯特·贝利

1
正如我自己的回答所说,如果图像名称相同,它也可以工作。仅仅是imagePullPolicy在错误的位置。为了我的辩护,k8s 1.0文档在这方面是错误的。
Torsten Bronger

当文档与行为不同步时,请点赞。:/
罗伯特·贝利

1
该网址也已过时。
Dan Tenenbaum


0

映像提取策略实际上总是在每次创建新容器时都帮助提取图像(在任何情况下,例如缩放副本或容器模具并创建新容器)

但是,如果要更新当前正在运行的Pod的映像,则部署是最佳方法。它使您的更新毫无瑕疵,没有任何问题(主要是当您将持久卷附加到Pod时):)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.