Architecture de référence¶
Vue d'ensemble¶
L'architecture CI/CD combine deux composants complementaires : Gitea Actions pour l'integration continue (build, test, scan, push) et Flux v2 pour le déploiement continu via GitOps (reconciliation, sync, drift detection).
graph LR
Dev["Developpeur<br/>git push"] --> CI
subgraph CI["Gitea Actions - CI"]
W["Workflow"] --> Build["Build (compile, image)"]
W --> Test["Test (unit, integration)"]
W --> Scan["Scan (Trivy, SonarQube)"]
W --> Push["Push (Harbor)"]
Push --> Update["Update manifests<br/>(image tag)"]
end
Update --> CD
subgraph CD["Flux v2 - CD/GitOps"]
Source["source-controller<br/>(GitRepository)"] --> Kustomize["kustomize-controller<br/>(Kustomization)"]
Kustomize --> K8s["Cluster K8s"]
Notif["notification-controller<br/>(Alert + Provider)"]
Kustomize --> Health["Health Checks"]
end Gitea Actions — Composant CI¶
Architecture du runner¶
Le runner Gitea Actions (act runner) est un agent qui se connecte au serveur Gitea via gRPC pour recevoir et exécuter les jobs.
graph TD
subgraph Gitea["Serveur Gitea"]
Dispatcher["Actions Dispatcher<br/>(file de jobs)"]
end
Dispatcher -->|gRPC TLS| Runner
subgraph Runner["act runner (registration)<br/>Labels: ubuntu-latest, self-hosted"]
Job1["Job container<br/>(ubuntu:latest)<br/>conteneur ephemere par job"]
Job2["Job container<br/>(node:20)<br/>un autre job en parallele"]
end Composants cles¶
| Composant | Rôle | Configuration |
|---|---|---|
| Actions Dispatcher | Distribue les jobs aux runners enregistres | Integre a Gitea (pas de config) |
| act runner | Execute les jobs dans des conteneurs | Token d'enregistrement + labels |
| Workflow file | Définition du pipeline en YAML | .gitea/workflows/*.yaml |
| Artifact storage | Stockage des artefacts uploades par les jobs | Local ou S3-compatible (MinIO) |
| Cache | Répertoires persistes entre les runs | Local ou S3-compatible |
Workflow dispatch¶
graph TD
A["Evenement Git (push, PR, tag)"] --> B["Gitea cherche .gitea/workflows/*.yaml"]
B --> C["Filtre sur les conditions<br/>(branches, paths, events)"]
C --> D["Cree un ActionRun avec<br/>les jobs a executer"]
D --> E["Dispatcher assigne les jobs<br/>aux runners par label"]
E --> F["Runner tire le job, cree le conteneur,<br/>execute les steps"]
F --> G["Runner renvoie le resultat<br/>(logs, status, artifacts)"] Flux v2 — Composant CD/GitOps¶
Architecture des controllers¶
Flux v2 est compose de controllers indépendants qui s'exécutent dans le cluster Kubernetes. Chaque controller a une responsabilité unique.
graph TD
subgraph K8s["Cluster Kubernetes"]
subgraph flux["Namespace flux-system"]
source["source-controller<br/>(GitRepository, HelmRepository,<br/>OCIRepository)"]
kustomize["kustomize-controller<br/>(Kustomization)"]
helm["helm-controller<br/>(HelmRelease)"]
notif["notification-controller<br/>(Alert, Provider, Receiver)"]
imgref["image-reflector-controller<br/>(ImageRepository, ImagePolicy)"]
imgauto["image-automation-controller<br/>(ImageUpdateAutomation)"]
end
subgraph app["Namespace application (cible)"]
resources["Deployment, Service,<br/>ConfigMap, Secret...<br/>(synchronises depuis Git)"]
end
end
source --> kustomize
source --> helm
kustomize --> resources
helm --> resources
imgref --> imgauto Controllers et CRD¶
| Controller | CRD principales | Rôle |
|---|---|---|
| source-controller | GitRepository, HelmRepository, OCIRepository, Bucket | Surveille et télécharge les sources (Git, Helm, OCI, S3) |
| kustomize-controller | Kustomization | Applique les manifestes Kustomize sur le cluster |
| helm-controller | HelmRelease | Installe et met a jour les charts Helm |
| notification-controller | Alert, Provider, Receiver | Envoie des alertes et reçoit des webhooks |
| image-reflector-controller | ImageRepository, ImagePolicy | Scanne les registres pour détecter les nouvelles images |
| image-automation-controller | ImageUpdateAutomation | Met a jour les manifestes Git avec les nouveaux tags |
Reconciliation¶
Flux reconcilie en permanence l'état du cluster avec l'état declare dans Git :
| Comportement | Configuration |
|---|---|
| Intervalle | spec.interval sur chaque Kustomization (defaut : 10m) |
| Auto-sync | Actif par defaut — Flux applique les changements Git |
| Prune | spec.prune: true — supprime les ressources retirees du dépôt Git |
| Force | spec.force: true — recrée les ressources immutables si necessaire |
| Drift detection | Feature gate DetectDrift=true — corrige les modifications manuelles |
| Health checks | spec.healthChecks — attend que les ressources soient saines |
Health checks¶
Flux evalue la sante des ressources déployées via les health checks Kubernetes natifs :
| État | Signification | Exemple |
|---|---|---|
| Ready: True | La ressource fonctionne normalement | Deployment avec tous les replicas |
| Ready: False | La ressource a un problème | Pod en CrashLoopBackOff |
| Reconciling | La ressource est en cours de déploiement | Deployment en rolling update |
| Stalled | La reconciliation est bloquée | Image introuvable dans le registre |
| Not Ready | La ressource n'a pas atteint l'état sain | Timeout du health check |
Flux complet : du push au déploiement¶
graph LR
Push["git push<br/>(code)"] --> Gitea["Gitea Actions<br/>Build image<br/>Test<br/>Scan Trivy"]
Gitea -->|Push image| Harbor["Harbor<br/>(registre)<br/>app:v1.2.3"]
Gitea -->|Update tag| Manifests["Depot manifests<br/>image: v1.2.3"]
Manifests --> Flux["Flux v2<br/>GitRepository poll<br/>Kustomization sync"]
Flux --> K8s["Cluster K8s<br/>(production)<br/>app:v1.2.3"] Étapes détaillées¶
- Le développeur pousse du code sur la branche
main - Gitea declenche le workflow
.gitea/workflows/ci.yaml - Le runner execute : build → test → scan Trivy → push image vers Harbor
- Le workflow met a jour le tag d'image dans le dépôt de manifestes (commit automatique)
- Flux source-controller détecte le changement dans le GitRepository (poll ou webhook via Receiver)
- Flux kustomize-controller applique le nouvel état desire sur le cluster
- Les Pods sont recrees avec la nouvelle image
Alternative : image automation¶
Flux peut aussi détecter automatiquement les nouvelles images dans Harbor sans commit CI :
graph LR
CI["Gitea Actions<br/>Build + Push"] -->|Push image| Harbor["Harbor<br/>app:v1.2.3"]
Harbor --> ImgRef["image-reflector<br/>scan registre"]
ImgRef --> ImgAuto["image-automation<br/>commit tag dans Git"]
ImgAuto --> Git["Depot manifests<br/>(commit auto)"]
Git --> Flux["kustomize-controller<br/>sync cluster"] Separation des dépôts
Bonne pratique : maintenir deux dépôts distincts :
- Dépôt applicatif : code source, Dockerfile, workflows CI
- Dépôt de manifestes : manifestes Kubernetes (Helm, Kustomize), références d'images
Cette separation permet à Flux de ne surveiller que les manifestes, sans déclencher de sync sur un changement de code source.
Dimensionnement¶
Gitea Actions runners¶
| Profil | CPU | RAM | Disque | Cas d'usage |
|---|---|---|---|---|
| Small | 2 vCPU | 4 Go | 50 Go | Builds legers (Go, Python, scripts) |
| Medium | 4 vCPU | 8 Go | 100 Go | Builds moyens (Java, Node, images) |
| Large | 8 vCPU | 16 Go | 200 Go | Builds lourds (monorepo, multi-arch) |
Flux v2 controllers¶
| Controller | CPU | RAM | Remarque |
|---|---|---|---|
| source-controller | 250m | 128 Mi | Clone Git et télécharge les charts Helm |
| kustomize-controller | 500m | 256 Mi | Reconciliation, applique les manifestes |
| helm-controller | 500m | 256 Mi | Installe et met a jour les HelmReleases |
| notification-controller | 100m | 64 Mi | Alertes et webhooks |
| image-reflector-controller | 250m | 128 Mi | Scan des registres d'images |
| image-automation-controller | 250m | 128 Mi | Commits automatiques dans Git |
| Total | ~1850m | ~960 Mi | Tous controllers actifs |
Architecture modulaire
Contrairement a un système monolithique, les controllers Flux sont indépendants. Si l'image automation n'est pas utilisee, les controllers image-reflector et image-automation peuvent etre désactivés, reduisant l'empreinte a ~600 Mi de RAM.