Skip to content

External DNS - Use it for our Applications

Image

Step-01: Update Ingress manifest by adding External DNS Annotation

  • Added annotation with two DNS Names
  • dnstest1.kubeoncloud.com
  • dnstest2.kubeoncloud.com
  • Once we deploy the application, we should be able to access our Applications with both DNS Names.
  • 07-ALB-Ingress-SSL-Redirect-ExternalDNS.yml
        # External DNS - For creating a Record Set in Route53
        external-dns.alpha.kubernetes.io/hostname: dnstest1.kubeoncloud.com, dnstest2.kubeoncloud.com    
    
  • In your case it is going to be, replace yourdomain with your domain name
  • dnstest1.yourdoamin.com
  • dnstest2.yourdoamin.com
  • Refer Presentation from slide 106 onwards

Kubernetes Manifests

#01-MySQL-externalName-Service.yml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ExternalName
  externalName: usermgmtdb.cxojydmxwly6.us-east-1.rds.amazonaws.com
#02-UserManagementMicroservice-Deployment-Service.yml
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: usermgmt-microservice
  labels:
    app: usermgmt-restapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: usermgmt-restapp
  template:  
    metadata:
      labels: 
        app: usermgmt-restapp
    spec:
      initContainers:
        - name: init-db
          image: busybox:1.31
          command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e "  >> MySQL DB Server has started";']      
      containers:
        - name: usermgmt-restapp
          image: stacksimplify/kube-usermanagement-microservice:1.0.0  
          ports: 
            - containerPort: 8095           
          env:
            - name: DB_HOSTNAME
              value: "mysql"            
            - name: DB_PORT
              value: "3306"            
            - name: DB_NAME
              value: "usermgmt"            
            - name: DB_USERNAME
              value: "dbadmin"        # RDS DB Username is dbadmin     
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-db-password
                  key: db-password           
          livenessProbe:
            exec:
              command: 
                - /bin/sh
                - -c 
                - nc -z localhost 8095
            initialDelaySeconds: 60
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /usermgmt/health-status
              port: 8095
            initialDelaySeconds: 60
            periodSeconds: 10          
#03-Kubernetes-Secrets.yml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-db-password
type: Opaque
data: 
  db-password: ZGJwYXNzd29yZDEx
#04-UserManagement-NodePort-Service.yml
apiVersion: v1
kind: Service
metadata:
  name: usermgmt-restapp-nodeport-service
  labels:
    app: usermgmt-restapp
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer  
    alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status    
spec:
  type: NodePort
  selector:
    app: usermgmt-restapp
  ports:
    - port: 8095
      targetPort: 8095
#05-Nginx-App1-Deployment-and-NodePortService.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1-nginx-deployment
  labels:
    app: app1-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1-nginx
  template:
    metadata:
      labels:
        app: app1-nginx
    spec:
      containers:
        - name: app1-nginx
          image: stacksimplify/kube-nginxapp1:1.0.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app1-nginx-nodeport-service
  labels:
    app: app1-nginx
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
spec:
  type: NodePort
  selector:
    app: app1-nginx
  ports:
    - port: 80
      targetPort: 80
#06-Nginx-App2-Deployment-and-NodePortService.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2-nginx-deployment
  labels:
    app: app2-nginx 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app2-nginx
  template:
    metadata:
      labels:
        app: app2-nginx
    spec:
      containers:
        - name: app2-nginx
          image: stacksimplify/kube-nginxapp2:1.0.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app2-nginx-nodeport-service
  labels:
    app: app2-nginx
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
    alb.ingress.kubernetes.io/healthcheck-path: /app2/index.html
spec:
  type: NodePort
  selector:
    app: app2-nginx
  ports:
    - port: 80
      targetPort: 80
#07-ALB-Ingress-SSL-Redirect-with-ExternalDNS.yml
# Annotations Reference:  https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-usermgmt-restapp-service
  labels:
    app: usermgmt-restapp
  annotations:
    # Ingress Core Settings  
    kubernetes.io/ingress.class: "alb"
    alb.ingress.kubernetes.io/scheme: internet-facing
    # Health Check Settings
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    #Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    #alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    ## SSL Settings
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:180789647333:certificate/9f042b5d-86fd-4fad-96d0-c81c5abc71e1
    #alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01 #Optional (Picks default if not used)    
    # SSL Redirect Setting
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'   
    # External DNS - For creating a Record Set in Route53
    external-dns.alpha.kubernetes.io/hostname: dnstest1.kubeoncloud.com, dnstest2.kubeoncloud.com      
