2025-07-24 15:49:35 +00:00
2025-07-19 15:35:27 +00:00
2025-07-19 15:35:27 +00:00
2025-07-19 15:35:27 +00:00
2025-07-19 15:35:27 +00:00
2025-07-19 15:35:27 +00:00
2025-07-19 15:35:27 +00:00
2025-07-23 06:40:11 +00:00
2025-07-23 22:45:25 +00:00
2025-07-21 21:53:18 +00:00
2025-07-21 22:33:32 +00:00
2025-07-24 15:49:35 +00:00
2025-07-23 18:03:44 +00:00

Guía de instalación K8s + KubeVirt en Ubuntu 24.04

0. Ejemplo de configuración de red (Netplan)

Aquí defines cómo se conectará tu servidor físicamente a la red: enlaces redundantes (bonding), VLANs para separar tráfico y bridges para que las máquinas virtuales y pods se conecten a varias redes internas. Es la base para un clúster flexible y segmentado.

Archivo: /etc/netplan/50-cloud-init.yaml

network:
  version: 2
  ethernets:
    enp2s0f0np0: {}
    enp2s0f1np1: {}
  bonds:
    bond0:
      interfaces:
        - enp2s0f0np0
        - enp2s0f1np1
      parameters:
        mode: "802.3ad"
        lacp-rate: "fast"
        transmit-hash-policy: "layer3+4"
  vlans:
    bond0.20:
      id: 20
      link: bond0
      dhcp4: no
    bond0.30:
      id: 30
      link: bond0
      addresses:
        - "192.168.3.4/24"
    bond0.40:
      id: 40
      link: bond0
      addresses:
        - "192.168.4.4/24"
  bridges:
    br0:
      interfaces:
        - bond0
      addresses:
        - "192.168.1.14/24"
      nameservers:
        addresses:
          - 192.168.1.1
          - 1.1.1.1
          - 8.8.8.8
      routes:
        - to: "default"
          via: "192.168.1.1"
      parameters:
        stp: false
        forward-delay: 0
    br-servicios:
      interfaces:
        - bond0.20
      addresses:
        - 192.168.200.4/22
      parameters:
        stp: false
        forward-delay: 0

No olvides aplicar cambios con: sudo netplan apply


1. Prerrequisitos del sistema

Hay que partir de un Ubuntu 24.04 actualizado y con permisos de administrador. En este paso instalamos utilidades básicas y configuramos el repositorio oficial de Kubernetes, necesario para instalar sus componentes más adelante.

a) Actualiza el sistema y paquetes básicos

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg

b) Añade el repositorio oficial de Kubernetes

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update

c) Ponerle el nombre correcto al nodo

sudo hostnamectl set-hostname srvfkvmX

2. Desactiva SWAP (requisito Kubernetes)

Kubernetes requiere que el intercambio de memoria (swap) esté desactivado para gestionar los recursos de forma predecible y evitar problemas de rendimiento y estabilidad.

sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

3. Instala containerd (runtime recomendado)

containerd es el motor que gestiona los contenedores en el clúster. Kubernetes necesita un “runtime” para crear y controlar los pods, y containerd es la opción oficial y más estable.

sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd

4. Prepara el kernel y sysctl

En este paso se habilitan módulos y parámetros de red necesarios para que Kubernetes gestione correctamente el tráfico entre pods y nodos.

sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system

5. Instala kubeadm, kubelet, kubectl

Aquí se instalan los tres componentes esenciales de Kubernetes:

  • kubelet: agente que corre en cada nodo y gestiona los pods
  • kubeadm: herramienta para iniciar y gestionar el clúster
  • kubectl: cliente de línea de comandos para operar el clúster
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

6. Inicializa el clúster (mononodo/laboratorio)

Este paso crea el clúster de Kubernetes en el nodo principal (control-plane). Aquí defines la red interna para los pods.

Si usas Flannel, usa este parámetro:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

a) Configura kubectl para tu usuario

Permite usar el comando kubectl como usuario normal copiando la configuración de administración del clúster a tu carpeta personal.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

7. Instala la red de pods (Flannel)

Kubernetes solo define la infraestructura; necesitas un complemento de red (CNI) para que los pods puedan comunicarse entre sí. Flannel es la opción más sencilla y compatible.

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

8. Instala Multus (opcional, para múltiples redes)

Multus permite que un pod tenga más de una interfaz de red, útil para aplicaciones avanzadas (firewalls, balanceadores, appliances virtuales). Instálalo solo si necesitas múltiples redes.

kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
  • Verifica:

    kubectl get pods -n kube-system | grep multus
    

9. (Opcional) Quita el taint del nodo master para poder programar pods en él

Por defecto, Kubernetes no programa pods de usuario en el nodo principal (control-plane). Si tienes solo un nodo (laboratorio), elimina este bloqueo para poder desplegar aplicaciones ahí.

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-

