【轉】kubevirt在360的探索之路(k8s接管虛擬化)

 

原文:https://blog.51cto.com/u_11451275/4140896?b=totalstatistic

--------------------------

 

KubeVirt是一個Kubernetes插件,在調度容器之餘也可以調度傳統的虛擬機。它通過使用自定義資源(CRD)和其它 Kubernetes 功能來無縫擴展現有的集羣,以提供一組可用於管理虛擬機的虛擬化的API。本文作者經過長時間對kubevirt的調研和實踐,總結了kubevirt的一些關鍵技術和使用經驗,現在就跟隨作者一起探討下吧。

 

背景簡介

當前公司的虛擬化存在兩套調度平臺,裸金屬和vm由openstack調度,容器肯定是k8s調度。兩套兩班人馬,人力和資源都存在着一定的重疊和浪費。當前vm和pod的比例在1:1,同時隨着業務的全面上雲,大部分web無狀態業務都開始容器化,所以未來k8s+容器肯定是業務發佈的主流選擇,業界也基本成型。

而vm的使用場景會被壓縮,但是vm作爲一個常用的運行時,未來也會長期存在較長時間,最後和容器達成一個三七開的比例。同時裸金屬物理機,由於部分業務的特性獨佔需求,也會在未來長期存在。

OpenStack轉型K8S

所以未來可能會長期存在openstack+k8s兩種虛擬化運行時調度系統,這個增加了團隊的維護和學習成本,再加上現在openstack社區整體趨於平穩和下滑,外加上openstack本身複雜和臃腫的調度架構,和python在大項目管理和維護方面天生的劣勢,造成了相關的人員招聘難度較大,大家的學習和維護熱情也降低。

於此相對的是k8s調度系統的全面優越,簡潔和更好的可擴展性,go語言的大項目和易部署維護的天然優勢,業界不少公司都在考慮是否可以由k8s來接管vm和裸金屬等,因爲本質上vm底層幹活的是libvirt,qemu-kvm等,裸金屬底層是物理機的ipmi,我們是否可以利用k8s的可擴展性,實現一些新的operator來接管vm和裸金屬。

基於上述考慮,最終的目標是用k8s來管一切虛擬化運行時,包含裸金屬,vm,kata,容器,一套調度,多種運行時,用戶按需選擇。

技術選型

有了以上想法以後,就開始調研,發現業界在從openstack轉型k8s的過程中湧現了這麼一部分比較好的項目,例如,kubevirt,virtlet,rancher/vm等,但是社區活躍度最高,設計最好的還是kubevirt。

https://kubevirt.io/2017/technology-comparison.html

文章核心談了幾個點:

kubevirt是不是一個vm管理平臺的替代品,和OpenStack還有ovirt等虛擬化管理平臺的區別。
簡單來說:kubevirt只是用k8s管vm,其中會複用k8s的cni和csi,所以只是用operator的方式來操作vm,他不去管網絡和存儲等。所以和OpenStack中包含nova,neutron,cinder等不一樣,可以理解成kubevirt是一個k8s框架下的,用go寫的nova vm管理組件。
kubevirt和kata的區別。
簡單來說:kata是有着vm的安全性和隔離性,以容器的方式運行,有着容器的速度和特點,但不是一個真正的vm,而kubevirt是借用k8s的擴展性來管vm,你用到的是一個真正的vm。
kubevirt和virtlet的區別。
簡單來說:virtlet是把vm當成一個cri來跑了,是按pod api來定義一個vm,所以vm的很多功能比如熱遷移等,virtlet是沒法滿足vm的全部特性的,算是一個70%功能的vm。

爲啥要用k8s管vm,而不是用OpenStack管容器。
簡單來說:k8s+容器是未來的主流方向,但是由於歷史和業務需要,vm也會存在很長時間,所以我們一套支持vm的容器管理平臺k8s,而不是需要一套支持容器的vm管理平臺例如OpenStack管容器Magnum這種類似項目。
選型插曲

有個插曲:在驗證kubevirt的這段時間,正好看到rancher也發佈了基於 kubevirt 和 k8s 的超融合基礎架構軟件 Harvester,從側面說明,這個方向是有共性的。所有上了年紀的公司,都有OpenStack和k8s的包袱,而rancher的老總也是cloudstack的創始人,以前和OpenStack競爭的時候落於下風,現在基於k8s和kubevirt又回到了iaas的地帶,所有技術圈好多也是輪迴啊。

