Showing posts with label kubernetes. Show all posts
Showing posts with label kubernetes. Show all posts

Thursday

Simple FastAPI App with Docker and Minikube

 Let's start with the simplest one. Which we can develop and test in our local system or laptop, or Mac.

✅ Simple FastAPI App with Docker and Minikube (Kubernetes)


๐Ÿ“ Folder Structure

fastapi-k8s-demo/
├── app/
│   └── main.py
├── Dockerfile
├── requirements.txt
├── k8s/
│   ├── deployment.yaml
│   └── service.yaml

๐Ÿ“„ app/main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI on Kubernetes!"}

๐Ÿ“„ requirements.txt

fastapi
uvicorn

๐Ÿ“„ Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

๐Ÿ“„ k8s/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
      - name: fastapi
        image: fastapi-demo:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8000

๐Ÿ“„ k8s/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: fastapi-service
spec:
  type: NodePort
  selector:
    app: fastapi
  ports:
    - port: 8000
      targetPort: 8000
      nodePort: 30036

๐Ÿงช Run Locally with Minikube

# Start minikube
minikube start

# Build docker image inside minikube
eval $(minikube docker-env)
docker build -t fastapi-demo .

# Apply Kubernetes configs
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

# Access app in browser
minikube service fastapi-service

✅ FastAPI on Minikube with Ingress, Live Reload, and Persistent Volume


๐Ÿ“ Updated Structure

fastapi-k8s-demo/
├── app/
│   └── main.py
├── Dockerfile
├── requirements.txt
├── k8s/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── pv-claim.yaml

๐Ÿ“„ Dockerfile (with live reload)

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

๐Ÿ“„ requirements.txt

fastapi
uvicorn[standard]

๐Ÿ“„ k8s/deployment.yaml (with volume)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
        - name: fastapi
          image: fastapi-demo:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8000
          volumeMounts:
            - mountPath: /app
              name: app-volume
      volumes:
        - name: app-volume
          persistentVolumeClaim:
            claimName: fastapi-pvc

๐Ÿ“„ k8s/pv-claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: fastapi-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

๐Ÿ“„ k8s/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: fastapi-service
spec:
  selector:
    app: fastapi
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000

๐Ÿ“„ k8s/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fastapi-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: fastapi.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: fastapi-service
                port:
                  number: 80

๐Ÿ”ง Enable Ingress and Mount App

minikube start --addons=ingress

# Use Minikube's Docker
eval $(minikube docker-env)
docker build -t fastapi-demo .

# Apply all configs
kubectl apply -f k8s/pv-claim.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml

# Add /etc/hosts entry (Linux/macOS)
echo "$(minikube ip) fastapi.local" | sudo tee -a /etc/hosts

# Open in browser
http://fastapi.local/

✅ FastAPI + PostgreSQL on Minikube with Secrets & ConfigMaps


๐Ÿ“ Project Structure

fastapi-k8s-demo/
├── app/
│   └── main.py
├── Dockerfile
├── requirements.txt
├── k8s/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── postgres-deployment.yaml
│   ├── postgres-service.yaml
│   ├── secret.yaml
│   └── configmap.yaml

๐Ÿ“„ requirements.txt

fastapi
uvicorn[standard]
psycopg2-binary

๐Ÿ“„ app/main.py

import os
import psycopg2
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    return {"message": "Hello from FastAPI + Postgres!"}

@app.get("/db-check")
def db_check():
    conn = psycopg2.connect(
        host=os.getenv("DB_HOST"),
        dbname=os.getenv("DB_NAME"),
        user=os.getenv("DB_USER"),
        password=os.getenv("DB_PASSWORD"),
    )
    cur = conn.cursor()
    cur.execute("SELECT version();")
    version = cur.fetchone()
    conn.close()
    return {"postgres_version": version}

๐Ÿ“„ Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

๐Ÿ“„ k8s/postgres-deployment.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  selector:
    matchLabels:
      app: postgres
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:13
          env:
            - name: POSTGRES_DB
              valueFrom:
                configMapKeyRef:
                  name: pg-config
                  key: POSTGRES_DB
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: pg-secret
                  key: POSTGRES_USER
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: pg-secret
                  key: POSTGRES_PASSWORD
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: pgdata
      volumes:
        - name: pgdata
          persistentVolumeClaim:
            claimName: postgres-pvc

๐Ÿ“„ k8s/postgres-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  ports:
    - port: 5432
  selector:
    app: postgres

๐Ÿ“„ k8s/secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: pg-secret
type: Opaque
stringData:
  POSTGRES_USER: myuser
  POSTGRES_PASSWORD: mypassword

๐Ÿ“„ k8s/configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: pg-config
data:
  POSTGRES_DB: mydb

๐Ÿ“„ k8s/deployment.yaml (FastAPI updated)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
        - name: fastapi
          image: fastapi-demo:latest
          ports:
            - containerPort: 8000
          env:
            - name: DB_HOST
              value: postgres
            - name: DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: pg-config
                  key: POSTGRES_DB
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: pg-secret
                  key: POSTGRES_USER
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: pg-secret
                  key: POSTGRES_PASSWORD

๐Ÿ“„ k8s/service.yaml (FastAPI)

apiVersion: v1
kind: Service
metadata:
  name: fastapi-service
spec:
  selector:
    app: fastapi
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000

๐Ÿ“„ k8s/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fastapi-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: fastapi.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: fastapi-service
                port:
                  number: 80

๐Ÿ”ง Deployment Commands

