Aller au contenu

Aide-mémoire FluxCD

Vue d’ensemble

FluxCD est un ensemble de solutions de livraison continue et progressive pour Kubernetes, ouvertes et extensibles. Il implémente les principes GitOps pour déployer automatiquement des applications et des changements d’infrastructure à partir de dépôts Git vers des clusters Kubernetes, offrant des déploiements déclaratifs, contrôlés par version et auditables.

⚠️ Note: Gratuit et open-source. Fait partie de la CNCF (Cloud Native Computing Foundation).

Installation

Prérequis

# Required tools
kubectl version --client
git --version
curl --version

# Verify Kubernetes cluster access
kubectl cluster-info
kubectl get nodes

# Check cluster permissions
kubectl auth can-i create namespaces
kubectl auth can-i create customresourcedefinitions

Installation de Flux CLI

# Linux/macOS
curl -s https://fluxcd.io/install.sh | sudo bash

# macOS with Homebrew
brew install fluxcd/tap/flux

# Windows with Chocolatey
choco install flux

# Windows with Scoop
scoop bucket add flux https://github.com/fluxcd/scoop-bucket
scoop install flux

# Verify installation
flux version --client

Initialisation de Flux

# GitHub bootstrap
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/my-cluster \
  --personal

# GitLab bootstrap
export GITLAB_TOKEN=<your-token>

flux bootstrap gitlab \
  --owner=$GITLAB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/my-cluster

# Generic Git bootstrap
flux bootstrap git \
  --url=ssh://git@example.com/my-org/my-fleet \
  --branch=main \
  --path=clusters/my-cluster

Installation Manuelle

# Install Flux components manually
flux install --export > flux-system.yaml
kubectl apply -f flux-system.yaml

# Verify installation
flux check
kubectl get pods -n flux-system

Composants Principaux

Contrôleur Source

# GitRepository source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 1m
  ref:
    branch: master
  url: https://github.com/stefanprodan/podinfo
---
# HelmRepository source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: bitnami
  namespace: flux-system
spec:
  interval: 1m
  url: https://charts.bitnami.com/bitnami
---
# Bucket source (S3, GCS, Azure Blob)
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket
metadata:
  name: artifacts
  namespace: flux-system
spec:
  interval: 1m
  provider: aws
  bucketName: my-artifacts
  endpoint: s3.amazonaws.com
  region: us-east-1

Contrôleur Kustomize

# Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 5m
  path: "./kustomize"
  prune: true
  sourceRef:
    kind: GitRepository
    name: podinfo
  validation: client
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: podinfo
      namespace: default
  timeout: 2m

Contrôleur Helm

# HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: nginx-ingress
  namespace: flux-system
spec:
  interval: 5m
  chart:
    spec:
      chart: nginx-ingress
      version: "4.0.6"
      sourceRef:
        kind: HelmRepository
        name: bitnami
        namespace: flux-system
  values:
    service:
      type: LoadBalancer
    metrics:
      enabled: true
  upgrade:
    remediation:
      retries: 3

Contrôleur de Notifications

# Provider (Slack)
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
  name: slack
  namespace: flux-system
spec:
  type: slack
  channel: general
  secretRef:
    name: slack-webhook
---
# Alert
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Alert
metadata:
  name: on-call-webhook
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: info
  eventSources:
    - kind: GitRepository
      name: '*'
    - kind: Kustomization
      name: '*'

Workflow GitOps

Structure du Dépôt

# Recommended GitOps repository structure
fleet-infra/
├── apps/
   ├── base/
   ├── podinfo/
   ├── kustomization.yaml
   ├── deployment.yaml
   └── service.yaml
   └── nginx/
   └── production/
       ├── kustomization.yaml
       └── podinfo-patch.yaml
├── infrastructure/
   ├── controllers/
   ├── kustomization.yaml
   └── ingress-nginx.yaml
   └── configs/
       ├── kustomization.yaml
       └── cluster-config.yaml
└── clusters/
    └── production/
        ├── flux-system/
   ├── gotk-components.yaml
   ├── gotk-sync.yaml
   └── kustomization.yaml
        ├── apps.yaml
        └── infrastructure.yaml