所以kubevirt這種項目也是在很多從iaas OpenStack轉型paas k8s的人羣中有更多共鳴,年輕k8s原住民可能對這個項目沒有太多感知。因爲kubevirt的發起方redhat,和核心開發者以前也是OpenStack社區的項目owner等。所以kubevirt的一些測試公司和用戶也都是有此類共同轉型背景的人和公司。

基於如上考慮,最終技術選型確定了kubevirt,接下來對kubevirt的一些概念和邏輯架構,還有在360的測試和驗證之路做一個簡單介紹。

1

Kubevirt 是什麼

 

Kubevirt 是 Redhat 開源一套以容器方式運行虛擬機的項目,通過 kubernetes 雲原生來管理虛擬機生命週期。

2

Kubevirt CRD

 

在介紹kubevirt 前我們先了解一下CRD,在kubernetes裏面有一個核心思想既一切都是資源,如同Puppet 裏面一切都是資源思想。CRD 是kubernetes 1.7之後添加的自定義資源二次開發來擴展kubernetes API,通過CRD 可以向API 中添加資源類型,該功能提升了 Kubernetes 的擴展能力,那麼KUBEVIRT 有哪些需要我們理解的CRD資源,這些資源會在我們的學習和理解過程中都是需要注意的,大概簡介紹如下幾種:

 

 

 

3

Kubevirt 組件介紹

 

與OpenStack 類似, kubevirt 每個組件負責不同的功能,不同點是資源調度策略由k8s 去管理,其中主要組件如下: virt-api,virt-controller,virt-handler,virt-launcher。

 

 

 

4

Kubevirt 常見操作

 

type DomainManager interface {
//SyncVMI 爲創建虛擬機
SyncVMI(*v1.VirtualMachineInstance, bool, *cmdv1.VirtualMachineOptions) (*api.DomainSpec, error)
//暫停VMI
PauseVMI(*v1.VirtualMachineInstance) error
//恢復暫停的VMI
UnpauseVMI(*v1.VirtualMachineInstance) error
KillVMI(*v1.VirtualMachineInstance) error
//刪除VMI
DeleteVMI(*v1.VirtualMachineInstance) error
SignalShutdownVMI(*v1.VirtualMachineInstance) error
MarkGracefulShutdownVMI(*v1.VirtualMachineInstance) error
ListAllDomains() ([]*api.Domain, error)
//遷移VMI
MigrateVMI(*v1.VirtualMachineInstance, *cmdclient.MigrationOptions) error
PrepareMigrationTarget(*v1.VirtualMachineInstance, bool) error
GetDomainStats() ([]*stats.DomainStats, error)
//取消遷移
CancelVMIMigration(*v1.VirtualMachineInstance) error
//如下需要啓用Qemu guest agent,沒啓用會包VMI does not have guest agent connected
GetGuestInfo() (v1.VirtualMachineInstanceGuestAgentInfo, error)
GetUsers() ([]v1.VirtualMachineInstanceGuestOSUser, error)
GetFilesystems() ([]v1.VirtualMachineInstanceFileSystem, error)
SetGuestTime(*v1.VirtualMachineInstance) error
}

5

kubevirt 虛機VMI

 

[root@openstack825 ~]# kubectl get vmi -o wide
NAME AGE PHASE IP NODENAME LIVE-MIGRATABLE
test100.foo.demo.example.com 8d Running 192.168.10.30 10.10.67.244 True
test200.foo.demo.example.com 8d Running 192.168.10.31 10.10.67.245 True

獲取已安裝的kubevirt pod
[root@openstack825 ~]# kubectl -n kubevirt get pod
NAME READY STATUS RESTARTS AGE
virt-api-68c958dd-6sx4n 1/1 Running 0 14d
virt-api-68c958dd-sldgr 1/1 Running 0 14d
virt-controller-647d666bd5-gsnzf 1/1 Running 1 14d
virt-controller-647d666bd5-hshnz 1/1 Running 1 14d
virt-handler-4g7ck 1/1 Running 3 14d
virt-handler-kzv86 1/1 Running 0 14d
virt-handler-m2ppb 1/1 Running 0 14d
virt-handler-v6fgt 1/1 Running 0 14d
virt-operator-65ccf74f56-b82kz 1/1 Running 0 14d
virt-operator-65ccf74f56-zs2xq 1/1 Running 0 14d
virtvnc-947874d99-hn7k5 1/1 Running 0 6d19h

