我有以下复制控制器在Kubernetes上的GKE:
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
执行滚动更新,但不重新拉取。为什么?
Kubernetes将在Pod创建时拉动(参见updates -images doc):
使用标记为:最新的图像
imagePullPolicy:始终被指定
如果你想一直拉,这很好。但如果您想按需执行该操作:例如,如果您想使用某些公共映像:latest,但只希望在您要求时手动提取更新的版本。您目前可以:
将imagePullPolicy设置为IfNotPresent或Never并预拉:在每个集群节点上手动拉出最新的图像,以便缓存最新的图像,然后执行kubectl滚动更新或类似的重启Pods(丑陋的容易破坏的hack!)
临时更改imagePullPolicy,执行kubectl apply,重新启动pod(例如kubectl roll -update),恢复imagePullPolicy,重做kubectl apply(难看!)
Pull - push一些公共映像:最新的到您的私有存储库,并执行kubectl滚动更新(重!)
没有好的解决方案按需拉。如果有变化,请评论;我会更新这个答案。
这个答案的目的是在节点已经下载了同名图像的情况下强制拉取图像,因此即使您将新图像推到容器注册表中,当您启动一些pod时,您的pod会显示“image already present”。
对于Azure容器注册表中的一个案例(可能AWS和GCP也提供了这个):
您可以查看Azure容器注册表,通过检查清单创建日期,可以确定哪个映像是最近的映像。
然后,复制它的摘要散列(格式为sha256:xxx…xxx)。
您可以通过运行下面的命令来缩小当前的副本。注意,这显然会停止容器并导致停机。
kubectl scale --replicas=0 deployment <deployment-name> -n <namespace-name>
然后您可以获得部署的副本。通过运行Yaml:
kubectl get deployments.apps <deployment-name> -o yaml > deployment.yaml
然后将带有图像字段的行从<image-name>:<tag>更改为<image-name>@sha256:xxx…Xxx,保存文件。
现在你可以再次放大你的复制品了。新图片将以其独特的摘要被拉出。
注意:假设imagePullPolicy: Always字段存在于容器中。
看了所有其他的答案,我还不满意,我在这里找到了更好的解决方案:https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps
它不使用latest标签或imagePullPolicy: Always。如果您通过指定image sha256文摘将新图像推到相同的标记,它也可以工作。
步骤:
从docker hub获取SHA256图像(见下图)
Kubectl set image deploy /<your-deployment> <your_container_name>=<some/image>@sha256:<your sha>
Kubectl规模部署<your-deployment>——replicas=0
Kubectl规模部署<your-deployment>——replicas=原始副本计数
注意:Rollout也可以代替scale工作,但在我的情况下,我们没有足够的硬件资源来创建另一个实例,k8s卡住了。