本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

瞭解 Kubevirt

一旦您習慣了在 Kubernetes 上執行 Linux 容器工作負載,您可能會發現自己希望能夠在 Kubernetes 叢集上執行其他型別的工作負載。也許您需要執行一個並非為容器設計的應用程式,或者需要與容器主機上可用的 Linux 核心版本不同(甚至完全不同的作業系統)的應用程式。

這些型別的工作負載通常非常適合在虛擬機器 (VM) 中執行,而 KubeVirt 是 Kubernetes 的一個虛擬機器管理外掛,旨在允許使用者在 Kubernetes 或 OpenShift 叢集中將虛擬機器與容器並行執行。

KubeVirt 透過 Kubernetes 的 自定義資源定義 API (CRD) 增加了虛擬機器和虛擬機器集資源型別,從而擴充套件了 Kubernetes。KubeVirt 虛擬機器在常規的 Kubernetes Pod 中執行,它們可以訪問標準的 Pod 網路和儲存,並且可以使用 kubectl 等標準 Kubernetes 工具進行管理。

與使用 oVirt 或 OpenStack 等工具相比,在 Kubernetes 中執行虛擬機器需要一些調整,瞭解 KubeVirt 的基本架構是一個很好的起點。

在這篇文章中,我們將簡要介紹 KubeVirt 中涉及的一些高階元件。我們將要探討的元件包括 CRD、KubeVirt 的 virt-controller、virt-handler 和 virt-launcher 元件、libvirt、儲存和網路。

KubeVirt 元件

Kubevirt Components

自定義資源定義(Custom Resource Definitions)

Kubernetes 資源是 Kubernetes API 中的端點,用於儲存相關 API 物件的集合。例如,內建的 Pod 資源包含 Pod 物件的集合。Kubernetes 自定義資源定義 API 允許使用者透過定義具有給定名稱和 schema 的新物件來擴充套件 Kubernetes,新增額外的資源。一旦您將自定義資源應用到您的叢集,Kubernetes API 伺服器就會提供並處理您的自定義資源的儲存。

KubeVirt 的主要 CRD 是 VirtualMachine (VM) 資源,它包含 Kubernetes API 伺服器中的 VM 物件集合。VM 資源定義了虛擬機器本身的所有屬性,例如機器和 CPU 型別、RAM 和 vCPU 的數量,以及虛擬機器中可用網絡卡的數量和型別。

virt-controller

virt-controller 是一個 Kubernetes Operator,負責叢集範圍的虛擬化功能。當新的 VM 物件釋出到 Kubernetes API 伺服器時,virt-controller 會注意到並建立虛擬機器將執行的 Pod。當 Pod 被排程到特定節點時,virt-controller 會使用節點名稱更新 VM 物件,並將進一步的職責交給節點特定的 KubeVirt 元件 virt-handler,該元件的例項在叢集中的每個節點上執行。

virt-handler

與 virt-controller 一樣,virt-handler 也是反應式的,它會監視 VM 物件的變化,並執行所有必要的操作來更改 VM 以滿足所需狀態。virt-handler 引用 VM 規範,並使用 VM Pod 中的 libvirtd 例項發出建立相應域的訊號。當 VM 物件被刪除時,virt-handler 會觀察到刪除並關閉該域。

virt-launcher

每個 VM 物件都會建立一個 Pod。這個 Pod 的主容器執行 virt-launcher KubeVirt 元件。virt-launcher Pod 的主要目的是提供用於託管 VM 程序的 cgroup 和名稱空間。

virt-handler 透過將 VM 的 CRD 物件傳遞給 virt-launcher 來向 virt-launcher 傳送啟動 VM 的訊號。然後 virt-launcher 使用其容器內的本地 libvirtd 例項來啟動 VM。之後,virt-launcher 監控 VM 程序,並在 VM 退出後終止。

如果 Kubernetes 執行時嘗試在虛擬機器退出之前關閉 virt-launcher Pod,virt-launcher 會將來自 Kubernetes 的訊號轉發給虛擬機器程序,並嘗試推遲 Pod 的終止,直到虛擬機器成功關閉。

# kubectl get pods

NAME                                   READY     STATUS        RESTARTS   AGE
virt-controller-7888c64d66-dzc9p   1/1       Running   0          2h
virt-controller-7888c64d66-wm66x   0/1       Running   0          2h
virt-handler-l2xkt                 1/1       Running   0          2h
virt-handler-sztsw                 1/1       Running   0          2h
virt-launcher-testvm-ephemeral-dph94   2/2       Running       0          2h

libvirtd

每個 VM Pod 中都存在一個 libvirtd 例項。virt-launcher 使用 libvirtd 來管理 VM 程序的生命週期。

儲存和網路

KubeVirt 虛擬機器可以配置為帶卷的磁碟。

持久卷宣告卷使 Kubernetes 持久卷作為直接連線到虛擬機器的磁碟可用。這是為 KubeVirt 虛擬機器提供持久儲存的主要方式。目前,持久卷必須是 iscsi 塊裝置,儘管正在努力啟用基於檔案的 PV 磁碟

臨時卷是寫時複製的本地映像,使用網路卷作為只讀後端儲存。KubeVirt 在虛擬機器啟動時動態生成與虛擬機器關聯的臨時映像,並在虛擬機器停止時丟棄臨時映像。目前,臨時卷必須由 PVC 卷支援。

Registry Disk 卷引用了嵌入 qcow 或 raw 磁碟的 Docker 映象。顧名思義,這些卷是從容器登錄檔拉取的。與常規的臨時容器映象一樣,這些卷中的資料僅在 Pod 存活時才保留。

CloudInit NoCloud 卷為虛擬機器提供了一個 cloud-init NoCloud 使用者資料源,該源作為磁碟新增到虛擬機器中,可用於向安裝了 cloud-init 的訪客提供配置詳細資訊。Cloud-init 詳細資訊可以以明文形式提供,也可以作為 base64 編碼的 UserData 檔案提供,或者透過 Kubernetes secrets 提供。

在下面的示例中,配置了一個登錄檔磁碟以提供用於啟動虛擬機器的映象。提供了一個 cloudInit NoCloud 卷,與儲存在 userData 欄位中的明文 ssh 金鑰配對,用於與虛擬機器進行身份驗證

apiVersion: kubevirt.io/v1alpha1
kind: VirtualMachine
metadata:
  name: myvm
spec:
  terminationGracePeriodSeconds: 5
  domain:
    resources:
      requests:
        memory: 64M
    devices:
      disks:
      - name: registrydisk
        volumeName: registryvolume
        disk:
          bus: virtio
      - name: cloudinitdisk
        volumeName: cloudinitvolume
        disk:
          bus: virtio
  volumes:
    - name: registryvolume
      registryDisk:
        image: kubevirt/cirros-registry-disk-demo:devel
    - name: cloudinitvolume
      cloudInitNoCloud:
        userData: |
          ssh-authorized-keys:
            - ssh-rsa AAAAB3NzaK8L93bWxnyp test@test.com

與常規 Kubernetes Pod 一樣,每個 KubeVirt VM 都會自動提供基本的網路功能,並且可以使用常規的 Kubernetes 服務將特定的 TCP 或 UDP 埠暴露給外部世界。無需特殊的網路配置。

參與其中

KubeVirt 的開發正在加速,專案渴望新的貢獻者。如果您有興趣參與,請檢視專案的開放問題並檢視專案日曆

如果您需要幫助或想聊天,可以透過 freenode IRC 的 #kubevirt 或 KubeVirt 郵件列表聯絡團隊。使用者文件可在 https://kubevirt.gitbooks.io/user-guide/ 獲取。