本篇文章已發布超過一年。較舊的文章可能包含過時的內容。請確認頁面中的資訊自發布以來是否已變得不正確。
Kubevirt 簡介
一旦您習慣在 Kubernetes 上執行 Linux 容器工作負載後,您可能會希望能在 Kubernetes 叢集上執行其他類型的工作負載。也許您需要執行的應用程式並非為容器架構設計,或者需要的 Linux 核心版本與容器主機上可用的版本不同,甚至是完全不同的作業系統。
這些類型的工作負載通常非常適合在虛擬機器 (VM) 中執行,而 KubeVirt 是 Kubernetes 的虛擬機器管理附加元件,旨在讓使用者能夠在 Kubernetes 或 OpenShift 叢集中,直接與容器並行執行 VM。
KubeVirt 透過 Kubernetes 的 自訂資源定義 API (CRD),為 VM 和 VM 集合新增資源類型,以擴展 Kubernetes。KubeVirt VM 在一般的 Kubernetes Pod 中執行,它們可以存取標準的 Pod 網路和儲存空間,並且可以使用標準的 Kubernetes 工具 (例如 kubectl) 進行管理。
與使用 oVirt 或 OpenStack 等工具相比,使用 Kubernetes 執行 VM 需要稍微調整,而了解 KubeVirt 的基本架構是良好的起點。
在本文中,我們將在高層次討論 KubeVirt 中涉及的一些組件。我們將檢視的組件包括 CRD、KubeVirt virt-controller、virt-handler 和 virt-launcher 組件、libvirt、儲存和網路。
KubeVirt 組件

自訂資源定義
Kubernetes 資源是 Kubernetes API 中的端點,用於儲存相關 API 物件的集合。例如,內建的 Pod 資源包含 Pod 物件的集合。Kubernetes 自訂資源定義 API 允許使用者透過定義具有指定名稱和結構描述的新物件,使用其他資源來擴展 Kubernetes。一旦您將自訂資源套用到叢集,Kubernetes API 伺服器就會提供並處理自訂資源的儲存。
KubeVirt 的主要 CRD 是 VirtualMachine (VM) 資源,其中包含 Kubernetes API 伺服器內部的 VM 物件集合。VM 資源定義虛擬機器本身的所有屬性,例如機器和 CPU 類型、RAM 和 vCPU 的數量,以及 VM 中可用的 NIC 數量和類型。
virt-controller
virt-controller 是一個 Kubernetes Operator,負責叢集範圍的虛擬化功能。當新的 VM 物件發布到 Kubernetes API 伺服器時,virt-controller 會注意到並建立 VM 將在其中執行的 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 執行階段嘗試在 VM 結束之前關閉 virt-launcher Pod,virt-launcher 會將來自 Kubernetes 的訊號轉發到 VM 程序,並嘗試阻止 Pod 終止,直到 VM 成功關閉為止。
# 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 VM 可以配置磁碟,由磁碟區支援。
Persistent Volume Claim 磁碟區使 Kubernetes 持續性磁碟區可用作直接連接到 VM 的磁碟。這是為 KubeVirt VM 提供持久儲存的主要方法。目前,持續性磁碟區必須是 iscsi 區塊裝置,但啟用基於檔案的 pv 磁碟的工作正在進行中。
臨時磁碟區是本地寫入時複製映像,使用網路磁碟區作為唯讀後端儲存。KubeVirt 在 VM 啟動時動態產生與 VM 關聯的臨時映像,並在 VM 停止時丟棄臨時映像。目前,臨時磁碟區必須由 pvc 磁碟區支援。
Registry Disk 磁碟區參考嵌入 qcow 或 raw 磁碟的 Docker 映像。顧名思義,這些磁碟區是從容器登錄檔中提取的。與一般的臨時容器映像一樣,這些磁碟區中的資料僅在 Pod 存活期間持續存在。
CloudInit NoCloud 磁碟區為 VM 提供 cloud-init NoCloud 使用者資料來源,該來源作為磁碟新增至 VM,可在其中為安裝了 cloud-init 的訪客提供組態詳細資訊。Cloud-init 詳細資訊可以純文字、base64 編碼的 UserData 檔案或透過 Kubernetes 密碼提供。
在以下範例中,Registry Disk 配置為提供從中啟動 VM 的映像。cloudInit NoCloud 磁碟區與以純文字形式儲存在 userData 欄位中的 ssh 金鑰配對,用於 VM 的身分驗證。
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/ 取得。