Kubernetes ingress as reverse proxy to Application running outside cluster
Let’s consider, We have an application which is running on a standalone virtual machine. We also have a Kubernetes cluster on which few applications are running and are accessible through ingress. And we want to access our application running on that standalone VM (outside K8s cluster) using same domain which we use to access all other applications running on Kubernetes cluster, without moving the application to K8s cluster.
This article will demonstrate on how to place an application running outside K8s cluster behind ingress running on a K8s cluster. So that application running outside K8s cluster is accessible using same domain which we use to access applications running on K8s cluster.
Before we start, Its assumed we are already familiar with Kubernetes concept and resources. To recap, Ingress in Kubernetes is a resource which helps you place application behind reverse proxy and enable us to access the application from internet. Service in K8s is a resource which help us access application running inside a pod.
Here, I have a blog running on a virtual machine, which is accessible on http://demoblog.navratangupta.in
. And I have a K8s cluster on which few other applications are running and are accessible on http://mycluster.navratangupta.in/*
.
We will place my blog behind my K8s cluster domain under path /blog
. So that this blog is accessible on http://mycluster.navratangupta.in/blog
.
For this, We need to create K8s service of type ExternalName
in K8s cluster. and an ingress. Service of ExternalName type maps the service to the content of externalName
field, by returning a CNAME record with its value.
Create Service and Ingress on K8s cluster
- Create a service.yaml file and add below content to it.
apiVersion: v1
kind: Service
metadata:
name: blog
namespace: demo
spec:
type: ExternalName
externalName: demoblog.navratangupta.in
Here, value of .spec.externalName
is the domain on which blog is accessible (without additional path).
Deploy this service on cluster.
kubectl apply -f service.yaml
2. Create a ingress.yaml file and add below content to it.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: blog
namespace: demo
spec:
rules:
- host: mycluster.navratangupta.in
http:
paths:
- backend:
service:
name: blog
port:
number: 80
path: /blog
pathType: ImplementationSpecific
Here,
.spec.rules[0].host
has the domain name on which applications running on K8s are accessible and our blog should be accessible.
.spec.rules[0].http.paths[0].backend.service.name
has the name of ExternalName type service created in step 1.
.spec.rules[0].http.paths[0].backend.service.port.number
has the port number of VM on which application is accessible. In our case its port 80.
.spec.rules[0].http.paths[0].path
has the path(or endpoint) on which our blog should be accessible. In our case, we want to access our blog under /blog
path.
If application is listening on port 443 and is accessible on HTTPS protocol, then We will have to add below annotation in ingress under .metadata.annotations
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
Its assumed that Nginx Ingress controller is already deployed and running on K8s cluster. Deploy the ingress on cluster
kubectl apply -f ingress.yaml
Re-Configure application running on VM
Once service and Ingress are created on K8s cluster. Configuration changes are required from application end. These configuration changes might be change in domain name and path in configuration files of application. This might or might not be necessary and is dependent on application. Look into application documentation for any domain and proxy changes required.
In our case, we are running our blog using Ghost CMS docker container. Ghost has domain and path set as environment variable url
. I will stop the container and re-create the container with new value of domain and path.
docker stop my-blog
docker rm my-blog # Volume will persist as I have used volume map
docker run -d --name my-blog -v ghost-data:/var/lib/ghost/content -e url=http://mycluster.navratangupta.in/blog -p 80:2368 ghost:alpine
Previous value of url was → http://demoblog.navratangupta.in
Once configurations are updated in application. Access the application with K8s cluster ingress domain and set path. For us, It will access it on http://mycluster.navratangupta.in/blog
That’s it. We should be able to access our application running outside cluster on the same domain which we access K8s applications.
All the links used here were only for demo purpose and has been removed after writing this article.
Thanks
Navratan Lal Gupta
Linux Shots