Saltar al contenido principal

Bootstrap

El nivel 0 instala Flux y lo que todos los demás niveles necesitan. Es el único punto con pasos manuales.

Requisitos​

brew install helm kubectl fluxcd/tap/flux sops age

Acceso de administrador al clúster (el kubeconfig que entrega el stack de Kubernetes) y una CNI funcionando. El stack ya deja Calico instalado.

Flux Operator​

Flux se instala con el Flux Operator: el operador es un Helm release, y Flux se describe con un recurso FluxInstance que el operador convierte en los controladores de Flux y mantiene actualizado.

helm install flux-operator oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator \
--version 0.61.0 \
--namespace flux-system --create-namespace \
--wait
helm list -n flux-system # flux-operator, deployed
kubectl -n flux-system get pods # flux-operator-... 1/1 Running

Una vez conectado, FluxCD adopta este mismo Helm release (mismo nombre y namespace) y lo actualiza desde el repositorio como cualquier otro componente.

Secrets con SOPS​

Los secrets se guardan en el repositorio cifrados con SOPS y una clave age por entorno. Flux los descifra dentro del clúster.

precaución

El repositorio es público. Subir un fichero sin cifrar no tiene fácil solución: Git lo recordará para siempre.

Generar la clave del entorno y guardarla en el clúster (la clave del secret debe terminar en .agekey):

age-keygen -o testing.agekey
# Public key: age1...

kubectl -n flux-system create secret generic sops-age \
--from-file=age.agekey=testing.agekey

La clave privada solo debe existir en el clúster y en un almacén seguro. Para editar secrets desde el equipo, se añade también donde la busca SOPS:

mkdir -p "$HOME/Library/Application Support/sops/age"
cat testing.agekey >> "$HOME/Library/Application Support/sops/age/keys.txt"
rm testing.agekey

La clave pública va en .sops.yaml, en la regla de su entorno. Con ella, sops elige la clave según la ruta del fichero y cifra únicamente data y stringData:

creation_rules:
- path_regex: ^(clusters|infrastructure|apps)/testing/.*\.yaml$
encrypted_regex: ^(data|stringData)$
age: age1...

Trabajar con secrets:

sops <fichero> # crear o editar; el texto plano nunca toca el disco
sops -e -i <fichero> # cifrar un fichero existente
sops -d <fichero> # leerlo

Un fichero está listo para subir cuando sus valores empiezan por ENC[AES256_GCM, y termina con un bloque sops:.

Notificaciones en Slack​

Flux informa en Slack de lo que cambia y lo que falla: recursos creados o modificados, instalaciones y actualizaciones de Helm, actualizaciones del propio Flux y cualquier error. Los eventos rutinarios se descartan.

En la app de Slack, en Incoming Webhooks, crear un webhook para el canal del entorno y guardarlo cifrado:

sops infrastructure/testing/00-bootstrap/configs/slack-token.yaml
apiVersion: v1
kind: Secret
metadata:
name: slack-token
namespace: flux-system
stringData:
address: https://hooks.slack.com/services/...
peligro

La URL del webhook es una credencial: cualquiera que la tenga puede escribir en el canal.

Conectar el clúster​

Toda la conexión es un fichero, clusters/<entorno>/flux-instance.yaml. Define la versión de Flux, sus controladores y, en el bloque sync, qué repositorio, rama y carpeta sigue el clúster:

apiVersion: fluxcd.controlplane.io/v1
kind: FluxInstance
metadata:
name: flux
namespace: flux-system
spec:
distribution:
version: "2.9.x"
registry: ghcr.io/fluxcd
components:
- source-controller
- kustomize-controller
- helm-controller
- notification-controller
cluster:
type: kubernetes
networkPolicy: true
sync:
kind: GitRepository
url: https://gitlab.com/reiizumi/fluxcd-thor-network.git
ref: refs/heads/main
path: clusters/testing
interval: 168h

Se aplica una única vez a mano. Es el momento en el que el clúster queda ligado al repositorio:

kubectl apply -f clusters/testing/flux-instance.yaml
kubectl -n flux-system wait fluxinstance/flux --for=condition=Ready --timeout=5m

El operador despliega los controladores de Flux y crea un GitRepository y una Kustomization que aplican todo lo que hay en la ruta. Como el propio flux-instance.yaml está en esa ruta, a partir de aquí Flux lee su propia definición de Git: cambiar Flux es un commit, no un comando.

información

Flux solo necesita acceso de lectura. El repositorio es público, así que se clona de forma anónima por HTTPS: no hay token que crear, guardar ni rotar, ni nada que configurar en GitLab. Si el repositorio pasara a ser privado, bastaría con un deploy token con el scope read_repository referenciado como pullSecret en el bloque sync.

Validar:

kubectl -n flux-system get fluxinstance # flux True Reconciliation finished
flux check # all checks passed
flux get sources git -n flux-system # main@sha1:<último commit>
flux get kustomizations -n flux-system # Applied revision: main@sha1:<último commit>

Flux revisa el repositorio cada 7 días. Para aplicar un cambio al momento:

flux reconcile kustomization flux-system --with-source

Actualizaciones​

  • Flux: los parches de 2.9.x los aplica el operador automáticamente. Una versión menor es un cambio en spec.distribution.version del flux-instance.yaml.
  • Flux Operator: los parches de 0.61.x son automáticos. Una versión menor es un cambio en su repository.yaml.

Rotación​

  • Webhook: crear uno nuevo en Slack, sustituir address con sops, subir y borrar el antiguo.
  • Clave age: generar una nueva, cambiar la pública en .sops.yaml, ejecutar sops updatekeys en cada secret del entorno, subir y sustituir el secret sops-age. Lo cifrado antes sigue legible con la clave antigua en el historial, así que, si una clave se compromete, hay que rotar también las credenciales.