Introduction
You are a developer and containerization holds no secrets for you, and you're looking to advance to the next level. In this tutorial, we will explore how to master container orchestration with Kubernetes. We will learn how to deploy a FastAPI app on the local Kubernetes cluster.
We will start by showing the source code of our example application with FastAPI. Next, we will create the Docker image that will be used to run the application. After that, we will move on to the step of creating the Kubernetes cluster, and we will finish the tutorial with the deployment and visualization of the results.
Prerequisites:
You must already have Docker-Destop installed in your machine.
You need to be familiar with containerization using Docker and have a basic understanding of Kubernetes concepts.
Creating a docker image for our FastAPI App:
Prepare FastAPI code source:
We will use a basic example of an API to simulate the FastAPI application for our tutorial. This is an API that will get or post users.
myproject/app/main.py:
from typing import List
from fastapi import FastAPI, APIRouter, HTTPException
from pydantic import BaseModel, Field
app = FastAPI()
user_router = APIRouter(
prefix='/users'
)
class User(BaseModel):
id: int = Field(gt=0)
name: str = Field(max_length=250)
mock_users = [
{'id': 1, 'name': "Jean Ton"},
{'id': 2, 'name': "Jean Toto"}
]
@user_router.get('/')
async def get_users() -> List[User]:
users = [User(**user) for user in mock_users]
return users
@user_router.get('/{user_id}')
async def get_user(user_id: int):
user = next((User(**user) for user in mock_users if user['id'] == user_id), None)
if user is None:
raise HTTPException(status_code=404, detail='User Not Found')
return user
@user_router.post('/', response_model=User, status_code=201)
async def add_user(user: User) -> User:
if any(existing_user['id'] == user.id for existing_user in mock_users):
raise HTTPException(status_code=400, detail="User already exists")
mock_users.append(user.dict())
return user
app.include_router(user_router)
myproject/requirements.txt:
fastapi==0.111.0
Build and push the docker image:
The next step is to create the docker image to be used to run FastAPI app
Build the image:
We will use the following Dockerfile:
myproject/Dockerfile:
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
EXPOSE 80
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
Run this command to create the image:
docker build . -t kubernetes-fastapi-app-img
Push the image to a private registry:
When deploying a Kubernetes application, you typically specify the container image that Kubernetes should pull from a container registry. However, if you want to use a local image (one that is not in a registry), you can use a few methods.
These are some methods to use local images in Kubernetes:
- Using Minikube or Kind (Kubernetes in Docker):
Both Minikube and Kind allow you to use local Docker images directly. You can load the image into the Minikube or Kind environment.
- Using a Private Registry:
If you are not using Minikube or Kind, you can set up a local Docker registry to which you push your image, and then configure Kubernetes to pull from this registry.
For this tutorial, we will use a private registry that we will run locally using the follwing command:
docker run -d -p 5000:5000 --name registry registry:2
Then we will tag the image:
docker tag kubernetes-fastapi-app-img:latest localhost:5000/kubernetes-fastapi-app-img:latest
Push the image to your local registry:
docker push localhost:5000/kubernetes-fastapi-app-img:latest
Create Kubernetes cluser:
Now that our FastAPI docker image is ready in the registry, let's install the Kubernetes cluser:
Open your Docker-desktop, go to Settings >> Kubernetes, then select the option 'Enable Kubernetes'. This will install all the necessary ressources for functional Kubernetes Cluser.
To check if Kubernetes is installed and is running, open your terminal and type the command kubectl
. Everything is fine if the output starts with kubectl controls the Kubernetes cluster manager
.
Deployment file:
The next step is to deploy our image in Kubernetes. For this, we need to create a YAML file that will contain the deployment configuration.:
myproject/deploy/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-deployment
labels:
app: fastapi
spec:
replicas: 1
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: fastapi
image: localhost:5000/kubernetes-fastapi-app-img
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "testing"
---
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
spec:
selector:
app: fastapi
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
This Kubernetes YAML file defines a Deployment resource for deploying our FastAPI application. Below is a brief explanation of key parts of the file:
Deployment Name: fastapi-deployment
Labels: app: fastapi for both the deployment and its pods.
Replicas: 1 instance (pods) of the FastAPI application.
Container Image: The container uses an image from a local registry (localhost:5000/kubernetes-fastapi-app-img).
Container Port: The container listens on port 80.
Apply the deployment configuation to Kubernetes cluster:
Firstly, make sure that the current context is set to docker-desktop
using:
kubectl config current-context
If that's not the case, you can switch to docker-desktop
using the following command:
kubectl config use-context docker-desktop
Now, we are ready to apply our deployment file:
kubectl apply -f deploy\deploy.yaml
Use the command bellow to see the status of the created pod:
kubectl get pods
We can show logs of our created pod:
kubectl logs fastapi-deployment-8fc7dd7d-z45k4
Our API swagger is accessible locally via http://localhost/docs
Conclusion
This tutorial is primarily aimed at developers who want to deploy their applications on Kubernetes, but it can also be useful for those who want to deploy their applications on remote Kubernetes clusters, such as those on Azure or AWS.
I would be delighted to see your comments or answer your questions.
Top comments (0)