Laboratorio k3d estable para ZimaOS
Este paquete reemplaza el deploy-lab.sh original por una versión idempotente y no destructiva.
Qué corrige
- No elimina
lab-clusteren cada ejecución. - Crea el clúster solo cuando no existe.
- Usa
subnet: autopara mantener IP internas estables tras reinicios. - Conserva el datastore SQLite, certificados y token de K3s en
/DATA/AppData/k3d-lab/k3s/server. - Conserva los datos de
local-path-provisionerfuera de los contenedores. - Usa un token de clúster persistente.
- Mantiene fijos los puertos
46421,90y9443. - Valida que ZimaOS siga usando
192.168.68.61antes de desplegar. - Instala Argo CD con versión fijada y
server-side apply. - No crea el
argocd-managerinnecesario para desplegar en el mismo clúster. - Crea RBAC de Headlamp y RBAC de solo lectura para la validación postdeploy.
- Regenera los archivos requeridos para los secrets de Gitea Actions.
- Instala opcionalmente un watchdog systemd para recuperar el clúster después del boot.
Primera recuperación / creación
Ejecutar como el usuario devops, no con sudo:
chmod +x deploy-lab.sh
LAB_HOST_IP=192.168.68.61 \
./deploy-lab.sh bootstrap
Como Docker y k3d están actualmente vacíos, bootstrap creará un clúster nuevo. En ejecuciones posteriores iniciará y reconciliará el clúster existente.
Validación
./deploy-lab.sh status
kubectl get nodes -o wide
kubectl get pods -A
kubectl get ingress -A
Autostart después de reinicios
Ejecutar solamente después de que bootstrap termine correctamente:
sudo ./deploy-lab.sh install-autostart
Verificar:
systemctl status k3d-lab-ensure.timer --no-pager
journalctl -u k3d-lab-ensure.service -n 200 --no-pager
El timer se ejecuta 60 segundos después del arranque y posteriormente cada cinco minutos. El servicio intenta iniciar el clúster, regenera el kubeconfig y valida los tres nodos.
Recuperación manual
./deploy-lab.sh recover
recover no crea ni elimina el clúster. Solo intenta iniciar uno existente y reconcilia Argo CD.
Applications de Argo CD
Guarda los manifiestos Application, ApplicationSet o el app-of-apps en:
/DATA/AppData/k3d-lab/bootstrap/
Al ejecutar nuevamente bootstrap, el script aplicará automáticamente todos los .yaml y .yml de ese directorio.
Secrets para la validación postdeploy
Después de crear un clúster nuevo, se generan:
/DATA/AppData/k3d-lab/gitea-actions-secrets/K8S_SERVER.txt
/DATA/AppData/k3d-lab/gitea-actions-secrets/K8S_CA_B64.txt
/DATA/AppData/k3d-lab/gitea-actions-secrets/K8S_TOKEN.txt
/DATA/AppData/k3d-lab/gitea-actions-secrets/K8S_TLS_SERVER_NAME.txt
Copia sus valores a los secrets equivalentes del repositorio devops/apps-registry en Gitea. No publiques el contenido de K8S_TOKEN.txt.
Headlamp
Genera un token cuando sea necesario:
kubectl create token headlamp-admin -n headlamp
El script crea el RBAC, pero el Deployment/Ingress de Headlamp debe provenir del repositorio GitOps.
Reset limpio
Solo cuando realmente quieras iniciar desde cero:
CONFIRM_RESET=DELETE-lab-cluster ./deploy-lab.sh reset
Antes de limpiar el estado, el script crea un archivo en:
/DATA/AppData/k3d-lab/backups/
Variables principales
CLUSTER_NAME=lab-cluster
APP_DATA_PATH=/DATA/AppData/k3d-lab
KUBECONFIG_PATH=/DATA/.kube/config
LAB_HOST_IP=192.168.68.61
EXPECTED_HOST_IP=192.168.68.61
K3S_IMAGE=rancher/k3s:v1.35.5-k3s1
ARGOCD_VERSION=v3.2.0
Para aceptar conscientemente una IP distinta:
LAB_HOST_IP=192.168.68.X \
ALLOW_IP_CHANGE=true \
./deploy-lab.sh bootstrap
También deberás actualizar NPM y los secrets de Gitea Actions.
Arranque automático reforzado v3
La versión v3 agrega:
subnet: autoal crear el clúster para mantener IP estática por nodo.restart=unless-stoppedsolamente a los contenedores delab-cluster.- Dependencias systemd sobre el
DockerRootDirreal yAPP_DATA_PATH. - Inicio 90 segundos después del boot.
- Reintento automático del servicio cada 30 segundos si falla.
- Watchdog cada 5 minutos.
- Regeneración del kubeconfig.
- Recuperación de agentes
NotReady. - Re-registro automático de un agente persistentemente obsoleto.
- Validación de Traefik, Argo CD y el puerto HTTP publicado.
Instalar
LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh bootstrap
sudo LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart
Prueba de reinicio
Antes:
./deploy-lab.sh status
systemctl status k3d-lab-ensure.timer --no-pager
systemctl cat k3d-lab-ensure.service
systemctl cat docker.service
Después del reboot, espera hasta 10 minutos y valida:
systemctl status k3d-lab-ensure.service --no-pager
journalctl -b -u k3d-lab-ensure.service --no-pager
./deploy-lab.sh status
curl -I -H 'Host: argocd.cruzcloud.net' http://127.0.0.1:90
curl -I -H 'Host: shop.cruzcloud.net' http://127.0.0.1:90
Corrección v3.1 para ZimaOS
ZimaOS puede no incluir el comando openssl. El script ya no lo exige:
- Usa
opensslcuando está disponible. - Si no, usa
/dev/urandomconod. - Como último fallback, usa
hexdump.
Para crear o recuperar el laboratorio, no uses sudo sh:
LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh bootstrap
Solo la instalación de systemd requiere sudo:
sudo LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart
Corrección v3.2: rollout de Argo CD
argocd-serversolo se reinicia cuandoserver.insecurecambia.- El timeout específico de Argo CD aumenta a 420 segundos.
- Si el rollout falla, el script muestra Pods y eventos.
- Si la réplica nueva ya está disponible y únicamente queda un Pod antiguo
atascado en
Terminating, elimina solo ese Pod antiguo y reintenta. - No fuerza la eliminación cuando todavía no existe una réplica nueva disponible.
Ejecución:
LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh bootstrap
Corrección v3.3: permisos de credenciales Gitea Actions
La generación de credenciales ya no ejecuta chmod sobre todos los .txt
históricos. Cada archivo se genera temporalmente y se instala con:
- propietario: usuario que ejecuta
bootstrap; - grupo: grupo principal del usuario;
- permisos:
0600.
Además se regenera KUBE_CONFIG_DATA.txt con un kubeconfig Base64 de
privilegios mínimos para gitea-postdeploy-validator, manteniendo
compatibilidad con el workflow anterior.
Para continuar:
LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh bootstrap
Corrección v3.4: propietario sin asumir grupo devops
ZimaOS tiene al usuario devops con grupo principal samba; no existe
necesariamente un grupo llamado devops.
La v3.4:
- usa
chown devopsy nochown devops:devops; - usa
install -o devopssin forzar grupo para archivos privados; - mantiene permisos
0700en el directorio de secretos; - mantiene permisos
0600en credenciales y kubeconfigs; - conserva el grupo existente del filesystem cuando solo cambia el propietario.
El grupo de la unidad systemd sigue obteniéndose dinámicamente con
id -gn devops, por lo que en ZimaOS será samba.
Corrección v3.5: kubeconfig sin current-context
La v3.5 valida y corrige el kubeconfig antes de instalarlo:
- obtiene el kubeconfig directamente desde k3d;
- confirma que contenga al menos un contexto;
- activa explícitamente ese contexto;
- confirma que exista un API Server;
- instala
/DATA/.kube/configcon propietariodevopsy permisos0600; - no depende de
.profile; - systemd continúa usando la ruta explícita de kubeconfig.
Reparación manual equivalente:
TMP_KUBECONFIG="$(mktemp)"
k3d kubeconfig get lab-cluster > "$TMP_KUBECONFIG"
CTX="$(KUBECONFIG="$TMP_KUBECONFIG" kubectl config get-contexts -o name | head -1)"
KUBECONFIG="$TMP_KUBECONFIG" kubectl config use-context "$CTX"
sudo install -d -m 0700 -o devops /DATA/.kube
sudo install -m 0600 -o devops "$TMP_KUBECONFIG" /DATA/.kube/config
rm -f "$TMP_KUBECONFIG"
Corrección v3.6: systemd en ZimaOS sin /usr/local/sbin
ZimaOS no garantiza que /usr/local/sbin exista o sea escribible. La v3.6
instala la copia persistente del script en:
/DATA/AppData/k3d-lab/bin/deploy-k3d-lab
La unidad usa Bash explícitamente:
ExecStart=/bin/bash /DATA/AppData/k3d-lab/bin/deploy-k3d-lab ensure
Esto también funciona cuando /DATA tiene la opción de montaje noexec.
Instalación:
sudo LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart
Corrección v3.7: watchdog systemd sin sudo
El servicio se ejecuta como devops y no dispone de una terminal para
introducir la contraseña de sudo. La v3.7 elimina sudo del camino de
ejecución del modo ensure.
Cambios:
- comprueba escritura en
/DATA/AppData/k3d-lab, no en la raíz/DATA; - regenera
/DATA/.kube/configdirectamente comodevops; - prepara propietario y permisos durante
install-autostart; - no intenta iniciar Docker mediante sudo desde systemd;
- muestra automáticamente
systemctl statusyjournalctlsi la prueba inicial del servicio falla.
Instalación:
sudo LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart
Corrección v3.8: PATH de systemd y ubicación de k3d
La shell interactiva de ZimaOS puede encontrar k3d en una ruta bajo
/DATA, mientras systemd utiliza un PATH mínimo. La v3.8:
- localiza automáticamente
k3d,kubectl,dockerycurl; - agrega los directorios detectados al PATH de la unidad;
- guarda las rutas en
/etc/default/k3d-lab; - permite indicar rutas explícitas con
K3D_BIN,KUBECTL_BIN,DOCKER_BINyCURL_BIN; - muestra el PATH efectivo al terminar.
Instalación normal:
sudo LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart
Fallback explícito:
K3D_BIN="$(command -v k3d)" \
KUBECTL_BIN="$(command -v kubectl)" \
DOCKER_BIN="$(command -v docker)" \
CURL_BIN="$(command -v curl)" \
sudo -E LAB_HOST_IP=192.168.68.61 ./deploy-lab.sh install-autostart