spec:
  rules:
    #- host: ssldemo.kubeoncloud.com    # SSL Setting (Optional only if we are not using certificate-arn annotation)
    - http:
        paths:
          - path: /* # SSL Redirect Setting
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation            
          - path: /app1/*
            backend:
              serviceName: app1-nginx-nodeport-service
              servicePort: 80                        
          - path: /app2/*
            backend:
              serviceName: app2-nginx-nodeport-service
              servicePort: 80            
          - path: /*
            backend:
              serviceName: usermgmt-restapp-nodeport-service
              servicePort: 8095              
# Important Note-1: In path based routing order is very important, if we are going to use  "/*", try to use it at the end of all rules.         

Step-02: Deploy all Application Kubernetes Manifests

Deploy

# Deploy
kubectl apply -f kube-manifests/

Verify Load Balancer & Target Groups

- Load Balancer -  Listeneres (Verify both 80 & 443) 
- Load Balancer - Rules (Verify both 80 & 443 listeners) 
- Target Groups - Group Details (Verify Health check path)
- Target Groups - Targets (Verify all 3 targets are healthy)
- Verify ingress controller from kubectl

Verify External DNS Log

# Verify External DNS logs
kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+')
- External DNS Log
time="2020-05-29T04:25:55Z" level=info msg="Desired change: CREATE dnstest1.kubeoncloud.com A [Id: /hostedzone/Z29P9D94N7I5H5]"
time="2020-05-29T04:25:55Z" level=info msg="Desired change: CREATE dnstest2.kubeoncloud.com A [Id: /hostedzone/Z29P9D94N7I5H5]"
time="2020-05-29T04:25:55Z" level=info msg="Desired change: CREATE dnstest1.kubeoncloud.com TXT [Id: /hostedzone/Z29P9D94N7I5H5]"
time="2020-05-29T04:25:55Z" level=info msg="Desired change: CREATE dnstest2.kubeoncloud.com TXT [Id: /hostedzone/Z29P9D94N7I5H5]"
time="2020-05-29T04:25:55Z" level=info msg="4 record(s) in zone zetaoptdemo.com. [Id: /hostedzone/Z29P9D94N7I5H5] were successfully updated"
time="2020-05-29T04:26:55Z" level=info msg="All records are already up to date"
time="2020-05-29T04:27:55Z" level=info msg="All records are already up to date"
time="2020-05-29T04:28:55Z" level=info msg="All records are already up to date"

Verify Route53

  • Go to Services -> Route53
  • You should see Record Sets added for dnstest1.kubeoncloud.com, dnstest2.kubeoncloud.com

Best Selling AWS EKS Kubernetes Course on Udemy

Start Learning Now!

Step-04: Access Application using newly registered DNS Name

Perform nslookup tests before accessing Application

  • Test if our new DNS entries registered and resolving to an IP Address
    # nslookup commands
    nslookup dnstest1.kubeoncloud.com
    nslookup dnstest2.kubeoncloud.com
    

Access Application using dnstest1 domain

# HTTP URLs (Should Redirect to HTTPS)
http://dnstest1.kubeoncloud.com/app1/index.html
http://dnstest1.kubeoncloud.com/app2/index.html
http://dnstest1.kubeoncloud.com/usermgmt/health-status

Access Application using dnstest2 domain

# HTTP URLs (Should Redirect to HTTPS)
http://dnstest2.kubeoncloud.com/app1/index.html
http://dnstest2.kubeoncloud.com/app2/index.html
http://dnstest2.kubeoncloud.com/usermgmt/health-status

Step-05: Clean Up

kubectl delete -f kube-manifests/

References

  • https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/alb-ingress.md
  • https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md

How ALB Ingress Controller Works?

AWS ALB Ingress Installation

AWS ALB Ingress Implementation Basics

Subscribe to our Youtube Channel

Free Courses

Image

Start with our Getting Started Free Courses!