# 🚀 Virtualización Next-Gen: Clúster K3s con DevOps: manual de instalacion ## 1. Instalar el sistema operativo en ambos servidores Configurar bonding (bond0) en ambos servidores como interfaz principal. - Configurar IP fija de la red (ejemplo): - tartaro: 192.168.1.7 - styx: 192.168.1.8 - niflheim: 192.168.1.10 --- ## 2. Preparación básica del sistema En **todos los servidores**: sudo apt update && sudo apt upgrade -y sudo apt install -y keepalived nfs-common > Asegúrate de tener los manifiestos clonados desde Gitea o preparados localmente antes de empezar. ### Configuración de ZFS en `niflheim` 1. Instalar ZFS: sudo apt install -y zfsutils-linux 2. Crear el pool ZFS con los 4 discos Toshiba (RAID10 con 2 espejos): sudo zpool create -o ashift=12 k8spool mirror /dev/sda /dev/sdb mirror /dev/sdc /dev/sde 3. Crear dataset: sudo zfs create k8spool/k8s sudo zfs set mountpoint=/mnt/storage/k8s k8spool/k8s sudo zfs set compression=lz4 k8spool/k8s sudo chown nobody:nogroup /mnt/storage/k8s 4. Verificar: sudo zpool status sudo zfs list sudo zfs get compression k8spool/k8s --- ## 3. Configuración de Keepalived En tartaro (MASTER): `sudo nano /etc/keepalived/keepalived.conf` vrrp_instance VI_1 { state MASTER interface bond0 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 42manabo42 } virtual_ipaddress { 192.168.1.9/24 } } En styx (BACKUP): `sudo nano /etc/keepalived/keepalived.conf` vrrp_instance VI_1 { state BACKUP interface bond0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 42manabo42 } virtual_ipaddress { 192.168.1.9/24 } } Después en ambos: sudo systemctl enable keepalived sudo systemctl start keepalived ## 4. Instalar K3s En `tartaro` (control plane principal): curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--cluster-init --disable traefik --write-kubeconfig-mode 644 --node-name tartaro --tls-san 192.168.1.7 --tls-san 192.168.1.9" sh - Obtener token: sudo cat /var/lib/rancher/k3s/server/node-token En `styx` (segundo nodo): curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --node-name styx --disable traefik" \ K3S_URL=https://192.168.1.7:6443 \ K3S_TOKEN="token" \ sh - En `niflheim` (control plane adicional, dedicado exclusivamente a almacenamiento): curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --node-name niflheim --disable traefik --node-taint storage=only:NoSchedule" \ K3S_URL=https://192.168.1.7:6443 \ K3S_TOKEN="token" \ sh - ### Verificar estado del clúster Desde tartaro (o con el kubeconfig copiado): kubectl get nodes En styx, niflheim para permitir acceso al kubeconfig: sudo chmod 644 /etc/rancher/k3s/k3s.yaml ## 5. Instalar driver de almacenamiento. En **Tartaro** (o en el nodo donde previamente hayamos clonado los repositorios): cd ~/k3s/k8s-storage/ kubectl apply -k . Comprobar: kubectl get pods -n nfs-provisioner ## 6. Desplegar sistema automatizado de Ingress ### Redirección de puertos desde el router - Hay que hacer port forwarding de puertos externos 80 y 443 a la IP virtual de Keepalived (192.168.1.9) - El `NodePort` está configurado en el manifiesto como: - 30080 → 80 (HTTP) - 30443 → 443 (HTTPS) - Por lo tanto la redireccion sera: - de 80 a 192.168.1.9:30080 - de 443 a 192.168.1.9:30443 >Si necesitamos ver los puertos en uso podemos listarlos por la via rapida con el comando: kubectl get svc --all-namespaces -o jsonpath="{range .items[*]}{.metadata.namespace}:{.metadata.name} → {.spec.ports[*].nodePort}{'\n'}{end}" | grep -v "→ $" ### Desplegar cert-manager cd ~/k3s/k8s-cert-manager/ kubectl apply -f namespace.yaml kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml kubectl apply -f clusterissuer-staging.yaml kubectl apply -f clusterissuer-prod.yaml ### Desplegar ingress-controller cd ~/k3s/k8s-ingress-controller/ kubectl apply -k . ## 7. Desplegar Gitea manualmente ### En Tartaro (o en el nodo donde hayas copiado los repositorios) cd ~/k3s/k8s-gitea/ kubectl apply -k . Comprueba que los pods estén en estado `Running`: kubectl get pods -n gitea -w >Con acceso ya a gitea, seria el momento de crear todos los repositorios remotos. Es una buena idea apoyarnos en [git-publish](herramienta%20git-publish.md). >Si tambien te has hartado de teclear git-publish, tambien tenemos un script para ti: [publicar-todos](herramienta%20publicar-todos.md) ## 8. Instalar ArgoCD ### En Tartaro (o donde tengamos los manifiestos locales clonados de Gitea) cd ~/k3s/k8s-argocd/ kubectl apply -f namespace.yaml # Instalar ArgoCD desde manifiesto oficial (26000 líneas aprox) kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml kubectl apply -f services/argocd.yaml kubectl apply -f ingress/ingress.yaml ### Acceder >Crear acceso en NPM es lo mas adecuado. Se puede obtener la contraseña de admin con: kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo ### Crear la App of Apps En la interfaz web: 1. Name: app-of-apps (todo en minúsculas) 2. Project: default 3. Repository URL: el repositorio k8s-master en Gitea: https://git.manabo.org/xavor/k8s-master.git 4. Path: apps 5. Cluster URL: https://kubernetes.default.svc 6. Namespace: argocd 7. Sync policy: automática 8. Marca las casillas: `AUTO-CREATE NAMESPACE` `PRUNE` `SELF HEAL` `DIRECTORY RECURSE` ## 9. Instalar KubeVirt KubeVirt permite crear y gestionar máquinas virtuales dentro de Kubernetes. Es compatible con el entorno actual y se integra fácilmente con el resto de recursos. ### Instalación manual del operador y CR Desde cualquier nodo con kubectl configurado, ejecutar: export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4) kubectl create namespace kubevirt kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml export CDI_VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4) kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-operator.yaml kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-cr.yaml ### Comprobar despliegue kubectl get pods -n kubevirt ### Instalar virtctl (herramienta de cliente) Virtctl es una herramienta de línea de comandos para gestionar máquinas virtuales con KubeVirt export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4) curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64 chmod +x virtctl sudo mv virtctl /usr/local/bin/ ## 10. Desplegar servidor HTTP para ISOs (KubeVirt ISO Server) El servidor de ISOs se encarga de exponer vía HTTP las imágenes necesarias para el despliegue de sistemas operativos en máquinas virtuales con KubeVirt. ## 11. Desplegar Apache Guacamole Guacamole permite conectarse desde el navegador a escritorios remotos a través de protocolos como VNC, RDP o SSH, sin necesidad de plugins. Se despliega con autenticación MySQL y se expone mediante Ingress con TLS automatizado por cert-manager. >⚠️ Es necesario inyectar manualmente el esquema SQL de la base de datos tras el despliegue. ## Inyectar full-schema.sql cd ~/k3s/k8s-guacamole/ kubectl cp full-schema.sql -n guacamole \ $(kubectl get pod -n guacamole -l app=mysql -o jsonpath="{.items[0].metadata.name}"):/full-schema.sql kubectl exec -n guacamole deploy/mysql -- \ bash -c "mysql -u root -pguacroot guacamole_db < /full-schema.sql" ## Comprobación Para verificar que el usuario guacadmin ha sido creado correctamente: kubectl exec -n guacamole deploy/mysql -it -- \ mysql -uguacuser -pguacpass -D guacamole_db -e \ "SELECT name FROM guacamole_entity WHERE type='USER';" >Usuario/pass por defecto: ```guacadmin/guacadmin```