Configuration Multi-Environnement

# clusters/staging/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/staging
  prune: true
  validation: client
---
# clusters/production/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/production
  prune: true
  validation: client
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: podinfo
      namespace: podinfo

Livraison Progressive

# Canary deployment with Flagger
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  service:
    port: 9898
    targetPort: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.example.com
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      thresholdRange:
        max: 500
      interval: 30s

Commandes CLI

Commandes de Base

# Check Flux installation
flux check

# Get system status
flux get all

# Get sources
flux get sources all
flux get sources git
flux get sources helm

# Get Kustomizations
flux get kustomizations

# Get Helm releases
flux get helmreleases

# Suspend/resume reconciliation
flux suspend kustomization podinfo
flux resume kustomization podinfo

Gestion des Sources

# Create Git source
flux create source git podinfo \
  --url=https://github.com/stefanprodan/podinfo \
  --branch=master \
  --interval=1m \
  --export > podinfo-source.yaml

# Create Helm source
flux create source helm bitnami \
  --url=https://charts.bitnami.com/bitnami \
  --interval=1m

# Update source
flux reconcile source git podinfo

# Delete source
flux delete source git podinfo

Gestion des Kustomizations

# Create Kustomization
flux create kustomization podinfo \
  --target-namespace=default \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --interval=5m

# Reconcile Kustomization
flux reconcile kustomization podinfo

# Get Kustomization status
flux get kustomization podinfo

# Suspend Kustomization
flux suspend kustomization podinfo

Gestion Helm

# Create Helm release
flux create helmrelease nginx-ingress \
  --source=HelmRepository/bitnami \
  --chart=nginx-ingress \
  --target-namespace=ingress-nginx \
  --create-target-namespace=true

# Upgrade Helm release
flux reconcile helmrelease nginx-ingress

# Get Helm release status
flux get helmreleases

# Delete Helm release
flux delete helmrelease nginx-ingress

Configuration Avancée

Multi-Locataires

# Tenant namespace and RBAC
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  labels:
    toolkit.fluxcd.io/tenant: tenant-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tenant-a-reconciler
  namespace: tenant-a
subjects:
- kind: ServiceAccount
  name: kustomize-controller
  namespace: flux-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
---
# Tenant Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: tenant-a-apps
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: tenant-a-repo
  path: "./apps"
  prune: true
  targetNamespace: tenant-a
  serviceAccountName: tenant-a-reconciler

Gestion des Secrets

# Sealed Secrets integration
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: mysecret
  namespace: default
spec:
  encryptedData:
    password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEQAx...
---
# External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: default
spec:
  provider:
    vault:
      server: "https://vault.example.com"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "example"
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: vault-secret
  namespace: default
spec:
  refreshInterval: 15s
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: example-secret
    creationPolicy: Owner
  data:
  - secretKey: password
    remoteRef:
      key: secret/data/database
      property: password

Automatisation d’Image

# Image repository
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  image: ghcr.io/stefanprodan/podinfo
  interval: 1m
---
# Image policy
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: podinfo
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: podinfo
  policy:
    semver:
      range: 5.0.x
---
# Image update automation
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 30m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        email: fluxcdbot@users.noreply.github.com
        name: fluxcdbot
      messageTemplate: |
        Automated image update
        
        Automation name: {{ .AutomationObject }}
        
        Files:
        {{ range $filename, $_ := .Updated.Files -}}
        - {{ $filename }}
        {{ end -}}
        
        Objects:
        {{ range $resource, $_ := .Updated.Objects -}}
        - {{ $resource.Kind }} {{ $resource.Name }}
        {{ end -}}
        
        Images:
        {{ range .Updated.Images -}}
        - {{.}}
        {{ end -}}
    push:
      branch: main
  update:
    path: "./clusters/my-cluster"
    strategy: Setters

Surveillance et Observabilité

Métriques Prometheus

