Azure Container Registry — Part 1
Azure Container Registry is a managed registry service based on the open-source Docker Registry 2.0 which we can use to create and maintain repositories to store and manage our container images, related artifacts and helm charts.
What are helm charts?
Helm uses a packaging format called charts. A chart is a collection of files that describe a related set of Kubernetes resources. A single chart might be used to deploy something simple, like a memcached pod, or something complex, like a full web app stack with HTTP servers, databases, caches, and so on.
Key Features of ACR
- Supported images and artifacts: zure Container Registry can contain both Linux and Windows images, Open Container Initiative (OCI) images and Helm charts and each image in the repository is a read-only container snapshot, which is compatible with Docker.
- Automated image builds: You can use Azure Container Registry Tasks (ACR Tasks) to simplify the build, test, push, and deployment phases of the container image pipeline in Azure.
- Registry service tiers: ACR is available in 3 main tiers inclusing the basic, standard and premium one. Every tier is different from the other due to some unique features they offer.
Basic — Provides storage and throughput that is suitablefor smaller usage scenarios.
Standard — Provides increased storage and throughput suitable for production scenarios.
Premium — This tier offers the highest quantity of storage and concurrent operation. And this tier also supports amazing features like zone redundancy, geo-replication, content trust, and private links with private endpoints.
You can change a registry’s service tier through Azure CLI or portal. Also, no registry downtime or impact is there on registry operations when you switch from one tier to another. E.g. az acr update — name myContainerRegistry — sku Premium
Common Features which all service tiers provide are as follows:
Encrypted storage /Encryption at rest — All container images in the registry are encrypted at rest by the Azure and are decrypted only when they are retrieved.
Regional storage — ACR automatically stores data in the region where the registry is created to help customers meet their data residency and compliance requirements.
Unlimited objects — ACR allows you create as many repositories, images, layers, or tags as needed, up to the registry storage limits.
4. Secure Access: Azure Container Registry transfers container images over HTTPS, and supports TLS to secure client connections.
And if you have a Premium tier ACR, you can leverage the features like Security content trust for image tag signing, and firewalls and virtual networks (preview) to restrict access to the registry. Also, we can integrate Microsoft Defender for Cloud with ACRto scan images whenever they are pushed to a registry.
5. ACR doesn’t support the feature of resiliency: If a regional outage occurs, the registry data may become unavailable and is not automatically recovered. Customers who wish to have their registry data stored in multiple regions for better performance across different geographies or who wish to have resiliency in the event of a regional outage should enable geo-replication.
Geo-replication: The feature of Geo-replication will help you to access your data in case of a regional failure. Geo-replication comes with another benefit and that is of network-close image storage for faster pushes and pulls when you are working with distributed development or deployment scenarios. Apart from all this, a single registry, image, and tag names can be used across multiple regions and data transfer rate is also reduced as images will be pulled from a local and replicated registry in the same or nearby region. Last but not the least, you can leverage the feature of storing same container images in more than 1 ACR when geo-replication is enabled.
6. Zone redundancy: This feature helps you to create a resilient and high-availability with premium based ACR and zone redundancy actually used the concept of Azure availability zones underneath to replicate your registry to a minimum of three separate zones in each enabled region.
Note: Retention policy prevents the registry from quickly filling up with images or other artifacts that aren’t needed after a certain period. When enabled, manifests that don’t have any associated tags (untagged manifests) and are not locked, will be automatically deleted after the number of retention days specified. Retention policy time range varies between 0–365 days.
Azure Container Registry — Key Terms
- Registry: A container registry is a service that stores and distributes container images and related artifacts. ACR also provides users with direct control of their container content, with integrated authentication, geo-replication supporting global distribution and reliability for network-close deployments, virtual network configuration with Private Link, tag locking, and many other enhanced features.
- Repository: A repository is a collection of container images or other artifacts in a registry that have the same name, but different tags and registry manages all repositories independently, not as a hierarchy.
- Artifact: A container image or other artifact within a registry is associated with one or more tags, has one or more layers, and is identified by a manifest. An artifact can be anything: a text file, a docker image, or a Helm chart, while an image typically refers to a container image.
- Tag: The tag for an image or other artifact specifies its version and the repository plus a tag defines an image’s name. The tag latest is used by default if you don’t provide one in your Docker commands.
- Layer: Container images and artifacts are made up of one or more layers. Different artifact types define layers differently. For example, in a Docker container image, each layer corresponds to a line in the Dockerfile that defines the image:
- Artifacts: in a registry share common layers, increasing storage efficiency. For example, several images in different repositories might have a common ASP.NET Core base layer, but only one copy of that layer is stored in the registry. To provide secure isolation and protection from potential layer manipulation, layers are not shared across registries.
- Manifest: Each container image or artifact pushed to a container registry is associated with a manifest. The manifest, generated by the registry when the content is pushed, uniquely identifies the artifacts and specifies the layers.
Types of Registries
1. Private Registry — Used by an organization or individual for dedicated projects. Eg. ACR
2. Public Registry — Used for open-source projects and to store publicly accessible images. Eg. Docker
Steps to create ACR in Azure Portal
- Login to azure portal and search for container registry.
- 2. Click on create and fill below mentioned details.
Choose subscription and resource group details.
Give a globally unique name to you registry and select location where you want to create it. Next, choose SKU depending on your requirement.
Note: If you are new to ACR and test it to pull and push images, choose either basic or standard. If you want features like Geo-Replication, you must choose Premium type SKU.
3. Choose network connectivity configuration.
Note: By default, public access is enabled for Basic/Standard type SKU. And if you want your ACR to only accessible from certain private endpoints, you must choose Premium SKU.
4. If you choose Private Access in connectivity configuration, you can either link an existing private endpoint or create a new one as shown below.
5. Choose Encryption type:
If you want Azure to manage your images and artifacts when they are at rest, choose disabled option. And if you want to manage everything by yourself, choose enabled and fill details as follow:
Note: Customer can only manage keys for Premium SKU.
6. Give tags to easily identify and locate your ACR (in case you have multiple environment and applications) — Optional
7. Click on review + create and after verifying details, choose create.
Push custom images to ACR repositories using Docker commands
· Pre-requisites: A Linux VM with Docker installed on it.
1. Login to Azure Linux VM using SSH keys/username-password.
2. Check if any Docker image exist by using command: sudo docker images
3. Similarly check for any stopped or running containers using: sudo docker ps –a
4. Pull an nginx image (above which you will build your custom images) from docker hub using:
sudo docker pull nginx
5. Create two files: Dockerfile and index.html using below commands. (optional step) (You can directly pull and image, tag it and push it to ACR)
Create index file: cat>index.html
This is a test image. (content of index.html file)
Create Dockerfile: cat>Dockerfile
FROM nginx
COPY index.html /usr/share/nginx/html
Note: COPY command will overwrite content of our index.html file into default index page of nginx which is stored at path: /usr/share/nginx/html
To view content of index.html and Docker file: cat index.html and cat Dockerfile
6. Build custom image using command:
sudo docker build –t testimage:v1 .
Note: testimage is name of your image, v1 is tag value and . at the end represent that you are committing changes in current working directory. –t is used to give image a tag.
7. Run your image using a container
sudo docker run –name testcont –p 80:80 –d testimage:v1
Note: testcont is name of container, -p is used to map port value where 80:80 means we are exposing port 80 of VM with port 80 of container. –d is used to run container in detached mode.
8. List out images and container using sudo docker images and sudo docker ps commands.
9. Login to ACR using command:
sudo docker login <acr-loginserver-name> and then enter username and password.
Note: Service Principal/Managed identities can also be used to login to ACR.
10. Tag your custom image to point it to ACR repo
sudo docker tag imagename:tag acr-login-server/reponame/imagename:tag
Eg. sudo docker tag testimage:v1 testacr1311.azurecr.io/testrepo/testimage:version1
Note: If you have an image in DockerHub, simply pull it using docker pull command and tag it using command no. 10 and then push it to ACR Repo. In this case, you can skip custom image building part.
11. Push custom image to ACR repo
sudo docker push testacr1311.azurecr.io/repo1/testimage:Version1
In Azure Portal, details will look like this:
How to use ACR images for deployment in AKS/ACS?
· For AKS, you need to either create an ACR at the time of AKS creation itself or you can link a new ACR to an existing AKS cluster also.
· For ACS, there is no need to separately link an ACR, because at the time of creation of ACS, registry will reflect by default.
Command to integrate an ACR with an existing AKS Cluster
· Pre-requisites: Azure CLI/PowerShell should be installed on your local system. And CloudShell could also be used to integrate ACR to AKS.
Command: az aks update -n myAKSCluster -g myResourceGroup — attach-acr <acr-name>
OR
az aks update -n myAKSCluster -g myResourceGroup — attach-acr <acr-resource-id>
Deploy a sample application in AKS using ACR images
- Go to AKS Cluster and under Kubernetes Resources, select Workloads. Then choose create at top and then select create a starter application.
3. Click on single-image application.
4. Verify container registry and image details as shown below.
3. Click next, and give a name to your deployment along with no. of replicas.
4. Under resource option, give CPU and Memory request depending on application requirement.
If you want to expose your deployment through a service, tick checkbox and give a service name.
5. Click next, Review Readable YAML file and click on Deploy. After that you will get output like this.
When you will browse the Service-IP, you will get an output like this:
The same content which we had given in index.html file in our custom image.
Methods of pushing an image to Azure Container Registry
Method 1: Using local CloudShell Repository
- Open cloudshell in bash mode.
- Type code, it will open a text editor where you can create Dockerfile and other files.
- Create Dockerfile and index.html file, save files and type below command:
az acr build — registry testacr1311 — image newimage:version1 .
Here, testacr1311 is the registry name and newimage:version1 is image name along with its tag value
Note: . At the end means we are committing all the change in our current working directory). Az acr build is doing authentication and connecting to ACR using AD credentials of user
Method 2: If Dockerfile is present in your local system: Windows System
Pre-requisite: Azure CLI must be installed on your system.
Install Azure CLI on Windows: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-cli
Switch to directory containing files and check if files are visible in particular path using dir command
- Login to azure using: az login
- Run: az acr build -r testacr1311 — image testimage:version1234 .
. means we are making changes in current working directory
Method 3: If Dockerfile is present in your local system: Linux VM
Pre-requisite: Azure CLI should be installed on linux vm
Install Azure CLI: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux?pivots=apt
To push image to ACR:
az acr build — registry testacr1311 — image newimage:version1 .
. means we are committing changes to current working directory
Can an Active Directory User who don’t have access to ACR also push images to ACR??
Method 4: Yes, this is allowed too
- Create a user in AD and give storage account contributor role to user at subscription level (so that user can use cloudshell feature by creating new storage account)
- Login to azure portal using AD Credentials and to CloudShell.
- Create 2 files: Dockerfile and index.html
- Push image to ACR: az acr build -r testacr1311 — image testimage:version1234 .
Suppose Dockerfile is present in storage account and you want to pull that file into CloudShell or azure Linux VM>??
sudo docker build -t testimage:v1 https://rganjalib8af.blob.core.windows.net/container1/Dockerfile
https://rganjalib8af.blob.core.windows.net/container1/Dockerfile is the URL of storage account container where Dockerfile is present and make the container as publicly accessible.
Method 4: By pulling source code from GitHub
az acr build -r testacr1311 https://github.com/dubeyanjali1998/ACR-Demo -f Demo/Dockerfile — image firstproject:version1
Note: For this command to run successfully, Your Git Repository should be public in nature.
Push Helm Charts to ACR
- Create a directory with any name by using the command: mkdir helmdemo
- Change the working directory to helmtest by using command: cd helmdemo
- Create a helm chart by giving any name and using command:
helm create helmfirstchart
This command creates a chart directory along with the common files and directories used in a chart. (helmfirstchart is the chart name here, you can give any name of your choice)
4. Change directory to the templates folder and first delete the contents there:
a. cd helmfirstchart/templates
Note: The templates/ directory is for template files. When Helm evaluates a chart, it will send all of the files in the templates/ directory through the template rendering engine. It then collects the results of those templates and sends them on to Kubernetes.
If you take a look at the helmfirstchart/templates/ directory, you’ll notice a few files already there.
NOTES.txt: The “help text” for your chart. This will be displayed to your users when they run helm install.
deployment.yaml: A basic manifest for creating a Kubernetes deployment
service.yaml: A basic manifest for creating a service endpoint for your deployment
_helpers.tpl: A place to put template helpers that you can re-use throughout the chart
Delete everything by running below command:
b. rm -rf *
The first template we are going to create will be a ConfigMap. In Kubernetes, a ConfigMap is simply an object for storing configuration data. Other things, like pods, can access the data in a ConfigMap.
The YAML file above is a bare-bones ConfigMap, having the minimal necessary fields. In virtue of the fact that this file is in the mychart/templates/ directory, it will be sent through the template engine.
It is just fine to put a plain YAML file like this in the mychart/templates/ directory. When Helm reads this template, it will simply send it to Kubernetes as-is.
5. In the templates folder, create a file called configmap.yaml, by running the following command:
Press CTRL+C to save and come out of terminal.
6. Save chart to local archive
Change directory to the hello-world subdirectory. Then, run helm package to save the chart to a local archive.
cd ..
helm package .
7. Authenticate with the registry
Run helm registry login
to authenticate with the registry. You may pass registry credentials appropriate for your scenario, such as service principal credentials, user identity, or a repository-scoped token.
1. SERVICE_PRINCIPAL_NAME=<acr-helm-sp>
2. ACR_NAME=<container-registry-name>
3. ACR_REGISTRY_ID=$(az acr show — name $ACR_NAME — query id — output tsv)
4. PASSWORD=$(az ad sp create-for-rbac — name demoacr-helm-sp — scopes $(az acr show — name demoacr1311 — query id — output tsv) — role acrpush — query “password” — output tsv)
5. USER_NAME=$(az ad sp list — display-name $SERVICE_PRINCIPAL_NAME — query “[].appId” — output tsv)
6. helm registry login $ACR_NAME.azurecr.io — username $USER_NAME — password $PASSWORD
List charts in the repository
az acr repository show — name $ACR_NAME — repository helmdemo/helmfirstchart
az acr manifest list-metadata — registry $ACR_NAME — name helm/hello-world
Pull chart to local archive
You can optionally pull a chart from the container registry to a local archive using helm pull. The chart tag is passed using the — version parameter. If a local archive exists at the current path, this command overwrites it.
helm pull oci://$ACR_NAME.azurecr.io/repository-name — version 0.1.0
helm pull oci://$ACR_NAME.azurecr.io/helm/hello-world — version 0.1.0
Delete chart from the registry
To delete a chart from the container registry, use the az acr repository delete command. Run the following command and confirm the operation when prompted:
az acr repository delete — name $ACR_NAME — image helm/hello-world:0.1.0