Hoja de Referencia de FluxCD
## Descripción General
FluxCD es un conjunto de soluciones de entrega continua y progresiva para Kubernetes que son abiertas y extensibles. Implementa principios de GitOps para implementar automáticamente aplicaciones y cambios de infraestructura desde repositorios Git a clústeres de Kubernetes, proporcionando implementaciones declarativas, controladas por versiones y auditables.
⚠️ Nota: Gratuito y de código abierto. Parte de la CNCF (Cloud Native Computing Foundation).
Instalación
Requisitos Previos
Instalación de Flux CLI
Inicialización de Flux
Instalación Manual
Componentes Principales
Controlador de Fuentes
Controlador Kustomize
Controlador Helm
Controlador de Notificaciones
Flujo de Trabajo GitOps
Estructura del Repositorio
Configuración Multi-Entorno
Entrega Progresiva
Comandos CLI
Comandos Básicos
Gestión de Fuentes
Gestión de Kustomización
Gestión de Helm
Configuración Avanzada
Multi-Tenencia
Gestión de Secretos
Automatización de Imágenes
Monitoreo y Observabilidad
Métricas de Prometheus
Note: Since some sections were empty in the original text, I’ve left them as empty translations. If you want me to add placeholder text or specific details, please let me know.```bash
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
### Flux CLI Installation
```bash
# 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
Manual Installation
# 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
Core Components
Source Controller
# 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
Notification Controller
# 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
Repository Structure
# 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
Multi-Environment Setup
# 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
Progressive Delivery
# 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 Commands
Basic Commands
# 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
Source Management
# 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
Advanced Configuration
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
Image Automation
# 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
Monitoring and Observability
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 Alertas
```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."
```### Configuración de Registro
```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
```## Seguridad y 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
```### Configuración de Cuenta de Servicio
```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
```### Políticas de Red
```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'
```### Estándares de Seguridad de Pod
```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
```## Resolución de Problemas
```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
```### Problemas Comunes
```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
```### Ajuste de Rendimiento
```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
```### Depuración de Autenticación 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
```## Mejores Prácticas
```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
```### Organización de Repositorio
```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
```### Mejores Prácticas de Seguridad
```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
```### Optimización de Rendimiento
```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
```### Recuperación de Desastres
https://fluxcd.io/docs/## Ejemplos de Integración
https://toolkit.fluxcd.io/### Migración de ArgoCD
https://pkg.go.dev/github.com/fluxcd/flux2### Integración de Tekton
https://cloud-native.slack.com/messages/flux## Recursos
https://github.com/fluxcd/flux2/discussions### Documentación
- [Documentación de FluxCD](https://www.cncf.io/projects/flux/### Entrenamientohttps://www.gitops.tech/- [Guía de GitOps](https://github.com/fluxcd/flux2-kustomize-helm-example- [Talleres de Flux](https://www.cncf.io/webinars/- [Seminarios web de CNCF](