Files
k3s/docs/guia-instalacion.md
2025-04-27 21:55:49 +00:00

13 KiB

📘 Guía de instalación del clúster K3s - Valhalla Cluster

1. Instalar el sistema operativo

En los tres servidores:

  • Configurar bond0 como interfaz principal.
  • Crear un bridge br0 sobre bond0 para tráfico sin NAT de VLAN 1 (administración y acceso).
  • Montar VLAN 30 (almacenamiento) y VLAN 40 (internode).
  • Configurar una interfaz de respaldo (enp88s0, eno1, etc.) con IP secundaria en VLAN 1.

Asignación de IPs principales:

Nodo VLAN 1 (Administración) VLAN 30 (Storage) VLAN 40 (Internode)
tartaro 192.168.1.11 192.168.3.1 192.168.4.1
styx 192.168.1.12 192.168.3.2 192.168.4.2
niflheim 192.168.1.13 192.168.3.3 192.168.4.3

📄 Netplan para cada servidor

Tartaro (/etc/netplan/00-installer-config.yaml):

network:
  version: 2
  ethernets:
    enp2s0f0np0: {}
    enp2s0f1np1: {}
    enp88s0:
      addresses:
        - "192.168.1.8/24"
  bonds:
    bond0:
      interfaces:
        - enp2s0f0np0
        - enp2s0f1np1
      parameters:
        mode: "802.3ad"
        lacp-rate: "fast"
        transmit-hash-policy: "layer3+4"
  vlans:
    bond0.30:
      id: 30
      link: bond0
      addresses:
        - "192.168.3.1/24"
    bond0.40:
      id: 40
      link: bond0
      addresses:
        - "192.168.4.1/24"
  bridges:
    br0:
      interfaces:
        - bond0
      addresses:
        - "192.168.1.11/24"
      nameservers:
        addresses:
          - 192.168.1.1
          - 1.1.1.1
          - 8.8.8.8
        search: []
      routes:
        - to: "default"
          via: "192.168.1.1"

Styx (/etc/netplan/00-installer-config.yaml):

network:
  version: 2
  ethernets:
    enp2s0f0np0: {}
    enp2s0f1np1: {}
    enp88s0:
      addresses:
        - "192.168.1.21/24"
  bonds:
    bond0:
      interfaces:
        - enp2s0f0np0
        - enp2s0f1np1
      parameters:
        mode: "802.3ad"
        lacp-rate: "fast"
        transmit-hash-policy: "layer3+4"
  vlans:
    bond0.30:
      id: 30
      link: bond0
      addresses:
        - "192.168.3.2/24"
    bond0.40:
      id: 40
      link: bond0
      addresses:
        - "192.168.4.2/24"
  bridges:
    br0:
      interfaces:
        - bond0
      addresses:
        - "192.168.1.12/24"
      nameservers:
        addresses:
          - 192.168.1.1
          - 1.1.1.1
          - 8.8.8.8
        search: []
      routes:
        - to: "default"
          via: "192.168.1.1"

Niflheim (/etc/netplan/00-installer-config.yaml):

network:
  version: 2
  ethernets:
    ens1f0: {}
    ens1f1: {}
    eno1:
      addresses:
        - "192.168.1.22/24"
  bonds:
    bond0:
      interfaces:
        - ens1f0
        - ens1f1
      parameters:
        mode: "802.3ad"
        lacp-rate: "fast"
        transmit-hash-policy: "layer3+4"
  vlans:
    bond0.30:
      id: 30
      link: bond0
      addresses:
        - "192.168.3.3/24"
    bond0.40:
      id: 40
      link: bond0
      addresses:
        - "192.168.4.3/24"
  bridges:
    br0:
      interfaces:
        - bond0
      addresses:
        - "192.168.1.13/24"
      nameservers:
        addresses:
          - 192.168.1.1
          - 1.1.1.1
          - 8.8.8.8
        search: []
      routes:
        - to: "default"
          via: "192.168.1.1"

2. Preparación básica

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 br0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 42manabo42
    }
    virtual_ipaddress {
        192.168.1.10/24
    }
}

En styx (BACKUP):

sudo nano /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state BACKUP
    interface br0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 42manabo42
    }
    virtual_ipaddress {
        192.168.1.10/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 \
--node-name tartaro \
--node-ip 192.168.4.1 \
--advertise-address 192.168.4.1 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.11 \
--write-kubeconfig-mode 644" 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 --disable traefik \
--node-name styx \
--node-ip 192.168.4.2 \
--advertise-address 192.168.4.2 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.12" \
K3S_URL=https://192.168.1.10:6443 \
K3S_TOKEN="token" \
sh -    

En niflheim (control plane adicional, dedicado exclusivamente a almacenamiento):

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable traefik \
--node-name niflheim \
--node-ip 192.168.4.3 \
--advertise-address 192.168.4.3 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.13 \
--node-taint storage=only:NoSchedule" \
K3S_URL=https://192.168.1.10: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 Harbor

8.1 Instalar helm

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Verifica que helm está instalado:

helm version

8.2 Añadir el repositorio de charts de Harbor

helm repo add harbor https://helm.goharbor.io
helm repo update

8.3 Instalar Harbor

helm install harbor harbor/harbor --namespace harbor --create-namespace -f values.yaml

Si todo es correcto, podrás acceder a https://harbor.manabo.org con usuario admin y contraseña Harbor12345.


Puedes loguearte desde tu equipo con:

docker login harbor.manabo.org

Y usar Harbor igual que Docker Hub.


En esta fase: dejamos desplegado nuestro servidor de imágenes privado (harbor.manabo.org) para reemplazar Docker Hub en nuestros proyectos.

9. 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

10. Instalar KubeVirt

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
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml

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)

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.1 Configurar Multus y las redes virtuales

En cada nodo:

sudo cp /var/lib/rancher/k3s/agent/etc/cni/net.d/10-flannel.conflist /etc/cni/net.d/
echo 'KERNEL=="kvm", MODE="0666"' | sudo tee /etc/udev/rules.d/99-kvm.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

y en tartaro (o cualquier nodo)

kubectl -n kube-system delete pod -l app=multus

11. Desplegar servidor HTTP para ISOs (KubeVirt ISO Server)

cd ~/k3s/k8s-kubevirt-isoserver/
kubectl apply -k .

12. Desplegar Apache Guacamole

cd ~/k3s/k8s-guacamole/
kubectl apply -k .

⚠️ 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

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