Would you like me to continue with the remaining sections?```yaml

ServiceMonitor for Flux controllers

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: flux-system namespace: flux-system spec: selector: matchLabels: app.kubernetes.io/part-of: flux endpoints:

  • port: http-prom interval: 15s path: /metrics

Grafana dashboard ConfigMap

apiVersion: v1 kind: ConfigMap metadata: name: flux-grafana-dashboard namespace: monitoring labels: grafana_dashboard: “1” data: flux-cluster.json: | { “dashboard”: { “title”: “Flux Cluster Stats”, “panels”: [ { “title”: “Reconciliation Duration”, “type”: “graph”, “targets”: [ { “expr”: “gotk_reconcile_duration_seconds{kind=“Kustomization”}” } ] } ] } }

```yaml
# PrometheusRule for Flux alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: flux-alerts
  namespace: flux-system
spec:
  groups:
  - name: flux
    rules:
    - alert: FluxReconciliationFailure
      expr: max(gotk_reconcile_condition{type="Ready",status="False"}) by (exported_namespace, name, kind) + on(exported_namespace, name, kind) (max(gotk_reconcile_condition{type="Ready",status="False"}) by (exported_namespace, name, kind)) > 0
      for: 10m
      labels:
        severity: critical
      annotations:
        summary: "Flux reconciliation failure"
        description: "{{ $labels.kind }}/{{ $labels.name }} in {{ $labels.exported_namespace }} has been failing for more than 10 minutes."
    
    - alert: FluxSuspendedResource
      expr: max(gotk_suspend_status) by (exported_namespace, name, kind) > 0
      for: 1h
      labels:
        severity: warning
      annotations:
        summary: "Flux resource suspended"
        description: "{{ $labels.kind }}/{{ $labels.name }} in {{ $labels.exported_namespace }} has been suspended for more than 1 hour."
