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