10. Test rápido de Multus

Aquí puedes comprobar que Multus funciona: se crea una red secundaria y un pod de prueba que recibe dos interfaces (una para la red de pods y otra para la red adicional configurada).

La carpeta multus/ del repositorio contiene el NAD y el pod de prueba:

  • multus/nad-br-servicios.yaml (NetworkAttachmentDefinition)
  • multus/test-multus-pod.yaml (pod alpine)

Despliega la NAD:

kubectl apply -f multus/nad-br-servicios.yaml

Despliega el pod de test:

kubectl apply -f multus/test-multus-pod.yaml

Comprueba las interfaces:

kubectl exec -it multus-test -- sh
ip a

El pod debería tener una interfaz extra de la red br-servicios además de la de Flannel.

Para limpiar:

kubectl delete pod multus-test

11. Instalación y configuración de MetalLB (LoadBalancer local)

MetalLB permite a tu clúster on-premise asignar IPs flotantes de tu red LAN a servicios tipo LoadBalancer, igual que hacen los clústeres en la nube. Es necesario si quieres exponer servicios (ingress, dashboards, etc.) con una IP accesible desde tu red.

a) Instala MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

Esto crea el namespace metallb-system y despliega los pods necesarios.


b) Crea la configuración del pool de IPs

Aquí defines qué rango de IPs puede repartir MetalLB dentro de tu red local. Estos archivos suelen estar versionados en la carpeta metallb/ del repositorio.

metallb/
├── ipaddresspool.yaml
├── l2advertisement.yaml
└── kustomization.yaml

Para aplicar:

kubectl apply -k metallb/

c) Uso de MetalLB

A partir de aquí, cualquier Service tipo LoadBalancer obtiene una IP flotante LAN automáticamente.

Ejemplo mínimo de Service:

apiVersion: v1
kind: Service
metadata:
  name: ejemplo
spec:
  selector:
    app: ejemplo
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

Verás la IP asignada en la columna EXTERNAL-IP al ejecutar:

kubectl get svc

Puedes acceder desde tu red local a esa IP.


12. Instalación de Traefik y cert-manager (Ingress + TLS)

Traefik actúa como el "router" de aplicaciones dentro de tu clúster, permitiendo exponer servicios a Internet o la red local de forma sencilla. cert-manager se encarga de gestionar certificados TLS automáticamente para que tus aplicaciones estén siempre seguras.

a) Instala Traefik como Ingress Controller

  • Aplica todos los recursos con Kustomize:
kubectl apply -k traefik/
  • Comprueba que MetalLB asigna una IP al Service principal:
kubectl get pods -n traefik
kubectl get svc -n traefik

b) Instala cert-manager

  • Crea el namespace:
kubectl apply -f cert-manager/namespace.yaml
  • Aplica el manifiesto oficial de cert-manager:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
  • Crea los ClusterIssuer para staging y producción:
kubectl apply -f cert-manager/clusterissuer-staging.yaml
kubectl apply -f cert-manager/clusterissuer-prod.yaml
  • Comprueba los pods:
kubectl get pods -n cert-manager

13. Instala KubeVirt y CDI

KubeVirt permite crear y gestionar máquinas virtuales dentro de Kubernetes, integrando cargas virtualizadas junto a contenedores. CDI (Containerized Data Importer) facilita la gestión y carga de discos e ISOs para esas VMs.

Nota: Puedes usar manifiestos oficiales, o crear tu carpeta kubevirt/ si deseas versionar los YAML personalizados.

# Instala KubeVirt (recomendado hacerlo tras tener la red y almacenamiento)
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

# Instala CDI (para gestión de discos/ISOs)
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

14. Instala virtctl (CLI de KubeVirt)

virtctl es una herramienta de línea de comandos para interactuar fácilmente con las máquinas virtuales de KubeVirt: arranque, apagado, consola, etc.

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/

15. Habilita KVM para tu usuario

Para poder crear y gestionar máquinas virtuales, tu usuario debe pertenecer al grupo kvm (acceso al hardware de virtualización).

sudo usermod -aG kvm $(whoami)
# Reinicia sesión o ejecuta 'newgrp kvm' para aplicar

16. Despliega kubevirt-manager

kubevirt-manager es una interfaz web sencilla para gestionar tus máquinas virtuales desde el navegador. Esta sección aplica sus manifiestos en Kubernetes.

La carpeta kubevirt-manager/ contiene todos los manifiestos organizados por tipo:

kubectl apply -k kubevirt-manager/

Puedes comprobar el estado:

kubectl get pods -n kubevirt-manager

17. Despliega el stack de almacenamiento NFS

