Kubernetes ingress as reverse proxy to A ...

Kubernetes ingress as reverse proxy to Application running outside cluster

Apr 16, 2022

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.

Illustration of concept

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/*.

Blog running on external Virtual Machine accessible on http://demoblog.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

  1. 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

Blog running on external Virtual Machine but accessible on K8s ingress 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

Enjoy this post?

Buy Linux Shots a coffee

More from Linux Shots