```### Configuration de Logging
```yaml
# Fluent Bit configuration for Flux logs
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: flux-system
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush         1
        Log_Level     info
        Daemon        off
        Parsers_File  parsers.conf
    
    [INPUT]
        Name              tail
        Path              /var/log/containers/*flux*.log
        Parser            docker
        Tag               flux.*
        Refresh_Interval  5
    
    [OUTPUT]
        Name  es
        Match flux.*
        Host  elasticsearch.logging.svc.cluster.local
        Port  9200
        Index flux-logs
```## Sécurité et RBAC
```yaml
# Custom service account for Flux
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flux-custom
  namespace: flux-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: flux-custom
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: flux-custom
  namespace: flux-system
---
# Use custom service account in Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  serviceAccountName: flux-custom
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps
```### Configuration du Compte de Service
```yaml
# Network policy for Flux system
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: flux-system
  namespace: flux-system
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/part-of: flux
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to: []
    ports:
    - protocol: TCP
      port: 443
    - protocol: TCP
      port: 80
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 6443
```### Politiques Réseau
```yaml
# Pod Security Policy for Flux
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: flux-psp
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'
```### Standards de Sécurité des Pods
```bash
# Check Flux system status
flux check

# Get events for debugging
kubectl get events -n flux-system --sort-by='.lastTimestamp'

# Check controller logs
kubectl logs -n flux-system deployment/source-controller
kubectl logs -n flux-system deployment/kustomize-controller
kubectl logs -n flux-system deployment/helm-controller

# Debug reconciliation
flux reconcile source git flux-system --verbose
flux reconcile kustomization flux-system --verbose

# Check resource conditions
kubectl describe gitrepository flux-system -n flux-system
kubectl describe kustomization apps -n flux-system
```## Dépannage
```yaml
# Tune controller resource limits
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kustomize-controller
  namespace: flux-system
spec:
  template:
    spec:
      containers:
      - name: manager
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 100m
            memory: 64Mi
        args:
        - --events-addr=http://notification-controller.flux-system.svc.cluster.local./
        - --watch-all-namespaces=true
        - --log-level=info
        - --log-encoding=json
        - --enable-leader-election
        - --concurrent=10  # Increase concurrency
        - --kube-api-qps=50  # Increase API QPS
        - --kube-api-burst=100  # Increase API burst
```### Problèmes Courants
```bash
# Test Git connectivity
flux create source git test-repo \
  --url=https://github.com/your-org/your-repo \
  --branch=main \
  --interval=1m \
  --secret-ref=git-credentials

# Check secret format
kubectl get secret git-credentials -n flux-system -o yaml

# For SSH keys
kubectl create secret generic git-credentials \
  --from-file=identity=/path/to/private/key \
  --from-file=identity.pub=/path/to/public/key \
  --from-file=known_hosts=/path/to/known_hosts \
  -n flux-system

# For HTTPS with token
kubectl create secret generic git-credentials \
  --from-literal=username=git \
  --from-literal=password=your-token \
  -n flux-system
```### Optimisation des Performances
```bash
# Separate concerns
fleet-infra/                    # Infrastructure and platform
├── clusters/                   # Cluster-specific configurations
├── infrastructure/             # Shared infrastructure components
└── tenants/                    # Tenant-specific configurations

app-manifests/                  # Application manifests
├── base/                       # Base configurations
├── overlays/                   # Environment-specific overlays
└── releases/                   # Helm releases
```### Débogage de l'Authentification Git
```bash
# 1. Use least-privilege RBAC
# 2. Enable Pod Security Standards
# 3. Use network policies
# 4. Scan images for vulnerabilities
# 5. Use sealed secrets or external secret management
# 6. Enable audit logging
# 7. Regular security updates
# 8. Monitor for drift and unauthorized changes
```## Meilleures Pratiques
```bash
# 1. Tune reconciliation intervals based on needs
# 2. Use health checks for critical deployments
# 3. Implement proper resource limits
# 4. Use dependency ordering with depends-on
# 5. Monitor controller resource usage
# 6. Use horizontal pod autoscaling for controllers
# 7. Optimize Git repository structure
# 8. Use shallow clones for large repositories
```### Organisation du Dépôt
```bash
# 1. Backup Flux configuration
kubectl get gitrepository,kustomization,helmrelease -A -o yaml > flux-backup.yaml

# 2. Document bootstrap procedure
# 3. Test recovery procedures regularly
# 4. Use multiple Git repositories for redundancy
# 5. Monitor cluster state drift
# 6. Implement automated backup strategies
# 7. Document rollback procedures
# 8. Test cross-cluster migrations
```### Meilleures Pratiques de Sécurité
```bash
# Convert ArgoCD Application to Flux Kustomization
# ArgoCD Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: podinfo
spec:
  source:
    repoURL: https://github.com/stefanprodan/podinfo
    path: kustomize
    targetRevision: master
  destination:
    server: https://kubernetes.default.svc
    namespace: default

# Equivalent Flux resources:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: podinfo
spec:
  url: https://github.com/stefanprodan/podinfo
  ref:
    branch: master
  interval: 1m
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
spec:
  sourceRef:
    kind: GitRepository
    name: podinfo
  path: ./kustomize
  targetNamespace: default
  interval: 5m
```### Optimisation des Performances
```yaml
# Tekton Pipeline to update Flux
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: update-flux-image
spec:
  params:
  - name: image-tag
    type: string
  - name: git-repo
    type: string
  tasks:
  - name: update-manifest
    taskSpec:
      params:
      - name: image-tag
      - name: git-repo
      steps:
      - name: update
        image: alpine/git
        script: |
          #!/bin/sh
          git clone $(params.git-repo) /workspace
          cd /workspace
          sed -i 's|image: .*|image: myapp:$(params.image-tag)|' apps/myapp/deployment.yaml
          git add .
          git commit -m "Update image to $(params.image-tag)"
          git push
```### Reprise sur Sinistre
https://fluxcd.io/docs/#

# Exemples d'Intégration
https://toolkit.fluxcd.io/##

# Migration ArgoCD
https://pkg.go.dev/github.com/fluxcd/flux2##

# Intégration Tekton
https://cloud-native.slack.com/messages/flux#

# Ressources
https://github.com/fluxcd/flux2/discussions##

# Documentation
- [Documentation FluxCD](https://www.cncf.io/projects/flux/##

# Formationhttps://www.gitops.tech/- [Guide GitOps](https://github.com/fluxcd/flux2-kustomize-helm-example- [Ateliers Flux](https://www.cncf.io/webinars/- [Webinaires CNCF](