文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

ArgoCD Image Updater是如何运作的?

2024-11-29 18:51

关注

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 https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

安装完成后我们就可以在 Argo CD 中看到 Argo CD Image Updater 组件了:

$ kubectl get pods -n argocd
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          21m
argocd-applicationset-controller-587b5c864b-2kt2v   1/1     Running   0          7d4h
argocd-dex-server-6958d7dcf4-66s6s                  1/1     Running   0          7d4h
argocd-image-updater-57b788886d-d4qh5               1/1     Running   0          34s
argocd-notifications-controller-6847bd5c98-wqbjj    1/1     Running   0          7d4h
argocd-redis-6fcf5c8898-c6752                       1/1     Running   0          7d4h
argocd-repo-server-9646985c8-7dmj5                  1/1     Running   0          7d4h
argocd-server-67b76b54d7-hxx6q                      1/1     Running   0          7d4h

现在我们就可以直接去监听镜像是否发生了变化,而不需要在 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:/ (pullsecret:argocd/dockerhub-secret)。

kubectl create -n argocd secret generic some-secret \
  --from-literal=creds=someuser:s0m3p4ssw0rd

该 secret 可以用 secret:/# (secret:argocd/some-secret#creds) 的方式引用。

env:
  - name: DOCKER_HUB_CREDS
    value: "someuser:s0m3p4ssw0rd"

该 secret 可以用 env: (env:DOCKER_HUB_CREDS) 的方式引用。

#!/bin/sh
echo "someuser:s0m3p4ssw0rd"

将其引用为 ext:

我们这里就以 Github 的 Container Registry 为例,来演示下如何使用 ArgoCD Image Updater 来更新镜像。

首先我们在 Github 个人设置页面中创建一个个人访问令牌,如下图所示:

Token

这个 Token 的权限要包括 write:packages 和 read:packages,这样我们才能推送和拉取镜像,创建后会得到一个 Token。

然后我们可以在终端或命令行中,使用 GitHub 用户名和 GitHub 的个人访问令牌(PAT)登录 GitHub Container Registry。

export PAT=
echo $PAT | docker login ghcr.io -u  --password-stdin

将替换为个人访问令牌,将替换为 GitHub 用户名。

登录成功后我们可以使用以下命令将 Docker 镜像标记为 GitHub Container Registry 镜像:

docker tag : ghcr.io//:

将 : 替换为本地 Docker 镜像名与 tag 名,将  替换为 GitHub 用户名, 替换想要使用的标签(例如默认的 latest 标签)。

然后使用以下命令将 Docker 镜像推送到 GitHub Container Registry 即可:

docker push ghcr.io//:

完成以上步骤后,就可以在 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: v1
kind: ConfigMap
metadata:
  name: argocd-image-updater-config
  namespace: argocd
data:
  registries.conf: |
    registries:
      - name: ghcr-hub
        api_url: https://ghcr.io # 镜像仓库地址
        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 仓库 https://github.com/cnych/k8s-devops-gitops-demo:

add git repo

接下来我们可以按照正常使用方式创建一个新的 Application 对象,对应的资源清单文件如下所示:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gitops-demo
  namespace: argocd
spec:
  destination:
    namespace: gitops-demo
    server: https://kubernetes.default.svc
  project: default
  source:
    path: helm # 从 Helm 存储库创建应用程序时,chart 必须指定 path
    repoURL: https://github.com/cnych/k8s-devops-gitops-demo.git
    targetRevision: master
    helm:
      parameters:
        - name: replicaCount
          value: "2"
      valueFiles:
        - my-values.yaml
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

直接创建上面的资源清单文件后,ArgoCD 会自动创建一个 Application 资源对象,并且会自动同步到 Git 仓库中,我们可以在 Git 仓库中看到对应的资源清单文件:

gitops-demo

如果该应用出现了如下所示的错误信息:

Namespace                gitops-demo                            SyncFailed        resource :Namespace is not permitted in project default

则表面当前使用的 project 没有权限创建 namespace,我们只需要为其添加对应的权限即可:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: default
  namespace: argocd
spec:
  clusterResourceWhitelist: # 白名单,表示允许访问的资源
    - group: "*"
      kind: "*"
  destinations:
    - name: "*"
      namespace: "*"
      server: "*"
  sourceRepos:
    - "*"

我们可以使用 argocd app get 命令来查看 Application 资源对象的状态:

$ argocd app get argocd/gitops-demo
Name:               argocd/gitops-demo
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          gitops-demo
URL:                https://grpc.argocd.k8s.local/applications/gitops-demo
Source:
- Repo:             https://github.com/cnych/k8s-devops-gitops-demo.git
  Target:           master
  Path:             helm
  Helm Values:      my-values.yaml
SyncWindow:         Sync Allowed
Sync Policy:        Automated (Prune)
Sync Status:        Synced to master (53d91ed)
Health Status:      Progressing

GROUP              KIND        NAMESPACE    NAME                        STATUS     HEALTH       HOOK  MESSAGE
                   Namespace                gitops-demo                 Running    Synced             namespace/gitops-demo created