Esta sección despliega tanto el servidor NFS (almacenamiento en red) como el "provisioner" para que Kubernetes pueda crear volúmenes dinámicos de manera automática. Es la forma más sencilla de tener almacenamiento persistente en el clúster.

La carpeta storage/ tiene todos los manifiestos del servidor y provisioner NFS, organizados en subcarpetas:

kubectl apply -k storage/

Puedes comprobar el estado:

kubectl get pods -n nfs-provisioner
  • Instala el cliente NFS en el nodo:

    sudo apt install nfs-common
    

12. Instalación de Traefik y cert-manager (Ingress + TLS)

Traefik actúa como router de aplicaciones dentro de tu clúster, exponiendo servicios HTTP/HTTPS en LAN o Internet. Cert-manager se encarga de gestionar automáticamente los certificados TLS (Let's Encrypt, CA propia, etc.), pero también puedes usar un certificado comprado (wildcard) y aplicarlo a múltiples dominios.


a) Instala Traefik como Ingress Controller

  1. Prepara tu carpeta de manifiestos (traefik/) con recursos desglosados:

    • Namespace, ServiceAccount, RBAC
    • Deployment o DaemonSet (según tu preferencia)
    • Service tipo LoadBalancer (usará MetalLB)
    • IngressClass (si lo quieres explícito)
    • ConfigMap con parámetros de Traefik
  2. Aplica los manifiestos con Kustomize:

kubectl apply -k traefik/
  1. Comprueba el estado y la IP asignada:
kubectl get pods -n traefik
kubectl get svc -n traefik
  • El Service principal (traefik o traefik-lb) debería tener una IP del pool de MetalLB (EXTERNAL-IP).

b) Instala cert-manager (opcional si solo usas certificados propios)

  1. Crea el namespace:
kubectl apply -f cert-manager/namespace.yaml
  1. Aplica el manifiesto oficial de cert-manager:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
  1. (Opcional) Crea los ClusterIssuer para Let's Encrypt (staging y producción):
kubectl apply -f cert-manager/clusterissuer-staging.yaml
kubectl apply -f cert-manager/clusterissuer-prod.yaml
  1. Comprueba los pods:
kubectl get pods -n cert-manager
  • Espera a que estén todos en estado Running.

c) ¿Cómo usar un certificado SSL wildcard comprado?

Si has adquirido un certificado wildcard (ej: *.miempresa.com) y tienes el .crt (certificado), .key (clave privada) y, opcionalmente, el CA bundle:

  1. Crea un Secret TLS en el namespace donde están tus Ingress:
kubectl -n traefik create secret tls wildcard-cert \
  --cert=certificado_wildcard.crt \
  --key=clave_wildcard.key
  • Si necesitas añadir la cadena de CA, concaténala al .crt:

    cat wildcard.crt ca-bundle.crt > fullchain.crt
    kubectl -n traefik create secret tls wildcard-cert --cert=fullchain.crt --key=clave.key
    
  1. Referéncialo en tus Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ejemplo-wildcard
  namespace: traefik
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - app1.miempresa.com
        - app2.miempresa.com
      secretName: wildcard-cert
  rules:
    - host: app1.miempresa.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: servicio1
                port:
                  number: 80
    - host: app2.miempresa.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: servicio2
                port:
                  number: 80
  • Todos los Ingress que referencien secretName: wildcard-cert usarán ese mismo certificado SSL, y funcionarán para todos los subdominios cubiertos por el wildcard.

d) ¿Dónde se guardan los certificados en Kubernetes?

Los certificados (wildcard, Let's Encrypt, CA propia…) se almacenan como objetos Secret de tipo kubernetes.io/tls en el namespace correspondiente. No están en disco ni en ninguna ruta específica del pod o nodo. Traefik accede al Secret por nombre, a través de la API de Kubernetes.

Puedes ver los secrets así:

kubectl get secrets -n traefik

El contenido real está en la base de datos interna de Kubernetes (etcd).


e) Cómo crear un Secret TLS a partir de tus archivos de certificado

Para cualquier certificado SSL (wildcard, multiSAN, CA interna, etc.), el comando general es:

kubectl -n <namespace> create secret tls <nombre-del-secret> \
  --cert=certificado.crt \
  --key=clave.key
  • <namespace>: donde esté el Ingress (ejemplo: traefik)
  • <nombre-del-secret>: el que quieras (ejemplo: wildcard-cert)
  • --cert: debe incluir el certificado y, opcionalmente, la cadena completa de CA (fullchain)
  • --key: la clave privada

¿Qué hace este comando?

  • Sube el contenido de los archivos al clúster y crea un objeto Secret de tipo kubernetes.io/tls.
  • Kubernetes lo guarda cifrado en etcd y lo inyecta a los pods/controllers cuando un Ingress lo solicita.

Description
No description provided
Readme 285 KiB
Languages
Text 100%