如何在Kubernetes上发布新构建版本时自动更新容器映像?

uqjltbpv  于 2023-01-01  发布在  Kubernetes
关注(0)|答案(6)|浏览(194)

我有一个私有存储库。我想在我的私有存储库中更新容器映像时,自动更新Kubernetes中的映像。如何实现这一点?

jckbn6z7

jckbn6z71#

Kubernetes本机没有在有新映像时自动重新部署pod的功能。理想情况下,您需要的是一个支持GitOps风格部署的工具,其中git中的状态更改将同步到Kubernetes集群。有FluxArgoCD开源工具支持GitOps。
最近有一个announcement将这两个项目合并为ArgoFlux。

wribegjk

wribegjk2#

你应该为每个构建分配某种唯一的标识符,它可以基于一个源码控制标记(如果你显式地标记发行版),一个提交ID,一个构建号,一个时间戳,或者其他的东西;但重要的细节是每个构建都创建一个具有唯一名称的唯一映像。
一旦您这样做了,那么您的CI系统需要用一个新的image:更新部署规范。如果您正在使用Kustomize或Helm这样的工具,有一些标准模式可以提供这个功能;如果您直接使用kubectl apply,那么在应用它之前,它需要以某种方式修改部署规范。
这些因素的结合意味着部署的嵌入式pod规范将发生实质性的变化(它的image:已经改变了),这将导致Kubernetes部署控制器自动为您做一个滚动更新。普通的Kubernetes回滚机制将工作良好(因为带有昨天标记的映像仍在存储库中)。您无需手动设置imagePullPolicy:或手动重新启动部署,改变部署中的图像标签就足以使正常的滚动显示发生。

uqzxnwby

uqzxnwby3#

看看各种各样的图像拉动策略。
imagePullPolicy: always可能最接近您的需要,我不知道是否有一种方法在“香草”K8实现自动图像拉取,但我知道RedHat的OpenShift(或OKD,免费版本)与image streams一起工作,这正是您所要求的。

t1qtbnec

t1qtbnec4#

imagePullPolicy和映像的标记会影响Kubelet何时尝试拉取指定的映像。
imagePullPolicy: IfNotPresent:仅当映像不在本地时才拉取映像。

imagePullPolicy: Always:每次启动pod时都会提取映像。

imagePullPolicy被省略,并且图像标签为:latest或被省略:始终应用。
imagePullPolicy被省略,并且图像标签存在,但不存在:latest:应用了IfNotPresent。
imagePullPolicy: Never:假定映像存在于本地。不尝试拉取映像。
因此,要实现这一点,你必须***设置imagePullPolicy: Always并重新启动你的pod***,它应该拉一个最新的映像副本。我不认为在K8s中有任何其他方法
容器图像

7xzttuei

7xzttuei5#

我刚刚编写了一个bash脚本来实现这一点。我的imagePullPolicy选项是always,我正在使用crontab运行此脚本。(您可以使用无限循环每次检查)。它正在检查存储库,如果发生任何更改,它将删除pod(由于imagePullPolicy设置为Always,因此会自动删除)并拉取更新的映像。

#!/bin/bash
registry="repository_name"
username="user_name"
password="password"

##BY this you can append all images from repository to the array
#images=($( echo $(curl -s https://"$username":"$password"@"$registry"/v2/_catalog | jq .repositories | jq .[])))
##Or you can set manuaaly your image array
images=( image_name_0 image_name_1 )
for i in "${images[@]}"
do
old_image=$(cat /imagerecords/"$i".txt)
new_image=$(echo $(curl -s https://"$username":"$password"@"$registry"/v2/"$i"/manifests/latest | jq ."fsLayers" | jq .[]))

if [ "$old_image" == "$new_image" ];then
echo "image: "$i" is already up-to-date"
else
echo "image: " $i" is updating"
kubectl delete pod pod_name
echo $new_image > /imagerecords/"$i".txt
fi
done

相关问题