🚀 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
-
Instalar ZFS:
sudo apt install -y zfsutils-linux
-
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
-
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
-
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.
Si tambien te has hartado de teclear git-publish, tambien tenemos un script para ti: publicar-todos
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:
- Name: app-of-apps (todo en minúsculas)
- Project: default
- Repository URL: el repositorio k8s-master en Gitea: https://git.manabo.org/xavor/k8s-master.git
- Path: apps
- Cluster URL: https://kubernetes.default.svc
- Namespace: argocd
- Sync policy: automática
- 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