8.0 KiB
KubeVirt en Kubernetes (SUSE) con Dashboard y ISO Server
Entorno: 4 nodos SUSE con Flannel + Multus, containerd con
SystemdCgroup=true, kubelet concgroupDriver: systemd.Dominios:
kubevirt.c2et.net(dashboard) yisoserver.c2et.net(HTTP para imágenes).Storage:
ceph-rbd(RWO) para el PVC del ISO server.
0) Prerrequisitos y comprobaciones
En cada nodo:
# Virtualización (debe devolver > 0)
egrep -o 'vmx|svm' /proc/cpuinfo | wc -l
# Cargar módulos KVM (Intel o AMD)
sudo modprobe kvm
sudo modprobe kvm_intel # o kvm_amd
# Persistir módulos al arranque
printf "kvm\nkvm_intel\n" | sudo tee /etc/modules-load.d/kvm.conf # (o kvm_amd)
# Verificar /dev/kvm y AppArmor
ls -l /dev/kvm
sudo aa-status | head -n 5
# containerd: SystemdCgroup=true
sudo grep -n "SystemdCgroup" /etc/containerd/config.toml
# kubelet: cgroupDriver: systemd
grep -i cgroup /var/lib/kubelet/config.yaml
PSA (opcional) si usas Pod Security Admission:
kubectl create ns kubevirt --dry-run=client -o yaml | kubectl apply -f -
kubectl label ns kubevirt \
pod-security.kubernetes.io/enforce=privileged \
pod-security.kubernetes.io/audit=privileged \
pod-security.kubernetes.io/warn=privileged --overwrite
kubectl create ns cdi --dry-run=client -o yaml | kubectl apply -f -
kubectl label ns cdi \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=baseline \
pod-security.kubernetes.io/warn=baseline --overwrite
1) Instalar KubeVirt y CDI (versionado recomendado)
Recomendación: fija versiones (no uses
latest) para reproducibilidad.
# Elige versiones estables (ejemplos; ajusta según tu política)
export KUBEVIRT_VERSION=v1.6.0
export CDI_VERSION=v1.62.0
# KubeVirt (operator + CR)
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
# CDI (operator + CR)
kubectl apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-operator.yaml
kubectl apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-cr.yaml
Checks mínimos:
kubectl -n kubevirt get kv kubevirt -o jsonpath='{.status.phase}'; echo # Debería: Deployed
kubectl -n kubevirt get pods
kubectl -n cdi get pods
2) Instalar virtctl (CLI)
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/
virtctl version
3) Dashboard (kubevirt-manager) en kubevirt.c2et.net
Estructura (kustomize) sugerida dentro de tu repo kubernetes/kubevirt/:
.
├─ deployments/
│ └─ dashboard.yaml # Deployment (image kubevirtmanager/kubevirt-manager:1.4.0)
├─ services/
│ └─ service-dashboard.yaml # Service ClusterIP (80 → 8001)
├─ ingress/
│ └─ ingress-dashboard.yaml # Ingress (class nginx, LE prod)
├─ rbac/
│ ├─ serviceaccount.yaml # SA kubevirt-manager
│ └─ clusterrolebinding.yaml # CRB a cluster-admin
└─ kustomization.yaml
Puntos clave:
- Namespace:
kubevirt. - Service ClusterIP exponiendo
port: 80→targetPort: 8001. - Ingress con
ingressClassName: nginx,cert-manager.io/cluster-issuer: letsencrypt-prod, hostkubevirt.c2et.net. - RBAC:
ClusterRoleBindingacluster-adminpara la SA del dashboard.
Aplicación y verificación:
kubectl apply -k kubernetes/kubevirt
kubectl -n kubevirt get deploy,svc,ingress | grep kubevirt-manager
Acceso: https://kubevirt.c2et.net/
4) ISO Server en isoserver.c2et.net (HTTP) + Samba (LB 192.168.0.105)
Estructura (kustomize) en el mismo módulo kubernetes/kubevirt/:
.
├─ pvc/
│ └─ iso-pvc.yaml # PVC ceph-rbd (RWO)
├─ deployments/
│ └─ isoserver.yaml # Pod con httpd:2.4 + dperson/samba
├─ services/
│ ├─ service-http.yaml # Service ClusterIP (para Ingress)
│ └─ service-samba.yaml # Service LoadBalancer (LB IP 192.168.0.105)
├─ ingress/
│ └─ ingress-isoserver.yaml # Ingress (host isoserver.c2et.net)
└─ kustomization.yaml
PVC (ceph-rbd) — ¡Importante!
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: iso-pvc
namespace: kubevirt
spec:
accessModes: [ReadWriteOnce] # RBD es RWO
resources:
requests:
storage: 800Gi
storageClassName: ceph-rbd
Deployment
httpd:2.4monta/usr/local/apache2/htdocsdperson/sambaexporta/share- Ambos montan el mismo PVC (
iso-pvc) → lo que subes por Samba se sirve por HTTP.
Services
-
iso-server-http→ ClusterIPport: 80(backend de Ingress) -
iso-server-samba→ LoadBalancerloadBalancerIP: 192.168.0.105port: 445- Asegura que 192.168.0.105 está dentro de un pool de MetalLB.
Ingress (HTTP/HTTPS)
- Host:
isoserver.c2et.net - Cert:
letsencrypt-prod - Sin
force-ssl-redirectpara poder usar HTTP con CDI si tu CA no es de confianza.
Aplicación y verificación:
kubectl apply -k kubernetes/kubevirt
kubectl -n kubevirt get pods | grep iso-server
kubectl -n kubevirt get svc iso-server-http iso-server-samba -o wide
kubectl -n kubevirt get ingress iso-server
Acceso:
- Samba:
\\192.168.0.105\isos(guest por defecto; puedes parametrizar usuarios) - HTTP:
http://isoserver.c2et.net/
Sugerencias de seguridad (opcionales):
- Añade credenciales a Samba:
args: ["-p","-u","iso;TuPass","-s","isos;/share;yes;no"]- Limita el Ingress por rangos:
nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.0.0/24"
5) Uso con CDI: importar imágenes/ISOs
5.1 Subir ficheros al ISO server
# Linux (guest)
sudo mkdir -p /mnt/isos
sudo mount -t cifs //192.168.0.105/isos /mnt/isos -o guest,vers=3.0
cp ./ubuntu-24.04.qcow2 /mnt/isos/
# Ver por HTTP
curl -I http://isoserver.c2et.net/ubuntu-24.04.qcow2
5.2 Crear un DataVolume desde URL (HTTP)
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: dv-ubuntu-24
namespace: default
spec:
source:
http:
url: "http://isoserver.c2et.net/ubuntu-24.04.qcow2"
pvc:
storageClassName: ceph-rbd
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
kubectl apply -f dv-ubuntu-24.yaml
kubectl -n default get dv,pvc
kubectl -n cdi get pods -w # verás el importer hasta Succeeded
HTTPS también funciona. Si usas CA propia, puedes inyectar la CA en el DV (campo
certConfigMap) o usarvirtctl image-upload --insecureen pruebas.
5.3 Usar el PVC en una VM
# Fragmento de spec de VirtualMachine
volumes:
- name: rootdisk
dataVolume:
name: dv-ubuntu-24
disks:
- name: rootdisk
disk: { bus: virtio }
Para ISOs, crea un DV de la ISO y móntalo como
cdrom: { readonly: true }.
6) Comprobaciones y troubleshooting
# KubeVirt / CDI
kubectl -n kubevirt get kv kubevirt -o jsonpath='{.status.phase}'; echo
kubectl -n kubevirt get deploy,ds,pods | egrep 'virt-|kubevirt-'
kubectl -n cdi get pods
# Dashboard
kubectl -n kubevirt get endpoints kubevirt-manager
# ISO server
kubectl -n kubevirt get endpoints iso-server-http
smbclient -L 192.168.0.105 -N
curl -I http://isoserver.c2et.net/
MetalLB asigna otra IP → asegúrate de que 192.168.0.105 está en el pool. Puedes recrear el Service o patch:
kubectl -n kubevirt patch svc iso-server-samba -p '{"spec":{"loadBalancerIP":"192.168.0.105"}}'
CDI falla con HTTPS → usa HTTP o confía la CA (o certConfigMap en el DV).
7) Referencias rápidas
- Namespace:
kubevirt - Dashboard host:
kubevirt.c2et.net(Ingressnginx, TLS LE) - ISO server host:
isoserver.c2et.net(HTTP para CDI; TLS opcional) - Samba LB:
192.168.0.105(MetalLB) - StorageClass ISO PVC:
ceph-rbd(RWO)