Skip to content

[Az] Day 09: Synchronizing Container Images to ACR for a Private AKS Cluster Using CI/CD Pipelines.

Published: at 12:00 PM

Introduction

Deploying applications in a private AKS cluster presents unique challenges, especially when the cluster lacks direct internet access. In such environments, the cluster cannot pull container images from public registries like Docker Hub or Quay.io. Instead, all container images must be sourced from a private ACR accessible within the cluster’s network.

To address this, we need a robust solution that not only synchronizes required images into the ACR but also integrates with Continuous Integration/Continuous Deployment (CI/CD) pipelines and adheres to Software Development Life Cycle (SDLC) best practices. This ensures that all images are reviewed and approved before being imported, enhancing security and compliance.


Table of Contents

Open Table of Contents

Implementation

By leveraging Azure DevOps CI/CD pipelines, we can automate the public image importing process as below.

1. Image Configuration File

The images.txt file lists all the container images that need to be imported into the private ACR.

Each line specifies the source image and the destination repository within the ACR, separated by =>. This format allows for easy maintenance and review of the images being imported.

Example images.txt

#registry.k8s.io/ingress-nginx/controller:v1.11.1 => ingress-nginx/controller
#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1 => ingress-nginx/kube-webhook-certgen
#quay.io/jetstack/cert-manager-controller:v1.15.2 => jetstack/cert-manager-controller
#quay.io/jetstack/cert-manager-webhook:v1.15.2 => jetstack/cert-manager-webhook
#quay.io/jetstack/cert-manager-cainjector:v1.15.2 => jetstack/cert-manager-cainjector
#docker.io/cloudflare/cloudflared:latest => cloudflare/cloudflared
#mcr.microsoft.com/azuredocs/aks-helloworld:v1 => azuredocs/aks-helloworld 

2. Synchronization Script

The sync-script.sh script automates the process of importing images listed in images.txt into the ACR. It reads each line of the configuration file, processes the source and destination information, and uses the Azure CLI to import the images.

View code

#!/bin/bash

# Define the name of your Azure Container Registry
ACR_NAME="$1"
IMAGE_LIST_PATH="$2"
DOCKER_USERNAME="$3"
DOCKER_PASSWORD="$4"

# Read the image list from the specified file
while IFS= read -r IMAGE; do
  # Ignore comment lines and empty lines
  if [[ $IMAGE == \#* ]] || [[ -z $IMAGE ]]; then
    continue
  fi

  # Split the source and destination using '=>' as the delimiter
  # Use parameter expansion to split
  SOURCE="${IMAGE%%=>*}"
  DESTINATION="${IMAGE##*=>}"

  # Trim whitespace from both source and destination
  SOURCE=$(echo "$SOURCE" | xargs)
  DESTINATION=$(echo "$DESTINATION" | xargs)

  # Extract the tag from the source image
  if [[ "$SOURCE" == *:* ]]; then
    TAG="${SOURCE##*:}"
  else
    TAG="latest"
  fi

  # Append the tag to the destination image
  DESTINATION_WITH_TAG="$DESTINATION:$TAG"

  # Extract the image name from the destination path
  IMAGE_NAME=$(basename "$DESTINATION")

  # Print a message indicating the import process
  echo "Importing $IMAGE_NAME:$TAG from $SOURCE to $DESTINATION_WITH_TAG..."
  
  # Build and execute the az acr import command
  # If the source is from docker.io, include username and password
  if [[ $SOURCE == docker.io* ]]; then
    az acr import --name "$ACR_NAME" --source "$SOURCE" --image "$DESTINATION_WITH_TAG" --username "$DOCKER_USERNAME" --password "$DOCKER_PASSWORD" --force
  else
    # Otherwise, import without authentication
    az acr import --name "$ACR_NAME" --source "$SOURCE" --image "$DESTINATION_WITH_TAG" --force
  fi

  # Confirm the import completion
  echo -e "The $IMAGE_NAME:$TAG has been imported.\n\n"
  
  # Pause for 15 seconds before processing the next image
  sleep 15
done < "$IMAGE_LIST_PATH"

3. Azure Pipeline

To streamline the synchronization process, we utilize a CI/CD pipeline. This pipeline is designed to automatically execute the synchronization script whenever there are updates to the images.txt file, ensuring that all container images in the ACR remain current.

View code

inline

Important Variables:

az-devops-sync-pipeline

Once the pipeline completes successfully, you can verify that all images have been correctly imported into the ACR. acr-imported-images

The imported images on ACR repositories


Conclusion

Synchronizing container images for a private AKS cluster without direct internet access requires careful planning and automation. By leveraging a combination of an image configuration file, a synchronization script, and an Azure DevOps CI/CD pipeline, we can:

This approach not only streamlines the deployment process but also integrates seamlessly with existing development workflows, promoting efficiency and reliability in managing containerized applications.


References


Next

Day 10: Implementing a Helm Deployment CI/CD AzureDevOps Pipeline for a Private AKS Cluster.

In the next article, We will create Helm charts for nginx-ingress and cert-manager, and set up a robust CI/CD pipeline using Azure DevOps for Helm deployments to a private AKS cluster.


Thank You

Thank you for taking the time to read this guide! We hope it has been helpful. Feel free to explore further and happy coding! 🌟✨

Steven | GitHub