Kubernetes: Deploying NGINX with a ConfigMap

Chanel
Nerd For Tech
Published in
7 min readMar 18, 2023
Photo Cred: https://platform9.com/blog/kubernetes-on-premises-why-and-how/

What exactly is Kubernetes? Kubernetes is an open-source container orchestration system that enables you to automate operational tasks for container management. So compared to Docker which is a container runtime, Kubernetes can run and manage containers from many different runtimes.

Kubernetes makes it easy to scale applications and takes care of failover if a container was to go down. Kubernetes also provides service directory, load balancing and storage orchestration.

In this tutorial we will go step-by-step spinning up 2 deployments with the NGINX image both including ConfigMaps that point to custom HTML pages. Lastly we will create a service that points to both deployments.

What you’ll need to get started:

  • Docker Desktop
  • VSCode
  • Basic Understanding of Linux
  • A Docker Hub Account
  • A GitHub Account

Step 1: Install Docker Desktop & VSCode

Docker Desktop is very easy to install and working with Kubernetes on Docker Desktop makes it even easier. Make sure to choose the right versions for your set up.

You can download the appropriate Visual Studio Code for your system here.

On Docker Desktop, to use Kubernetes it is important to enable it by going to the settings in the top right corner. Click on Kubernetes, enable Kubernetes and then click on “Apply and restart”. This may take some time so be patient. Once it’s complete you can leave Docker Desktop running in the background.

Last you are going to want to download the Docker & Kubernetes extensions for VSCode so that it’s able to communicate with Docker Desktop. If you want to push your code to GitHub in the end, you can download that as well.

Step 2: Create ConfigMaps with Custom HTML page

In VSCode you can create a new repository or clone one down from GitHub to work out of. Make sure to create a new branch so if you decide to push the final code up to GitHub, you’re not pushing directly to the main branch.

In the command line on VS code we will create our YAML file for our first config file by using the vim text editor. We will enter the following in the file.

apiVersion: v1
data:
index.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<title>A simple HTML document</title>
</head>
<body>
<p>This is Deployment One!<p>
</body>
</html>
kind: ConfigMap
metadata:
name: my-config1
namespace: default

Before we can create our YAML file for our deployments, we first have to create the ConfigMap for it to reference. We will create the config file with the following command.

#create ConfigMap
kubectl apply -f config-file1.yaml

#list ConfigMap
kubectl get configmap

Now that the configMap is created we will use the vim text editor to create our other YAML file for our deployment.

vim config-file2.yaml

Now we are going to follow the same steps for creating the second configMap but we are going to change a few things. The name of this file will be config-file2.yaml and the content of the file will be as follows.

apiVersion: v1
data:
index.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<title>A simple HTML document</title>
</head>
<body>
<p>This is Deployment Two!<p>
</body>
</html>
kind: ConfigMap
metadata:
name: my-config2
namespace: default

We now have our two configMaps.

Step: 3 Creating Deployments with the NGINX image using a YAML file

Now we are going to create 2 deployments using a YAML file. Each YAML file is required to have the following at a minimum.

  • apiVersion
  • kind
  • metadata
  • spec

There is no one specific way to create resources from a YAML file but the official Kubernetes website is a great resource to reference for documentation formatting.

Also if you want to verify what should be in the YAML file you can run the following command.

kubectl api-resources #shows what needs to match labels in yaml file

Under the headings, everything is lined up for what should be included for the KIND and APIVERSION depending on the resource you are deploying.

As you can see, the APIVERSION for a Pod would be v1 but for a Deployment it’s apps/v1 so that distinction is important.

We will now create a file called “deployment1.yaml” using the vim text editor and the contents will include the following.

#YAML to Delploy NGINX with 2 Replicas

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.3 #latest version on DockerHub
ports:
- containerPort: 80

Now the only thing we have to do is add our ConfigMap to our YAML file by mounting it as a volume.

Your final YAML file should look like this.

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

Formatting is extremely important. Make sure the spacing is correct or it will cause an error during launch.

Now that we’ve created our YAML we will create the deployment with the following command.

kubectl create -f deployment1.yaml

We will create the second deployment and change a few things in the file like the name of the deployment and the config file it’s using. You can’t have two resources with the same name in the same namespace.

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment2
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.3
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /usr/share/nginx/html #nginx specific
volumes:
- name: nginx-config
configMap:
name: my-config2

We now have our two deployments created.

Step 4: Create a Service That Points to Both Deployments

Now that we have created our deployments, we want to create a service for them to check that we can reach our webpage.

In Kubernetes, a Service is a method for exposing a network application that is running as one or more Pods in your cluster. (reference)

Since we are on a Mac using Docker Desktop, we are going to use the Load Balancer type of service. This way the external IP will be exposed so when we run the command in our terminal it will return the webpage.

kubectl expose deployment/nginx-deployment --port 80 --name nginx-service-lb --type LoadBalancer

We have now just exposed our nginx-deployment to port 80 but both our deployments will use this service. We can check the service with the command “kubectl get svc or service”.

List of Services

Under External-IP we have localhost listed which is just Docker Desktop. Under ports we have two numbers listed. The first number 80 is the port that is listening on the inside and the second number 32410 is a randomized high port that is selected that is able to reach outside the container.

To check our port we are going to use the curl command.

curl localhost:80

Because it’s a load balancer you can’t predict what you will get so I personally had to run the command 3 times before it showed the other deployment. You may have to run it more to see that it is working correctly.

We’ve have just created two Kubernetes deployments pointing to custom ConfigMaps that share the same service.

If you’ve made it this far thank you so much for sticking with me and if you’d like to follow more of my journey please connect with me on LinkedIn!

--

--

Chanel
Nerd For Tech

Cloud/Devops Engineer | AWS | Terraform | Linux 🐧