Seamless Kubernetes Deployment: From Docker to Browser
"Effortlessly Containerize and Deploy Your Python Web App with Docker and Kubernetes"
Here, let's see how to deploy a simple static web application into Kubernetes by containerizing the application using Docker.
Requirement: We received the application's source code from a GitHub repository. After analyzing it, we discovered that the application is written in Python and will run on port 80.
To gather more details (If needed), we can discuss with the developer to understand the application's basic requirements, which will help us with the containerization process.
With the available information, we proceed to containerize the application.
For this, we use Docker. We create a Dockerfile, selecting Ubuntu as the base image and copying the necessary dependencies into the container. We then install Python, as it is required to run the application, and expose port 80, ensuring the container runs on that port.
FROM ubuntu
WORKDIR /app
COPY requirements.txt /app/ COPY devops /app/
RUN apt-get update && apt-get install -y python3 python3-pip python3-venv
SHELL ["/bin/bash", "-c"]
RUN python3 -m venv venv1 &&
source venv1/bin/activate &&
pip install --no-cache-dir -r requirements.txt
EXPOSE 80
CMD source venv1/bin/activate && python3 manage.py runserver 0.0.0.0:80
Once the Dockerfile is ready, we build the image using the following command:
docker build -t <reponame/imagename>:<tag> .
After building the image, we are pushing it to Docker Hub, making it available for other DevOps engineers on the team using the following command:
docker push <reponame/imagename>:<tag>
Now that our application is available on Docker Hub, we are deploying it on Kubernetes by creating deployment and service files.
A Deployment is a resource used to manage the lifecycle of your application (pods). It defines how many replicas (copies) of your app should be running at any given time, and it can automatically update or rollback your application when needed.
A Service is a way to expose your application (or pods) to other services or external traffic. Kubernetes Services provide a stable endpoint (IP address or DNS name) for accessing the application, even if the underlying pods are constantly changing.
Here is our deployment file, where we have specified 2 replicas of the pod to ensure zero application downtime. An important aspect of this YAML file is the label app: webapp-deployment
, which we will use as a selector in the service configuration.
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
labels:
app: webapp-deployment
spec:
replicas: 2
selector:
matchLabels:
app: webapp-deployment
template:
metadata:
labels:
app: webapp-deployment
spec:
containers:
- name: webapp-container
image: <repo name>/webapp:V1
ports:
- containerPort: 80
Once the deployment.yaml file is ready, we are creating the deployment using the following command.
kubectl apply -f <deployment-file.yaml>
Let’s validate if the pods are available by running the command kubectl get pods
.
Now, let’s access the cluster and check if our application is working by using the pod IP.
curl -L http://<ip address>:<80>/demo
Yeah! It's working now, but what if something goes wrong and we get the pod recreated? In that case, we won’t have the same IP address, right?
I’ve got an idea! Let’s use Kubernetes' service resource to fix this issue. Here’s our service.yaml file where we’re using app: webapp-deployment
(remember we talked about this when we were creating the deployment) as the selector.
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: NodePort
selector:
app: webapp-deployment
ports:
- port: 80
targetPort: 80
nodePort: 30007
We’re using a NodePort service to expose our application to external traffic by opening a specific port on each node in the cluster.
We’ve now overcome the issue of changing IPs during POD recreation, and with NodePort mode, our application is accessible outside the POD (i.e., from the cluster).
But our client needs to access the application through a web browser, not from the cluster. :(
No worries! We can still make it work by using the NodePort command.
kubectl port-forward service/<servicename> 8080:80
Once this is done we can now check in our browser using url localhost:8080/demo
Yah! that’s our web application working in our web browser.! :)
In conclusion, deploying a static web application in Kubernetes involves several key steps, including containerizing the application with Docker, building and pushing the image to Docker Hub, and creating Kubernetes deployment and service files. By using a Deployment, we ensure the application runs with the desired number of replicas, providing resilience and scalability. The Service resource, particularly with NodePort, allows external access to the application, overcoming the challenge of changing pod IPs. This process not only ensures the application is accessible and stable but also aligns with best practices for managing applications in a Kubernetes environment. With these steps, we can confidently deploy and manage applications, ensuring they are robust and accessible to users.