Setup Kubernetes Ingress with AWS ALB Ingress with SSL enabled

Posted By : Amarnath Arora | 29-Sep-2019

 

What is Ingress?


Ingress will expose HTTP and HTTPS routes from outside the cluster to services. Traffic will be routed based on rules defined on the Ingress resource. Ingress can be used to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name-based virtual hosting.

 

The AWS ALB Ingress controller is a controller that triggers the creation of an ALB and the necessary supporting AWS resources whenever a Kubernetes user declares an Ingress resource on the cluster. The Ingress resource will use the ALB to route traffic to different endpoints within the cluster.

 

Prerequisites :


1) RBAC Roles and RoleBindings configured for AWS ALB Ingress controller
2) AWS ACM SSL for domain

 

Let's create a sample service, create a file with name nginx-admin.yaml

 


apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf-admin
data:
  default.conf: |
    server {
        listen 80;
        server_name yourdomain.com;

        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;

        location / {
            root   /var/app/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-admin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-admin
  template:
    metadata:
      labels:
        app: nginx-admin
    spec:
      containers:
      - name: frontend-admin
        image: nginx:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d/
          readOnly: true
          name: nginx-conf-admin
        - mountPath: /var/log/nginx
          name: log
      volumes:
      - name: nginx-conf-admin
        configMap:
          name: nginx-conf-admin
          items:
            - key: default.conf
              path: default.conf
      - name: log
        emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-admin
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx-admin

 

Create the configmap, pod and service using kubectl apply -f nginx-admin.yaml

 

So now our service is exposed using NodePort, you can check if it working by using command

 

kubectl get svc

 

in the ports column there would be a random port mapped to 80 port of service, something like 80:31856/TCP, now you can access it with nodeip:31856, make sure to allow access to 31856 port in your security group.

 

But this is not a production ready solution as it allocates a port from a range of 30000-32767 and we cannot specify a port in the A Record for Domain DNS.

 

Let's create an ingress for our nginx-admin service, create a file with name ingress.yaml

 

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "my-ingress"
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn:   arn:aws:acm:ap-southeast-1:286565389093:certificate/c179d7e2-6831-48b9-a0ad-10b852e5d081
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
  labels:
    app: my-ingress
spec:
  rules:
  - host: yourdomain.com
    http:
      paths:
       - path: /*
         backend:
           serviceName: ssl-redirect
           servicePort: use-annotation
       - path: /*
         backend:
           serviceName: nginx-admin
           servicePort: 80

 


Replace the arn:aws:acm:ap-southeast-1:286565389093:certificate/c179d7e2-6831-48b9-a0ad-10b852e5d081 with arn of your SSL certificate & host: stage.oodlestechnologies.com with your domain name.

 

the ssl-redirect rule will apply to only Http(80) listener and redirect to https(443).

 

Deploy the ingress using kubectl apply -f ingress.yaml

 

After a few seconds, verify that the Ingress is created and DNS name is available.

 

kubectl get ing

 

Now you can add DNS record for your domain with AWS ALB DNS name, it takes up to 48hrs for DNS propagation.

 

Verify the DNS has propagated
dig yourdomain.com

 

Thanks

 

About Author

Author Image
Amarnath Arora

Amarnath has keen interest in cloud technologies & automation. He is very eager to learn and implement new technologies.

Request for Proposal

Name is required

Comment is required

Sending message..