Files
k3s-cluster/README.md
2026-06-23 01:03:06 +02:00

12 KiB

K3s Cluster Deployment

Aquest repositori conté les configuracions de Kubernetes per desplegar diverses aplicacions en un clúster K3s. Totes les aplicacions s'executen en l'entorn local amb accés a través del domini rogi.casa.

📋 Visió General

Aquest clúster K3s gestiona els següents serveis:

  • Glance - Dashboard personal
  • Pi-hole - Bloqueig de publicitat a nivell de xarxa
  • LiteLLM - Proxy per a models de llenguatge
  • Gitea - Servidor Git self-hosted
  • Home Assistant - Automatització de la llar
  • Jellyfin - Servidor multimèdia
  • n8n - Automatització de fluxos de treball
  • OpenWebUI - Interfície web per a LLMs
  • Phoenix - Observabilitat per a aplicacions d'IA
  • Vaultwarden - Gestor de contrasenyes
  • qBittorrent - Client de torrents
  • Minecraft Server - Servidor de Minecraft
  • Monitoring - Prometheus i Grafana per a monitorització

🏗️ Estructura del Repositori

.
├── README.md                    # Aquest fitxer
├── argocd-bootstrap.yaml        # App-of-apps: llavor per a ArgoCD (aplicar 1 cop)
├── <aplicació>/                 # Cada aplicació té el seu directori
│   ├── deployment.yaml          # Definició del Deployment
│   ├── service.yaml            # Definició del Service
│   ├── ingress.yaml             # Configuració d'Ingress de l'aplicació
│   ├── namespace.yaml           # Namespace dedicat (opcional)
│   ├── configmap.yaml          # ConfigMaps (opcional)
│   └── pvc.yaml                 # PersistentVolumeClaims (opcional)
├── argocd/                      # ArgoCD
│   ├── ingress.yaml             # Ingress d'ArgoCD
│   ├── apps/                    # Applications + AppProject declaratius
│   └── gen-apps.sh              # Genera argocd/apps/* i argocd-bootstrap.yaml
└── nas/                         # Servei extern per al NAS
    ├── transport.yaml           # ServersTransport de Traefik
    └── ingress.yaml             # Ingress del NAS

Nota: Cada aplicació té el seu propi ingress.yaml dins del seu directori. Ja no hi ha cap ingress.yaml centralitzat a l'arrel.

🚀 Desplegament

Prerequisits

  1. K3s instal·lat: El clúster K3s ha d'estar funcionant
  2. kubectl configurat: Accés al clúster amb kubectl
  3. cert-manager: Per a certificats SSL (utilitza Cloudflare Origin Issuer)
  4. DNS configurat: Els dominis *.rogi.casa han d'apuntar al clúster

Desplegar una Aplicació

Per desplegar una aplicació específica:

# Desplegar una aplicació completa (tots els recursos del directori)
kubectl apply -f <aplicació>/

# Desplegar un recurs específic
kubectl apply -f <aplicació>/<fitxer>.yaml

Desplegar Tot el Clúster

La forma recomanada és deixar que ArgoCD sincronitzi el repo (veure secció ArgoCD (GitOps)). Per a un desplegament manual sense ArgoCD:

# Desplegar totes les aplicacions
for dir in */; do
  kubectl apply -f "$dir"
done

# O aplicar recursos globals primer (opcional)
kubectl apply -f nas/

Eliminar una Aplicació

# Eliminar tots els recursos d'una aplicació
kubectl delete -f <aplicació>/

# Eliminar un recurs específic
kubectl delete -f <aplicació>/<fitxer>.yaml

🌐 Ingress i Networking

Configuració d'Ingress per Aplicació

Cada aplicació té el seu propi fitxer ingress.yaml dins del seu directori, seguint el model de pihole/ingress.yaml. Característiques:

  • Traefik: Controlador per defecte de K3s (ingressClassName: traefik)
  • TLS/SSL: Certificats per host gestionats per cert-manager amb el cluster-issuer letsencrypt-prod
  • Secret per aplicació: Cada ingress té el seu propi <aplicació>-tls
  • Namespace dedicat: Cada ingress pertany al namespace de la seva aplicació

Exemple (pihole/ingress.yaml):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pihole
  namespace: pihole
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: traefik
  tls:
  - hosts:
    - pihole.rogi.casa
    secretName: pihole-tls
  rules:
  - host: pihole.rogi.casa
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: pihole-web
              port:
                number: 80

🐙 ArgoCD (GitOps)

Totes les aplicacions del repo es despleguen de forma declarativa amb ArgoCD. Hi ha un Application per cada directori d'aplicació, agrupades sota un AppProject anomenat k3s-cluster.

Estructura

Flux

  1. El AppProject i tots els Application estan versionats a argocd/apps/.
  2. L'app k3s-cluster-root (a argocd-bootstrap.yaml) llegeix argocd/apps/ i crea/actualitza el projecte i totes les applications.
  3. Cada Application sincronitza el seu directori (ex: pihole/) cap al seu namespace, amb prune i selfHeal activats.

Bootstrap (una sola vegada)

Prerequisits:

  1. ArgoCD instal·lat al clúster (namespace argocd).
  2. cert-manager instal·lat (veure cert-manager/install.sh) — el ClusterIssuer depèn dels seus CRDs.
  3. El repo registrat a ArgoCD (Settings → Repositories). Si el repo és públic a GitHub, l'HTTPS funciona sense credencials.

Llançar la llavor:

kubectl apply -f argocd-bootstrap.yaml

A partir d'aquí ArgoCD crea el projecte k3s-cluster, totes les Application i les sincronitza automàticament. Qualsevol canvi al repo es propaga sol (self-heal).

Recrear el clúster des de zero

