Skip to content

mathewsrc/python-cli-tool-with-docker-and-kubernetes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python CLI tool with Docker and Kubernetes

Project: Create a simple Python CLI app and deploy it with Kubernetes

What is Kubernetes

The official documentation defines Kubernetes as a portable, extensible, open-source platform for managing containerized workloads and services. Kubernetes extends all benefits of container deployment such as continuous development (CD), integration (CI), deployment, observability, consistency, isolation, and security. Kubernetes can automatically handle scaling and failover for your application by adding more units of work, replacing or restarting failure containers, and using load balance to distribute network traffic keeping our services stable.

What is Docker

The official documentation of Docker defines a container as a standard unit of software that packages up code and all its dependencies. We can create containers by using Docker images which contain all information needed to create and run a container: code, runtime, system tools, system libraries, and settings. Containers add an extra layer of security as it isolates the application from its host environment and ensure that it works at any environment (Windows, Linux, MacOS, etc).

Instaling tools

Before starting to use Kubernetes we need to install Docker Desktop, Minikube or Kind, and Kubectl. I linked the official websites for you below:

Docker Desktop is an application for macOS, Linux, and Windows machines that enables us to build and share containerized applications and microservices. Docker Desktop comes with a Graphical User Interface that lets us easily manage our containers, applications, and images directly from our machine. One advantage of Docker Desktop is that it comes with Kubernetes support, so we do not need to install Kubectl by ourselves. Another advantage of this tool is that it enables us to use local Docker images with Kubernetes without having to push it to a registry first that means that Kubernetes can create containers from images stored in the Docker Engine image cache. The only thing we need to do is to set imagePullPolicy: IfNotPresent in our Kubernetes yaml file. This ensures that the image from the local cache is going to be used.

Docker Desktop

Minikube and Kind are both tools that enable us to create a local cluster to run Kubernetes on our local computer. Kind and Minikube require that you have Docker installed. If you already have installed the Docker Desktop you do not have to worry about this requirement and you can proceed with Minikube or/and Kind installation.

Minikube or Kind

Installing Kind (PowerShell or Git Bash)

  1. Download Kind: curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.20.0/kind-windows-amd64
  2. Move it to some dir: .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe
  3. Create a cluster using kind.exe (or kind) create cluster

(Optional) If you have installed Docker Desktop you can skip this step

Kubeclt

VSCODE extensions

For this project, I am using the following extensions:

  • Docker
  • Kubernetes
  • Kubernetes Kind
  • Makefile
  • Python
  • YAML

Project tree structure

- kubernetes
    |-- app.py # This is the Python application code.
    |-- Dockerfile # This is the Dockerfile used to build a Docker container for the application.
    |-- k8s.yml #  This is the Kubernetes configuration file for creating the application.
    |-- Makefile # This file contains build and deployment automation commands.
    |-- requirements.txt # This file lists the Python dependencies required for the application.
    |-- run_kubernetes.sh # This shell script is used to run the Kubernetes application.

Some useful commands from Kubeclt

kubectl cluster-info - Verify kubectl configuration
kubectl version - Print the version of kubectl
kubectl get services - Verify services running
kubectl get pods - Verify all pods running
kubectl get pods -o wide - Verify more details about all pods running
kubectl apply -f <NAME>.yaml --namespace=<NAME> - Create a Pod
kubectl get pod <NAME> --namespace=<NAME> - Verify that the Pod is running
kubectl top pod <NAME> --namespace=<NAME> - Fetch the metrics for the Pod
kubectl delete pod <NAME> --namespace=<NAME> - Delete a Pod
kubectl describe pod <NAME> --namespace=<NAME> - View detailed information about the Pod
kubectl delete namespace <NAME> - Delete a namespace

Some useful commands from Minikube

minikube version - Print the version of minikube
minikube start - Start minikube
minikube status - Check minikube status

Some useful commands from Kind

kind --version - Print the version of kind
kind create cluster - Create a new local cluster

Creating a Pod

What is a Pod

The official documentation of Kubernetes defines a Pod as units of computing that you can create and manage in Kubernetes. Each pod contains one or more application containers, with shared storage and network. We can define a Pod using a yaml file with some information about the Pod and the application container as the example below:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Lifecycle of a Pod

Whenever a new Pod is created, it is automatically scheduled to run on a specific Node within your cluster. Throughout its execution, the Pod remains on that particular Node. Once the Pod completes its task, the Pod object is deleted and is evicted from its Node for lack of resources, or the node fails.

Note:

Make sure to replace all <NAME> placeholders with any name you want

Step 1: Start minikube

minikube start

Step 2: Create a Docker image

docker build -t <NAME>:<VERSION> -f Dockerfile

Step 3: Execute this command to use Kubernetes with local Docker images

eval $(minikube -p minikube docker-env)

Step 4: Create a Pod from a Docker image

kubectl apply -f k8s.yaml --namespace=<NAME>

Step 5: Check if Pod ruined successfully

kubectl logs <POD NAME>

Successful example

The following photo shows a successful Pod logs

kubernetes

Kubernetes yaml file for deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp
        imagePullPolicy: Never
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80

Some differences from Pod yaml

apiVersion: apps/v1

This indicates the API version for the Kubernetes resource, which, in this case, is a Deployment.

kind: Deployment

Specifies the type of Kubernetes resource, which is a Deployment in this case

replicas: 3

This defines the desired number of replicas (pods) that should be maintained by the Deployment

selector

Specifies the labels that the Deployment uses to identify the pods it manages.

minikube start

Step 2: Create a Docker image

docker build -t <NAME>:<VERSION> -f Dockerfile

Step 3: Execute this command to use Kubernetes with local Docker images

eval $(minikube -p minikube docker-env)

Step 4: Create a Pod from a Docker image

kubectl apply -f k8s_deploy.yaml --namespace=<NAME>

k8s_deployment

Step 5: Check if Pod ruined successfully

kubectl get deployment 

k8s_deploy_status

kubectl describe deployment myapp-deployment

Manually Horizontal Scaling/Decrease the deployment

kubectl scale deployment myapp-deployment --replicas=<NumberOfReplicas>

manuallyscalingdeploy

Exposing the deployment

kubectl expose deployment myapp-deployment --type=LoadBalancer --name=myapp --port=80

exposingdeployment

As we are utilizing a local cluster with Minikube, we will need to manually obtain the URL provided by Minikube using the following commands:

minikube service --url myapp

The last command will display the IP and PORT that we can access in our computer

Example: http://127.0.0.1:56820