概述
本文介绍如何在ACK上使用Git、Appcenter和ACR构建应用GitOps全自动化交付流水线。
我们将演示Appcenter自动监听ACR镜像仓库变化,若有符合过滤条件的容器镜像tags更新,则自动触发以下流程:
ACR中镜像仓库tags更新 -> 自动更新Appcenter中应用参数配置 -> 镜像变更信息自动回写Git -> 将变更自动同步到ACK集群
这实际上是解耦了CI和CD流程,你可以使用任意第三方CI系统完成CI流程:
Git应用源码拉取 -> 容器镜像构建 -> 容器镜像推送至ACR
当CI流程成功将应用镜像推送到ACR镜像仓库时,就可以自动化触发CD流程的运行并更新应用容器镜像。
使用限制说明
● 只适用于通过Appcenter创建的应用
● 只适用于通过Kustomize或Helm编排渲染托管在Git系统中的应用编排
● 仅对同步策略设置为auto-sync的应用生效
● 私有镜像拉取凭证必须与Appcenter系统部署在同一个集群中,暂不支持跨集群读取私有镜像拉取凭证
● Appcenter组件版本需要>=2.2.5.1
快速开始
示例应用概述
示例应用Github地址
请fork到您自己的账号下,方便后续示例应用自动更新容器镜像并正确回写到Github应用仓库;
guestbook应用编排目录结构如下:
├── helm
│ ├── Chart.yaml
│ ├── templates
│ │ ├── frontend-deployment.yaml
│ │ ├── frontend-service.yaml
│ │ ├── ingress.yaml
│ │ ├── redis-master-deployment.yaml
│ │ ├── redis-master-service.yaml
│ │ ├── redis-slave-deployment.yaml
│ │ └── redis-slave-service.yaml
│ ├── values-idc.yaml
│ └── values.yaml
└── README.md
guestbook应用中频繁更新的应用镜像为frontend deployment中的guestbook镜像,values.yaml中相关参数如下所示:
frontend:
replicaCount: 3
image:
repository: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
tag: "v1"
配置Appcenter定期检查ACR镜像仓库的Container Registry访问凭证
Appcenter定期检查ACR镜像仓库的Container Registry访问凭证配置在appcenter命名空间下名为argocd-image-updater-config的Configmap中,默认配置如下所示:
$ kubectl -n appcenter get cm argocd-image-updater-config -oyaml
apiVersion: v1
data:
registries.conf: |
registries:
- name: AlibabaCloud Container Registry
api_url: https://registry.cn-hangzhou.aliyuncs.com
prefix: registry.cn-hangzhou.aliyuncs.com
credentials: secret:appcenter/acr#acr
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: appcenter
● name: 容器镜像仓库配置的名称
● api_url: 容器镜像仓库API地址
● prefix: 容器镜像仓库的查询前缀
● credentials:容器镜像仓库访问凭证,格式为secret:<secret_namespace>/<secret_name>#<your_key>
以默认配置为例,需要在appcenter命名空间下配置名为acr的secret,用于appcenter访问cn-hongkong区域的ACR镜像仓库:
$ kubectl -n appcenter apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: acr
type: Opaque
stringData:
acr: <your_username>:<your_password>
EOF
注意:请将<your_username>:<your_password>更换为您自己的容器镜像仓库访问凭证
使用Appcenter部署Git源类型的应用
控制台创建应用可以参考
步骤一:使用Appcenter创建一个guestbook应用
依照上述文档使用Appcenter创建一个guestbook应用,示例应用的yaml编排如下所示:
$ kubectl -n appcenter get application guestbook -oyaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: appcenter
spec:
destination:
namespace: guestbook
server: https://192.168.0.32:6443
project: default
source:
helm:
valueFiles:
- values.yaml
path: helm
repoURL: https://github.com/haoshuwei/guestbook.git
targetRevision: main
步骤二: 设置guestbook应用更新策略为auto-sync
$ cat <<EOF > syncPolicy.patch
spec:
syncPolicy:
automated: {}
EOF
$ kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat syncPolicy.patch)"
步骤三: 设置guestbook应用自动更新容器镜像
$ cat <<EOF > imageUpdate.patch
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
argocd-image-updater.argoproj.io/guestbook.helm.image-name: frontend.image.repository
argocd-image-updater.argoproj.io/guestbook.helm.image-tag: frontend.image.tag
EOF
$ kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat imageUpdate.patch)"
你可以使用如下的格式的Annotation描述1个或多个容器镜像:
argocd-image-updater.argoproj.io/image-list: <image_spec_list>
<image_spec_list>是一个容器镜像,或使用“,”隔开的容器镜像列表,完整的描述方式如下所示:
[<alias_name>=]<image_path>[:<version_constraint>]
你可以使用如下的格式的Annotation描述Helm编排的应用如何更新image name和image tag:
argocd-image-updater.argoproj.io/<alias_name>.helm.<image_name>: <helm_values>
argocd-image-updater.argoproj.io/<alias_name>.helm.<image_tag>: <helm_values>
本示例中,guestbook的values.yaml文件中frontend组件对应的容器镜像编排参数如下所示:
frontend:
replicaCount: 3
image:
repository: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
tag: "v1"
所以对应的Annotation描述如下:
argocd-image-updater.argoproj.io/guestbook.helm.image-name: frontend.image.repository
argocd-image-updater.argoproj.io/guestbook.helm.image-tag: frontend.image.tag
步骤四: 设置guestbook应用自动更新容器镜像后回写git
$ cat <<EOF > gitWriteback.patch
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git
EOF
$ kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat gitWriteback.patch)"
测试应用容器镜像自动更新
推送新版本的guestbook镜像
$ docker tag registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v1 registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v4
$ docker push registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v4
查看Appcenter下argocd-image-updater组件日志
$ kubectl -n appcenter logs -f argocd-image-updater-<xxx>
$ kubectl -n appcenter logs -f argocd-image-updater-<xxx>
time="2022-03-28T07:28:27Z" level=info msg="Successfully updated image 'registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v1' to 'registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v4', but pending spec update (dry run=false)" alias=guestbook application=guestbook image_name=haoshuwei24/guestbook image_tag=v1 registry=registry.cn-hangzhou.aliyuncs.com
time="2022-03-28T07:28:27Z" level=info msg="Committing 1 parameter update(s) for application guestbook" application=guestbook
查看Github上guestbook应用中是否自动生成.argocd-source-guestbook.yaml文件
查看guestbook应用是否已自动更新最新版本容器镜像:
$ kubectl -n guestbook get deploy frontend -ojsonpath="{.spec.template.spec.containers[0].image}"
registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook:v4
配置解析
密钥凭证配置
在guestbook的示例应用中,我们演示了Appcenter自动监听ACR镜像仓库变化并更新应用的示例。
这个过程中会涉及到秘钥凭证有:
● Appcenter定期检查ACR镜像仓库的Container Registry访问凭证
● Appcenter回写应用容器镜像变更信息到Git系统的Git Credentials访问凭证
(1)Appcenter定期检查ACR镜像仓库的Container Registry访问凭证
请参考https://yuque.antfin-inc.com/op0cg2/xggqal/ufdih5/edit#CTbq9
(2)配置Appcenter回写应用容器镜像变更信息到Git系统的Git Credentials访问凭证
Appcenter回写应用容器镜像变更信息到Git系统的Git Credentials访问凭证配置有2种方式:
● 使用Appcenter中存储的Git Credentials访问凭证(使用Appcenter创建应用并配置git访问凭证时创建)
指定Application使用git凭证的方式如下所示:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git
● 存储在Secret中,示例如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git:secret:appcenter/git-creds
其中 git:secret:appcenter/git-creds 表示appcenter命名空间下名为git-creds的Secret资源,创建该Secret的示例如下:
$ kubectl -n appcenter create secret generic git-creds \
--from-literal=username=<your_username> \
--from-literal=password=<your_password>
配置容器镜像的更新
Annotation格式说明
你可以在Appcenter创建的应用中通过设置Annotation标记1个或者多个容器镜像可被自动更新,格式如下所示:
argocd-image-updater.argoproj.io/image-list: <image_spec_list>
<image_spec_list> 可以是单个容器镜像,也可以是“,”逗号分割的一组容器镜像列表,每1个容器镜像描述的格式都可以是如下所示:
[<alias_name>=]<image_path>[:<version_constraint>]
下面会对镜像描述的格式有进一步说明。
镜像tags条件过滤
以registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook镜像为例,当ACR镜像仓库中guestbook镜像有新tags推送时:
(1)任何镜像tags都可以触发应用更新,如下所示:
argocd-image-updater.argoproj.io/image-list: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
(2)通过正则表达式过滤允许的tags,格式如下所示:
argocd-image-updater.argoproj.io/<image_name>.allow-tags: <match_func>
其中<match_func>的格式如下所示:
regexp:<expression>
即标准的正则表达式。
例如只允许v2到v9的tags触发应用更新,Annotation如下所示:
argocd-image-updater.argoproj.io/<image_name>.allow-tags: regexp:^v[1-9]
为容器镜像设置别名
可以为应用的容器镜像设置别名,方便在做配置时引用,别名只允许字母字符串,容器镜像别名只允许在 image-list的Annotation重使用,如下所示:
argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
guestbook即容器镜像registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook的别名
设置镜像更新策略
容器镜像更新策略支持以下几种,默认的镜像更新策略为semver
策略 | 描述 |
---|---|
semver | 按语义化版本号排序并更新到最新的镜像tag |
latest | 按创建时间排序并更新到最新的镜像tag |
name | 按字母排序并更新到最新的镜像tag |
digest | 更新到最新的推送的可变标签版本 |
Annotation的格式如下所示:
argocd-image-updater.argoproj.io/<image_name>.update-strategy: <strategy>
例如设置guestbook=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook的镜像更新策略为latest:
argocd-image-updater.argoproj.io/guestbook.update-strategy: latest
Helm编排类型应用的参数设置
Helm编排类型的应用可能包含多个容器镜像的描述,比如guestbook示例应用中有frontend.image.repository、frontend.image.tag、redis.master.image.repository、redis.master.image.tag,示例如下所示:
annotations:
argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook,redis-master=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/redis
argocd-image-updater.argoproj.io/guestbook.helm.image-name: frontend.image.repository
argocd-image-updater.argoproj.io/guestbook.helm.image-tag: frontend.image.tag
argocd-image-updater.argoproj.io/redis-master.helm.image-name: redis.master.image.repository
argocd-image-updater.argoproj.io/redis-master.helm.image-tag: redis.master.image.tag
Kustomize编排类型应用的参数设置
Kustomize编排类型的应用容器镜像的自动更新设置,需要先为被更新的容器镜像设置别名(可以包含tag),然后设置原始容器镜像地址(不包含tag),Annotation格式如下所示:
annotations:
argocd-image-updater.argoproj.io/image-list: <image_alias>=<image_name>:<image_tag>
argocd-image-updater.argoproj.io/<image_alias>.kustomize.image-name: <original_image_name>
示例:
annotations:
argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook
argocd-image-updater.argoproj.io/guestbook.kustomize.image-name: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/guestbook