總結:同時我們在調研過程遇到一些問題,比如重啓數據丟失、VMI 重啓和熱遷移後IP 改變、鏡像導入數據緩慢、VMI 啓動調度緩慢、熱遷移網絡與存儲支持等等。Kubevirt 通過CRD 方式將 VM 管理接口接入到k8s集羣,而 POD 使用 libvirtd 管理VMI,如容器一樣去管理VMI,最後通過標準化插件方式管理調度網絡和存儲資源對象,將其整合在一起形成一套 具有 K8s 管理虛擬化的技術棧。

6

kubevirt 存儲

 

虛擬機鏡像(磁盤)是啓動虛擬機必不可少的部分,目前 KubeVirt 中提供多種方式的虛擬機磁盤。

cloudInitNoCloud/cloudInitConfigDrive:用於提供 cloud-init 初始化所需要的 user-data,使用 configmap 作爲數據源,此時VMI 內部將出現第二塊大約爲356KB的第二塊硬盤。
devices: disks: - disk: bus: virtio name: cloudinit - cloudInitNoCloud: userData: | #cloud-config password: kubevirt [centos@xxxv ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 47G 0 disk └─vda1 253:1 0 47G 0 part / vdb 253:16 0 366K 0 disk
dataVolume:虛擬機啓動流程中自動將虛擬機磁盤導入 pvc 的功能,在不使用 DataVolume 的情況下,用戶必須先準備帶有磁盤映像的 PVC,然後再將其分配給 VM 或 VMI。dataVolume 拉取鏡像的來源可以是HTTP、PVC。
spec: pvc: accessModes: - ReadWriteMany volumeMode: Block resources: requests: storage: 55G storageClassName: csi-rbd-sc source: http: url: http://127.0.0.1:8081/CentOS7.4_AMD64_2.1
PersistentVolumeClaim: PVC 做爲後端存儲,適用於數據持久化,即在虛擬機重啓或關機後數據依然存在。PV 類型可以是 block 和 filesystem,爲 filesystem 時,將使用 PVC 上的 disk.img,格式爲 RAW 格式的文件作爲硬盤。block 模式時,使用 block volume 直接作爲原始塊設備提供給虛擬機。缺點在於僅支持RAW格式鏡像,若鏡像較大CDI 導入鏡像會比較慢(如果是QCW2 CDI 內部機制qemu.go 會將其進行格式轉換爲RAW並導入PVC中),因此降低快速創建 VMI 體驗感。當然社區目前支持一種較smart-clone 方式導入,目前筆者還沒進行測試。
spec: pvc: accessModes: - ReadWriteMany volumeMode: Block resources: requests: storage: 55G storageClassName: csi-rbd-sc source: pvc: namespace: "default" name: "q18989v.cloud.bjyt.qihoo.net"
ephemeral、containerDisk: 數據是無法持久化,故在存儲選型上,我們採用 CEPH 作爲後端存儲,通過調用Ceph CSI 插件創建 PVC 卷方式管理虛機磁盤設備。Ceph CSI 插件實現了容器存儲編排與Ceph集羣交互的接口,它可以爲容器應用分配 存儲集羣中的存儲空間,同時在選擇 Ceph-CSI 版本需要考慮到當前 K8S 版本、及 CEPH 版本號。

當前支持的版本列表:

 

 

 

Dynamically provision, de-provision Block mode RWX volume

支持RBD 塊 RWX 的模式,使用此模式主要涉及到Kubevirt 熱遷移場景,虛擬機調用 VirtualMachineInstanceMigration CRD 資源,熱遷移時會檢測Volume 模式,此時塊設備必須 RWX 模式,代碼如下.  

位置:pkg/vm-handler/vm.go

