本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
瞭解 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 元件

自定義資源定義(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/ 獲取。