在 K8S 上也能跑 VM!KubeVirt 簡介與建立(部署篇)

Jul 20, 2022 Eddie yen

Photo by Alvaro Reyes on Unsplash

Kubevirt Logo

上一篇,介紹了 Kubevirt 基礎知識與架構後,本篇將繼續以實作來介紹如何部署 Kubevirt。

在部署 KubeVirt 之前,除了要先部署好 K8S 及預設的 CNI 套件外,還需先做以下事前安裝:

  1. 安裝 KVM 套件
  2. 確保實體機器上的 CPU 虛擬化技術相關設定是否已經啟用
  3. 建立一個適合環境的 K8S CSI 以建立 StorageClass

這邊就不再概述這類的安裝與設定檢查。

之後,可直接到 KubeVirt 的 GitHub 找到適合當前 K8S 的版本,並直接套用兩個部署 YAML 檔,分別為 Operator 與 CR(Custom Role)。

kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/v0.41.4/kubevirt-operator.yaml
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/v0.41.4/kubevirt-cr.yaml

另外下載其專屬的 Virtctl,這是 KubeVirt 專屬的 CLI 工具,下載完畢後重新命名並丟到 /usr/bin 或 /usr/sbin 底下,再賦予可執行權限即可。注意,Virtctl 的版本必須與當前部署的 KubeVirt 版本一致。

wget https://github.com/kubevirt/kubevirt/releases/download/v0.41.4/virtctl-v0.41.0-linux-amd64
mv virtctl-v0.41.4-linux-amd64 /usr/sbin/virtctl && chmod +x /usr/sbin/virtctl

部署下去後,會在 K8S 環境下建立名為 kubevirt 的 namespace,並產生以下Pod:

部署 KubeVirt CDI

CDI 全名為 Containerized Data Importer,是讓各類 VM 或 ISO 映像檔轉換成能夠在 KubeVirt 環境下使用的狀態,並同時建立與管理 KubeVirt 的映像儲存空間。

部署的方式與 KubeVirt 一致,套用 CDI 的 Operator 與 CR 兩個 YAML 即可。

kubectl apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.21.0/cdi-operator.yaml
kubectl apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.21.0/cdi-cr.yaml

套用後,會建立名為 cdi 的 namespace,並產生以下 Pod:

匯入 ISO 映像檔

這邊會以建立 Windows VM 做為範例。由於 KubeVirt 本身通常支援 PVC/DV 以及 containerDisk 為多數,為了要讓 KubeVirt 建立的 VM 能夠使用 ISO 安裝檔,必須先將 ISO 匯入進 PVC 內才行,可以透過 Virtctl 來自動建立 PVC 並上傳到 CDI 內作轉換與置放作業。

要透過 Virtctl 匯入,必須要先知道 CDI 的 upload proxy 的位址,先透過 kubectl get svc -n cdi 的方式,得知 proxy 的位址。下圖所顯示的 cdi-uploadproxy 所顯示的 IP 即是我們需要得到的資訊。

接著,就可以使用 Virtctl 進行上傳。範例的情況是已經先建立一個以 NFS-CSI 為基底的 StorageClass,會先在這 StorageClass 上建立 PVC 後,再把 ISO 轉換放到此 PVC 內。

virtctl image-upload pvc <要建立的名稱> \
--size=<建立的PVC大小> \
--storage-class=<建立PVC所使用的StorageClass> \
--image-path=<要匯入的映像檔路徑> \
--uploadproxy-url=<cdi-uploadproxy的網址> \
--insecure   <- 允許不安全的HTTPS連線

輸入範例
輸入範例

等待 PVC 建立、上傳並轉換後,便可使用此 PVC 進行 Windows 安裝

匯入成功畫面
匯入成功畫面


建立KubeVirt VM

接著我們就可以來建立第一個 VM 了。與在 K8S 建立 Pod 一樣,透過匯入 YAML 的方式來建立。以下是我們會使用到的 YAML 檔案內容:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: win10-test
spec:
  running: false
  template:
    metadata:
      labels:
        kubevirt.io/domain: win10-test
    spec:
      domain:
        cpu:
          cores: 4
        features:
          acpi: {}
          apic: {}
          hyperv:
            relaxed: {}
            vapic: {}
            spinlocks:
              spinlocks: 8191
        devices:
          disks:
          - cdrom:
              bus: sata
            name: ins-iso
            bootOrder: 2
          - disk:
              bus: virtio
            name: harddrive
            bootOrder: 1
          - cdrom:
              bus: sata
            name: virtiocontainer
          interfaces:
          - name: default
            model: virtio
            bridge: {}
          inputs:
          - type: tablet
            name: tablet1
        machine:
          type: q35
        resources:
          requests:
            memory: 16G
      networks:
      - name: default
        pod: {}
      volumes:
      - name: ins-iso
        persistentVolumeClaim:
          claimName: iso-win10
      - name: harddrive
        persistentVolumeClaim:
          claimName: win10-drive
      - name: virtiocontainer
        containerDisk:
          image: kubevirt/virtio-container-disk

上面的部分參數或格式,對於有接觸過 KVM 的使用者來說會帶有一點熟悉感,只是編寫架構上仍有些差異,我們就具體看看這些設定上的意義。

