AKS Cluster Part.2
Published Date: 28-JAN-2019
Over in Part 1 we used Terraform to spin up a really basic Kubernetes cluster in azure. CLI for the win always!
For the record, I'm following some really good documentation from Microsoft's Azure documentation site (all references credited at the end). These are just my notes, screenshots and outputs for my own reference.
A lot of the how this I write these is how I would want to it to read if I were trying to learn this again myself :)
In this part, we just want to setup an Azure Container Registry (ACR) that's going to be our private, or internal, holder of all things docker/container images and what-not.
Once we get this up and ready for service, this is where we will throw our applications to deploy from!
Series Overview
- Part 1 - get Kubernetes cluster up and running on Azure Kubernetes Managed Service (AKS)
- Part 2 - create a private Docker Registry in the cloud using Azure's Container Registry Managed service (ACR)
- Part 3 - deploy a simple application to it.
Now that we know where we are, let's go!
Pre-requisites
As in Part 1, you'll need the following already installed to get going:
- Azure portal account
- Azure az-cli (command line interface)
- Terraform installed (zipped binary, copy to ~/bin)
- (optional) Kubectl installed
Right, let's have a look at the two methods we can use to stand things up:
Method 1: az-cli
with this method, we'll be going through a series of azure-cli 'az' calls to set things up
login with azure-cli
from a terminal, login to your azure account
az login
a browser window opens, you select the email that gets you into your azure portal account.
create a resource group
az group create --name cloudbuilder-rg --location australiaeast
output looks like this
{
"id": "/subscriptions/0d667072-XXXX-46ef-a5b4-86979fd2XXXX/resourceGroups/cloudbuilder-rg",
"location": "australiaeast",
"managedBy": null,
"name": "cloudbuilder-rg",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": null
}
create a container registry
run this command
az acr create --resource-group "cloudbuilder-rg" --name cloudBRegistry --sku Basic
take note the registry name you choose after "--name" has to be a unique name when combined with suffix ".azurecr.io" otherwise you'll get denied like so
az acr create --resource-group "cloudbuilder-rg" --name cloudRegistry --sku Basic
The registry DNS name cloudregistry.azurecr.io is already in use.
successful output looks like this
{
"adminUserEnabled": false,
"creationDate": "2019-02-04T08:19:59.124377+00:00",
"id": "/subscriptions/0d667072-XXXX-46ef-a5b4-86979fd2XXXX/resourceGroups/cloudbuilder-rg/providers/Microsoft.ContainerRegistry/registries/cloudBRegistry",
"location": "australiaeast",
"loginServer": "cloudbregistry.azurecr.io",
"name": "cloudBRegistry",
"networkRuleSet": null,
"provisioningState": "Succeeded",
"resourceGroup": "cloudbuilder-rg",
"sku": {
"name": "Basic",
"tier": "Basic"
},
"status": null,
"storageAccount": null,
"tags": {},
"type": "Microsoft.ContainerRegistry/registries"
}
right, so far so good.
key output here to take note of = "loginServer": "cloudbregistry.azurecr.io"
OR short-cut:
az acr list --resource-group $NAME_OF_ACR --query "[].{acrLoginServer:loginServer}" --output table
login to new ACR
I had issues with this on a corporate setup with multiple Azure accounts so it kept giving me weird errors and not letting me login. On my personal, simple, single account setup, the login is really straight forward
az acr login --name cloudBRegistry
Login Succeeded
that's it.
Congratulations, you've got a brand spanking new ACR setup!
but its a bit useless sitting there doing nothing, let's try and push some images to it!
Push an image?
hmmm, let's just test it with a local docker image we can re-tag and push to see how it goes.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tiangolo/uwsgi-nginx-flask python3.6 0f8df7d438f3 3 weeks ago 949MB
localhost:5000/golang 1.10 b65fe5418f5f 5 weeks ago 729MB
golang 1.10 b65fe5418f5f 5 weeks ago 729MB
nginx 1.14 3f55d5bb33f3 5 weeks ago 109MB
mysql 5.7 ba7a93aae2a8 5 weeks ago 372MB
redis latest 5d2989ac9711 5 weeks ago 95MB
wordpress php7.1-fpm-alpine 87b83134b87c 6 weeks ago 113MB
registry 2 9c1f09fe9a86 6 weeks ago 33.3MB
alpine 3.8 3f53bb00af94 6 weeks ago 4.41MB
'registry' looks small enough
docker tag registry:2 cloudbregistry.azurecr.io/registry:2
re-tagged with our new ACR as the destination, now for a Push
docker push cloudbregistry.azurecr.io/registry:2
The push refers to a repository [cloudbregistry.azurecr.io/registry]
2c2e689683cd: Pushed
0d2f98178000: Pushed
2a02e265caaa: Pushed
aa889911e071: Pushed
4a9dd85dec45: Pushed
2: digest: sha256:4dc58b720da3630db2be1cc811837c1671c55e419bf14f775752cee4178832d6 size: 1364
easy as that!
Useful ACR commands
quick look at all the images in our ACR
az acr repository list --name cloudbregistry --output table
Result
--------
registry
hmmm, not many!
any cool tags?
az acr repository show-tags --name cloudbregistry --repository registry --output table
Result
--------
2
ah, just the 'registry:2' tag!
ah well, we're done with the ACR, so quick way to DELETE IT ALL, is to delete the resource group - you remember the one "cloudbuilder-rg"
az group delete --name "cloudbuilder-rg"
Are you sure you want to perform this operation? (y/n): y
That's it. pretty anti-climatic huh.
Method 2: Terraform
This post has been updated from here on: 03/06/2019. {: .notice--info}
Ok, let's try doing it with terraform.
main.tf
# Azure Container Registry (managed)
resource "azurerm_resource_group" "rg" {
name = "${var.resource_group_name-acr}"
location = "${var.location}"
}
resource "azurerm_container_registry" "acr" {
name = "${var.acr_name}"
resource_group_name = "${azurerm_resource_group.rg.name}"
location = "${azurerm_resource_group.rg.location}"
sku = "Basic"
admin_enabled = true
}
variables.tf
# variables
variable "resource_group_name-acr" {
description = "ACR Resource Group."
default = "AKS-CLOUDRESOURCES"
}
variable "location" {
description = "for ACR"
default = "australiaeast"
}
variable "acr_name" {
description = "ACR Name"
default = "registercloudbuilderio"
}
outputs.tf
note: only outputs admin username & password if you have admin_enabled=true.
# ACR Outputs
output "login_server" {
value = "${azurerm_container_registry.acr.login_server}"
}
output "admin_password" {
value = "${azurerm_container_registry.acr.admin_password}"
}
output "admin_username" {
value = "${azurerm_container_registry.acr.admin_username}"
}
run a plan
run terraform plan to check what we're doing
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# azurerm_container_registry.acr will be updated in-place
~ resource "azurerm_container_registry" "acr" {
~ admin_enabled = false -> true
id = "/subscriptions/.../resourceGroups/AKS-CLOUDRESOURCES/providers/Microsoft.ContainerRegistry/registries/registercloudbuilderio"
location = "australiaeast"
login_server = "registercloudbuilderio.azurecr.io"
name = "registercloudbuilderio"
resource_group_name = "AKS-CLOUDRESOURCES"
sku = "Basic"
tags = {}
}
Plan: 0 to add, 1 to change, 0 to destroy.
------------------------------------------------------------------------
Terraform Apply
22:07 $ terraform apply -auto-approve
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/.../resourceGroups/AKS-CLOUDRESOURCES]
azurerm_container_registry.acr: Creating...
azurerm_container_registry.acr: Creation complete after 8s [id=/subscriptions/.../resourceGroups/AKS-CLOUDRESOURCES/providers/Microsoft.ContainerRegistry/registries/registercloudbuilderio]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
admin_password = SomePassWOrdz
admin_username = registercloudbuilderio
login_server = registercloudbuilderio.azurecr.io
Right, we should be able to tear through all the ACR stuff we did with the az-cli method
Quick: ACR run-through checks for Terraform method
docker login
22:16 $ docker login -u "registercloudbuilderio" -p "SomePassWOrdz" https://registercloudbuilderio.azurecr.io
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/amosar/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
docker pull, tag, push
pull
22:18 $ docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
e7c96db7181b: Pull complete
Digest: sha256:769fddc7cc2f0a1c35abb2f91432e8beecf83916c421420e6a6da9f8975464b6
Status: Downloaded newer image for alpine:latest
tag
22:18 $ docker tag alpine:latest registercloudbuilderio.azurecr.io/alpine:latest
push
22:19 $ docker push registercloudbuilderio.azurecr.io/alpine:latest
The push refers to repository [registercloudbuilderio.azurecr.io/alpine]
f1b5933fe4b5: Pushed
latest: digest: sha256:bf1684a6e3676389ec861c602e97f27b03f14178e5bc3f70dce198f9f160cce9 size: 528
yep, looks good!
(can probably destroy it now, but I'll clean up later)
So there you go. Azure Container Registry, at your beck and call, via 2 methods.
Thanks for reading!
In Part 3 - we tie it all together with an application deploy into our Kubernetes cluster, pulling from our private ACR!!