//主要通過調用磁盤、網絡相關函數,來判斷當前VMI 是否適合遷移
func (d *VirtualMachineController) calculateLiveMigrationCondition(vmi *v1.VirtualMachineInstance, hasHotplug bool) (*v1.VirtualMachineInstanceCondition, bool) {
liveMigrationCondition := v1.VirtualMachineInstanceCondition{
Type: v1.VirtualMachineInstanceIsMigratable,
Status: k8sv1.ConditionTrue,
}
//調用 checkvolume 方法
isBlockMigration, err := d.checkVolumesForMigration(vmi)
if err != nil {
//如果返回錯誤信息則會限制遷移
liveMigrationCondition.Status = k8sv1.ConditionFalse
liveMigrationCondition.Message = err.Error()
liveMigrationCondition.Reason = v1.VirtualMachineInstanceReasonDisksNotMigratable
return &liveMigrationCondition, isBlockMigration
}
//調用網絡模式檢查方法
err = d.checkNetworkInterfacesForMigration(vmi)
if err != nil {
liveMigrationCondition = v1.VirtualMachineInstanceCondition{
Type: v1.VirtualMachineInstanceIsMigratable,
Status: k8sv1.ConditionFalse,
Message: err.Error(),
Reason: v1.VirtualMachineInstanceReasonInterfaceNotMigratable,
}
return &liveMigrationCondition, isBlockMigration
}
if hasHotplug {
liveMigrationCondition = v1.VirtualMachineInstanceCondition{
Type: v1.VirtualMachineInstanceIsMigratable,
Status: k8sv1.ConditionFalse,
Message: "VMI has hotplugged disks",
Reason: v1.VirtualMachineInstanceReasonHotplugNotMigratable,
}
return &liveMigrationCondition, isBlockMigration
}
return &liveMigrationCondition, isBlockMigration
}

//checkvolume 定義
/檢查所有VMI卷共享可以在源和實時遷移的目的地之間熱遷移
//當所有卷均已共享且VMI沒有本地磁盤時,blockMigrate才返回True
//某些磁盤組合使VMI不適合實時遷移, 在這種情況下,將返回相關錯誤
func (d *VirtualMachineController) checkVolumesForMigration(vmi *v1.VirtualMachineInstance) (blockMigrate bool, err error) {
for _, volume := range vmi.Spec.Volumes {
volSrc := volume.VolumeSource
if volSrc.PersistentVolumeClaim != nil || volSrc.DataVolume != nil {
var volName string
if volSrc.PersistentVolumeClaim != nil {
volName = volSrc.PersistentVolumeClaim.ClaimName
} else {
volName = volSrc.DataVolume.Name
}
//pvcutils.IsSharedPVCFromClient
_, shared, err := pvcutils.IsSharedPVCFromClient(d.clientset, vmi.Namespace, volName)
if errors.IsNotFound(err) {
return blockMigrate, fmt.Errorf("persistentvolumeclaim %v not found", volName)
} else if err != nil {
return blockMigrate, err
}
if !shared {
return true, fmt.Errorf("cannot migrate VMI with non-shared PVCs")
}
} else if volSrc.HostDisk != nil {
shared := volSrc.HostDisk.Shared != nil && *volSrc.HostDisk.Shared
if !shared {
return true, fmt.Errorf("cannot migrate VMI with non-shared HostDisk")
}
} else {
blockMigrate = true
}
}
return
}
func IsSharedPVCFromClient(client kubecli.KubevirtClient, namespace string, claimName string) (pvc *k8sv1.PersistentVolumeClaim, isShared bool, err error) {
pvc, err = client.CoreV1().PersistentVolumeClaims(namespace).Get(claimName, v1.GetOptions{})
if err == nil {
//IsPVCShared
isShared = IsPVCShared(pvc)
}
return
}
//IsPVCShared Shared 判斷,函數返回bool 類型,成功則返回true
func IsPVCShared(pvc *k8sv1.PersistentVolumeClaim) bool {
//循環PVC的accessModes
for _, accessMode := range pvc.Spec.AccessModes {
if accessMode == k8sv1.ReadWriteMany {
return true
}
}
return false
}

Ceph CSi 啓動的POD 進程

