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.
Motivation
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.
Prerequisites
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.
Let's do it
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
So what exactly Ingress do?
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.
DNS
It is just not enough, we need to explicitly configure our domain DNS to navigate to our server cluster IP.
Note:
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
It could take couple of minutes for your DNS configuration propagate over global.
Tadaaa
Now we can access multiple services on our Kubernetes cluster with only one domain.
Conclusion
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.
Top comments (1)
what if my cluster on localhost rancher