minikube start --addons ingress
eval $(minikube docker-env)

# Build image
docker build -t fastapi-demo .

# Apply K8s resources
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/postgres-deployment.yaml
kubectl apply -f k8s/postgres-service.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml

# Add to /etc/hosts
echo "$(minikube ip) fastapi.local" | sudo tee -a /etc/hosts

# Open
http://fastapi.local/db-check

Hope now you have a solid understanding of how to develop a Python FastAPI application in Docker and deploy it in Kubernetes clusters.

The whole application code is here with different branches https://github.com/dhirajpatra/fastapi-k8s-demo


OPEA (Open Platform for Enterprise AI)

                                                                opea.dev

Recently, I have tried to deploy my multi-agent application. Which I developed on my laptop. However, I wanted to deploy it in a production-grade environment for my office's R&D POC project. Let me break down why I chose OPEA.

OPEA (Open Platform for Enterprise AI) is an open-source framework designed to help you build and deploy production-grade AI applications, including multi-agent systems.1 While Docker Compose is excellent for local development and smaller-scale deployments, OPEA aims to provide the robust infrastructure and capabilities needed for enterprise-level production environments.

Here's how OPEA can help you transition your Docker Compose multi-agent application to production:

1. Enterprise-Grade Orchestration (Beyond Docker Compose):

  • Kubernetes Integration: OPEA's core strength lies in its integration with Kubernetes. While Docker Compose is great for defining and running multi-container applications on a single host, Kubernetes is the industry standard for orchestrating containerized applications at scale across a cluster of machines. OPEA provides Helm Charts for deploying its components and examples, making it easier to leverage Kubernetes for:
    • Scalability: Automatically scale your agents up or down based on demand, ensuring your application can handle varying loads.
    • High Availability: Distribute your agents across multiple nodes to ensure continuous operation even if a node fails.
    • Self-Healing: Kubernetes can automatically restart failed containers or reschedule them to healthy nodes, maintaining application resilience.2
    • Load Balancing: Distribute incoming requests across multiple instances of your agents.
  • Automated Terraform Deployment: OPEA supports automated Terraform deployment for major cloud platforms like AWS, GCP, and Azure. This allows you to provision and manage your underlying infrastructure (Kubernetes clusters, databases, etc.) in a consistent and automated way, which is crucial for production environments.

2. Enhanced Features for Multi-Agent Systems:

  • Component Management: OPEA has a OpeaComponentRegistry and OpeaComponentLoader to manage the lifecycle of your agent components.3 This allows for modularity and easier integration of different agent functionalities.
  • Service Wrappers and Providers: OPEA structures components into service wrappers (optional, for protocol handling) and service providers (for actual functionality).4 This promotes a clean architecture and makes it easier to swap out or update specific agent functionalities without affecting the entire system.
  • Model Integration: OPEA supports various LLM backends (e.g., Amazon Bedrock, and potentially others via LiteLLM or Vertex AI Model Garden).5 This flexibility allows you to choose the best-fit LLM for your agents in a production setting.
  • Evaluation and Observability:
    • Enhanced Evaluation: OPEA includes features for evaluating AI models and agents, which is critical for ensuring performance and quality in production.6 This can include evaluating long-context models, SQL agents, toxicity detection, and more.
    • Monitoring and Debugging: While not explicitly detailed for multi-agent systems, OPEA, being designed for production, likely integrates with observability tools to monitor agent interactions, performance, and identify issues.
  • Security: OPEA focuses on enhanced security with features like Istio Mutual TLS (mTLS) and OIDC (Open ID Connect) based Authentication with APISIX, essential for securing your production multi-agent applications.
  • Guardrail Hallucination Detection: This is particularly relevant for LLM-based agents, helping to detect and mitigate issues like hallucination in AI-generated content, enhancing the trustworthiness of your production application.7

3. Streamlined Development to Deployment Workflow:

  • Consistency: By defining your multi-agent application components within OPEA's structure, you get a consistent way to deploy them, whether it's for testing or production.
  • Reduced Technical Debt: OPEA aims to reduce redundancy and improve code quality, which translates to a more robust and maintainable production application.
  • Clearer Guidance and Documentation: As an open-source project, OPEA strives to provide clear guidance and documentation to help developers deploy their applications.8

In summary, while Docker Compose is your sandbox for building and iterating, OPEA offers the necessary scaffolding and integrations to take your multi-agent application from a local setup to a resilient, scalable, and secure production environment, leveraging the power of Kubernetes and cloud infrastructure automation.

To effectively use OPEA for your production deployment, you would typically:

  1. Refactor your Docker Compose application: Break down your agents into OPEA components and services.
  2. Containerize your agents: Ensure each agent and its dependencies are properly containerized (which you've likely done with Docker Compose).
  3. Define OPEA configurations: Use OPEA's configuration files (and potentially Helm Charts) to define how your agents should be deployed and orchestrated within a Kubernetes cluster.
  4. Set up your Kubernetes environment: Provision a Kubernetes cluster on your preferred cloud provider (AWS, GCP, Azure) using Terraform, if desired.
  5. Deploy with OPEA's tools: Use OPEA's deployment mechanisms (e.g., Helm) to deploy your multi-agent application to the Kubernetes cluster.
  6. Monitor and manage: Utilize Kubernetes' and OPEA's monitoring capabilities to observe your agents in production.

House Based Manufacturing Micro Clustering

                                 image generated by meta ai House-based manufacturing micro-clustering in China refers to the hyper-local, v...