ArgoCD Image Updater 完全实战指南
1. 环境准备
1.1 创建 Kind 集群
在开始之前,我们需要一个实验环境。如果你没有现成的Kubernetes集群,可以基于kind搭建测试集群快速创建一个:
配置文件:
kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4networking: apiServerAddress: "10.10.151.201"nodes:- role: control-plane extraPortMappings: - containerPort: 6443 hostPort: 6443 listenAddress: "10.10.151.201" protocol: tcp- role: control-plane- role: control-plane- role: worker- role: worker- role: worker创建高可用集群命令:
sudo kind create cluster --config=huari.yaml --name huari-test --image kindest/node:v1.34.0 --retain; sudo kind export logs --name huari-test切换kubectl上下文:
sudo kubectl cluster-info --context kind-huari-test查看信息:
# 查看集群节点sudo kubectl get nodes
# 查看集群全部的podsudo kubectl get pods -A -owide删除集群:
sudo kind delete cluster --name huari-test2. 安装 ArgoCD
参考argocd简介及多种模式部署来在kind集群安装ArgoCD。
2.1 部署 ArgoCD
# 更新helm repohelm repo add argo https://argoproj.github.io/argo-helmhelm repo update
# 部署argocdhelm upgrade --install argocd argo/argo-cd \ --version 7.3.5 \ --namespace argo \ --create-namespace如果网络存在问题,也可以从本地chart进行安装:
helm pull argo/argo-cd --version 7.3.5helm upgrade --install argocd ./argo-cd-7.3.5.tgz \ --namespace argo \ --create-namespace2.2 暴露 ArgoCD 服务
# 使用端口转发访问 UIkubectl port-forward svc/argocd-server -n argo 8080:443 --address 0.0.0.02.3 获取初始密码
# 获取初始管理员密码kubectl -n argo get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d3. 安装 ArgoCD Image Updater
3.1 安装 Image Updater
helm install argocd-image-updater argo/argocd-image-updater --namespace argo --create-namespace --set installCRDs=true
# 等待部署完成kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-image-updater -n argo --timeout=300s3.2 验证安装
# 确认 Pod 正常运行kubectl get pods -n argo -l app.kubernetes.io/name=argocd-image-updater
# 确认 ImageUpdater CRD 已安装(v1.x 必须有此 CRD)kubectl get crd | grep imageupdater# 期望输出:imageupdaters.argocd-image-updater.argoproj.ioCRD 缺失处理:若上一条命令无输出,说明 Helm chart 版本较旧未包含 v1.x CRD,手动补装:
kubectl apply -f https://github.com/argoproj-labs/argocd-image-updater/releases/download/v1.1.0/install.yaml或升级 Helm chart:
helm upgrade argocd-image-updater argo/argocd-image-updater --namespace argo --set installCRDs=true
# 查看 Image Updater 日志(controller 名称为 argocd-image-updater-controller)kubectl logs -n argo deployment/argocd-image-updater-controller -f4. 配置镜像仓库访问
4.1 配置私有仓库(可选)
如果你使用私有镜像仓库(如 Docker Hub、Harbor、阿里云 ACR 等),需要配置访问凭证:
创建 Secret:
# Docker Hubkubectl create secret docker-registry dockerhub-secret \ --docker-username=your-username \ --docker-password=your-password \ -n argo
# 或者阿里云 ACRkubectl create secret docker-registry aliyun-acr-secret \ --docker-server=registry.cn-hangzhou.aliyuncs.com \ --docker-username=your-username \ --docker-password=your-password \ -n argo配置 Image Updater 使用 Secret:
编辑 ConfigMap:
kubectl edit configmap argocd-image-updater-config -n argo添加仓库配置:
apiVersion: v1kind: ConfigMapmetadata: name: argocd-image-updater-config namespace: argodata: registries.conf: | registries: - name: Docker Hub api_url: https://registry-1.docker.io ping: yes credentials: pullsecret:argo/dockerhub-secret - name: Aliyun ACR api_url: https://registry.cn-hangzhou.aliyuncs.com ping: yes credentials: pullsecret:argo/aliyun-acr-secret重启 Image Updater:
kubectl rollout restart deployment argocd-image-updater-controller -n argo5. 验证安装(test 命令实战)
安装完成后,建议先使用 test 子命令验证 Image Updater 能否正常访问镜像仓库,无需修改任何 ArgoCD 应用配置,是排查问题的最快途径。
v1.x 架构说明:从 v1.0 开始,controller 的 entrypoint 改为
/manager(Kubernetes controller-manager 模式),Pod 内不再内置argocd-image-updaterCLI binary。test命令需在本地单独下载 CLI binary 运行。
5.1 下载 CLI binary
# 查看集群中安装的版本kubectl get pod -n argo -l app.kubernetes.io/name=argocd-image-updater \ -o jsonpath='{.items[0].spec.containers[0].image}'# 示例输出:quay.io/argoprojlabs/argocd-image-updater:v1.1.0
# 下载对应版本的 CLI binary(以 v1.1.0 linux/amd64 为例)curl -Lo argocd-image-updater \ https://github.com/argoproj-labs/argocd-image-updater/releases/download/v1.1.0/argocd-image-updater-linux_amd64chmod +x argocd-image-updater5.2 基础测试
# 基本测试(默认使用 semver 策略,查看 nginx 的最新版本)./argocd-image-updater test nginx --loglevel info预期输出:
INFO[0000] retrieving information about image command=test image_name=nginx image_registry=INFO[0000] Fetching available tags and metadata from registry command=test image_name=nginx image_registry=INFO[0001] Found 1049 tags in registry command=test image_name=nginx image_registry=INFO[0001] latest image according to constraint is nginx:1.29.5 command=test image_name=nginx image_registry=5.3 测试 semver 版本约束
# 查看 nginx 1.17.x 分支中的最新 patch 版本./argocd-image-updater test nginx --semver-constraint "1.17.x" --loglevel info# 预期:latest image according to constraint is nginx:1.17.105.4 测试不同更新策略
# newest-build 策略(按构建时间排序,适合 CI 产出的非 semver 镜像)./argocd-image-updater test ghcr.io/argoproj/argocd \ --update-strategy newest-build --loglevel info5.5 测试私有仓库(使用环境变量传入凭证)
export REGISTRY_CREDS="myuser:mypassword"./argocd-image-updater test registry.cn-hangzhou.aliyuncs.com/your-ns/your-image \ --credentials env:REGISTRY_CREDS --loglevel info多架构注意:
test命令默认采用当前运行机器的平台架构。在 Mac 上运行时大多数镜像找不到结果,需通过--platforms linux/amd64指定目标平台。
5.6 调整日志级别(便于调试)
Image Updater 默认日志级别为 info,首次使用建议调成 debug:
kubectl edit configmap argocd-image-updater-config -n argo在 data 下添加:
data: log.level: debug修改后重启:
kubectl rollout restart deployment argocd-image-updater-controller -n argo6. 更新策略详解
更新策略决定 Image Updater 如何从镜像仓库中筛选”最新”镜像,默认策略为 semver。
6.1 semver(默认,推荐生产环境)
适用场景:遵循语义化版本(x.y.z)的镜像。
版本约束直接附加在镜像名称后:
| 配置示例 | 含义 |
|---|---|
nginx:1.x | 允许升级到 1.x 任意版本(不跨大版本) |
nginx:1.25.x | 仅允许 1.25 的 patch 更新 |
nginx:2.x-0 | 允许包含预发布版本(如 2.0-rc1) |
nginx(无约束) | 取仓库中所有 semver tag 的最高版本 |
v前缀可选,v1.x与1.x等效。当前运行的 tag 不需要符合 semver,Image Updater 会直接从仓库找到满足约束的最新版本。
6.2 newest-build(原 latest,按构建时间)
适用场景:镜像 tag 不遵循 semver,使用 Git commit SHA 或 CI 流水线生成的随机标签。
⚠️ 此策略需要拉取每个 tag 的 manifest 以获取构建时间,会消耗 Docker Hub 免费账户的 pull 配额,不推荐在 Docker Hub 公共镜像上使用。
通常需配合 allowTags 过滤标签,避免误选 latest、master 等:
commonUpdateSettings: updateStrategy: "newest-build" allowTags: "regexp:^[0-9a-f]{7}$" # 仅匹配 7 位 git commit sha ignoreTags: ["latest", "master"] # 排除特定标签注意:如果使用可复现构建(每次构建的镜像创建时间相同),此策略无法正确区分版本。
6.3 digest(追踪可变标签)
适用场景:追踪 latest、dev、staging 等可变标签。当镜像内容(digest)变化时触发更新,标签名本身不变。
其余策略(semver、newest-build、alphabetical)均假设 tag 不可变;如需追踪可变 tag,必须用 digest 策略。
6.4 alphabetical(原 name,按字典序)
适用场景:使用日历版本(calver)或其他可字典序排序的标签,如 2024-01-15、YYYYMMDD 格式。
按标签名称字典序降序排列,取最大值。
commonUpdateSettings: updateStrategy: "alphabetical" allowTags: "regexp:^[0-9]{4}-[0-9]{2}-[0-9]{2}$" # 仅匹配 YYYY-MM-DD 格式策略名称变更说明(stable 版本):
| 旧名称(已废弃) | 新名称(推荐) |
|---|---|
latest | newest-build |
name | alphabetical |
继续使用旧名称会在 Image Updater 日志中产生警告,未来版本将移除对旧名称的支持。
7. 配置应用自动更新(ImageUpdater CR)
Image Updater 通过 ImageUpdater CR 声明要监控哪些应用的哪些镜像以及如何写回。
操作前提:必须先创建 ArgoCD Application,再创建 ImageUpdater CR。顺序颠倒时 controller 会报
No applications found in target namespace并跳过所有处理。
7.1 CR 字段速查
| 字段 | 是否必填 | 说明 |
|---|---|---|
metadata.namespace | 必填 | 必须与 ArgoCD 同命名空间(如 argo) |
spec.namespace | 必填 | ArgoCD Application 所在的命名空间 |
spec.writeBackConfig.method | 可选 | argocd(默认)或 git |
spec.applicationRefs[].namePattern | 必填 | glob 模式匹配 Application 名称,精确匹配直接写名字 |
spec.applicationRefs[].labelSelectors | 可选 | 与 namePattern 组合过滤 Application |
spec.applicationRefs[].images[].alias | 必填 | 此镜像的别名,同一 appRef 内唯一 |
spec.applicationRefs[].images[].imageName | 必填 | 镜像全名,semver 约束直接附加(如 nginx:1.x) |
spec.commonUpdateSettings.updateStrategy | 可选 | 全局默认策略,可被应用级/镜像级覆盖 |
配置优先级(从高到低):镜像级 > 应用级 > 全局级。
7.2 实操:单镜像更新(argocd 写回)
argocd写回方式直接修改集群中 Application 资源的 source 参数,无需 Git 写权限,适合快速验证和非 Git 管理的 Application。
步骤 0:清理旧资源(如有)
# 删除可能存在的旧 Application 和 ImageUpdater CR,避免配置冲突kubectl delete application nginx-test -n argo --ignore-not-foundkubectl delete imageupdater nginx-test-updater -n argo --ignore-not-found步骤 1:创建 Application
cat <<EOF | kubectl apply -f -apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nginx-test namespace: argospec: project: default source: repoURL: docker.m.daocloud.io/bitnamicharts # OCI Helm 仓库 chart: nginx targetRevision: 18.3.6 helm: parameters: - name: image.registry value: docker.io - name: image.repository value: library/nginx # 改为官方 nginx 仓库 - name: image.tag value: "1.24.0" # 官方 nginx 存在该 tag - name: global.security.allowInsecureImages value: "true" # 可选,对官方镜像无影响 destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueEOF说明:bitnami 已将 Helm 仓库从传统 HTTP 格式(
https://charts.bitnami.com/bitnami)迁移至 OCI 格式(oci://registry-1.docker.io/bitnamicharts)。ArgoCD 使用 OCI 时repoURL不加oci://前缀,直接写域名路径即可。国内使用docker.m.daocloud.io/bitnamicharts作为代理。
等待 Application 同步(STATUS 变为 Synced,HEALTH 变为 Healthy):
kubectl get application nginx-test -n argo -w步骤 2:创建 ImageUpdater CR
cat <<EOF | kubectl apply -f -apiVersion: argocd-image-updater.argoproj.io/v1alpha1kind: ImageUpdatermetadata: name: nginx-test-updater namespace: argospec: namespace: argo writeBackConfig: method: argocd applicationRefs: - namePattern: "nginx-test" images: - alias: nginx imageName: docker.io/library/nginx:1.x # 版本约束直接写在 imageName 中 commonUpdateSettings: updateStrategy: semver manifestTargets: helm: tag: "image.tag" # 映射到 Helm 参数 image.tagEOF步骤 3:观察日志(每 2 分钟轮询一次)
kubectl logs -n argo deployment/argocd-image-updater-controller -f|grep images_updated=1首次更新成功时的关键日志:
level=info msg="Successfully updated image 'docker.io/nginx:1.24.0' to 'docker.io/nginx:1.29.5'
level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0说明:如果日志显示
already on latest allowed version,说明当前 tag(1.24.0)已是1.x约束下的最新版本。此时可以:
- 手动降低 Application 的 tag 到更低版本(如
1.23.0)来演示更新功能:kubectl patch application nginx-test -n argo --type='json' \-p='[{"op":"replace","path":"/spec/source/helm/parameters/2/value","value":"1.23.0"}]'- 或者改用更宽松的版本约束(如
1.27.x),前提是镜像仓库中有对应版本。
步骤 4:验证更新结果
通过以下命令判断 ImageUpdater 是否真正工作:
# 1. 查看 Application 的 image.tag 参数是否已被自动更新kubectl get application nginx-test -n argo \ -o jsonpath='{.spec.source.helm.parameters[?(@.name=="image.tag")].value}'# 期望输出:1.29.5(或其他最新版本,而不是初始的 1.25.0)
# 2. 查看 Application 同步状态和实际运行的镜像版本kubectl get application nginx-test -n argo \ -o jsonpath='{.status.sync.status} {.status.summary.images}'# 期望输出:Synced ["docker.io/nginx:1.29.5"]
# 3. 查看 Application 的完整更新历史kubectl get application nginx-test -n argo \ -o jsonpath='{.status.history[*].source.helm.parameters[?(@.name=="image.tag")].value}'# 期望输出:1.25.0 1.29.5(显示从旧版本更新到新版本的历史)
# 4. 查看 ImageUpdater CR 状态kubectl describe imageupdater nginx-test-updater -n argo清理:
kubectl delete imageupdater nginx-test-updater -n argokubectl delete application nginx-test -n argo7.3 实操:多应用批量管理(namePattern 通配)
用一个 ImageUpdater CR 同时管理多个命名相似的 Application。
步骤 1:创建两个测试 Application
# nginx-test(已在 7.2 创建,若已清理需重新创建)cat <<EOF | kubectl apply -f -apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nginx-test namespace: argospec: project: default source: repoURL: docker.m.daocloud.io/bitnamicharts chart: nginx targetRevision: "18.3.6" helm: parameters: - name: image.registry value: docker.io - name: image.repository value: library/nginx - name: image.tag value: "1.24.0" - name: global.security.allowInsecureImages value: "true" destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: {prune: true, selfHeal: true} syncOptions: [CreateNamespace=true]EOF
# redis-testcat <<EOF | kubectl apply -f -apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: redis-test namespace: argospec: project: default source: repoURL: docker.m.daocloud.io/bitnamicharts chart: redis targetRevision: "20.6.0" helm: parameters: - name: image.registry value: docker.io - name: image.repository value: library/redis - name: image.tag value: "7.0.0" - name: global.security.allowInsecureImages value: "true" destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: {prune: true, selfHeal: true} syncOptions: [CreateNamespace=true]EOF确认两个 Application 都已创建:
kubectl get application -n argo步骤 2:创建 ImageUpdater CR(同时管理两个 Application)
cat <<EOF | kubectl apply -f -apiVersion: argocd-image-updater.argoproj.io/v1alpha1kind: ImageUpdatermetadata: name: multi-app-updater namespace: argospec: namespace: argo writeBackConfig: method: "argocd" applicationRefs: - namePattern: "nginx-test" images: - alias: "nginx" imageName: "docker.io/library/nginx:1.x" commonUpdateSettings: updateStrategy: "semver" - namePattern: "redis-test" images: - alias: "redis" imageName: "docker.io/library/redis:7.x" commonUpdateSettings: updateStrategy: "semver"EOF步骤 3:观察日志
kubectl logs -n argo deployment/argocd-image-updater-controller -f首次更新成功时的关键日志:
level=info msg="Processing results: applications=2 images_considered=2 images_skipped=0 images_updated=2 errors=0"清理:
kubectl delete imageupdater multi-app-updater -n argokubectl delete application nginx-test redis-test -n argo7.4 实操:标签选择器批量匹配
通过给 Application 打标签,用 labelSelectors 自动匹配一批 Application,适合按团队、环境等维度管理。
步骤 1:创建带标签的 Application
cat <<EOF | kubectl apply -f -apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nginx-test namespace: argo labels: env: test team: platformspec: project: default source: repoURL: docker.m.daocloud.io/bitnamicharts chart: nginx targetRevision: "18.3.6" helm: parameters: - name: image.registry value: docker.io - name: image.repository value: library/nginx - name: image.tag value: "1.24.0" - name: global.security.allowInsecureImages value: "true" destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: {prune: true, selfHeal: true} syncOptions: [CreateNamespace=true]EOF步骤 2:创建 ImageUpdater CR(通过标签匹配)
namePattern: "*" 表示不限名称,配合 labelSelectors 只匹配带 env: test 标签的 Application:
cat <<EOF | kubectl apply -f -apiVersion: argocd-image-updater.argoproj.io/v1alpha1kind: ImageUpdatermetadata: name: label-selector-updater namespace: argospec: namespace: argo writeBackConfig: method: "argocd" applicationRefs: - namePattern: "*" labelSelectors: matchLabels: env: test images: - alias: "nginx" imageName: "docker.io/library/nginx:1.x" commonUpdateSettings: updateStrategy: "semver"EOF步骤 3:观察日志
kubectl logs -n argo deployment/argocd-image-updater-controller -f关键日志:
level=info msg="Committing 1 parameter update(s) for application nginx-test"
level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"清理:
kubectl delete imageupdater label-selector-updater -n argokubectl delete application nginx-test -n argo8. Git 写回配置
Git 写回是 GitOps 的推荐方式:Image Updater 将镜像版本更新以 commit 形式写回 Git 仓库,ArgoCD 再从 Git 同步到集群,确保 Git 始终是唯一真相源。
8.1 工作流程
- Image Updater 检测到新版本镜像
- Clone Git 仓库到本地
- 创建或更新目标文件(
.argocd-source-<appName>.yaml或kustomization.yaml或values.yaml) - Commit & Push 到指定分支
- ArgoCD 检测到 Git 变化,自动同步到集群
重要:ArgoCD Application 的
spec.source.targetRevision必须跟踪一个分支(如main),而非固定 commit 或 tag,否则 ArgoCD 无法感知到 Image Updater 的提交并自动同步。
8.2 配置 Git 凭证
默认情况下,Image Updater 会复用 ArgoCD 中已配置的 Git 仓库凭证,无需额外设置。
8.3 Kustomize 应用的 Git 写回
官方文档:https://argocd-image-updater.readthedocs.io/en/stable/basics/update-methods/#git-write-back-target
写回到 kustomization.yaml,效果等同于执行 kustomize edit set image:
apiVersion: argocd-image-updater.argoproj.io/v1alpha1kind: ImageUpdatermetadata: name: kustomize-updater namespace: argospec: writeBackConfig: method: "git" gitConfig: branch: "main" writeBackTarget: "kustomization" # 直接更新 kustomization.yaml applicationRefs: - namePattern: "my-kustomize-app" images: - alias: "myapp" imageName: "myregistry/myapp:1.x" commonUpdateSettings: updateStrategy: "semver"更新特定路径的 kustomization(用于 overlays 结构):
gitConfig: branch: "main" # 相对于 Application 的 spec.source.path writeBackTarget: "kustomization:../../base" # 或绝对路径(以 / 开头): # writeBackTarget: "kustomization:/config/base"8.4 Helm 应用的 Git 写回
官方文档:https://argocd-image-updater.readthedocs.io/en/stable/basics/update-methods/#git-write-back-target
将镜像 tag 更新写入指定的 values 文件:
spec: writeBackConfig: method: "git" gitConfig: branch: "main" writeBackTarget: "helmvalues:values.yaml" # 相对于 spec.source.path # 或绝对路径: # writeBackTarget: "helmvalues:/helm/config/values.yaml"注意:使用
helmvalues时,必须指定 values 文件名(含路径),不能只写目录。
8.5 分支保护时使用独立写回分支
当主分支设有保护规则无法直接推送时,可配置 Image Updater 写入另一个分支,再通过 PR 合并:
gitConfig: branch: "main:image-updater-updates" # 基于 main,写入 image-updater-updates 分支使用模板生成唯一分支名(避免多次更新冲突):
gitConfig: branch: "main:image-updater-{{.SHA256}}"模板可用变量:.Images(更新列表,含 .Name、.Alias、.OldTag、.NewTag)、.SHA256(本次变更的唯一哈希)。
8.6 自定义 commit 消息
在 argocd-image-updater-config ConfigMap 中配置:
data: git.commit-message-template: | build: automatic update of {{ .AppName }} {{ range .AppChanges -}} updates image {{ .Image }} tag '{{ .OldTag }}' to '{{ .NewTag }}' {{ end -}}8.7 实操:Git 写回完整测试
本节演示如何使用 GitLab 公开仓库测试 Git 写回功能。
前置准备
步骤 1:创建 GitLab 测试仓库
- 在 Gitlab 创建一个新的公开仓库(如
argocd-image-updater-test) - 创建
kustomization.yaml文件:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - deployment.yamlimages: - name: nginx newName: docker.io/library/nginx newTag: "1.24.0"- 创建
deployment.yaml文件:
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-testspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.24.0 ports: - containerPort: 80- 提交并推送到
main分支
步骤 2:创建 GitLab 访问令牌
- 移除main分支保护(测试使用)
- GitLab → 设置(项目) → 访问令牌
- 生成访问令牌
- 令牌名称:argocd-image-updater-test
- 角色:Developer
- 选择范围:api、read_api、read_repository、write_repository
- 复制生成的 token(格式如
glpat-xxxxxxxxxx)
步骤 3:在 ArgoCD 中配置 Git 仓库
# 在 ArgoCD 中注册 Git 仓库(替换为你的实际 GitLab 信息)cat <<EOF | kubectl apply -f -apiVersion: v1kind: Secretmetadata: name: repo-gitlab-test namespace: argo labels: argocd.argoproj.io/secret-type: repositorystringData: type: git url: https://gitlab.your-domain.com/your-username/argocd-image-updater-test.git username: your-gitlab-username password: glpat-your-actual-token-hereEOF
# 验证 Secret 创建成功kubectl get secret -n argo repo-gitlab-test -o jsonpath='{.data.url}' | base64 -decho ""重要:
url: 你的 GitLab 仓库完整 URL(以.git结尾)username: 你的 GitLab 用户名password: 步骤 2 生成的访问令牌(glpat-xxxxxxxxxx)
测试步骤
步骤 4:创建 ArgoCD Application(使用 Kustomize)
cat <<EOF | kubectl apply -f -apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nginx-git-test namespace: argospec: project: default source: repoURL: https://gitlab.your-domain.com/your-username/argocd-image-updater-test.git targetRevision: main # 必须跟踪分支,不能是固定 commit path: . destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueEOF步骤 5:创建 ImageUpdater CR(启用 Git 写回)
cat <<EOF | kubectl apply -f -apiVersion: argocd-image-updater.argoproj.io/v1alpha1kind: ImageUpdatermetadata: name: nginx-git-updater namespace: argospec: namespace: argo writeBackConfig: method: git gitConfig: branch: main writeBackTarget: kustomization # 写回到 kustomization.yaml applicationRefs: - namePattern: "nginx-git-test" images: - alias: nginx imageName: docker.io/library/nginx:1.x commonUpdateSettings: updateStrategy: semver manifestTargets: kustomize: name: nginx # 必须与 kustomization.yaml 中的 name 字段匹配EOF步骤 6:观察日志和验证结果
# 1. 观察 ImageUpdater 日志kubectl logs -n argo deployment/argocd-image-updater-controller -f | grep -E "nginx-git-test|git push|images_updated"
# 期望看到:# - level=info msg="Committing 1 parameter update(s) for application nginx-git-test"# - level=info msg="Successfully updated the live application spec"# - level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"# - level=info msg="Successfully updated the live application spec"
# 2. 检查 GitLab 仓库# 访问你的 GitLab 仓库,应该看到:# - 新的 commit(由 argocd-image-updater 提交)# - kustomization.yaml 中的 newTag 已更新到最新版本(如 1.29.5)
# 3. 验证 Application 同步状态kubectl get application nginx-git-test -n argo
# 4. 查看实际运行的 Pod 镜像版本kubectl get deployment nginx-test -n default -o jsonpath='{.spec.template.spec.containers[0].image}'# 期望输出:docker.io/library/nginx:1.29.5清理:
kubectl delete imageupdater nginx-git-updater -n argokubectl delete application nginx-git-test -n argokubectl delete secret repo-gitlab-test -n argo常见问题排查
问题 1:日志显示 authentication required 或 permission denied
- 检查 GitLab 访问令牌是否有
read_repository和write_repository权限 - 确认 Secret
repo-gitlab-test中的 username 和 password 正确 - 验证 ArgoCD 能访问该仓库:
kubectl get secret -n argo repo-gitlab-test -o yaml
问题 2:日志显示 failed to push 或 branch protection
- 确认 GitLab 仓库的
main分支没有保护规则 - 或使用独立分支:
branch: "main:image-updater-updates"
问题 3:Git 有 commit 但 ArgoCD 未同步
- 确认 Application 的
targetRevision: main(跟踪分支,不是固定 commit) - 检查 ArgoCD 的自动同步是否启用:
syncPolicy.automated - 手动触发同步:
argocd app sync nginx-git-test
9. 镜像仓库认证配置
Image Updater 支持多种凭证来源,可在 Section 4 的 ConfigMap 中配置仓库级凭证,也可在 ImageUpdater CR 的 images 配置中按镜像覆盖。
9.1 凭证来源格式一览
| 格式 | 说明 |
|---|---|
pullsecret:<namespace>/<secret> | 标准 Docker pull secret(含 .dockerconfigjson 字段) |
secret:<namespace>/<secret>#<field> | 自定义 Secret 中的指定字段,内容格式为 username:password |
env:<ENV_VAR_NAME> | 环境变量,内容格式为 username:password |
ext:/path/to/script | 执行脚本,脚本输出一行 username:password(适合动态 token,如 AWS ECR) |
9.2 使用 pull secret(推荐)
# 创建 Docker Hub pull secretkubectl create -n argo secret docker-registry dockerhub-secret \ --docker-username someuser \ --docker-password s0m3p4ssw0rd \ --docker-server "https://registry-1.docker.io"
# 创建阿里云 ACR pull secretkubectl create -n argo secret docker-registry aliyun-acr-secret \ --docker-server registry.cn-hangzhou.aliyuncs.com \ --docker-username your-username \ --docker-password your-password在 ImageUpdater CR 中的镜像配置里按镜像引用:
images: - alias: "myapp" imageName: "registry.cn-hangzhou.aliyuncs.com/your-ns/myapp:1.x" pullSecret: "pullsecret:argo/aliyun-acr-secret" commonUpdateSettings: updateStrategy: "semver"9.3 使用自定义 Secret
当多个镜像仓库共用同一套凭证,不想为每个仓库维护独立 pull secret 时:
kubectl create -n argo secret generic registry-creds \ --from-literal=creds="myuser:mypassword"引用格式:secret:argo/registry-creds#creds
9.4 使用环境变量(适合测试)
# 测试时在 exec 中临时传入export MY_CREDS="user:password"./argocd-image-updater test myregistry/myimage --credentials env:MY_CREDS --loglevel info9.5 配置仓库级默认凭证
在 Section 4 中已介绍的 argocd-image-updater-config ConfigMap 中配置的 registries.conf 即为仓库级凭证,对该仓库的所有镜像生效,无需逐个镜像配置。
10. 故障排查
10.1 查看 Image Updater 日志
# 实时日志(关注 WARN/ERROR 行)kubectl logs -n argo deployment/argocd-image-updater-controller -f
# 过滤特定应用的相关日志kubectl logs -n argo deployment/argocd-image-updater-controller | grep "my-app"10.2 用 test 命令精确定位问题
test 命令是最直接的调试手段,可在不影响任何配置的情况下验证:
# 验证仓库连通性和版本筛选结果(开 debug 级别看详情)./argocd-image-updater test nginx --semver-constraint "1.x" --loglevel debug
# 验证私有仓库 pull secret 是否有效./argocd-image-updater test myregistry/myapp \ --credentials "pullsecret:argo/my-secret" --loglevel info10.3 常见问题
问题 1:ImageUpdater CR 创建后没有任何动作
# 确认 CR 是否正确创建kubectl get imageupdater -n argo
# 查看 CR 事件和状态kubectl describe imageupdater <name> -n argo问题 2:无法访问私有仓库(registry authentication failed)
# 确认 Secret 存在且在正确命名空间kubectl get secret -n argo
# 用 test 命令验证凭证是否正确./argocd-image-updater test myregistry/myimage \ --credentials "pullsecret:argo/my-secret" --loglevel debug问题 3:Git 写回失败(push rejected / authentication failed)
# 检查 git-creds Secret 是否存在kubectl get secret git-creds -n argo -o yaml
# 查看日志中的 git 错误kubectl logs -n argo deployment/argocd-image-updater-controller | grep -iE "git|push|commit|credential"问题 4:ArgoCD 没有感知到 Image Updater 的 Git commit
检查 Application 的 targetRevision 是否跟踪的是分支名而非 commit hash 或 tag:
kubectl get application my-app -n argo \ -o jsonpath='{.spec.source.targetRevision}'# 期望输出:main(或其他分支名),而非 commit hash问题 5:策略名称警告(newest-build / alphabetical)
日志中出现策略名称废弃警告时,检查 ImageUpdater CR 中的 updateStrategy 字段,将 latest 改为 newest-build,name 改为 alphabetical。
11. 总结与最佳实践
| 场景 | 推荐配置 |
|---|---|
| 生产环境稳定版本管理 | semver 策略 + 版本约束(如 1.x、1.25.x) |
| CI/CD 流水线产出镜像 | newest-build 策略 + allowTags 过滤 commit sha |
追踪 latest 等可变 tag | digest 策略 |
| 日历版本(YYYY-MM-DD) | alphabetical 策略 |
| GitOps 标准流程 | git 写回 + kustomization 或 helmvalues 目标 |
| 快速验证 / 无 Git 写权限 | argocd 写回(注意非持久化) |
| 主分支有保护规则 | 配置独立写回分支 + PR 合并 |
核心最佳实践
- 先用
test命令验证,确认仓库连通和策略配置正确,再创建 ImageUpdater CR - 生产环境使用 semver + 版本约束,防止意外跨大版本升级
- Git 写回时 Application 必须跟踪分支,而非固定 commit 或 tag
- 凭证优先复用 ArgoCD 中已有配置,避免重复管理
- newest-build 慎用 Docker Hub,会消耗免费账户的 pull 配额
- ImageUpdater CR 必须与 ArgoCD 部署在同一命名空间,多集群场景下需部署在 ArgoCD 所在的控制平面集群
参考文档
部分信息可能已经过时









