Azure CLI #
Install Azure CLI (Linux) #
Use the following script to install Azure CLI on Debian based distributions:
# Install dependencies
sudo apt update && sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y
# Add Microsoft signing key
sudo mkdir -p /etc/apt/keyrings
curl -sLS https://packages.microsoft.com/keys/microsoft.asc |
sudo gpg --dearmor -o /etc/apt/keyrings/microsoft.gpg
sudo chmod go+r /etc/apt/keyrings/microsoft.gpg
# Add the Azure CLI software repository
AZ_DIST=$(lsb_release -cs)
echo "Types: deb
URIs: https://packages.microsoft.com/repos/azure-cli/
Suites: ${AZ_DIST}
Components: main
Architectures: $(dpkg --print-architecture)
Signed-by: /etc/apt/keyrings/microsoft.gpg" | sudo tee /etc/apt/sources.list.d/azure-cli.sources
# Install Azure CLI
sudo apt update && sudo apt install azure-cli -y
Use the following script to install Azure CLI on any distribution:
# Install Azure CLI
curl -L https://aka.ms/InstallAzureCli | bash
Verify Installation #
# Verify installation / check version
az --version
Login to Azure #
# Login to Azure account: Use browser code
az login --use-device-code
Verify Login #
# List details about current user and subscription
az account show
Install Kubectl (with Azure CLI) #
# Install Kubectl with Azure CLI
sudo az aks install-cli
Verify Installation #
# Verify installation / check version
kubectl version --client
Create AKS CLuster #
List Available Regions #
# List available regions
az account list-locations --output table
# Shell output:
DisplayName Name RegionalDisplayName
------------------------ ------------------- -------------------------------------
East US eastus (US) East US
South Central US southcentralus (US) South Central US
West US 2 westus2 (US) West US 2
West US 3 westus3 (US) West US 3
Australia East australiaeast (Asia Pacific) Australia East
Southeast Asia southeastasia (Asia Pacific) Southeast Asia
North Europe northeurope (Europe) North Europe
Sweden Central swedencentral (Europe) Sweden Central
UK South uksouth (Europe) UK South
West Europe westeurope (Europe) West Europe
Central US centralus (US) Central US
South Africa North southafricanorth (Africa) South Africa North
Central India centralindia (Asia Pacific) Central India
East Asia eastasia (Asia Pacific) East Asia
Japan East japaneast (Asia Pacific) Japan East
Korea Central koreacentral (Asia Pacific) Korea Central
Canada Central canadacentral (Canada) Canada Central
France Central francecentral (Europe) France Central
Germany West Central germanywestcentral (Europe) Germany West Central
Italy North italynorth (Europe) Italy North
Norway East norwayeast (Europe) Norway East
Poland Central polandcentral (Europe) Poland Central
Spain Central spaincentral (Europe) Spain Central
Switzerland North switzerlandnorth (Europe) Switzerland North
Mexico Central mexicocentral (Mexico) Mexico Central
UAE North uaenorth (Middle East) UAE North
Brazil South brazilsouth (South America) Brazil South
Israel Central israelcentral (Middle East) Israel Central
Qatar Central qatarcentral (Middle East) Qatar Central
Central US (Stage) centralusstage (US) Central US (Stage)
East US (Stage) eastusstage (US) East US (Stage)
East US 2 (Stage) eastus2stage (US) East US 2 (Stage)
North Central US (Stage) northcentralusstage (US) North Central US (Stage)
South Central US (Stage) southcentralusstage (US) South Central US (Stage)
West US (Stage) westusstage (US) West US (Stage)
West US 2 (Stage) westus2stage (US) West US 2 (Stage)
Asia asia Asia
Asia Pacific asiapacific Asia Pacific
Australia australia Australia
Brazil brazil Brazil
Canada canada Canada
Europe europe Europe
France france France
Germany germany Germany
Global global Global
India india India
Israel israel Israel
Italy italy Italy
Japan japan Japan
Korea korea Korea
New Zealand newzealand New Zealand
Norway norway Norway
Poland poland Poland
Qatar qatar Qatar
Singapore singapore Singapore
South Africa southafrica South Africa
Sweden sweden Sweden
Switzerland switzerland Switzerland
United Arab Emirates uae United Arab Emirates
United Kingdom uk United Kingdom
United States unitedstates United States
United States EUAP unitedstateseuap United States EUAP
East Asia (Stage) eastasiastage (Asia Pacific) East Asia (Stage)
Southeast Asia (Stage) southeastasiastage (Asia Pacific) Southeast Asia (Stage)
Brazil US brazilus (South America) Brazil US
East US 2 eastus2 (US) East US 2
East US STG eastusstg (US) East US STG
North Central US northcentralus (US) North Central US
West US westus (US) West US
Japan West japanwest (Asia Pacific) Japan West
Jio India West jioindiawest (Asia Pacific) Jio India West
Central US EUAP centraluseuap (US) Central US EUAP
East US 2 EUAP eastus2euap (US) East US 2 EUAP
West Central US westcentralus (US) West Central US
South Africa West southafricawest (Africa) South Africa West
Australia Central australiacentral (Asia Pacific) Australia Central
Australia Central 2 australiacentral2 (Asia Pacific) Australia Central 2
Australia Southeast australiasoutheast (Asia Pacific) Australia Southeast
Jio India Central jioindiacentral (Asia Pacific) Jio India Central
Korea South koreasouth (Asia Pacific) Korea South
South India southindia (Asia Pacific) South India
West India westindia (Asia Pacific) West India
Canada East canadaeast (Canada) Canada East
France South francesouth (Europe) France South
Germany North germanynorth (Europe) Germany North
Norway West norwaywest (Europe) Norway West
Switzerland West switzerlandwest (Europe) Switzerland West
UK West ukwest (Europe) UK West
UAE Central uaecentral (Middle East) UAE Central
Brazil Southeast brazilsoutheast (South America) Brazil Southeast
Create Resource Group #
# Create resouce group
az group create --name aks-playground --location westeurope
List Available Kubernetes Version #
# List available Kubernetes versions
az aks get-versions --location westeurope -o table
# Shell output
KubernetesVersion IsPreview Upgrades SupportPlan
------------------- ----------- ----------------------- --------------------------------------
1.30.0 True None available KubernetesOfficial
1.29.4 1.30.0 KubernetesOfficial
1.29.2 1.29.4, 1.30.0 KubernetesOfficial
1.28.9 1.29.2, 1.29.4 KubernetesOfficial
1.28.5 1.28.9, 1.29.2, 1.29.4 KubernetesOfficial
1.27.13 1.28.5, 1.28.9 KubernetesOfficial, AKSLongTermSupport
1.27.9 1.27.13, 1.28.5, 1.28.9 KubernetesOfficial, AKSLongTermSupport
Create Kubernetes Cluster #
Default region
If no region is specified, Azure defaults to using the region of the resource group.
# Create Kubernetes cluster
az aks create \
--resource-group aks-playground \
--name aks-cluster-1 \
--kubernetes-version 1.30.0 \
--node-count 1 \
--node-vm-size Standard_DS2_v2 \
--node-osdisk-size 30 \
--generate-ssh-keys
# Shell output:
SSH key files '/home/ubuntu/.ssh/id_rsa' and '/home/ubuntu/.ssh/id_rsa.pub' have been generated under ~/.ssh to allow SSH access to the VM. If using machines without permanent storage like Azure Cloud Shell without an attached file share, back up your keys to a safe location
Specific region
If necessary, define the region wherethe cluster is deployed:
az aks create \
--resource-group aks-playground \
--name aks-cluster-1 \
--location northeurope \
--kubernetes-version 1.30.0 \
--node-count 1 \
--node-vm-size Standard_DS2_v2 \
--node-osdisk-size 30 \
--generate-ssh-keys
-
--node-count
Number of worker nodes. AKS manages the controller nodes, they do not count toward the node count. -
--generate-ssh-keys
Used to access the AKS nodes. Azure CLI checks for the presence of SSH keys in the default location~/.ssh
and generates a new SSH key pair if no keys exist.
Configure Kubectl #
# Configure Kubectl to use the AKS cluster
az aks get-credentials \
--resource-group aks-playground \
--name aks-cluster-1
# Shell output:
Merged "aks-cluster-1" as current context in /home/ubuntu/.kube/config
Verify Cluster Nodes #
# List nodes
kubectl get nodes
# Shell output:
NAME STATUS ROLES AGE VERSION
aks-nodepool1-23540999-vmss000000 Ready <none> 4m7s v1.30.0
# List nodes: More details
kubectl get nodes -o wide
# Shell output:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
aks-nodepool1-23540999-vmss000000 Ready <none> 4m18s v1.30.0 10.224.0.4 <none> Ubuntu 22.04.4 LTS 5.15.0-1066-azure containerd://1.7.15-1
Helm #
Install Helm #
# Install Helm with script
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 &&
chmod +x get_helm.sh &&
./get_helm.sh
# Verify the installation / check version
helm version
Nginx Ingress #
Add Helm Chart #
# Add Helm chart
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# Update package index
helm repo update
Install Nginx Ingress #
# Install the Nginx ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.externalTrafficPolicy=Local
Verify Ingress Resources #
# List Ingress resources
kubectl get all -n ingress-nginx
# Shell output:
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-controller-5bfc858768-thxqj 1/1 Running 0 67s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.0.7.167 57.153.157.142 80:31149/TCP,443:30480/TCP 67s
service/ingress-nginx-controller-admission ClusterIP 10.0.195.163 <none> 443/TCP 67s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 67s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-5bfc858768 1 1 1 67s
Cert Manager #
Install Cert Manager #
Find latest release: https://github.com/cert-manager/cert-manager/tags
# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
# Update your local Helm chart repository cache
helm repo update
# Install Cert Manager Custom Resource Definitions (CRDs)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.1/cert-manager.crds.yaml
# Install the cert-manager Helm chart: In "ingress-nginx" namespace
helm install cert-manager jetstack/cert-manager \
--namespace ingress-nginx \
--version v1.15.1
# Shell output:
NAME: cert-manager
LAST DEPLOYED: Sun Jul 14 16:07:15 2024
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.15.1 has been deployed successfully!
In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them
can be found in our documentation:
https://cert-manager.io/docs/configuration/
For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:
https://cert-manager.io/docs/usage/ingress/
Configure Let’s Encrypt ClusterIssuer #
# Create manifest file
vi cert-manager.yml
# Cluster Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: juergen@jklug.work
privateKeySecretRef:
name: letsencrypt-production-private-key
solvers:
- http01:
ingress:
class: nginx
# Apply configuration
kubectl apply -f cert-manager.yml
Find Ingress Public IP #
# List services
kubectl get svc -n ingress-nginx
# Shell output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cert-manager ClusterIP 10.0.26.0 <none> 9402/TCP 57s
cert-manager-webhook ClusterIP 10.0.29.94 <none> 443/TCP 57s
ingress-nginx-controller LoadBalancer 10.0.7.167 57.153.157.142 80:31149/TCP,443:30480/TCP 4m1s
ingress-nginx-controller-admission ClusterIP 10.0.195.163 <none> 443/TCP 4m1s
Create DNS Entry #
Create an A record the points to the public IP of the Nginx Ingress LoadBalancer:
# Create DNS entry
57.153.157.142 aks-cluster.jklug.work
# Verify the DNS entry
ping aks-cluster.jklug.work
Example Deployment with TLS Encryption #
Example Pod & Service #
# Create deployment
kubectl create deployment my-container --image=jueklu/container-1
# Expose deployment with ClusterIP: So that the container port can be accessed
kubectl expose deployment my-container --port=8888 --target-port=8080 --type=ClusterIP --name=my-container-deployment
Create a Certificate #
# Create YML file
vi cert-manager-certificate.yml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-certificate
spec:
secretName: my-certificate-secret
dnsNames:
- "aks-cluster.jklug.work"
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
# Apply configuration
kubectl apply -f cert-manager-certificate.yml
Verify TLS Certificate #
# List certificates
kubectl get certificate
# Shell output: Wait till the READY status is "TRUE"
NAME READY SECRET AGE
my-certificate False my-certificate-secret 14s
# Shell output:
NAME READY SECRET AGE
my-certificate True my-certificate-secret 4s
# List certificate details
kubectl describe certificate my-certificate
# List the certificate secret (contains the actual TLS certificate) details
kubectl describe secret my-certificate-secret
Create Ingress for Deployment Service #
Create an Ingress resources for the service that points to the deployment:
# Create YML file
vi ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-container-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-production
spec:
ingressClassName: nginx
tls:
- hosts:
- "aks-cluster.jklug.work"
secretName: my-certificate-secret
rules:
- host: "aks-cluster.jklug.work"
http:
paths:
- path: /mypath
pathType: Prefix
backend:
service:
name: my-container-deployment
port:
number: 8888
# Apply configuration
kubectl apply -f ingress.yml
Verify Ingress #
# Verify Ingress
kubectl get ing --namespace ingress-nginx
# Shell output:
NAME CLASS HOSTS ADDRESS PORTS AGE
my-container-ingress nginx aks-cluster.jklug.work 80, 443 37s
Test the Deployment #
# Curl the DNS name
curl https://aks-cluster.jklug.work/mypath
# Shell output:
jklug.work container :)
Delete Example Deployment Resources #
# Delete the deployment ingress resource
kubectl delete -f ingress.yml
# Delete the certificate
kubectl delete certificate my-certificate
# Delete the example deployment
kubectl delete deployment my-container
# Delete the service for the deployment
kubectl delete svc my-container-deployment
Delete Azure Resources #
Delete Kubernetes Cluster #
# Delete Kubernetes cluster
az aks delete --resource-group aks-playground --name aks-cluster-1 --yes --no-wait
Delete Resource Group #
# Delete resource group
az group delete --name aks-playground --yes --no-wait
Links #
# Azure Portal
https://portal.azure.com/
# Install Azure CLI
https://learn.microsoft.com/en-us/cli/azure/install-azure-cli
# Azure CLI Commands
https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-install-cli
# Deploy AKS Cluster
https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-cli