[root@kubevirt01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
csi-rbdplugin-7bprd 3/3 Running 0 14d
csi-rbdplugin-fl5c9 3/3 Running 0 14d
csi-rbdplugin-ggj9q 3/3 Running 0 14d
csi-rbdplugin-provisioner-84bb9bdd56-7qtnh 6/6 Running 0 14d
csi-rbdplugin-provisioner-84bb9bdd56-sdscf 6/6 Running 0 14d
csi-rbdplugin-provisioner-84bb9bdd56-xjz2r 6/6 Running 0 14d
csi-rbdplugin-svfv2

        

已創建的VMI 對應的 PVC卷

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: testzhangsanlisi
spec:
accessModes:
- ReadWriteMany
volumeMode: Block
resources:
requests:
storage: 10Gi
storageClassName: csi-rbd-sc
kubectl apply -f pvc-test.yaml
[root@kubevirt01 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
testzhangsanlisi Bound pvc-2c98391d-a2eb-4dd1-a1f0-2a8ef27d4ca3 10Gi RWX csi-rbd-sc 3s

CEPH 架構相關,使用三副本策略,不同交換機下及高容量 SATA 盤 作爲 OSD 數據載體,保證數據的可用性

(ceph-mon)[root@example100 /]# ceph -s
cluster:
id: d8ab2087-f55c-4b8f-913d-fc60d6fc455d
health: HEALTH_OK
services:
mon: 3 daemons, quorum 192.168.10.100 192.168.20.100 192.168.30.100 (age 4d)
mgr: ceph100(active, since 4d), standbys: ceph200, ceph300
osd: 27 osds: 27 up (since 2w), 27 in (since 2w)
data:
pools: 1 pools, 1024 pgs
objects: 55.91k objects, 218 GiB
usage: 682 GiB used, 98 TiB / 98 TiB avail
pgs: 1024 active+clean
io:
client: 2.2 KiB/s wr, 0 op/s rd, 0 op/s wr
(ceph-mon)[root@example100 /]# ceph df
RAW STORAGE:
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 98 TiB 98 TiB 655 GiB 682 GiB 0.68
TOTAL 98 TiB 98 TiB 655 GiB 682 GiB 0.68

7

kubevirt 網絡

 

 

 

 

VMI 通信流程

kubernetes是Kubevirt 底座,提供了管理容器和虛擬機的混合部署的方式,存儲和網絡也是通過集成到kubernetes中, VMI 使用了POD進行通信。爲了實現該目標,KubeVirt 的對網絡做了特殊實現。虛擬機具體的網絡如圖所示, virt-launcher Pod 網絡的網卡不再掛有 Pod IP,而是作爲虛擬機的虛擬網卡的與外部網絡通信的交接物理網卡。

在當前的場景我們使用經典的大二層網絡模型,用戶在一個地址空間下,VM 使用固定IP,在OpenStack社區,虛擬網絡方案成熟,OVS 基本已經成爲網絡虛擬化的標準。所以我門選擇目前靈雀雲(alauda) 開源的網絡方案:Kube-OVN,它是基於OVN的Kubernetes網絡組件,提供了大量目前Kubernetes不具備的網絡功能,並在原有基礎上進行增強。通過將OpenStack領域成熟的網絡功能平移到Kubernetes,來應對更加複雜的基礎環境和應用合規性要求。 

 

 

 

Kube-OVN 是一款基於 OVS/OVN 的 Kubernetes網絡項目

網絡 VLAN underlay

在網絡平面,管理網和 VMI 虛擬機流量分開,其中使用Vlan 模式的 underlay 網絡,容器網絡可以直接通過 vlan 接入物理交換機

//Demo Yaml
//IP 地址段來自源與網絡物理設備分配時
spec:
cidrBlock: 192.168.10.0/23
default: true
excludeIps:
- 192.168.10.1
gateway: 192.168.10.1
gatewayNode: ""
gatewayType: distributed
// 需要設置成false
natOutgoing: false
private: false
protocol: IPv4
provider: ovn
//需要設置成true,若爲false,會在主機側加上route,導致net不通
underlayGateway: true
vlan: ovn-vlan

[root@kubevirt01 ~]# kubectl -n kube-system get pod
NAME READY STATUS RESTARTS AGE
coredns-65dbdb44db-8bxlr 1/1 Running 33 17d
kube-ovn-cni-4v4xb 1/1 Running 0 18d
kube-ovn-cni-kvgrj 1/1 Running 0 18d
kube-ovn-cni-nj2pr 1/1 Running 0 18d
kube-ovn-cni-xv476 1/1 Running 0 18d
kube-ovn-controller-7f6db69b48-6c7w8 1/1 Running 0 18d
kube-ovn-controller-7f6db69b48-82kjt 1/1 Running 0 18d
kube-ovn-controller-7f6db69b48-mhkfc 1/1 Running 0 18d
kube-ovn-pinger-n2rn4 1/1 Running 0 18d
kube-ovn-pinger-s4hrz 1/1 Running 0 18d
kube-ovn-pinger-tccz5 1/1 Running 0 18d
kube-ovn-pinger-x2tqq 1/1 Running 0 18d
ovn-central-775c4ff46d-4nqjw 1/1 Running 1 18d
ovn-central-775c4ff46d-822v2 1/1 Running 0 18d
ovn-central-775c4ff46d-txkn8 1/1 Running 0 18d
ovs-ovn-mbpv2 1/1 Running 0 18d
ovs-ovn-r9mvc 1/1 Running 0 18d
ovs-ovn-wkxld 1/1 Running 0 18d
ovs-ovn-z89hw 1/1 Running 0 18d

虛擬機固定IP

k8s的資源是在運行時才分配ip的,但是筆者希望能夠對虛擬機的ip進行綁定從而實現固定ip的目的。爲此,我們首先正常創建虛擬機,在虛擬機運行時k8s會爲之分配ip,當檢測到虛擬機的ip後,我們通過替換vmi的配置文件的方式將ip綁定改虛擬機中。但是在實際操作時會報出如下錯誤:

Invalid value: 0x0: must be specified for an update

實際上 Kubernetes API Server是支持樂觀鎖(Optimistic concurrency control)的機制來防止併發寫造成的覆蓋寫問題,因此在修改的body中需要加入metadata.resourceVersion,筆者的做法是首選調用 read_namespaced_virtual_machine方法獲取metadata.resourceVersion,其次再修改body。具體方案可參考:

https://www.codeleading.com/article/27252474726/

8

kubevirt SDK

 

kubevirt sdk現狀    當前kubevirt提供了Python版本以及Golang版本的SDK,具體的信息參考如下:

https://github.com/kubevirt/client-python
https://github.com/kubevirt/client-go

2.
筆者實際使用的是python的sdk,所以接下來重點敘述一下python版本的sdk的使用心得,使用時發現了一些問題,並加以解決也將在下面的內容中記錄。

sdk實現的功能本章筆者詳細介紹一下使用到的一些sdk中的功能,在初體驗的過程中筆者只是用了部分功能,完整的功能可以詳見github。

創建使用實例
sdk主要使用的是kubevirt.apis.default_api中的DefaultApi對象,進行接口調用個的。DefaultApi對象需要ApiClient對象,該對象實際上是連接k8s的實例。因此在使用之前,需要在底層的k8s中起一個proxy。通過創建DefaultApi對象即可調用後續的接口了,具體的創建方法如下:
import kubevirt def get_api_client(host): api_client = kubevirt.ApiClient(host=host, header_name="Content-Type", header_value="application/json") return api_client api_client = get_api_client(host="http://127.0.0.1:8001") api_instance = kubevirt.DefaultApi(api_client)
kubvirt sdk 的本質
實際上我們知道,kubevirt是在k8s中定義了集中CRD,那麼調用kubevirt的sdk實際上也是調用k8s中CRD相關接口,通過查看k8中CRD的接口我們知道,具體的url表示爲:/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}因此重要的是找到group以及plural參數具體是什麼。通過下圖可以看出group都是kubevirt.io,plural根據需要的不同可以定義不同的類型


sdk部分功能以及注意事項
筆者主要使用了以下的功能:
創建虛擬機( create_namespaced_virtual_machine) 注意:body是json格式,官方sdk的example有誤
刪除虛擬機( delete_namespaced_virtual_machine)
展示某個namespace下的vm資源( list_namespaced_virtual_machine)
展示某個namespace下的vmi資源( list_namespaced_virtual_machine_instance)
展示所有namespace下的vm資源( list_virtual_machine_for_all_namespaces)
展示所有namespace下的vmi資源( list_virtual_machine_instance_for_all_namespaces)
獲取某個namespace某個name下的vm資源( read_namespaced_virtual_machine)
獲取某個namespace某個name下的vmi資源( read_namespaced_virtual_machine_instance) 注意:在獲取vm資源時無法獲取到node_name,uuid,ip的數據,獲取vmi資源時無法獲取到disk以及image_url的數據,筆者認爲vm是虛擬機資源,vmi是虛擬機實例資源,只有在running狀態下的vm纔是vmi,由於k8s中ip是動態分配的,因此纔會出現node_name,uuid,ip數據在vm中獲取不到
啓動虛擬機( v1alpha3_start)
停止虛擬機( v1alpha3_stop)
重啓虛擬機( v1alpha3_restart) 注意: 重啓虛擬機只能在虛擬機狀態是running是才能調用,否則會失敗
修改虛擬機名稱( v1alpha3_rename)
替換虛擬機的配置文件( replace_namespaced_virtual_machine_instance)

sdk使用注意事項

k8s版本問題
官方給出的kubevirt sdk中對於創建刪除以及替換配置文件等部分接口,k8s版本是固定的穩定版v1版本,這顯然不滿足於sdk的靈活使用,因此筆者在使用時對api版本進行了兼容,保證用戶可以通過傳參的形式正確的使用。
修改虛擬機名稱缺乏參數
誠如標題所述,修改虛擬機名稱接口官方給出的參數有誤,缺乏新名稱參數

 


筆者通過查看virtclt源碼找到了缺少的參數的具體名稱並添加至sdk中,具體代碼如下:

def v1alpha3_rename_with_http_info(self, name, newName, namespace, **kwargs):
"""
Rename a stopped VirtualMachine object.
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please define a `callback` function
to be invoked when receiving the response.
>>> def callback_function(response):
>>> pprint(response)
>>>
>>> thread = api.v1alpha3_rename_with_http_info(name, namespace, newName, callback=callback_function)
:param callback function: The callback function
for asynchronous request. (optional)
:param str name: Name of the resource (required)
:param str namespace: Object name and auth scope, such as for teams and projects (required)
:param str newName: NewName of the resource (required)
:return: str
If the method is called asynchronously,
returns the request thread.
"""
all_params = ['name', 'namespace', 'newName']
all_params.append('callback')
all_params.append('_return_http_data_only')
all_params.append('_preload_content')
all_params.append('_request_timeout')
params = locals()
for key, val in iteritems(params['kwargs']):
if key not in all_params:
raise TypeError(
"Got an unexpected keyword argument '%s'"
" to method v1alpha3_rename" % key
)
params[key] = val
del params['kwargs']
# verify the required parameter 'name' is set
if ('name' not in params) or (params['name'] is None):
raise ValueError("Missing the required parameter `name` when calling `v1alpha3_rename`")
# verify the required parameter 'namespace' is set
if ('namespace' not in params) or (params['namespace'] is None):
raise ValueError("Missing the required parameter `namespace` when calling `v1alpha3_rename`")
collection_formats = {}
path_params = {}
# if 'name' in params:
# path_params['name'] = params['name']
# if 'namespace' in params:
# path_params['namespace'] = params['namespace']
query_params = []
header_params = {}
form_params = []
local_var_files = {}
body_params = {"newName": params["newName"]}
# Authentication setting
auth_settings = []
api_route = "/apis/subresources.kubevirt.io/v1alpha3/namespaces/{namespace}/virtualmachines/{name}/rename".format(namespace=params["namespace"], name=params["name"])
return self.api_client.call_api(api_route, 'PUT',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type='str',
auth_settings=auth_settings,
callback=params.get('callback'),
_return_http_data_only=params.get('_return_http_data_only'),
_preload_content=params.get('_preload_content', True),
_request_timeout=params.get('_request_timeout'),
collection_formats=collection_formats)

9

Ultron 平臺創建基於kubevirt 的虛擬機

 

奧創平臺是公司內的私有云管理平臺(類似horizon),可以通過其管理openstack VM,本次我們同時納入到對Kubevirt 虛擬機的支持,創建方式和OpenStack方式一樣。最後用戶體驗和功能特性也和OpenStack一致,用戶本身也是不關注底層實現,性能特性方面後續文章會有對比。

 

10

總結

 

kubevirt作爲一個兼容方案,當前在cncf中孵化的也挺好,好像也要開始自己的KubeVirt Summit,主要是實際的解決了一些痛點,但目前看,kubevirt還是適合在私有云,肯定滿足不了公有云,因爲k8s在iaas方面有先天劣勢,所以kubevirt應該是給大家在私有云領域落地虛擬化除了用OpenStack以外多了一種選擇方案。

相關文章

https://kubevirt.io/
https://xie.infoq.cn/article/9c911e195aa9b02a69f875489
-----------------------------------
kubevirt在360的探索之路(k8s接管虛擬化)
https://blog.51cto.com/u_11451275/4140896

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章