Saltar a contenido

Hoja de Cheat FluxCD

"Clase de la hoja" id="copy-btn" class="copy-btn" onclick="copyAllCommands()" Copiar todos los comandos id="pdf-btn" class="pdf-btn" onclick="generatePDF()" Generar PDF seleccionado/button ■/div titulada

Sinopsis

FluxCD es un conjunto de soluciones de entrega continua y progresiva para Kubernetes que son abiertas y extensibles. Implementa los principios de GitOps para desplegar automáticamente aplicaciones y cambios de infraestructura de los depósitos de Git a grupos de Kubernetes, proporcionando despliegues declarativos, controlados por versiones y auditables.

NOVEDAD Nota: Libre y de código abierto. Parte de la CNCF (Cloud Native Computing Foundation).

Instalación

Prerrequisitos

# 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

Instalación 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

Bootstrap 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

Instalación manual

# 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

Componentes básicos

Controlador de Fuentes

# 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

Kustomize Controller

# 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

Helm Controller

# 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

Controlador de notificaciones

# 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: '*'

GitOps Workflow

Estructura del repositorio

# 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

Configuración multiambiente

# 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

Entrega progresiva

# 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

CLI Comandos

Comandos básicos

# 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

Gestión de fuentes

# 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

Kustomization Management

# 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

Helm Management

# 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

Configuración avanzada

Multi-Tenancy

# 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

Secret Management

# 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

Imagen Automatización

# 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

Vigilancia y observabilidad

Prometheus Metrics

# 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\"}"
              }
            ]
          }
        ]
      }
    }

Reglas de alerta

# 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."

Configuración de registro

# 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

Seguridad y RBAC

Configuración de la cuenta de servicio

# 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

Políticas de red

# 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

Normas de Seguridad Pod

# 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'

Solución de problemas

Cuestiones comunes

# 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

Performance Tuning

# 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

Debugging Git Authentication

# 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

Buenas prácticas

Repository Organization

# 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

Prácticas óptimas de seguridad

# 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

Optimización del rendimiento

# 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

Recuperación de Desastres

# 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

Ejemplos de integración

Migración ArgoCD

# 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

Tekton Integration

# 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

Recursos

Documentación

Comunidad

Capacitación