How to deploy a Python application in Kubernetes?
Tags: kubernetes, python, docker, devops
Published: 2023-04-10 17:45:05

To deploy a Python application in Kubernetes, you can follow these general steps:

A. Containerize your Python application by creating a Docker image that includes your application code and its dependencies.

B. Push the Docker image to a Docker registry (such as Docker Hub or Amazon ECR).

C. Create a Kubernetes deployment that defines the Docker image to use, the number of replicas of the application to run, and any environment variables or other configuration needed by the application.

D. Create a Kubernetes service that exposes the deployment to the network.

Here is an example of how to do this using a basic Flask application:

A. Create a Dockerfile that describes how to build the Docker image. 

Here's an example Python Flask application:

```
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
```

This creates a simple web application with one endpoint at the root (/) that returns the string "Hello, World!".

You can save this code in a file called app.py. 

To run it locally, you can execute python app.py in your terminal and the Flask application will start running.

```
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
```

This Dockerfile assumes that your Flask application is named app.py and that its dependencies are listed in a requirements.txt file.

B. Build the Docker image by running the following command from the directory containing the Dockerfile:

```
docker build -t myapp:latest .
```

This will create a Docker image named myapp with the latest tag.

C. Push the Docker image to a Docker registry, such as Docker Hub:

```
docker tag myapp dmrsoft/myapp:latest

docker push dmrsoft/myapp:latest
```

This assumes that you have a Docker Hub account and have logged in using the docker login command.

D. Create a Kubernetes deployment that specifies the Docker image to use, the number of replicas to run, and any configuration needed by the application. Here is an example:

deployment.yaml

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: dmrsoft/myapp:latest
        ports:
        - containerPort: 5000
        env:
        - name: ENVIRONMENT
          value: "production"
```

This deployment specifies that the myapp image should be used, and sets an environment variable named ENVIRONMENT to "production".

E. Create a Kubernetes service that exposes the deployment to the network. Here is an example:

service.yaml

```
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    targetPort: 5000
```

This service exposes the deployment on port 80, forwarding traffic to port 5000 on the containers.

After creating these YAML files, you can apply them to your Kubernetes cluster using the kubectl apply command. For example, to create the deployment and service described above, you could run:

```
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
```

This will deploy your Python application to the Kubernetes cluster, making it accessible via the service you created.

```
dmi@dmi-laptop:~$ kubectl get pods
NAME                     READY   STATUS              RESTARTS   AGE
myapp-649c88df9d-ccw8g   1/1     Running             0          23m
myapp-649c88df9d-qvfxf   1/1     Running             0          23m
myapp-649c88df9d-vpq9k   1/1     Running             0          23m

dmi@dmi-laptop:~$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    17h
myapp        ClusterIP   10.98.125.53    <none>        80/TCP     24m
```

You can also use kubectl to call a service by using the port-forward command to forward a local port to the service's port. For example:

```
kubectl port-forward svc/myapp 9090:80            
Forwarding from 127.0.0.1:9090 -> 5000
Forwarding from [::1]:9090 -> 5000
Handling connection for 9090
Handling connection for 9090
```