My intention of writing this post is to share with you things that I learned today and hope that might help some guy on the Internet just like me searching for a quick way to do something rather than reading a lot of dry text.
The demand emerges when there is a fact that I have multiple applications running on my Kubernetes cluster, I have only one domain though. That is where Kubernetes Ingress resource comes into play.
For the sake of simplicity and focusing on Ingress resource, I will assume that you are familiar with Kubernetes resource objects like: Deployment, Service,... and having control over your cluster with kubectl.
For demonstration purpose, I am going to spin up two applications, portfolio and healthinsight respectively. To achieve that, I simply create two deployments with one replica each, and also two services in order to keep track of IP of the pods created and destroy frequently.
If not mentioned otherwise, all resources are deployed on default namespace.
Yaml file for portfolio app
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: portfolio namespace: default spec: selector: matchLabels: run: portfolio template: metadata: labels: run: portfolio spec: containers: - image: gcr.io/phuong-devops/portfolio:v2 imagePullPolicy: IfNotPresent name: portfolio ports: - containerPort: 3000 protocol: TCP imagePullSecrets: - name: gcr-key --- apiVersion: v1 kind: Service metadata: name: portfolio namespace: default spec: ports: - port: 3000 protocol: TCP targetPort: 3000 selector: run: portfolio type: NodePort
YAML file for healthinsight app
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: healthinsight-app namespace: default spec: selector: matchLabels: run: healthinsight-app template: metadata: labels: run: healthinsight-app spec: containers: - image: gcr.io/phuong-devops/healthinsight-frontend:v1 name: healthinsight-app ports: - containerPort: 80 protocol: TCP imagePullSecrets: - name: gcr-key --- apiVersion: v1 kind: Service metadata: name: healthinsight-app namespace: default spec: ports: - port: 3001 protocol: TCP targetPort: 80 selector: run: healthinsight-app type: NodePort
Deploying these two applications is easy as a piece of cake.
The problem is our application is unreachable from the external network (Internet), so I deploy an Ingress resource on our Kubernetes cluster so as to it routes the traffic from Internet to our pods (applications).
Keep in mind that you have to setup an Ingress Controller to satisfy Ingress Resource. Only creating Ingress Resource below has no effect.
There are a bunch of Controller that may fit your preferences, take a look at here. For demonstration purpose, I will pick Nginx Ingress Controller, you could easily have your Nginx controller installed on your cluster after following the official documentation here
Ingress exposed HTTP and HTTPS routes from outside the cluster to services within cluster. Traffic routing is controlled by rules defined on the Ingress resource.
An Ingress can be configured to give Services externally-reachable URL, load balance, terminate SSL/TLS, and offer name based virtual hosting.
The below diagram illustrates our implementation.
I am going to deploy our Ingress resource configured to satisfy above demand.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: "nginx" name: cluster-ingress namespace: default spec: rules: - host: hi.phuonghau.com http: paths: - backend: serviceName: healthinsight-app servicePort: 3001 - host: phuonghau.com http: paths: - backend: serviceName: portfolio servicePort: 3000
Check out if our Ingress resource deployment works fine.
It is just not enough, we need to explicitly configure our domain DNS to navigate to our server cluster IP.
When we expose our applications on cluster on a domain name, we need the external IP address of an application to be static that does not change. So that the domain can correctly navigate to our clusters.
I am using GoDaddy for example, the steps are not the same if you are using other domain broker services, but the terms is applicable.
To reiterate, I want phuonghau.com to points to portfolio service and hi.phuonghau.com to point to health insight service.
Simply add an A record pointing to cluster IP (phuonghau.com points to clusterIP), and a CName hi points to phuonghau.com. Check the brief differences between an A record and Cname at here
With Kubernetes Ingress we are able to expose many applications to outside on the Internet with ease, those above steps is basically describe practical steps. The official document still the best place which we should take a glance at. Any feedback on this article is more than welcome.Thanks for reading.