KubeVirt 的 VM 物件主要有 VirtualMachine、VirtualMachineInstance 這兩種,前者是 VM 的範本,後者則是 VM 的執行 Profile。可以注意到在 spec內,主要是由一個 template 來撰寫整個內容,也就是底下是在定義VirtualMachineInstance 的參數;在 template 內的 metadata,則是定義真正建立 VM 時的名稱。

在主要的 spec 內,常規來說主要會使用到以下幾個必要類別:domain、network 和 volumes。

先提 domain,主要會使用到的有這幾個類別:

範例中另外出現的選擇性使用類別:

devices/disks

我們就挑幾個重點來講。在 disks 部分,每一個 YAML Array 就是一個掛載的儲存裝置,以此範例來說,我們掛載了 3 個 disk 裝置,其中有兩個光碟機與一個硬碟。

devices/interfaces

此為設定 VM 的網路卡,同樣一個 YAML Array 代表一個連接埠的設定值。

networks

主要設定 VM 的後端連接方式。

volumes

主要設定 disks 後端的連接方式

以上大略說明,在寫好後就可以把 YAML 匯入進 KubeVirt 內

kubectl apply -f windows_kubevirt.yaml

之後需要為 VM Disk 建立一個空的 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: win10-drive
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: nfs-csi

接著就可以透過 virtctl 指令讓 VM 開機,注意開機的名稱要是 metadata 內所填入的 label 名稱。

virtctl start win10-test

開機後,便可透過 kubectl 相關指令確認 VM 是否有成功啟動 啟動時會自動開一個 Pod,確定都是 Ready 與 Running 及表示 VM 正常運行。


VNC連線

那麼我們要怎麼連線到 VM 畫面呢?畢竟 KubeVirt 不像傳統 KVM 具有 virt-manager 可以直接連到 VM 的 VNC Server 去看畫面。這部分可以透過 virtctl 功能來建立 VNC 連線

virtctl vnc <VM名稱> [--proxy-only]

輸入後就會在執行的主機畫面上出現 VM 畫面,如果帶入 — proxy-only 則只會給連入的 Port 號碼,再使用第三方連線軟體連入。

但這邊有個問題,透過 virtctl 或者其他方式所建立的 VNC 連線,都限制了外部連入,必須要在運行 VM 的本機上才可以連線。這會限制到實體機系統必須要安裝帶桌面的版本,以及衍生出的遠端管理問題等。

這邊分享一個工具,virtvnc 是 KubeVirt 社群上的參與者所開發的 VNC Proxy 工具,主要用途是在平台上建立一個 VNC 代理,會自動偵測 KubeVirt 所建立的 VMI 並且獲取這些的連入 API 位址,並將當前運行的 VM 列出來並附上 VNC 連線連結,點入即可透過 noVNC 方式看到 VM 畫面。

首先先到該 GitHub 位址,照說明套用 YAML 檔案,之後獲取 virtvnc 的 NodePort。

連入後,可以在頁面上看到目前運行的 VM,點擊旁邊的 VNC 即可連到 VM 畫面操作。


遠端連入VM

前面我們提到網路模式時,特別提到 KubeVirt 網路的連線方式與一般的 Pod 可以相容,假設 VM 系統裝好了,要如何透過 RDP、SSH 等方式連入到 VM 內?

在 Pod 模式下,可以直接透過 Service 建立開放連入的 Port,可以獨立寫 SVC 的 YAML,或者是與 VM 的 YAML 寫在一起,只要 selector 有寫對即可。

匯入後的SVC Edit範本
匯入後的SVC Edit範本

如果嫌寫 YAML 太麻煩且不需要一些額外的設定,也可以透過 virtctl 來達成。

virtctl expose vm <VM名稱> --name=<要建立的SVC名稱> --port=<要開放的Port號碼> --type=<開放的類型>

之後就可以再透過 get svc 的方式取得開放的資訊


小結

本篇我們簡單介紹了 KubeVirt、其運作架構、部署方式,另外還提到如何在上面建立第一個 VM、畫面與遠端連入等。可以說,KubeVirt 本身的操作方式稍微複雜,但部署難度與建立等方式,對於已有接觸 K8S 一段時間的使用者而言,上手難度不高,整體架構相對簡單。之後我們將進一步探討KubeVirt 的額外功能,包括 Multus、containerDisk、GPU Passthrough 等。


雙子星雲端為 CNCF 會員,是 CNCF 所認證的 Kubernetes 服務提供商,在雲端技術擁有十多年以上的經驗,為台灣雲端技術早期領先者。目前為國家級 AI 雲的軟體及 Kubernetes 技術與服務提供商,更是諸多企業與單位導入容器與管理平台的最佳夥伴。

雙子星雲端除了既有的產品 AI Console 與 Gemini API Gateway 之外,也提供企業諮詢與導入雲原生與 Kubernetes 相關技術服務,協助企業擁抱 Cloud Natvive,達到數位轉型的目標。


相關文章

回雙子星技術部落格列表

Gemini AI Console

熱門文章


kubernetes professional service

關於我們

雙子星雲端是混合多雲技術的領導者,是國際認證之 KCSP - Kubernetes 服務提供商,同時也為 CNCF 雲原生計算基金會會員。

雙子星的雲端專家擁有 Kubernetes、OpenStack 與 Google Cloud Platform 等多項證照,我們的軟體至今已為上百家機構和數千台的 CPU/GPU 伺服器提供雲端服務。