KubeVirt umożliwia uruchamianie maszyn wirtualnych (VM) obok kontenerów w klastrze Kubernetes. Dzięki KubeVirt można zarządzać maszynami wirtualnymi za pomocą natywnych narzędzi Kubernetes. Jeśli chciałbyś/chciałabyś przetestować KubeVirt lokalnie, możesz to zrobić za pomocą kind (Kubernetes IN Docker) oraz Calico jako CNI (Container Network Interface). W jaki sposób ? Poniżej znajdziesz instrukcję krok po kroku.

Przygotowanie środowiska Link to heading

Zakładam, że masz już zainstalowany Docker Desktop lub inny silnik kontenerów, a także kubectl i kind. Jeśli tak już jest, to pierwszym krokiej jest utworzenie klastra kind z wyłączonym domyślnym CNI i zdefiniowaną podsiecią dla podów:

kind create cluster --name kubevirt --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
  disableDefaultCNI: true
  podSubnet: 192.168.0.0/16
EOF
kind get clusters

Konfiguracja Calico jako CNI Link to heading

Komunikacja sieciowa w Kubernetes jest realizowana przez CNI (Container Network Interface). W moim przewodniku używam Calico, ponieważ jest to popularne rozwiązanie CNI, które oferuje zaawansowane funkcje sieciowe i bezpieczeństwa.

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.0/manifests/operator-crds.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.0/manifests/custom-resources.yaml

watch kubectl get pods -l k8s-app=calico-node -A

Wdrożenie KubeVirt Link to heading

Następnym krokiem jest zainstalowanie KubeVirt w klastrze Kubernetes. Poniższe polecenia pobierają najnowszą stabilną wersję KubeVirt i wdrażają ją w klastrze.

export VERSION=$(curl -s https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
echo $VERSION
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml"
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml"

Status wdrożenia KubeVirt można sprawdzić za pomocą poniższych poleceń:

kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.phase}"
kubectl get all -n kubevirt
kubectl wait --for=condition=Ready pod --all -n kubevirt --timeout=300s

Instalacja Krew Link to heading

Krew jest menedżerem wtyczek dla kubectl, który umożliwia łatwe instalowanie i zarządzanie wtyczkami.

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

Dodaj Krew do zmiennej środowiskowej PATH np. w ~/.bashrc lub ~/.zshrc:

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

source ~/.zshrc

Instalacja Virtctl Link to heading

Następnie zainstalujemy wtyczkę virtctl, która pozwala na zarządzanie maszynami wirtualnymi za pomocą kubectl.

kubectl krew update
kubectl krew search
kubectl krew install virt
kubectl krew list

Włączenie emulacji (wymagane dla kind) Link to heading

Poniższe polecenie włącza emulację w konfiguracji KubeVirt.

kubectl patch kubevirt kubevirt -n kubevirt --type=merge --patch='
{
  "spec": {
    "configuration": {
      "developerConfiguration": {
        "useEmulation": true
      }
    }
  }
}'

Tworzenie maszyny wirtualnej Link to heading

Mając już wszystko skonfigurowane, możemy utworzyć maszynę wirtualną. Poniższe polecenie tworzy maszynę wirtualną o nazwie testvm z obrazem Cirros.

kubectl apply -f https://kubevirt.io/labs/manifests/vm.yaml

lub w przypadku problemów z wystartowaniem maszyny (np. CrashLoopBackOff), użyj poniższego sposobu:

kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: testvm-custom
spec:
  runStrategy: Halted
  template:
    metadata:
      labels:
        kubevirt.io/size: small
        kubevirt.io/domain: testvm-custom
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 64M
      networks:
      - name: default
        pod: {}
      volumes:
        - name: containerdisk
          containerDisk:
            image: quay.io/kubevirt/cirros-container-disk-demo
        - name: cloudinitdisk
          cloudInitNoCloud:
            userDataBase64: SGkuXG4=
EOF

By sprawdzić, czy maszyna wirtualna została utworzona, można użyć poniższych poleceń:

kubectl get vms
kubectl get vms -o yaml testvm
kubectl describe vm testvm
kubectl get events --sort-by=.metadata.creationTimestamp | grep testvm | tail -10

Z kolei informacje o maszynach wirtualnych (VMI) można uzyskać za pomocą polecenia:

kubectl get vmi -o wide

Ostatnim krokiem jest uruchomienie maszyny wirtualnej:

kubectl virt start testvm

Czasami podczas uruchamiania maszyny wirtualnej może pojawić się następujący błąd:

Server error. command SyncVMI failed: "LibvirtError(Code=67, Domain=10, Message='unsupported configuration: CPU mode 'host-passthrough' for aarch64 qemu domain on aarch64 host is not supported by hypervisor')"

Zarządzanie maszyną wirtualną Link to heading

W celu podłączenia do konsoli maszyny wirtualnej, użyj poniższego polecenia:

kubectl virt console testvm

By zatrzymać maszynę wirtualną, wykonaj polecenie:

kubectl virt stop testvm

A następnie by ją usunąć, wykonaj polecenie:

kubectl delete vm testvm

Posprzątanie środowiska Link to heading

W celu usunięcia klastra kind oraz zwolnienia zasobów zajmowanych przez obrazy i kontenery Dockera, użyj poniższych poleceń:

kind delete cluster --name kubevirt

docker image prune --all --force
docker system prune --all --force

Linki Link to heading