Argo CD Image Updater是一种自动更新由 Argo CD 管理的 Kubernetes 工作负载的容器镜像的工具。 该工具可以检查与 Kubernetes 工作负载一起部署的容器镜像的新版本,并使用 Argo CD 自动将其更新到允许的最新版本。它通过为 Argo CD 应用程序设置适当的应用程序参数来工作,类似于argocd app set --helm-set image.tag=v1.0.1,但以完全自动化的方式。
Argo CD Image Updater 会定期轮询 Argo CD 中配置的应用程序,并查询相应的镜像仓库以获取可能的新版本。如果在仓库中找到新版本的镜像,并且满足版本约束,Argo CD 镜像更新程序将指示 Argo CD 使用新版本的镜像更新应用程序。
根据您的应用程序自动同步策略,Argo CD 将自动部署新的镜像版本或将应用程序标记为不同步,您可以通过同步应用程序来手动触发镜像更新。
Image Updater 程序通过读取 ArgoCD 应用程序资源中的annotations来工作,这些注解指定应自动更新哪些镜像。它会检查指定镜像仓库中是否有较新的标签,如果它们与预定义的模式或规则匹配,则使用这些较新的标签更新应用程序清单。此自动化过程可确保您的应用程序始终运行最新版本的镜像,遵循 GitOps 的一致性和可追溯性原则。
Image Updater 基本的工作流程如下所示:
另外需要注意的是使用该工具目前有几个限制:
建议在运行 Argo CD 的同一个 Kubernetes 命名空间集群中运行 Argo CD Image Updater,但这不是必需的。事实上,甚至不需要在 Kubernetes 集群中运行 Argo CD Image Updater 或根本不需要访问任何 Kubernetes 集群。但如果不访问 Kubernetes,某些功能可能无法使用,所以强烈建议使用第一种安装方法。
运行镜像更新程序的最直接方法是将其作为 Kubernetes 工作负载安装到运行 Argo CD 的命名空间中。这样就不需要任何配置,也不会对你的工作负载产生任何影响。
kubectl apply -n argocd -f
安装完成后我们就可以在 Argo CD 中看到Argo CD Image Updater组件了:
$ kubectl get pods -n argocdNAMEREADYSTATUSRESTARTSAGEargocd-application-controller-01/1Running021margocd-applicationset-controller-587b5c864b-2kt2v1/1Running07d4hargocd-dex-server-6958d7dcf4-66s6s1/1Running07d4hargocd-image-updater-57b788886d-d4qh51/1Running034sargocd-notifications-controller-6847bd5c98-wqbjj1/1Running07d4hargocd-redis-6fcf5c8898-c67521/1Running07d4hargocd-repo-server-9646985c8-7dmj51/1Running07d4hargocd-server-67b76b54d7-hxx6q1/1Running07d4h
现在我们就可以直接去监听镜像是否发生了变化,而不需要在 CI 流水线中去手动提交修改资源清单到代码仓库了。
要充分利用 ArgoCD 镜像更新程序,将其配置连接到镜像仓库至关重要,尤其是在使用私有仓库或公共仓库上的私有存储库时。以下是如何配置必要的凭据并了解可用的不同方法。
ArgoCD Image Updater 可以使用以下方法获取凭据:
kubectl create -n argocd secret docker-registry dockerhub-secret \--docker-username someuser \--docker-password s0m3p4ssw0rd \--docker-server "https://registry-1.docker.io"
这个 secret 可以被引用为pullsecret:<namespace>/<secret_name>(pullsecret:argocd/dockerhub-secret)。
kubectl create -n argocd secret generic some-secret \--from-literal=creds=someuser:s0m3p4ssw0rd
该 secret 可以用secret:<namespace>/<secret_name>#<field_name>(secret:argocd/some-secret#creds) 的方式引用。
env:- name: DOCKER_HUB_CREDSvalue: "someuser:s0m3p4ssw0rd"
该 secret 可以用env:<name_of_environment_variable>(env:DOCKER_HUB_CREDS) 的方式引用。
#!/bin/shecho "someuser:s0m3p4ssw0rd"
将其引用为ext:<full_path_to_script>。
我们这里就以 Github 的 Container Registry 为例,来演示下如何使用 ArgoCD Image Updater 来更新镜像。
首先我们在 Github 个人设置页面中创建一个个人访问令牌,如下图所示:
这个 Token 的权限要包括write:packages和read:packages,这样我们才能推送和拉取镜像,创建后会得到一个 Token。
然后我们可以在终端或命令行中,使用 GitHub 用户名和 GitHub 的个人访问令牌(PAT)登录 GitHub Container Registry。
export PAT=<your-token>echo $PAT | docker login ghcr.io -u <your-github-username> --password-stdin
将替换为个人访问令牌,将替换为 GitHub 用户名。
登录成功后我们可以使用以下命令将 Docker 镜像标记为 GitHub Container Registry 镜像:
docker tag <your-image-name>:<tag> ghcr.io/<your-github-username>/<your-image-name>:<tag>
将<your-image-name>:<tag>替换为本地 Docker 镜像名与 tag 名,将<your-github-username>替换为 GitHub 用户名,<tag>替换想要使用的标签(例如默认的latest标签)。
然后使用以下命令将 Docker 镜像推送到 GitHub Container Registry 即可:
docker push ghcr.io/<your-github-username>/<your-image-name>:<tag>
完成以上步骤后,就可以在 GitHub 个人账号的 的Packages部分看到 Docker 镜像了,但是该镜像默认为 private 镜像,Pull 使用时需要先登录。
github packages
现在回到我们的镜像更新程序中,使用上面的 Token 来创建一个 Secret:
kubectl create -n argocd secret docker-registry ghcr-secret \--docker-username=cnych \--docker-password=$PAT \--docker-server="https://ghcr.io"
设置凭据后,将它们配置在 ArgoCD 镜像更新程序的配置中,以通过镜像仓库进行身份验证,我们可以修改镜像更新程序的配置:
apiVersion: v1kind: ConfigMapmetadata:name: argocd-image-updater-confignamespace: argocddata:registries.conf: |registries:- name: ghcr-hubapi_url:# 镜像仓库地址credentials: pullsecret:argocd/ghcr-secret # 凭据defaultns: library # 默认命名空间default: true # 默认仓库
上面配置中我们指定了 GitHub 镜像仓库的凭据为pullsecret:argocd/ghcr-secret,这样 ArgoCD Image Updater 在访问ghcr.io时就会使用这个凭据。
接下来我们还需要将 ArgoCD Image Updater 与 Git 集成,这也是重点,这样 ArgoCD Image Updater 就可以将镜像更新直接提交回源 Git 仓库。
我们可以在 ArgoCD 的 Dashboard 中先添加一个 Git 仓库:
add git repo
接下来我们可以按照正常使用方式创建一个新的Application对象,对应的资源清单文件如下所示:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: gitops-demonamespace: argocdspec:destination:namespace: gitops-demoserver:defaultsource:path: helm # 从 Helm 存储库创建应用程序时,chart 必须指定 pathrepoURL:masterhelm:parameters:- name: replicaCountvalue: "2"valueFiles:- my-values.yamlsyncPolicy:automated:prune: trueselfHeal: truesyncOptions:- CreateNamespace=true
直接创建上面的资源清单文件后,ArgoCD 会自动创建一个Application资源对象,并且会自动同步到 Git 仓库中,我们可以在 Git 仓库中看到对应的资源清单文件:
gitops-demo
如果该应用出现了如下所示的错误信息:
Namespacegitops-demoSyncFailedresource :Namespace is not permitted in project default
则表面当前使用的 project 没有权限创建 namespace,我们只需要为其添加对应的权限即可:
apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata:name: defaultnamespace: argocdspec:clusterResourceWhitelist: # 白名单,表示允许访问的资源- group: "*"kind: "*"destinations:- name: "*"namespace: "*"server: "*"sourceRepos:- "*"
我们可以使用argocd app get命令来查看Application资源对象的状态:
$ argocd app get argocd/gitops-demoName:argocd/gitops-demoProject:defaultServer:Repo:Values:my-values.yamlSyncWindow:Sync AllowedSync Policy:Automated (Prune)Sync Status:Synced to master (53d91ed)Health Status:ProgressingGROUPKINDNAMESPACENAMESTATUSHEALTHHOOKMESSAGENamespacegitops-demoRunningSyncednamespace/gitops-demo createdappsDeploymentdefaultgitops-demo-helm-guestbookSucceededPrunedprunedServicedefaultgitops-demo-helm-guestbookSucceededPrunedprunedServicegitops-demogitops-demo-devops-demoSyncedHealthyservice/gitops-demo-devops-demo createdappsDeploymentgitops-demogitops-demo-devops-demoSyncedProgressingdeployment.apps/gitops-demo-devops-demo creatednetworking.k8s.ioIngressgitops-demogitops-demo-devops-demoSyncedProgressingingress.networking.k8s.io/gitops-demo-devops-demo created
正常我们这个应用就可以运行了:
$ curl{"msg":"Hello Tekton On GitLab With ArgoCD"}
但是在 Dashboard 中我们可以看到应用虽然已经是Synced状态,但是APP HEALTH一直显示为Progressing状态。
这是因为 ArgoCD 的健康状态机制引起的,我们可以在源码中看到健康状态的检查逻辑。
func getIngressHealth(obj *unstructured.Unstructured) (*HealthStatus, error) { ingresses, _, _ := unstructured.NestedSlice(obj.Object, "status", "loadBalancer", "ingress") health := HealthStatus{} if len(ingresses) > 0 {health.Status = HealthStatusHealthy } else {health.Status = HealthStatusProgressing } return &health, nil}
他需要检查 Ingress 资源对象的status.loadBalancer.ingress字段是否为空,如果为空则表示健康状态为Progressing,否则为Healthy,但实际情况却是并不是所有的 Ingress 资源对象都会自动生成status.loadBalancer.ingress字段,比如我们这里就并没有生成。
这个时候我们可以通过配置argocd-cm的配置资源来修改健康状态检查逻辑,添加如下所示的配置:
apiVersion: v1kind: ConfigMapmetadata:name: argocd-cmnamespace: argocddata:resource.customizations: |networking.k8s.io/Ingress:health.lua: |hs = {}if obj.metadata ~= nil and obj.metadata.creationTimestamp ~= nil thenhs.status = "Healthy"hs.message = "Ingress 已创建"elsehs.status = "Progressing"hs.message = "Ingress 正在创建中"endreturn hs
上面的配置表示如果 Ingress 资源对象的metadata.creationTimestamp字段不为空,则表示健康状态为Healthy,否则为Progressing,更新上面的配置后,我们再次查看应用的健康状态就会发现已经变成了Healthy状态:
接下来我们就可以使用 ArgoCD Image Updater 来更新镜像了,修改上面的Application资源清单文件,我们需要添加一些注解来指定需要更新的镜像规则策略,如下所示:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: gitops-demonamespace: argocdannotations:argocd-image-updater.argoproj.io/image-list: myalias=ghcr.io/cnych/gitops-demo # 指定镜像仓库argocd-image-updater.argoproj.io/myalias.allow-tags: regexp:^.*$ # 允许所有标签argocd-image-updater.argoproj.io/myalias.pull-secret: pullsecret:argocd/ghcr-secret # 指定凭据argocd-image-updater.argoproj.io/myalias.update-strategy: latest # 指定更新策略# argocd-image-updater.argoproj.io/myalias.ignore-tags: latest, master # 指定忽略的标签argocd-image-updater.argoproj.io/write-back-method: git # 指定写回方法argocd-image-updater.argoproj.io/git-branch: master # 指定 Git 分支argocd-image-updater.argoproj.io/myalias.force-update: "true" # 强制更新spec:destination:namespace: gitops-demoserver:defaultsource:path: helm # 从 Helm 存储库创建应用程序时,chart 必须指定 pathrepoURL:masterhelm:parameters:- name: replicaCountvalue: "2"valueFiles:- my-values.yamlsyncPolicy:automated:prune: trueselfHeal: truesyncOptions:- CreateNamespace=true
这个新的资源对象中,我们添加了一些注释,这些注释用于配置 Argo CD Image Updater。这些配置用于指定自动更新容器镜像的策略、参数和相关信息。以下是对这些注释的详细解释:
现在我们重新更新 Application 资源对象即可。接下来我们只需要重新推送一个新的镜像到 GitHub Container Registry 即可自动触发 ArgoCD Image Updater 更新镜像。
我们更新下仓库中的main.go文件:
修改代码
现在我们重新构建一个新的镜像并推送到 GitHub Container Registry:
docker build --platform linux/amd64 -t ghcr.io/cnych/gitops-demo:v0.1.1 .docker push ghcr.io/cnych/gitops-demo:v0.1.1
推送新的镜像后,然后Argo CD Image Updater将会每 2 分钟从镜像仓库去检索镜像版本变化,一旦发现有新的镜像版本,它将自动使用新版本来更新集群内工作负载的镜像,并将镜像版本回写到 Git 仓库中去,我们可以去查看 Argo CD Image Updater 的日志变化:
$ kubectl logs -f argocd-image-updater-57b788886d-d4qh5 -n argocdtime="2024-09-27T06:51:32Z" level=info msg="argocd-image-updater v0.14.0+af844fe starting [loglevel:INFO, interval:2m0s, healthport:8080]"time="2024-09-27T06:51:32Z" level=warning msg="commit message template at /app/config/commit.template does not exist, using default"time="2024-09-27T08:35:39Z" level=warning msg="\"latest\" strategy has been renamed to \"newest-build\". Please switch to the new convention as support for the old naming convention will be removed in future versions." image_alias=myalias image_name=ghcr.io/cnych/gitops-demo registry_url=ghcr.iotime="2024-09-27T08:35:40Z" level=info msg="Processing results: applicatinotallow=1 images_cnotallow=1 images_skipped=0 images_updated=0 errors=0"xxxxxxxxxxxxxxtime="2024-09-27T08:37:40Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update"time="2024-09-27T08:37:40Z" level=warning msg="\"latest\" strategy has been renamed to \"newest-build\". Please switch to the new convention as support for the old naming convention will be removed in future versions." image_alias=myalias image_name=ghcr.io/cnych/gitops-demo registry_url=ghcr.iotime="2024-09-27T08:37:44Z" level=info msg="Setting new image to ghcr.io/cnych/gitops-demo:v0.1.1" alias=myalias applicatinotallow=gitops-demo image_name=cnych/gitops-demo image_tag=latest registry=ghcr.iotime="2024-09-27T08:37:44Z" level=info msg="Successfully updated image 'ghcr.io/cnych/gitops-demo:latest' to 'ghcr.io/cnych/gitops-demo:v0.1.1', but pending spec update (dry run=false)" alias=myalias applicatinotallow=gitops-demo image_name=cnych/gitops-demo image_tag=latest registry=ghcr.iotime="2024-09-27T08:37:44Z" level=info msg="Committing 1 parameter update(s) for application gitops-demo" applicatinotallow=gitops-demotime="2024-09-27T08:37:44Z" level=info msg="Starting configmap/secret informers"time="2024-09-27T08:37:44Z" level=info msg="Configmap/secret informer synced"time="2024-09-27T08:37:44Z" level=info msg="Initializingto /tmp/git-gitops-demo1873820104"time="2024-09-27T08:37:44Z" level=info msg="secrets informer cancelled"time="2024-09-27T08:37:44Z" level=info msg="configmap informer cancelled"time="2024-09-27T08:37:44Z" level=info msg="git fetch origin --tags --force --prune" dir=/tmp/git-gitops-demo1873820104 execID=acebctime="2024-09-27T08:37:46Z" level=info msg=Trace args="[git fetch origin --tags --force --prune]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=1640.146246time="2024-09-27T08:37:46Z" level=info msg="git config user.name argocd-image-updater" dir=/tmp/git-gitops-demo1873820104 execID=7ec2dtime="2024-09-27T08:37:46Z" level=info msg=Trace args="[git config user.name argocd-image-updater]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=1.5687190000000002time="2024-09-27T08:37:46Z" level=info msg="git config user.email noreply@argoproj.io" dir=/tmp/git-gitops-demo1873820104 execID=6e796time="2024-09-27T08:37:46Z" level=info msg=Trace args="[git config user.email noreply@argoproj.io]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=1.688394time="2024-09-27T08:37:46Z" level=info msg="git checkout --force master" dir=/tmp/git-gitops-demo1873820104 execID=403bbtime="2024-09-27T08:37:46Z" level=info msg=Trace args="[git checkout --force master]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=4.522311time="2024-09-27T08:37:46Z" level=info msg="git clean -ffdx" dir=/tmp/git-gitops-demo1873820104 execID=b3f03time="2024-09-27T08:37:46Z" level=info msg=Trace args="[git clean -ffdx]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=1.429556time="2024-09-27T08:37:46Z" level=info msg="git -c gpg.format=openpgp commit -a -F /tmp/image-updater-commit-msg441967746" dir=/tmp/git-gitops-demo1873820104 execID=0efc6time="2024-09-27T08:37:46Z" level=info msg=Trace args="[git -c gpg.format=openpgp commit -a -F /tmp/image-updater-commit-msg441967746]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=5.239213time="2024-09-27T08:37:46Z" level=info msg="git push origin master" dir=/tmp/git-gitops-demo1873820104 execID=fcd1ftime="2024-09-27T08:37:47Z" level=info msg=Trace args="[git push origin master]" dir=/tmp/git-gitops-demo1873820104 operation_name="exec git" time_ms=1934.14529time="2024-09-27T08:37:47Z" level=info msg="Successfully updated the live application spec" applicatinotallow=gitops-demotime="2024-09-27T08:37:47Z" level=info msg="Processing results: applicatinotallow=1 images_cnotallow=1 images_skipped=0 images_updated=1 errors=0"
然后在 Git 仓库中我们也可以看到有一条新的 commit 提交记录,可以看到在回写时,ArgoCD Image Updater并不会直接修改仓库的values.yaml文件,而是会创建一个专门用于覆盖 Helm Chartvalues.yaml的.argocd-source-devops-demo.yaml文件。
自动提交变更后,Argo CD 就会自动同步部署应用了。
当然现在访问应用结果就是我们更改后的内容了:
$ curl{"msg":"Hello ArgoCD With Image Updater"}
另外我们可以注意到每次 Git 提交都与作者的姓名和电子邮件地址相关联。如果未配置,Argo CD 镜像更新程序执行的提交将使用argocd-image-updater <noreply@argoproj.io>作为作者。您可以使用--git-commit-user和--git-commit-email命令行开关覆盖作者,或在argocd-image-updater-config ConfigMap中设置git.user和git.email即可。
同样我们可以将 Argo CD Image Updater 使用的默认提交消息更改为适合你的方式。可以创建一个简单的模板(使用 Golang Template),并通过将argocd-image-updater-configConfigMap 中的密钥git.commit-message-template设置为模板的内容来使其可用,例如:
data:git.commit-message-template: |build: automatic update of {{ .AppName }}{{ range .AppChanges -}}updates image {{ .Image }} tag '{{ .OldTag }}' to '{{ .NewTag }}'{{ end -}}
模板中提供了两个顶级变量:
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://www.jmbhsh.com/baihuokuaixun/36377.html