Hello All,
In my previous blogs, we have discussed on creating k8s cluster and launched the demo application and exposed them with elb (classic). let’s discuss more the exposing the services.
If you have missed out my previous blogs have a look at here Part 1 : https://medium.com/@jothimanikrish/my-first-path-to-kubernetes-setup-in-production-fe54358d1de3 Part 2 :https://medium.com/@jothimanikrish/my-first-path-to-kubernetes-setup-in-production-part-2-of-2-1cd3c718b824
What are the different possibilities of exposing the services?
Cluster IP: Exposes the Service on an internal IP in the cluster. This type makes the Service only reachable from within the cluster.
NodePort: Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a Service accessible from outside the cluster using <NodeIP>:<NodePort>
LoadBalancer: Creates an external load balancer in the current cloud (AWS in our case)
ExternalName: Exposes the Service using an arbitrary name (specified by externalName in the spec) by returning a CNAME record with the name
For more notes refer k8s documents:
Let us discuss how to expose a service to access via AWS ingress controller (Application Load Balancer)
Before that, in our previous tutorial we have exposed the service using elastic load balancer, There are some tough breaks points in that; yes
- though we have load balancer in place proxying the node port for us; We are unable to do path based routing. More importantly http to https redirection is not possible. I have tried out a lot google here and planned to move for ALB. But how? ALB highlights,
- path based routing to the app,
- http to https redirection in the Load balancer level. :) and more..
Lets launch the application with a Application load balancer
- Create a delpoyment for the application
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
app: jenkins
spec:
replicas: 2
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: demo-jenkins
image: jenkins:2.3-alpine
ports:
- containerPort: 8080
- Create a service for the application
kind: Service
apiVersion: v1
metadata:
name: jenkins-deployment
spec:
selector:
app: jenkins
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: NodePort
Form the above service script, stead of Loadbalancer we have to expose it via NodePort, so that we can the ALB to listen from nodeport.
its time to configure and install AWS Ingress controller:
you can also follow the aws docs: https://aws.amazon.com/blogs/opensource/kubernetes-ingress-aws-alb-ingress-controller/
step 1:
Deploy RBAC Roles and RoleBindings needed by the AWS ALB Ingress controller:
kubectl apply -f [https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/rbac-role.yaml](https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/rbac-role.yaml```)
step 2:
Download the AWS ALB Ingress controller YAML into a local file:
Note: before applying this file update the CLUSTER NAME
curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/alb-ingress-controller.yaml" > alb-ingress-controller.yaml
step 3: Apply the configuration
kubectl apply -f alb-ingress-controller.yaml
to confirm the installation; check with the below command:
kubectl logs -n kube-system $(kubectl get po -n kube-system | egrep -o alb-ingress[a-zA-Z0-9-]+)
the output should look similar to this
--------------------------------------------------------------------
AWS ALB Ingress controller
Release: v1.0.0
Build: git-6ee1276
Repository: https://github.com/kubernetes-sigs/aws-alb-ingress-controller
--------------------------------------------------------------------
Now getting back to our application setup:
we are going to listen the app in 443 via alb; and redirect all the requests from 80 to 443 using ALB.
Note: make sure to have aws ssl certificates from ACM
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/subnets: 'SUBNETS, 'SUBNETS'
alb.ingress.kubernetes.io/security-group: 'SECURITYGROUP'
alb.ingress.kubernetes.io/healthcheck-path: "/"
alb.ingress.kubernetes.io/success-codes: "200,404,400"
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn:** REPLACE-YOUR-ARN**
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": $
labels:
name: jenkins
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: jenkins
servicePort: 80
Make sure to replace, ssl certificate ARN received from ACM, subnets and security groups.
save the above file as jenkins-alb.yaml
kubectl apply -f jenkins-alb.yaml
once the deployment was success; describe the service to get ALB CName:
kubectl get ingress
copy and paste the alb arn in the browser to access the app…
Note: also create cname record for cname with route53 for the domain you have purchased the SSL from ACM
Bingo!