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

时间:2015-10-13 21:17:28

标签: image pull kubernetes

我在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

执行滚动更新,但没有重新拉动。为什么呢?

14 个答案:

答案 0 :(得分:71)

如果任何一个(参见updating-images doc):

,Kubernetes将会创建Pod
  • 使用标记为:latest
  • 的图片 指定了
  • imagePullPolicy: Always

如果你想永远拉扯,这很棒。但是,如果您想要按需,该怎么办?例如,如果您想使用some-public-image:latest,但只想在您要求时手动提取新版本。你现在可以:

  • imagePullPolicy设置为IfNotPresentNeverpre-pull:在每个群集节点上手动拉取图像,以便最新缓存,然后执行kubectl rolling-update或类似于重启Pods(丑陋容易破解黑客!)
  • 暂时更改imagePullPolicy,执行kubectl apply,重新启动广告连播(例如kubectl rolling-update),还原imagePullPolicy,重做{{1} (丑陋!)
  • kubectl apply拉入并推送到您的私人存储库并执行some-public-image:latest(重!)

没有很好的解决方案来解决这个问题。如果有变化,请评论;我会更新这个anwser。

答案 1 :(得分:37)

必须将imagePullPolicy分组到容器数据中,而不是在规范数据中。但是,我对此提出了issue,因为我发现它很奇怪。此外,没有错误信息。

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

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

答案 2 :(得分:16)

我在开发过程中的黑客攻击是更改我的部署清单以添加最新标记,并始终如此拉

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

然后我手动删除pod

kubectl delete pod my-app-3498980157-2zxhd

因为它是部署,Kubernetes会自动重新创建窗格并提取最新图像。

答案 3 :(得分:6)

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

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

答案 4 :(得分:6)

此答案旨在在您的节点已下载同名镜像的情况下强制拉取镜像,因此即使您将新镜像推送到容器注册表,当您启动一些 pod 时,您的 pod 也会显示“图像已经存在”。

对于 Azure Container Registry 中的一个案例(可能 AWS 和 GCP 也提供了这个):

  1. 您可以查看您的 Azure 容器注册表,通过检查清单创建日期,您可以确定哪个映像是最新的。

  2. 然后,复制其摘要哈希(格式为 sha256:xxx...xxx)。

  3. 您可以通过运行以下命令缩小当前副本。请注意,这显然会停止您的容器并导致停机。

kubectl scale --replicas=0 deployment <deployment-name> -n <namespace-name>
  1. 然后您可以通过运行以下命令获取 deployment.yaml 的副本:
kubectl get deployments.apps <deployment-name> -o yaml > deployment.yaml
  1. 然后将带有图像字段的行从 <image-name>:<tag> 更改为 <image-name>@sha256:xxx...xxx,保存文件。

  2. 现在您可以再次扩展您的副本。新图像将以其独特的摘要被拉取。

注意:假设容器中存在 imagePullPolicy: Always 字段。

答案 5 :(得分:5)

  1. 将策略指定为:
  strategy: 
    type: Recreate
    rollingUpdate: null
  1. 确保每个部署都有不同的注释。头盔就像这样:
  template:
    metadata:
      labels:
        app.kubernetes.io/name: AppName
        app.kubernetes.io/instance: ReleaseName
      annotations:
        rollme: {{ randAlphaNum 5 | quote }}
  1. 指定图像拉出策略-始终
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: Always

答案 6 :(得分:4)

滚动更新命令,当给定图像参数assumes that the image is different时,复制控制器中当前存在的参数。

答案 7 :(得分:4)

popular workaround将使用虚拟注释(或标签)来修补部署:

CREATE PROCEDURE name_p(IN modelNumber integer)
LANGUAGE plpgsql
AS $$
 BEGIN
 DELETE FROM product WHERE model = modelNumber;
 DELETE FROM pc WHERE model = modelNumber;
 END;
 $$;

假设您的部署为meets these requirements,这将导致K8拉动任何新映像并重新部署。

答案 8 :(得分:2)

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

但是,如果要更新当前正在运行的pod的映像,则部署是最好的方法。这样一来,您就可以进行完美无瑕的更新,而不会出现任何问题(主要是当您将持久卷附加到Pod时):)

答案 9 :(得分:1)

会有一个新的命令可以直接做到这一点:

创建一个新的kubectl rollout restart命令,该命令可滚动重启部署。

pull request被合并。它将是版本1.15changelog

的一部分

答案 10 :(得分:1)

您可以在部署文件中定义systrace

答案 11 :(得分:1)

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

答案 12 :(得分:1)

浏览了所有其他答案但并不满意,我在这里找到了更好的解决方案:https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps

无需使用 latest 标签或 imagePullPolicy: Always 即可工作。如果您通过指定图像 sha256 摘要将新图像推送到同一标签,它也可以工作。

步骤:

  1. 从 docker hub 获取图像 SHA256(见下图)
  2. kubectl set image deployment/<your-deployment> <your-pod-name>=<some/image>@sha256:<your sha>
  3. kubectl scale deployment <your-deployment>--replicas=0
  4. kubectl scale deployment <your-deployment>--replicas=original replicas count

注意:Rollout 也可以代替规模化,但在我的情况下,我们没有足够的硬件资源来创建另一个实例,k8s 卡住了。

docker hub sha256 location

答案 13 :(得分:0)

# 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('+','_') , "\""}}}}}"))