我在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
执行滚动更新,但没有重新拉动。为什么呢?
答案 0 :(得分:71)
如果任何一个(参见updating-images doc):
,Kubernetes将会创建Pod:latest
imagePullPolicy: Always
如果你想永远拉扯,这很棒。但是,如果您想要按需,该怎么办?例如,如果您想使用some-public-image:latest
,但只想在您要求时手动提取新版本。你现在可以:
imagePullPolicy
设置为IfNotPresent
或Never
和pre-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 也提供了这个):
您可以查看您的 Azure 容器注册表,通过检查清单创建日期,您可以确定哪个映像是最新的。
然后,复制其摘要哈希(格式为 sha256:xxx...xxx
)。
您可以通过运行以下命令缩小当前副本。请注意,这显然会停止您的容器并导致停机。
kubectl scale --replicas=0 deployment <deployment-name> -n <namespace-name>
kubectl get deployments.apps <deployment-name> -o yaml > deployment.yaml
然后将带有图像字段的行从 <image-name>:<tag>
更改为 <image-name>@sha256:xxx...xxx
,保存文件。
现在您可以再次扩展您的副本。新图像将以其独特的摘要被拉取。
注意:假设容器中存在 imagePullPolicy: Always 字段。
答案 5 :(得分:5)
strategy:
type: Recreate
rollingUpdate: null
template:
metadata:
labels:
app.kubernetes.io/name: AppName
app.kubernetes.io/instance: ReleaseName
annotations:
rollme: {{ randAlphaNum 5 | quote }}
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.15
(changelog)
答案 10 :(得分:1)
您可以在部署文件中定义systrace
。
答案 11 :(得分:1)
现在,将命令kubectl rollout restart deploy YOUR-DEPLOYMENT
与imagePullPolicy: Always
策略结合使用,您可以使用最新版本的映像重新启动所有pod。
答案 12 :(得分:1)
浏览了所有其他答案但并不满意,我在这里找到了更好的解决方案:https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps
无需使用 latest 标签或 imagePullPolicy: Always 即可工作。如果您通过指定图像 sha256 摘要将新图像推送到同一标签,它也可以工作。
步骤:
kubectl set image deployment/<your-deployment> <your-pod-name>=<some/image>@sha256:<your sha>
kubectl scale deployment <your-deployment>--replicas=0
kubectl scale deployment <your-deployment>--replicas=original replicas count
注意:Rollout 也可以代替规模化,但在我的情况下,我们没有足够的硬件资源来创建另一个实例,k8s 卡住了。
答案 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('+','_') , "\""}}}}}"))