This topic describes how to use Git, appcenter, and Container Registry to create a GitOps pipeline to automate container image updates for applications that are deployed in Container Service for Kubernetes (ACK).
Background information
You can use a third-party Continuous Integration (CI) system to complete the following CI pipeline:
After the CI system pushes a container image of an application to a Container Registry repository, the Continuous Delivery (CD) pipeline is triggered and the container image of the application is updated. This example shows how appcenter automatically monitors image updates in a Container Registry repository. If an image tag that matches the specified filter condition is updated, the following pipeline is triggered:
Limits
The GitOps pipeline is available only for applications that are created by using appcenter 2.2.5.1 or a later version.
The GitOps pipeline is available only for applications whose manifests are rendered and managed by using Kustomize or Helm.
The GitOps pipeline takes effect only on applications that use the
auto-sync
update policy.The credentials that are used to pull private images must be stored in the cluster in which appcenter is deployed. appcenter cannot retrieve credentials from other clusters.
Preparations
The GitHub address of the application that is used in this example is appcenter-guestbook.
You must log on to GitHub and create a branch within your account for the application. Modify the image address in the values.yaml file of the application as described in the Configure container image update section. This allows datacenter to automatically update the container image of the application and write the updated container image back to the GitHub repository.
The following code block shows the orchestration catalog of the application named 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
The guestbook image in the
frontend Deployment
of the guestbook application. The following code block shows the relevant parameters in the values.yaml file:frontend: replicaCount: 3 image: repository: registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook tag: "v1"
Configure container image update
Annotation format
You can add an annotation to an application that is created in appcenter to specify one or more container images to be automatically updated. The annotation must be in the following format:
argocd-image-updater.argoproj.io/image-list: <image_spec_list>
<image_spec_list>
specifies a list of container images that are separated by commas (,). You must specify container images in the following format:[<alias_name>=]<image_path>[:<version_constraint>]
Image tag filter conditions
You can configure two types of image tag filter conditions to limit the image tags that can trigger image updates. In the following filter conditions, the
registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
image is used as an example.The following filter condition allows all tags to trigger image updates:
argocd-image-updater.argoproj.io/image-list: registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
The following filter condition allows only tags that match the regular expression to trigger image updates:
argocd-image-updater.argoproj.io/<image_name>.allow-tags: <match_func>
NoteThe value of the
<match_func>
parameter must be in theregexp:<expression>
format, in which<expression>
specifies a standard regular expression.To allow only tags from
v2
tov9
to trigger image updates, use the following annotation:argocd-image-updater.argoproj.io/<image_name>.allow-tags: regexp:^v[1-9]
Specify an alias for a container image
You can specify an alias for a container image and then use the alias in relevant configurations. Container image aliases can contain only letters. You can use container image aliases only in the
image-list
annotation, as shown in the following example:argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
NoteIn the preceding example,
guestbook
is the alias of theregistry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
image.Configure a container image update policy
The following table describes the container image update policies that you can configure. The default container image update policy is
semver
.Policy
Description
semver
Update to the latest image version in a list that is sorted based on semantic versions.
latest
Update to the latest image version in a list that is sorted based on creation dates.
name
Update to the latest image version in an alphabetically sorted list.
digest
Update to the latest image version that is pushed with a mutable tag.
The annotation that is used to specify a container image update policy must be in the following format:
argocd-image-updater.argoproj.io/<image_name>.update-strategy: <strategy>
The following example shows how to specify the
latest
policy for theguestbook=registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
image:argocd-image-updater.argoproj.io/guestbook.update-strategy: latest
Image update annotations for different types of applications
Image update annotation for applications whose manifests are rendered and managed by using Helm: The image update annotation may specify multiple container images. For example, the image update annotation for the
guestbook
application specifiesfrontend.image.repository
,frontend.image.tag
,redis.master.image.repository
, andredis.master.image.tag
. The annotation must be in the following format:annotations: argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook,redis-master=registry.cn-hongkong.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
Image update annotation for applications whose manifests are rendered and managed by using Kustomize: You must specify the aliases of the new images and the addresses of the original images. You can include image tags in image aliases but cannot include image tags in image addresses. The annotation must be in the following format:
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>
The following code block shows two examples:
annotations: argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook argocd-image-updater.argoproj.io/guestbook.kustomize.image-name: registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook
Step 1: Specify credentials
You must specify the credentials that are required by appcenter before appcenter can monitor image updates in a Container Registry repository and automatically update applications.
Specify the Container Registry credentials that are used by appcenter to periodically check image repositories
To specify the Container Registry credentials that are used by appcenter to periodically check image repositories, perform the following steps to modify the ConfigMap
named argocd-image-updater-config
in the appcenter namespace:
Run the following command to query the
ConfigMap
namedargocd-image-updater-config
:kubectl -n appcenter get cm argocd-image-updater-config -oyaml
Expected output:
apiVersion: v1 data: registries.conf: | registries: - name: AlibabaCloud Container Registry api_url: https://registry.cn-hongkong.aliyuncs.com prefix: registry.cn-hongkong.aliyuncs.com credentials: secret:appcenter/acr#acr kind: ConfigMap metadata: name: argocd-image-updater-config namespace: appcenter
Parameter
Description
name
The name of the image repository.
api_url
The API endpoint of the image repository. When the system installs appcenter, the system automatically generates the API endpoint based on the region where appcenter is installed.
prefix
The prefix of the image repository. When the system installs appcenter, the system automatically generates the prefix based on the region where appcenter is installed.
credentials
The credentials that are used to access the image repository. The credentials must be in the following format:
secret:<secret_namespace>/<secret_name>#<your_key>
.Run the following command to configure a Secret named
acr
in the appcenter namespace.The Secret is used by appcenter to access the image repository in the
cn-hongkong
region.kubectl -n appcenter apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: acr type: Opaque stringData: acr: <your_username>:<your_password> # Replace <your_username>:<your_password> with the credentials of your image repository. EOF
(Optional) Specify the Git Credentials that are used by appcenter to write updated images back to the Git repository
If you already specified the Git credentials when you created an application in appcenter, you can skip this step because appcenter can automatically use the specified credentials to write updated images back to the Git repository. You can use one of the following methods to specify the Git Credentials that are used by appcenter to write updated images back to the Git repository:
Method 1: Use the Git credentials that are stored in appcenter. The credentials are created when you create the corresponding application in appcenter.
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: annotations: argocd-image-updater.argoproj.io/write-back-method: git
Method 2: Use the Git credentials that are stored in a 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
indicates a Secret namedgit-creds
in the appcenter namespace. The following code block shows how to create the Secret:kubectl -n appcenter create secret generic git-creds \ --from-literal=username=<your_username> \ --from-literal=password=<your_password>
Step 2: Use appcenter to create an application from an image that is stored in a Git repository
Use appcenter to create an application named guestbook.
Run the following command to query the guestbook application:
kubectl -n appcenter get application guestbook -oyaml
Expected output:
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/AliyunContainerService/appcenter-guestbook.git targetRevision: main
Specify the
auto-sync
update policy for the guestbook application.Create a file named syncPolicy.patch based on the following content:
cat <<EOF > syncPolicy.patch spec: syncPolicy: automated: {} EOF
Run the following command to update the guestbook application in the appcenter namespace:
kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat syncPolicy.patch)"
Configure automatic container image update for the guestbook application.
Create a file named imageUpdate.patch based on the following content:
cat <<EOF > imageUpdate.patch metadata: annotations: argocd-image-updater.argoproj.io/image-list: guestbook=registry.cn-hongkong.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
Run the following command to update the guestbook application in the appcenter namespace:
kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat imageUpdate.patch)"
You can use an annotation in the following format to specify one or more container images:
argocd-image-updater.argoproj.io/image-list: <image_spec_list>
<image_spec_list>
specifies a list of container images that are separated by commas (,). The container image list must be in the following format:[<alias_name>=]<image_path>[:<version_constraint>]
You can use an annotation in the following format to specify how to update
image name
andimage tag
for applications whose manifests are rendered and managed by using Helm:argocd-image-updater.argoproj.io/<alias_name>.helm.<image_name>: <helm_values> argocd-image-updater.argoproj.io/<alias_name>.helm.<image_tag>: <helm_values>
If the image parameters of the frontend component in the values.yaml file of the guestbook application are set to the following values:
frontend: replicaCount: 3 image: repository: registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook tag: "v1"
The corresponding annotation is:
argocd-image-updater.argoproj.io/guestbook.helm.image-name: frontend.image.repository argocd-image-updater.argoproj.io/guestbook.helm.image-tag: frontend.image.tag
Configure the Git write-back feature to write the updated image of the guestbook application back to the Git repository.
Create a file named gitWriteback.patch based on the following content:
cat <<EOF > gitWriteback.patch metadata: annotations: argocd-image-updater.argoproj.io/write-back-method: git EOF
Run the following command to update the guestbook application in the appcenter namespace:
kubectl -n appcenter patch Application guestbook --type=merge -p "$(cat gitWriteback.patch)"
Step 3: Verify that the container image is automatically updated
Run the following command to push the new guestbook image:
docker tag registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook:v1 registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook:v4 docker push registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook:v4
Run the following command to print the log of the argocd-image-updater component in the appcenter namespace:
kubectl -n appcenter logs -f argocd-image-updater-<xxx>
Expected output:
time="2022-03-28T07:28:27Z" level=info msg="Successfully updated image 'registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook:v1' to 'registry.cn-hongkong.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-hongkong.aliyuncs.com time="2022-03-28T07:28:27Z" level=info msg="Committing 1 parameter update(s) for application guestbook" application=guestbook
Check whether the guestbook application generates a file named .argocd-source-guestbook.yaml on GitHub.
Run the following command to check whether the guestbook application is updated to the latest container image:
kubectl -n guestbook get deploy frontend -ojsonpath="{.spec.template.spec.containers[0].image}"
Expected output:
registry.cn-hongkong.aliyuncs.com/haoshuwei24/guestbook:v4