Author : HASSAN MD TAREQ | Updated : 2021/06/09

What Is It?

Note: for production use Application Gateway Ingress Controller

What It Does?

When enabled, it does the followings

Enable Http Application Routing In Azure Portal

In Azure portal

CLI command

az aks enable-addons --resource-group myResourceGroup --name myAKSCluster --addons http_application_routing

Using Http Application Routing

Copy <CLUSTER_SPECIFIC_DNS_ZONE>

We will deploy 2 apps

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)

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

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

Allow third party root CAs in windows

Import our root ca .pem

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

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

Create K8s secret using TLS cert and key (use either of the followings):

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:

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