apps               Deployment  default      gitops-demo-helm-guestbook  Succeeded  Pruned             pruned
                   Service     default      gitops-demo-helm-guestbook  Succeeded  Pruned             pruned
                   Service     gitops-demo  gitops-demo-devops-demo     Synced     Healthy            service/gitops-demo-devops-demo created
apps               Deployment  gitops-demo  gitops-demo-devops-demo     Synced     Progressing        deployment.apps/gitops-demo-devops-demo created
networking.k8s.io  Ingress     gitops-demo  gitops-demo-devops-demo     Synced     Progressing        ingress.networking.k8s.io/gitops-demo-devops-demo created

需要注意要在目标命名空间中添加 Image Pull Secret。

正常我们这个应用就可以运行了:

$ curl http://gitops-demo.k8s.local/
{"msg":"Hello Tekton On GitLab With ArgoCD"}

但是在 Dashboard 中我们可以看到应用虽然已经是 Synced 状态,但是 APP HEALTH 一直显示为 Progressing 状态。

App Health

这是因为 ArgoCD 的健康状态机制引起的,我们可以在源码 https://github.com/argoproj/gitops-engine/blob/master/pkg/health/health_ingress.go#L7 中看到健康状态的检查逻辑。

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: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  resource.customizations: |
    networking.k8s.io/Ingress:
      health.lua: |
        hs = {}
        if obj.metadata ~= nil and obj.metadata.creationTimestamp ~= nil then
          hs.status = "Healthy"
          hs.message = "Ingress 已创建"
        else
          hs.status = "Progressing"
          hs.message = "Ingress 正在创建中"
        end
        return hs

上面的配置表示如果 Ingress 资源对象的 metadata.creationTimestamp 字段不为空,则表示健康状态为 Healthy,否则为 Progressing,更新上面的配置后,我们再次查看应用的健康状态就会发现已经变成了 Healthy 状态:

App Health

接下来我们就可以使用 ArgoCD Image Updater 来更新镜像了,修改上面的 Application 资源清单文件,我们需要添加一些注解来指定需要更新的镜像规则策略,如下所示:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gitops-demo
  namespace: argocd
  annotations:
    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-demo
    server: https://kubernetes.default.svc
  project: default
  source:
    path: helm # 从 Helm 存储库创建应用程序时,chart 必须指定 path
    repoURL: https://github.com/cnych/k8s-devops-gitops-demo.git
    targetRevision: master
    helm:
      parameters:
        - name: replicaCount
          value: "2"
      valueFiles:
        - my-values.yaml
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - 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 argocd
time="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.io
time="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.io
time="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.io
time="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.io
time="2024-09-27T08:37:44Z" level=info msg="Committing 1 parameter update(s) for application gitops-demo" applicatinotallow=gitops-demo
time="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="Initializing https://github.com/cnych/k8s-devops-gitops-demo.git to /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=acebc
time="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.146246
time="2024-09-27T08:37:46Z" level=info msg="git config user.name argocd-image-updater" dir=/tmp/git-gitops-demo1873820104 execID=7ec2d
time="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.5687190000000002
time="2024-09-27T08:37:46Z" level=info msg="git config user.email noreply@argoproj.io" dir=/tmp/git-gitops-demo1873820104 execID=6e796
time="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.688394
time="2024-09-27T08:37:46Z" level=info msg="git checkout --force master" dir=/tmp/git-gitops-demo1873820104 execID=403bb
time="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.522311
time="2024-09-27T08:37:46Z" level=info msg="git clean -ffdx" dir=/tmp/git-gitops-demo1873820104 execID=b3f03
time="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.429556
time="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=0efc6
time="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.239213
time="2024-09-27T08:37:46Z" level=info msg="git push origin master" dir=/tmp/git-gitops-demo1873820104 execID=fcd1f
time="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.14529
time="2024-09-27T08:37:47Z" level=info msg="Successfully updated the live application spec" applicatinotallow=gitops-demo
time="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 Chart values.yaml 的 .argocd-source-devops-demo.yaml 文件。

git commit

自动提交变更后,Argo CD 就会自动同步部署应用了。

app sync

当然现在访问应用结果就是我们更改后的内容了:

$ curl http://gitops-demo.k8s.local/
{"msg":"Hello ArgoCD With Image Updater"}

另外我们可以注意到每次 Git 提交都与作者的姓名和电子邮件地址相关联。如果未配置,Argo CD 镜像更新程序执行的提交将使用 argocd-image-updater  作为作者。您可以使用 --git-commit-user 和 --git-commit-email 命令行开关覆盖作者,或在 argocd-image-updater-config ConfigMap 中设置 git.user 和 git.email 即可。

同样我们可以将 Argo CD Image Updater 使用的默认提交消息更改为适合你的方式。可以创建一个简单的模板(使用 Golang Template),并通过将 argocd-image-updater-config ConfigMap 中的密钥 git.commit-message-template 设置为模板的内容来使其可用,例如:

data:
  git.commit-message-template: |
    build: automatic update of {{ .AppName }}

    {{ range .AppChanges -}}
    updates image {{ .Image }} tag '{{ .OldTag }}' to '{{ .NewTag }}'
    {{ end -}}

模板中提供了两个顶级变量:

来源:k8s技术圈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