Phase 6 — Applications Python
Déploiement des 3 applications Python sur le cluster k3s via GitOps (ArgoCD).
Vue d'ensemble
| Application | Stack | Déploiement |
|---|---|---|
| FastAPI | API REST, Prometheus client | ArgoCD → k3s |
| Streamlit | Dashboard data | ArgoCD → k3s |
| Flask | Application web simple | ArgoCD → k3s |
Bootstrap Ansible — namespaces et ArgoCD Applications
# playbooks/20-apps-bootstrap.yml
- hosts: k3s_master
tasks:
- name: Créer les namespaces
ansible.builtin.shell:
cmd: |
kubectl create namespace {{ item }} --dry-run=client -o yaml | kubectl apply -f -
loop:
- fastapi
- streamlit
- flask
- name: Déployer les Applications ArgoCD
ansible.builtin.shell:
cmd: |
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ item.name }}
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.com/Mounicou/homelab-proxmox
targetRevision: HEAD
path: manifests/apps/{{ item.name }}
destination:
server: https://kubernetes.default.svc
namespace: {{ item.name }}
syncPolicy:
automated:
prune: true
selfHeal: true
EOF
loop:
- { name: fastapi }
- { name: streamlit }
- { name: flask }
Structure d'un projet applicatif
Chaque application suit la même structure de dépôt GitLab :
app-name/
├── .gitlab-ci.yml
├── Dockerfile
├── requirements.txt
├── app/
│ └── main.py
├── tests/
│ └── test_main.py
└── manifests/
├── deployment.yaml
├── service.yaml
└── ingress.yaml
Dockerfile générique
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Manifest Kubernetes (exemple FastAPI)
# manifests/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi
namespace: fastapi
spec:
replicas: 2
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: app
image: harbor.mounik.ovh/fastapi/app:latest
ports:
- containerPort: 8000
env:
- name: OIDC_ISSUER
value: "https://keycloak.mounik.ovh/realms/homelab"
# manifests/service.yaml
apiVersion: v1
kind: Service
metadata:
name: fastapi
namespace: fastapi
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8000
selector:
app: fastapi
# manifests/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fastapi
namespace: fastapi
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
rules:
- host: app-fastapi.mounik.ovh
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: fastapi
port:
number: 80
Pipeline CI/CD (applicatif)
# .gitlab-ci.yml de chaque application
stages:
- test
- sast
- build
- scan
- push
- dast
- deploy
variables:
DOCKER_IMAGE: harbor.mounik.ovh/{{ CI_PROJECT_NAME }}/app
DD_URL: https://defectdojo.mounik.ovh
Chaque pipeline suit le même schéma décrit dans la Phase 7 — DevSecOps.
Déploiement
- Le développeur pousse du code sur GitLab.com
- Le pipeline CI/CD build, scan et push l'image sur Harbor
- Le pipeline met à jour le manifest Kubernetes (tag image)
- ArgoCD détecte le changement et synchronise le cluster
- L'application est déployée sur k3s
Livrable : 3 applications déployées et accessibles via app-*.mounik.ovh.
Pour aller plus loin
- Phase 7 — DevSecOps — pipeline complet avec sécurité
- Phase 5 — Kubernetes — cluster k3s et ArgoCD
- Playbooks Ansible — dans
ansible/du dépôt