# 1. Instal·lar K3s
# 2. Instal·lar ArgoCD
# 3. Instal·lar cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
kubectl wait --for=condition=available --timeout=120s deployment/cert-manager -n cert-manager
# 4. Registrar el repo a ArgoCD (o deixar-lo públic)
# 5. Llançar la llavor
kubectl apply -f argocd-bootstrap.yaml

Afegir o treure una aplicació

  1. Crea/esborra el directori de l'aplicació.
  2. Afegeix/treu la línia corresponent a l'array APPS de argocd/gen-apps.sh amb el format name|namespace|path|recurse|validate.
  3. Executa ./argocd/gen-apps.sh per regenerar els manifests.
  4. Fes commit i push; ArgoCD ho sincronitza sol.

Notes

  • Els Application/AppProject pertanyen al namespace argocd (recursos propis d'ArgoCD).
  • L'app argocdrecurse: false sobre el directori argocd/ per gestionar només ingress.yaml i no els seus propis manifests sota argocd/apps/.
  • L'app phoenix usa Validate=false per tolerar el CRD ServiceMonitor si el Prometheus Operator encara no és instal·lat.
  • Els secrets que no estan al repo (ex: gitea-registry per a gym-tracker) s'han de crear manualment al seu namespace; Argo no els gestiona ni els esborra.

💾 Persistència de Dades

Les aplicacions que necessiten emmagatzematge persistent utilitzen:

  • PersistentVolumeClaims (PVC): Per a volums dinàmics
  • ConfigMaps: Per a fitxers de configuració
  • StatefulSets: Per a aplicacions que requereixen identitat persistent (ex: bases de dades)

Exemple: Minecraft utilitza pvc.yaml i ss.yaml (StatefulSet).

📊 Monitorització

El directori monitoring/ conté un stack complet de monitorització:

  • Prometheus: Recollida de mètriques
  • Grafana: Visualització de dades
  • RBAC: Permisos per a Prometheus
  • ServiceMonitors: Descobriment automàtic de serveis (ex: Phoenix)

Accés:

  • Grafana: Configurat a través de l'Ingress principal
  • Datasources preconfigurats per connectar amb Prometheus

🔧 Gestió de Configuracions

ConfigMaps

Les aplicacions utilitzen ConfigMaps per gestionar configuracions:

# Veure ConfigMaps
kubectl get configmaps -n <namespace>

# Editar un ConfigMap
kubectl edit configmap <nom> -n <namespace>

Secrets

Els secrets es gestionen de forma segura:

# Crear un secret
kubectl create secret generic <nom> --from-literal=key=value -n <namespace>

# Veure secrets (encoded)
kubectl get secrets -n <namespace>

Secret per al Registre de Gitea

Per utilitzar imatges del registre privat de Gitea, cal crear un secret de tipus docker-registry:

# Crear el secret per al registre de Gitea (namespace default)
kubectl create secret docker-registry gitea-registry \
  --docker-server=gitea.rogi.casa \
  --docker-username=<teu-usuari-gitea> \
  --docker-password=<teu-password-o-token> \
  --docker-email=<teu-email>

# Si l'aplicació està en un namespace específic, afegeix -n <namespace>
kubectl create secret docker-registry gitea-registry \
  --docker-server=gitea.rogi.casa \
  --docker-username=<teu-usuari-gitea> \
  --docker-password=<teu-password-o-token> \
  --docker-email=<teu-email> \
  -n <namespace>

Nota: És recomanable utilitzar un token d'accés personal de Gitea en lloc de la contrasenya. Pots generar-lo a: Gitea > Settings > Applications > Generate New Token.

Les aplicacions que utilitzen imatges del registre de Gitea (com gym-tracker) han d'incloure imagePullSecrets al seu deployment:

spec:
  imagePullSecrets:
  - name: gitea-registry
  containers:
  - name: app
    image: gitea.rogi.casa/user/repo/image:tag

🔍 Troubleshooting

Verificar l'estat dels Pods

# Veure tots els pods
kubectl get pods --all-namespaces

# Descriure un pod amb problemes
kubectl describe pod <nom-pod> -n <namespace>

# Veure logs
kubectl logs <nom-pod> -n <namespace>
kubectl logs <nom-pod> -n <namespace> --previous  # Logs del contenidor anterior

Verificar Serveis i Ingress

# Veure serveis
kubectl get services --all-namespaces

# Veure configuració d'Ingress
kubectl get ingress --all-namespaces
kubectl describe ingress <nom> -n <namespace>

Verificar Volums

# Veure PVCs
kubectl get pvc --all-namespaces

# Veure PVs
kubectl get pv

📝 Bones Pràctiques

  1. Namespaces: Totes les aplicacions tenen un namespace dedicat; cap queda al namespace default
  2. Labels: Tots els recursos utilitzen labels consistents per facilitar la gestió
  3. Resources Limits: Configura limits de CPU/memòria per evitar overconsumption
  4. Health Checks: Implementa liveness i readiness probes quan sigui possible
  5. Backup: Fes còpies de seguretat regulars dels PVCs i ConfigMaps crítics

🔄 Actualitzacions

Per actualitzar una aplicació:

# Editar el fitxer YAML amb la nova versió de la imatge
vim <aplicació>/deployment.yaml

# Aplicar els canvis
kubectl apply -f <aplicació>/deployment.yaml

# Verificar el rollout
kubectl rollout status deployment/<nom> -n <namespace>

# Revertir si cal
kubectl rollout undo deployment/<nom> -n <namespace>

🌟 Serveis Externs

NAS

El fitxer nas/nas.yaml configura un servei extern que apunta al NAS local (10.88.88.238:5000) sense desplegar pods dins del clúster. L'Ingress corresponent és a nas/ingress.yaml.

📚 Recursos Addicionals