Azure Container Registry (ACR)
Note: Special thanks to Navisite leaders John Rudenauer , Balaji Sundara and Mike Gallo for their continued support on this blog series.
Overview
Azure Container Registry (ACR) is a managed Docker registry service based on the open-source Docker Registry. It is a secure private registry managed by Azure, and also a managed service so Azure handles the security, backend infrastructure and storage so the developers can focus on their applications. ACR allows you to store images for all types of container deployments including OpenShift, Docker Swarm, Kubernetes and others. It reduces latency by creating a registry in the same Azure location as your deployments. In this blog, we will walk through step-by-step process of ACR creation and integration with Azure Kubernetes Service (AKS) using Azure Service Principal.
For more information on AKS, see our first blog in this series.
This the 2nd blog in the Azure Container Series…stay tuned for more on this series.
- Azure Kubernetes Services (AKS) – Kubenet Network Design (Part 1)
- Azure Container Registry (ACR)
- Azure Kubernetes Services (AKS) – Advanced Network Design with CNI (Part 2)
- Custom Kubernetes Cluster on IaaS VMs in Azure using Flannel Overlay
- AKS with Persistent volumes using Azure Disks and Azure Files
Architecture
This diagram represents the overall flow of how developers can leverage Azure Container Registry in Azure with Azure Kubernetes Service (AKS)
Key Architectural Components
Azure provides great documentation here.
Registry
Registries are available in three SKUs: Basic, Standard, and Premium, each of which support webhook integration, registry authentication with Azure Active Directory, and delete functionality. A fully qualified registry name has the form nnaksacr.azurecr.io
.
Example nehali@nn-ubuntu-vm:~$ az acr list --resource-group nn-aks-rg --query [].loginServer [ "nnaksacr.azurecr.io" ]
Repository
A registry contains one or more repositories, which store groups of container images
Example nehali@nn-ubuntu-vm:~$ az acr repository list -n nnaksacr -o table Result -------- nndemo
Image
Stored in a repository, each image is a read-only snapshot of a Docker-compatible container. Azure container registries can include both Windows and Linux images.
example: nehali@nn-ubuntu-vm:~$ az acr repository show-tags --name nnaksacr --repository nndemo --output table Result -------- v1
Container
A container defines a software application and its dependencies wrapped in a complete filesystem including code, runtime, system tools, and libraries.
Create a Container Registry
There are three SKUs available. Basic is cost-optimized option for developers learning about ACR. In this example, we will use the Standard registry. Review the full feature matrix on the Azure Documentation.
******************************** Login to Azure from Developer VM ******************************** az login az account set --subscription "Microsoft Azure 2" nehali@nn-ubuntu-vm:~$ az account show --output table EnvironmentName IsDefault Name State TenantId ----------------- ----------- ----------------- ------- ------------------------------------ AzureCloud True Microsoft Azure 2 Enabled XXXXX-2648-4ac4-b364-3dc67eXXXXXX nehali@nn-ubuntu-vm:~$ az account show
************************************* Create Azure Container Registry (ACR) ************************************* nehali@nn-ubuntu-vm:~$ az acr create --name nnaksacr --resource-group nn-aks-rg --sku standard --location eastus { "adminUserEnabled": false, "creationDate": "2019-01-31T23:04:30.055730+00:00", "id": "/subscriptions/XXXXX-496c-a43c-XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "location": "eastus", "loginServer": "nnaksacr.azurecr.io", "name": "nnaksacr", "networkRuleSet": null, "provisioningState": "Succeeded", "resourceGroup": "nn-aks-rg", "sku": { "name": "Standard", "tier": "Standard" }, "status": null, "storageAccount": null, "tags": {}, "type": "Microsoft.ContainerRegistry/registries" nehali@nn-ubuntu-vm:~$ az acr list [ { "adminUserEnabled": false, "creationDate": "2019-01-31T23:04:30.055730+00:00", "id": "/subscriptions/XXXX-f308-496c-a43c-XXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "location": "eastus", "loginServer": "nnaksacr.azurecr.io", "name": "nnaksacr", "networkRuleSet": null, "provisioningState": "Succeeded", "resourceGroup": "nn-aks-rg", "sku": { "name": "Standard", "tier": "Standard" }, "status": null, "storageAccount": null, "tags": {}, "type": "Microsoft.ContainerRegistry/registries" } ]
Login to ACR and push a test image
****************** Login to ACR ****************** nehali@nn-ubuntu-vm:~$ az acr login -n nnaksacr Please verify if docker is installed. nehali@nn-ubuntu-vm:~$ az acr login -n nnaksacr Login Succeeded WARNING! Your password will be stored unencrypted in /home/nehali/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store nehali@nn-ubuntu-vm:~$ az acr list -o table NAME RESOURCE GROUP LOCATION SKU LOGIN SERVER CREATION DATE ADMIN ENABLED -------- ---------------- ---------- -------- ------------------- -------------------- --------------- nnaksacr nn-aks-rg eastus Standard nnaksacr.azurecr.io 2019-01-31T23:04:30Z
***************************** Push a test image to ACR **************************** nehali@nn-ubuntu-vm:~$ docker pull nginxdemos/hello Using default tag: latest latest: Pulling from nginxdemos/hello 550fe1bea624: Pull complete d421ba34525b: Pull complete fdcbcb327323: Pull complete bfbcec2fc4d5: Pull complete 0497d4d5654f: Pull complete f9518aaa159c: Pull complete a70e975849d8: Pull complete Digest: sha256:f5a0b2a5fe9af497c4a7c186ef6412bb91ff19d39d6ac24a4997eaed2b0bb334 Status: Downloaded newer image for nginxdemos/hello:latest nehali@nn-ubuntu-vm:~$ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE nginxdemos/hello latest aedf47d433f1 11 months ago 16.8MB nehali@nn-ubuntu-vm:~$ docker tag nginxdemos/hello:latest nnaksacr.azurecr.io/nndemo:v1 nehali@nn-ubuntu-vm:~$ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE nginxdemos/hello latest aedf47d433f1 11 months ago 16.8MB nnaksacr.azurecr.io/nndemo v1 aedf47d433f1 11 months ago 16.8MB nehali@nn-ubuntu-vm:~$ docker push nnaksacr.azurecr.io/nndemo The push refers to repository [nnaksacr.azurecr.io/nndemo] fc9922555bc3: Pushed 767e894eb5e9: Pushed e45dbf549a90: Pushed f93c2b24cb18: Pushed 343bb8320f2b: Pushed 7066df57739c: Pushed d39d92664027: Pushed v1: digest: sha256:f5a0b2a5fe9af497c4a7c186ef6412bb91ff19d39d6ac24a4997eaed2b0bb334 size: 1775 nehali@nn-ubuntu-vm:~$ az acr repository list -n nnaksacr -o table Result -------- nndemo
Use ACS with AKS
When an application need to interact with Azure services, it is not recommended to use your normal AD account. It is more optimal to register the application with Azure AD and create an identity for the application (this identity is called service principal. Antother option is MSI.)
AKS uses service principal to access other azure services like ACR. Default role is contributor so use “–skip-assignment”. Other available roles are as follow:
- Owner (pull, push, and assign roles to other users)
Contributor (pull and push)
Reader (pull only access)
Once the service principal has been created, copy the client_id (named appId in the response) and the client_secret (named password in the response).
**************************** Create a service principal **************************** nehali@nn-ubuntu-vm:~$ az ad sp create-for-rbac -n "nnapp-sp" --skip-assignment Changing "nnapp-sp" to a valid URI of "https://nnapp-sp", which is the required format used for service principal names { "appId": "XXXXX-1c24-42db-8314-0ae768XXXXX", "displayName": "nnapp-sp", "name": "https://nnapp-sp", "password": "XXXXXXX-6ca8-4acf-bd1a-030cbXXXXXXX", "tenant": "93e5c8a2-2648-4ac4-b364-3dc67eb6c7bd" } Get the resource ID of ACR nehali@nn-ubuntu-vm:~$ az acr show --name nnaksacr --resource-group nn-aks-rg --query "id" --output tsv /subscriptions/XXXXXXX-f308-496c-a43c-faae39XXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr Assign reader role to AKS Resource (get the app ID) nehali@nn-ubuntu-vm:~$ az role assignment create --assignee "07f78806-1c24-42db-8314-0ae7681843be" --role Reader --scope "/subscriptions/XXXXXXX-f308-496c-a43c-faae392XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr" { "canDelegate": null, "id": "/subscriptions/XXXXX-f308-496c-a43c-faae39XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr/providers/Microsoft.Authorization/roleAssignments/34f54bb3-c111-4243-bc98-aeb44b36a755", "name": "34f54bb3-c111-4243-bc98-aeb44b36a755", "principalId": "f1fd02ea-19b2-46aa-803e-a459d0c14779", "resourceGroup": "nn-aks-rg", "roleDefinitionId": "/subscriptions/XXXX-f308-496c-a43c-faae39XXXX/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", "scope": "/subscriptions/XXXXXXX-f308-496c-a43c-XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "type": "Microsoft.Authorization/roleAssignments" }
In the portal you should see the reader access undel nnaksacr resource -> Access Control -> Resource Assignment
Get app ID for AKS Service Principal that was already created nehali@nn-ubuntu-vm:~$ az ad sp list --display-name nn-aks-cluster --query [].appId [ "7f60d835-e5f5-4678-87a0-d3453e6a650b" ] Get ACR Resource ID nehali@nn-ubuntu-vm:~$ az acr show --name nnaksacr { "adminUserEnabled": false, "creationDate": "2019-01-31T23:04:30.055730+00:00", "id": "/subscriptions/XXXXX-f308-496c-a43c-XXXXXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "location": "eastus", "loginServer": "nnaksacr.azurecr.io", "name": "nnaksacr", "networkRuleSet": null, "provisioningState": "Succeeded", "resourceGroup": "nn-aks-rg", "sku": { "name": "Standard", "tier": "Standard" }, "status": null, "storageAccount": null, "tags": {}, "type": "Microsoft.ContainerRegistry/registries" } Grant AKS service principal the right permission to the ACR Resource to pull the images nehali@nn-ubuntu-vm:~$ az role assignment create --assignee "7f60d835-e5f5-4678-87a0-d3453e6a650b" --role Reader --scope "/subscriptions/XXXXX-f308-496c-a43c-faae39XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr" { "canDelegate": null, "id": "/subscriptions/XXXXXX-f308-496c-a43c-XXXXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr/providers/Microsoft.Authorization/roleAssignments/2f919c55-d224-412b-bbe7-e39997c09eb3", "name": "2f919c55-d224-412b-bbe7-e39997c09eb3", "principalId": "bc828337-e1b4-47a1-bd6b-3c8a94450973", "resourceGroup": "nn-aks-rg", "roleDefinitionId": "/subscriptions/XXXXXX-f308-496c-a43c-faae3XXXXXX/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", "scope": "/subscriptions/XXXXXX-f308-496c-a43c-faaeXXXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "type": "Microsoft.Authorization/roleAssignments" } Get the login server nehali@nn-ubuntu-vm:~$ az acr list [ { "adminUserEnabled": false, "creationDate": "2019-01-31T23:04:30.055730+00:00", "id": "/subscriptions/XXXXXX-f308-496c-a43c-faae3XXXXXX/resourceGroups/nn-aks-rg/providers/Microsoft.ContainerRegistry/registries/nnaksacr", "location": "eastus", "loginServer": "nnaksacr.azurecr.io", "name": "nnaksacr", "networkRuleSet": null, "provisioningState": "Succeeded", "resourceGroup": "nn-aks-rg", "sku": { "name": "Standard", "tier": "Standard" }, "status": null, "storageAccount": null, "tags": {}, "type": "Microsoft.ContainerRegistry/registries" } ] nehali@nn-ubuntu-vm:~$ az acr list --resource-group nn-aks-rg --query [].loginServer [ "nnaksacr.azurecr.io" ] nehali@nn-ubuntu-vm:~$ az acr list --resource-group nn-aks-rg --query [].loginServer --output table Result ------------------- nnaksacr.azurecr.io nehali@nn-ubuntu-vm:~$ az acr list --resource-group nn-aks-rg --query [].{nnlogin:loginServer} --output table Nnlogin ------------------- nnaksacr.azurecr.io nehali@nn-ubuntu-vm:~$ az acr list --resource-group nn-aks-rg --query [].{ACRloginServer:loginServer} --output table ACRloginServer ------------------- nnaksacr.azurecr.io
Create a deployment to pull the image from ACR
nehali@nn-ubuntu-vm:~$ az acr repository list -n nnaksacr -o table Result -------- nndemo nehali@nn-ubuntu-vm:~$ az acr repository show-tags --name nnaksacr --repository nndemo --output table Result -------- v1 nehali@nn-ubuntu-vm:~$ grep image acr-deployment.yaml image: nnaksacr.azurecr.io/nndemo:v1 nehali@nn-ubuntu-vm:~$ kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh-6fbc77d848-ghdzh 1/1 Running 6 2d23h nn-nginx-deployment-77fcff4b8-f6pxc 1/1 Running 0 2d20h nn-nginx-deployment-77fcff4b8-klvsj 1/1 Running 0 2d20h nn-nginx-deployment-77fcff4b8-n98q9 1/1 Running 0 2d20h nnacr-nginx-deployment-6c49f4b5c6-4d2vj 0/1 ErrImagePull 0 35s nnacr-nginx-deployment-6c49f4b5c6-9gwsf 0/1 ErrImagePull 0 35s nnacr-nginx-deployment-6c49f4b5c6-hgbvf 0/1 ErrImagePull 0 35s nehali@nn-ubuntu-vm:~$ vi acr-deployment.yaml nehali@nn-ubuntu-vm:~$ kubectl delete -f acr-deployment.yaml deployment.apps "nnacr-nginx-deployment" deleted service "nnacr-nginx-service" deleted nehali@nn-ubuntu-vm:~$ kubectl create -f acr-deployment.yaml deployment.apps/nnacr-nginx-deployment created service/nnacr-nginx-service created nehali@nn-ubuntu-vm:~$ kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh-6fbc77d848-ghdzh 1/1 Running 6 2d23h nn-nginx-deployment-77fcff4b8-f6pxc 1/1 Running 0 2d20h nn-nginx-deployment-77fcff4b8-klvsj 1/1 Running 0 2d20h nn-nginx-deployment-77fcff4b8-n98q9 1/1 Running 0 2d20h nnacr-nginx-deployment-5685b4485f-6ddnc 1/1 Running 0 3s nnacr-nginx-deployment-5685b4485f-7vdqm 1/1 Running 0 3s nnacr-nginx-deployment-5685b4485f-qzrt2 1/1 Running 0 3s nehali@nn-ubuntu-vm:~$ kubectl get service --watch NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d nn-nginx-service LoadBalancer 10.0.140.61 40.71.30.139 80:31278/TCP 2d20h nnacr-nginx-service LoadBalancer 10.0.149.63 <pending> 80:32365/TCP 64s nnacr-nginx-service LoadBalancer 10.0.149.63 40.87.95.43 80:32365/TCP 2m10s
Cleanup
nehali@nn-ubuntu-vm:~$ kubectl delete -f acr-deployment.yaml deployment.apps "nnacr-nginx-deployment" deleted service "nnacr-nginx-service" deleted
Summary
Azure Container Registry allows you to build, store and manage images for various types of container deployments. It reduces the network latency and eliminate ingress/egress charges by keeping your Docker registry in the same data center as your deployments. Azure Container Registry is a managed service so Azure handles the security, backend infrastructure and storage so the developers can focus on their applications.
To explore more about how Navisite can help you deploy Azure Container Registry, touch base today, or call us at (888) 298-8222 for additional information. Learn more about our Azure Management Services.