Python API Scaling with Kubernetes: dockerization (1/4)

Vijay Maurya
4 min readJun 16, 2024

--

We will explore how to scale a Python API using Docker and Kubernetes. The comprehensive solution is segmented into four parts:

1. Creation and dockerization of a simple Python API
2. Local setup of Minikube
3. Scaling the API using Kubernetes
4. Testing the entire scaling system

In this initial segment, our focus will be on developing a straightforward Python API, containerizing it with Docker, and uploading the Docker image to Docker Hub. This establishes the foundation for the deployment and scaling of the API with Kubernetes in the following segments.

1. Simple Python API Creation and Dockerization

API Creation

First, let’s create a simple Python API using Flask. Flask is a lightweight WSGI web application framework in Python. It is easy to set up and perfect for small to medium-sized applications.

Our API will have three endpoints:

  • /: A simple endpoint that returns a greeting message along with the hostname and IP address of the server.
  • /reverse: An endpoint that reverses the text provided in the request body.
  • /cpu-intensive: An endpoint that simulates a CPU-intensive task. we will use this function to increase CPU load. which help us to scale based on CPU utilization.

Here is the code for our API:

from flask import Flask, request, jsonify
import socket
import time
import threading

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def hello():
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
return f"Hello from {hostname} with IP address {ip_address}!"

@app.route('/reverse', methods=['POST'])
def reverse_text():
time.sleep(2)
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
data = request.json
if 'text' in data:
reversed_text = ' '.join(word[::-1] for word in data['text'].split())
return jsonify({
'reversed_text': reversed_text,
'hostname': hostname,
'ip_address': ip_address
})
else:
return jsonify({'error': 'No text provided'}), 400

@app.route('/cpu-intensive', methods=['GET'])
def cpu_intensive():
def cpu_task():
end_time = time.time() + 8
while time.time() < end_time:
pass # Busy-wait to simulate CPU load

thread = threading.Thread(target=cpu_task)
thread.start()
thread.join() # Wait for the thread to complete

hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
return jsonify({
'message': 'CPU intensive task completed',
'hostname': hostname,
'ip_address': ip_address
})

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Dockerization of the Python API

Next, we will create a Dockerfile to containerize our Python API. A Dockerfile is a script that contains a series of instructions on how to build a Docker image.

Here is the Dockerfile for our API:

# Use the official Python image from the Docker Hub
FROM python:3.9-slim

# Set the working directory
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install Flask

# Make port 5000 available to the world outside this container
EXPOSE 5000

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Building Docker Image

To build the Docker image, navigate to the directory containing the Dockerfile and run the following command:

docker build -t your_dockerhub_username/python-api .

You can view created docker image using

docker image list

Now it's time to test are API using docker. For running docker image you can use below command to run docker

docker run -p 5000:5000 mldecodee/python-k8s-api

Now let's test this API using below curl command

curl --location 'http://localhost:5000/reverse' \
--header 'Content-Type: application/json' \
--data '{
"text":"Hello world"

}'

You can open in browser will give you greetings

http://localhost:5000/ 
Hello from abcdefe with IP address 10.33.44.2 !

Pushing the Docker Image

Once the image is built, you can push it to Docker Hub using the following commands:

docker login
docker push your_dockerhub_username/python-api

Make sure to replace your_dockerhub_username with your actual Docker Hub username.

you can directly pull my docker image for learning which is I have used for this tutorial

docker pull mldecode/python-k8s-api:latest

Conclusion

In this part of the series, we created a simple Python API using Flask, dockerized it, and pushed the Docker image to Docker Hub.

This sets the stage for deploying and scaling the API using Kubernetes, which we will cover in the next parts of this series.

In next part where we will set up Minikube locally to create a Kubernetes cluster for our API!

All the important link

  1. Creation and dockerization of a simple Python API : Current Blog
  2. Local setup of Minikube : link
  3. Scaling the API using Kubernetes: Link
  4. Testing the entire scaling system : Link

Stay tuned for more insights and optimizations in future posts!

LinkedIn profile: https://www.linkedin.com/in/vk-maurya

GitHub Link: https://github.com/vk-maurya/python-api-k8s-autoscaling

--

--