One IP to Rule Them All: Hosting Multiple Websites with Kubernetes! ☸️

Terminals & Coffee
6 min readMay 9, 2023

--

Hello everyone and welcome to my blog! This week we have a new Kubernetes-based scenario.

The project this week is based on a company that needs to host multiple websites or web applications using a single IP address and port. This could be a cost-effective solution for smaller businesses that cannot afford to have separate servers for each website or application.

We will be utilizing Kubernetes to help our company become more cost-effective and you may read some terms such as deployments, services, ConfigMaps, persistent volumes, and persistent volume claims which may sound confusing, but fret not! I will do my best to explain these concepts and showcase how they are beneficial to our build.

Our managers were kind enough to provide us with the following to-do list:

· Spin up two deployments. One deployment contains 2 pods running the nginx image.
Include a ConfigMap that points to a custom index.html page that contains the line “This is Deployment One”.

· The second deployment also contains 2 pods running the nginx image.
Include a ConfigMap that points to a custom index.html page that contains the line “This is Deployment Two”.

· Create a service that points to both deployments. You should be able to access both deployments using the same ip address and port number.

Before we begin, let’s simplify a few things by explaining what the jargon above means.

What are deployments? A Kubernetes deployment is an object that represents a set of replica pods that are running your application. You can define the number of replicas you want to run, and Kubernetes will create and manage those replicas for you. The deployment also provides features like rolling updates, which allow you to update your application without downtime, and roll back to a previous version if necessary.

What are ConfigMaps? ConfigMaps are API objects that can store unencrypted data in key-value pairs. Pods (a set of containers) can reference ConfigMaps environment variables, CLI arguments, or as config files in a volume.

I hope that sheds some light on what we are about to build, so let’s begin!

In our first step, we are going to want to make sure we have our custom index.html for both deployments.

You can reference mine if you wish.

We’re going to want to save those two HTML files and then focus on creating our ConfigMaps next. We can do that with the following commands.

kubectl create configmap deployment-one-config --from-file=index.html=./deployment_one_index.html

kubectl create configmap deployment-two-config --from-file=index.html=./deployment_two_index.html

We want to create our ConfigMaps immediately after our HTML files to make the custom HTML content available to the Kubernetes deployments.

In this scenario, we use ConfigMaps to store the custom index.html files. By doing this, we can keep the Nginx container images unchanged and simply provide our custom content through ConfigMaps. This makes it easy to update the content without rebuilding the container images.

I decided to switch to VSCode since we will need to build and edit several YAML files for our project. Not sure why I didn’t think of that in the first place. I must need more coffee ☕

VS Code Terminal

Now we can create the YAML file for both deployments.

apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-one
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19.0
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: deployment-one-config

Deployment two should look very similar. I will leave that as a challenge to you to create your own. Once those two are built out and saved locally, we can apply both files.

kubectl apply -f deployment_one.yaml
kubectl apply -f deployment_two.yaml

kubectl get cm is to confirm the ConfigMaps are deployed successfully.

If we run kubectl get all, we can confirm all 4 pods are up and running, just as we needed.

Alright, so that's our 4 pods. Two for deployment one and two for deployment two, each pointing to their own custom index.html page.

Seems like smooth sailing so far.

Our last task is to create a service that points to both deployments, and we should be able to access both with the same IP address and port number.

Our service will be a load balancer. I chose a Load Balancer since they are generally simpler and this is for a project. Feel free to reference the yaml build below.

apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80

Add the service file.

kubectl apply -f service.yaml

If you’re using your local Windows PC and get an FW pop-up, go ahead and click Allow access.

Cool, so it looks like our load-balancer applied with no issues. Now we can type in the following command to get our IP address and Port Number.

kubectl get svc nginx-service

If you see “localhost” instead of a public IP address, it’s likely because you are using a local K8’s cluster. This is fine, we can use the curl command to test our environment.

We see deployment one and deployment two responding because the load balancer service will distribute the traffic between both deployments! 🤓

And that completes all steps required to complete this week's blog!

To recap, we created ConfigMaps for two different deployments, each with its own webpage (HTML file) that share the same IP address and port number saving our small business cost expenses!

👔 Cost📉 Profit 📈

Thank you for taking the time to read this week’s blog! I will leave the following link below if you would like to reference how to delete all of your resources that were created. As for me, I will keep mine up for now since I plan on working toward a more advanced project based on this foundation.

--

--