All Products
Search
Document Center

:Use Git, appcenter, and Container Registry to create a GitOps pipeline to automate container image updates

Last Updated:Aug 22, 2023

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:

process

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:

process2

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>
      Note

      The value of the <match_func> parameter must be in the regexp:<expression> format, in which <expression> specifies a standard regular expression.

      To allow only tags from v2 to v9 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
    Note

    In the preceding example, guestbook is the alias of the registry.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 the guestbook=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 specifies frontend.image.repository, frontend.image.tag, redis.master.image.repository, and redis.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:

  1. Run the following command to query the ConfigMap named argocd-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>.

  2. 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 named git-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

  1. Use appcenter to create an application named guestbook.

  2. 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
  3. Specify the auto-sync update policy for the guestbook application.

    1. Create a file named syncPolicy.patch based on the following content:

      cat <<EOF > syncPolicy.patch
      spec:
        syncPolicy:
          automated: {}
      EOF
    2. 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)"
  4. Configure automatic container image update for the guestbook application.

    1. 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
    2. 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 and image 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
  5. Configure the Git write-back feature to write the updated image of the guestbook application back to the Git repository.

    1. 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
    2. 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

  1. 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
  2. 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
  3. Check whether the guestbook application generates a file named .argocd-source-guestbook.yaml on GitHub.

    pull
  4. 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