Author : MD TAREQ HASSAN | Updated : 2021/06/09
What Is It?
- An add-on of AKS
- Creates publicly accessible DNS names for application endpoints and therefore makes it easy to access applications deployed to AKS cluster
- Creates a DNS zone in your subscription
- Designed for easily getting started with ingress controllers
- Cuasions:
- not for production clusters
- Only for PoC/test/demo
Note: for production use Application Gateway Ingress Controller
What It Does?
When enabled, it does the followings
- Ingress controller:
- Installs nginx ingress controller (basic, only one pod will be running and that’s why it’s not for production)
- Ingress controller is exposed to the internet by using a Kubernetes service of type LoadBalancer
- The Ingress controller watches and implements Kubernetes Ingress resources, which creates routes to application endpoints
- DNS zone:
- Azure DNS Zone is created
- DNS records are added to Azure DNS Zone by ExternalDNS controller (according to ingress rules)
- External DNS controller:
- Uses ExternalDNS (which synchronizes exposed Kubernetes Services and Ingresses with DNS providers)
- Watches for Kubernetes Ingress resources and creates DNS A records in the cluster-specific DNS zone
Enable Http Application Routing In Azure Portal
In Azure portal
- Azure portal > AKS
- Settings: Networking > Check “Enable HTTP application routing”
- Save
- A DNS zone will be created in AKS resouce group (
mc_<your-resource-group>_<your-aks-name>_<your-region>
)
CLI command
az aks enable-addons --resource-group myResourceGroup --name myAKSCluster --addons http_application_routing
Using Http Application Routing
Copy <CLUSTER_SPECIFIC_DNS_ZONE>
- Go AKS resouce group (
mc_<your-resource-group>_<your-aks-name>_<your-region>
) - Select the DNS zone and copy url (see: screenshot here)
We will deploy 2 apps
aks-helloworld-one.<CLUSTER_SPECIFIC_DNS_ZONE_URL>
:aks-helloworld-one.yaml
aks-helloworld-two.<CLUSTER_SPECIFIC_DNS_ZONE_URL>
:aks-helloworld-two.yaml
Commands:
kubectl apply -f aks-helloworld-one.yaml -n demo
kubectl apply -f aks-helloworld-two.yaml -n demo
aks-helloworld-one.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-one
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-one
template:
metadata:
labels:
app: aks-helloworld-one
spec:
containers:
- name: aks-helloworld-one
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "AKS - Hello World 1"
---
apiVersion: v1
kind: Service
metadata:
name: aks-helloworld-one
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: aks-helloworld-one
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld-one
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
spec:
rules:
- host: aks-helloworld-one.xxxxxxxx.japaneast.aksapp.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: aks-helloworld-one
port:
number: 80
aks-helloworld-two.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-two
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-two
template:
metadata:
labels:
app: aks-helloworld-two
spec:
containers:
- name: aks-helloworld-two
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "AKS - Hello World 2"
---
apiVersion: v1
kind: Service
metadata:
name: aks-helloworld-two
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: aks-helloworld-two
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld-two
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
spec:
rules:
- host: aks-helloworld-two.xxxxxxxx.japaneast.aksapp.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: aks-helloworld-two
port:
number: 80
Now visit those URLs and check 2 apps are available with those URLs
Creating Self Signed SSL Certicate
Become self proclaimed Certificate Authority (CA)
- Generate “Root CA” private key that will be used to sign SSL certificate as a CA
- Use passphrase to protect your private key so that only you can sign certificate as CA
openssl genrsa -des3 -out root_ca_private_key.key 2048
Now generate root ca .pem
using private key. You will be promted for pass phrase for private key
openssl req -x509 -new -nodes -key root_ca_private_key.key -sha256 -days 1825 -out root_ca.pem
Now we got the followings
- Our private key:
root_ca_private_key.key
- Our root certificate:
root_ca.pem
From now we can use our private key and root ca to sign certificates as CA. We can manually import our root ca to our PC/browser so that we become valid CA to our PC/browser and PC/browser trust all the certificates we sign.
Allow third party root CAs in windows
- Ctrl + R >
secpol.msc
> enter - Select Public key policies > Double click on “Certificate path validation settings”
- Check: “Define these policy setting” > apply > ok
Import our root ca .pem
- Using command:
certutil –addstore –f "Root" <path-to-certificate-file>
- More on importing certificate:
- Using
certmgr.msc
andmmc
: https://windowsreport.com/install-windows-10-root-certificates/ - StackOverflow question: https://superuser.com/questions/1031444/importing-pem-certificates-on-windows-7-on-the-command-line/1032179
- Using
cd <path-to-certificate-file>
#
# For current user only
#
# 'f' flag to force (will override previously imported certificate)
#
certutil –addstore –f "Root" root_ca.pem
#
# For PC
#
certutil –addstore -enterprise –f "Root" root_ca.pem
Now we are Certificate Authority on our own PC and we can sign certificate for our website.
Create private key for our website certificate
openssl genrsa -out api.9a869c38808849ea9ea0.japaneast.aksapp.io.key 2048
Create Certificate Signing Request (CSR) using private key
openssl req -new -key api.9a869c38808849ea9ea0.japaneast.aksapp.io.key -out api.9a869c38808849ea9ea0.japaneast.aksapp.io.csr
Create extra parameter for openssl command: api.9a869c38808849ea9ea0.japaneast.aksapp.io.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = api.9a869c38808849ea9ea0.japaneast.aksapp.io
Now sign certificate for website using CSR and extra parameters
openssl x509 -req -in api.9a869c38808849ea9ea0.japaneast.aksapp.io.csr -CA root_ca.pem -CAkey root_ca_private_key.key -CAcreateserial -out api.9a869c38808849ea9ea0.japaneast.aksapp.io.crt -days 30 -sha256 -extfile api.9a869c38808849ea9ea0.japaneast.aksapp.io.ext
Using Self Signed SSL Certicate
Create namesapce for demo if needed
kubectl create namespace demo
Create TLS cert and key
- A 2048 bit RSA key/cert pair with an arbitrarily chosen hostname using OpenSSL
- https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/PREREQUISITES.md#tls-certificates
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt
#openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Now trust those selfsigned certificates manually
- Windows:
certutil -addstore -f "ROOT" /path/to/selfsigned.crt
- Chrome:
- Go to:
chrome://settings/privacy
- Security > Manage certificates
- Import certificate to “Trusted root certificate store”
- Go to:
Create K8s secret using TLS cert and key (use either of the followings):
- kubectl command:
kubectl create secret tls demo-tls-secret --key selfsigned.key --cert selfsigned.crt -n demo
- yaml manifest:
kubectl apply -f demo-tls-secret.yaml -n demo
yaml manifest: demo-tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: demo-tls-secret
namespace: demo
type: kubernetes.io/tls
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
Example ingress with TLS
... ... ...
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
spec:
tls: # Ingress with TLS
- hosts:
- aks-helloworld-one.xxxxxxxx.japaneast.aksapp.io
secretName: example-tls
... ... ...
Now deploy 2 applications:
- Both service of type ClusterIP
- Both will use TLS secret
aks-helloworld-one.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-one
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-one
template:
metadata:
labels:
app: aks-helloworld-one
spec:
containers:
- name: aks-helloworld-one
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "AKS TLS (https) - Hello World 1"
---
apiVersion: v1
kind: Service
metadata:
name: aks-helloworld-one
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: aks-helloworld-one
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld-one
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
spec:
tls:
- hosts:
- aks-helloworld-one.9a869c38808849ea9ea0.japaneast.aksapp.io
secretName: demo-tls-secret
rules:
- host: aks-helloworld-one.9a869c38808849ea9ea0.japaneast.aksapp.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: aks-helloworld-one
port:
number: 80
aks-helloworld-two.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-two
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-two
template:
metadata:
labels:
app: aks-helloworld-two
spec:
containers:
- name: aks-helloworld-two
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "AKS TLS (https) - Hello World 2"
---
apiVersion: v1
kind: Service
metadata:
name: aks-helloworld-two
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: aks-helloworld-two
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld-two
annotations:
kubernetes.io/ingress.class: addon-http-application-routing
spec:
tls:
- hosts:
- aks-helloworld-two.xxxxxxxx.japaneast.aksapp.io
secretName: demo-tls-secret
rules:
- host: aks-helloworld-two.xxxxxxxx.japaneast.aksapp.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: aks-helloworld-two
port:
number: 80
Check that 2 apps are available with those URLs
Links
- https://docs.microsoft.com/en-us/azure/aks/http-application-routing
- https://docs.microsoft.com/en-us/azure/aks/ingress-internal-ip#create-an-ingress-controller
- https://docs.microsoft.com/en-us/azure/aks/ingress-tls
- https://carlos.mendible.com/2019/01/10/aks-configure-tls-termination-with-the-http-application-routing-addon/