【转】kubevirt在360的探索之路(k8s接管虚拟化)

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

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 网络

【转】kubevirt在360的探索之路(k8s接管虚拟化)

VMI 通信流程

kubernetes是Kubevirt 底座,提供了管理容器和虚拟机的混合部署的方式,存储和网络也是通过集成到kubernetes中, VMI 使用了POD进行通信。为了实现该目标,KubeVirt 的对网络做了特殊实现。虚拟机具体的网络如图所示, virt-launcher Pod 网络的网卡不再挂有 Pod IP,而是作为虚拟机的虚拟网卡的与外部网络通信的交接物理网卡。

在当前的场景我们使用经典的大二层网络模型,用户在一个地址空间下,VM 使用固定IP,在OpenStack社区,虚拟网络方案成熟,OVS 基本已经成为网络虚拟化的标准。所以我门选择目前灵雀云(alauda) 开源的网络方案:Kube-OVN,它是基于OVN的Kubernetes网络组件,提供了大量目前Kubernetes不具备的网络功能,并在原有基础上进行增强。通过将OpenStack领域成熟的网络功能平移到Kubernetes,来应对更加复杂的基础环境和应用合规性要求。

【转】kubevirt在360的探索之路(k8s接管虚拟化)

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

Original: https://www.cnblogs.com/oxspirt/p/16419216.html
Author: 立志做一个好的程序员
Title: 【转】kubevirt在360的探索之路(k8s接管虚拟化)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/545482/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球