来源:之家技术
1. 为什么用Kubevirt?
随着k8s容器技术的容错性、高可用性、开放性和可扩展性,目前之家核心且重要的业务已全面容器化,然而,在某些场景下,对于一些历史较久改造成本较高的Windows场景,无法满足现有环境迁移,通过技术调研,社区活跃性,以及各大厂的背书,目前采用kubevirt 实现之家业务全面容器化的最后一公里。
2. 什么是Kubevirt?
2.1
概念
Kubevirt: 是一个在Kubernetes集群中运行和管理的(RedHat)开源项目,他可以帮助用户在k8s中轻松创建,启动和管理虚拟机,从而实现了之家业务全面容器化和统一管理及运维
2.2
架构设计
该方案设计思想源自于现有openstack 资源快速交付,OS系统盘基于external-snapshotter实现快照克隆,做到系统秒级交付,DATA盘采用PV/PVC 形式通过ceph-csi 管理(创建,扩容,删除),接合现有云主机资源交付流程,通过FSM 状态机实现k8s API与kubevirt CRUD操作,实现资源快速交付。
2.3
组件说明
Virt-api:是一个 RESTful API 服务器,提供了一系列的 API 接口来管理和操作 KubeVirt 中的虚拟机资源,virt-api 支持多种虚拟机资源类型,基于API 进行管理和操作
Virt-controller: 负责监控 k8s集群中的虚拟机资源,并根据用户定义的规则自动调整资源分配,负责管理虚拟机生命周期管理,它通过自动化资源分配、弹性扩展、监控和报警等功能
Virt-handler: 是 KubeVirt 的一个核心组件,它运行在 k8s 集群中每个节点上,并负责管理和监控节点上的虚拟机资源,监控虚拟机事件,维护节点状态,实现自动化管理和部署
Virt-launcher: 负责在 k8s集群中启动和管理虚拟机实例, 通过管理虚拟机生命周期、支持多种虚拟化技术、提供安全性和高可用性等功能
Virt-vnc: 是 KubeVirt的一个核心组件,它提供了一种 VNC 远程访问虚拟机的方式,使得用户可以通过 VNC 客户端远程访问和操作虚拟机, 支持多种虚拟化技术、提供安全性和高可用性等功能
CDI: (Containerized Data Importer)是 KubeVirt 的一个组件,它提供了一种在 k8s 集群中导入、管理和使用虚拟机镜像的方式
Ceph-csi: 是k8s存储插件,它可以将 Ceph 存储集成到 k8s 集群中,并提供了一系列的 API 接口来管理和操作 Ceph 存储并集成到k8s集群中,实现了高效、可靠的存储服务。
External-snapshotter:是 k8s 的一个存储插件,它可以将外部存储系统的快照(Snapshot)集成到 k8s 集群中,并通过 API 接口提供了快照管理和操作功能。
FSM: 自研分布式状态机,在任意可用区实现资源的创建,调度、打通内部系统,实现多种(虚拟机、实体机,公有云)资源交付。
3.如何落地Kubevirt
3.1
业务需求
1.第三方私有化服务,针对特殊license业务迁移
2.历史较久改造成本较高的Windows场景
3.特定网络专项对接的私有服务
4.特定场景的第三方机器学习服务
3.2
接入流程化
►用户->服务器申请工单->隔级审批->资源确认(管理员审批)->资源调度(创建)->完成交付
•镜像定制化
(1)采用kvm相关命令实现基础镜像制作
创建基础镜像
virt-install-nwindows2012-f/data/centos74.img-s120-r16384-v--vcpus=16--vnc---cdrom=/mnt/windows2012
virt-install-nwindows2012-f/data/centos74.img-s120-r16384-v--vcpus=16--vnc---cdrom=/mnt/windows2012
(3)系统标准化
完善系统基础服务安装包定制、系统分区、系统安全、内核参数等标准化定制
开机启动(init)脚本:实现系统启动后网络配置自动生成,Salt Agent网络可达
数据盘格式化:虚拟机交付后可实现PVC 卷格式化并自动挂载/data目录
•组件标准化
因kubevirt 采用组件较多,验证较稳定版本,可上传至内部镜像(harbor)仓库,实现组件版本统一,避免线上自动更新最新版本引起不可逆问题
•标准化部署
选择版本是需经过多维度测试,建议选择较新且稳定版,避免出现未知问题影响生产业务
(1)CDI 部署(采用v1.55.0版本)
下载cdi yaml文件
核心cdi-cry配置
•针对CDI 核心POD 在Master上运行(占用资源较少且需稳定)
spec:
imagePullPolicy:IfNotPresent
infra:
nodeSelector:
node-role.kubernetes.io/control-plane:""
tolerations:
-key:CriticalAddonsOnly
operator:Exists
-effect:NoSchedule
key:node-role.kubernetes.io/master
-effect:NoSchedule
key:node-role.kubernetes.io/control-plane
workload:
nodeSelector:
node-role.kubernetes.io/control-plane:""
tolerations:
-key:CriticalAddonsOnly
operator:Exists
-effect:NoSchedule
key:node-role.kubernetes.io/master
-effect:NoSchedule
key:node-role.kubernetes.io/control-plane
•cdi-operator.yaml 修改namespace 为kubevirt
•cdi-operator镜像地址设置为私有镜像仓库地址
创建服务
Kubectlapply-fcdi-operator.yaml
Kubectlapply-fcdi-cr.yaml
检查服务
•Kubevirt 部署
下载yaml文件
修改kubevirt-cr 配置(核心POD 在master运行,Workloads运行独立BIZ-kubevirt标签)
spec:
certificateRotateStrategy:{}
configuration:
developerConfiguration:
featureGates:[]
customizeComponents:{}
imagePullPolicy:IfNotPresent
imageregistry: ts3.harbor.com.cn/kubernetes/kubevirt
infra:
nodePlacement:
nodeSelector:
node-role.kubernetes.io/control-plane:""
workloads:
nodePlacement:
nodeSelector:
node-role.kubernetes.io/BIZ-Kubevirt:"true"
workloadUpdateStrategy:{}
修改kubevirt-operator 私有镜像地址
创建服务
Kubectlapply-fkubevirt-operator.yaml
Kubectlapply-fkubevirt-cr.yaml
检查服务
•Ceph-csi 部署
Ceph RBD 集群环境部署暂且不在论述,通过ceph csi实现Ceph 存储并集成到k8s集群,管理 pod/vmi pvc存储应用
Kubevirt pool 创建
cephosdpoolcreatekubevirt1024
创建Ceph rbd Key 实现k8s对RBD 管理
cephauthget-or-createclient.kubevirtmon'profilerbd'osd'profilerbdpool=kubevirt'mgr'profilerbdpool=kubevirt'
获取kubevirt key
cephauthls|grepkubevirt-A1
•ceph csi 相关配置
下载ceph-csi包
wget
tar-xzvfv3.7.2.tar.gz
cd./ceph-csi-3.7.2/deploy/rbd/kubernetes
配置csi-config-map.yaml
apiVersion:v1
kind:ConfigMap
data:
config.json:|-
[
{
"clusterID":"ceph集群ID",
"monitors":["ceph集群Mon服务端口"]
}
]
metadata:
name:ceph-csi-config
namespace:csi
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:csi-rbd-sc
provisioner:rbd.csi.ceph.com
parameters:
clusterID:Ceph集群ID
pool:kubevirt
imageFeatures:layering
csi.storage.k8s.io/provisioner-secret-name:csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace:csi
csi.storage.k8s.io/controller-expand-secret-name:csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace:csi
csi.storage.k8s.io/node-stage-secret-name:csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace:csi
csi.storage.k8s.io/fstype:xfs
reclaimPolicy:Delete
allowVolumeExpansion:true
mountOptions:
-discard
apiVersion:v1
kind:Secret
metadata:
name:csi-rbd-secret
namespace:csi
stringData:
userID:kubevirt
userKey:xx-xxx-xxx#通过命令获取:ceph auth ls |grep kubevirt -A 1"
#-name:ceph-csi-encryption-kms-config
#configMap:
#name:ceph-csi-encryption-kms-config
kubectlapply-fcm-ceph-config.yaml
kubectlapply-fcsi-config-map.yaml
kubectlapply-fcsi-rbd-sc.yaml
kubectlapply-fsecret-csi-rbd.yaml
kubectlapply-fcsi-nodeplugin-rbac.yaml
kubectlapply-fcsi-provisioner-rbac.yaml
kubectlapply-fcsi-rbdplugin-provisioner.yaml
kubectlapply-fcsi-rbdplugin.yaml
服务检查
•External-snapshotter 部署
下载yaml文件
wget1.
tar-xzvfv6.1.0.tar.gz
启动服务
cd./external-snapshotter-6.1.0/client/config/crd
kubectlapply-fsnapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectlapply-fsnapshot.storage.k8s.io_volumesnapshots.yaml
kubectlapply-fsnapshot.storage.k8s.io_volumesnapshotclasses.yaml
cd./kubevirt/external-snapshotter-6.1.0/deploy/Kubernetes/
kubectlcreate-fcsi-snapshotter/
kubectlcreate-fsnapshot-controller/
检查服务
cp-frvirtctl-v0.55.2-linux-amd64/usr/bin//virtctl
获取cdi upload proxy 地址
kubectlgetall-nkubevirt|grep'cdi-uploadproxy'|grep'ClusterIP'|awk'{print$3}'
上传镜像
virtctlimage-upload--namespace=vm-windows-12--pvc-size=129G--storage-class=csi-rbd-sc--pvc-name=windows2012--image-path=/data/windows2012.qcow2--uploadproxy-url=–insecure
•创建系统镜像snapshot
构建 snapshotclass.yaml
apiVersion:snapshot.storage.k8s.io/v1
kind:VolumeSnapshotClass
metadata:
name:ceph-rbd-class
namespace:csi
driver:rbd.csi.ceph.com
parameters:
clusterID:ceph集群ID
csi.storage.k8s.io/snapshotter-secret-name:csi-rbd-secret
csi.storage.k8s.io/snapshotter-secret-namespace:csi
deletionPolicy:Delete
构建 windows-snapshot.yaml
apiVersion:snapshot.storage.k8s.io/v1
kind:VolumeSnapshot
metadata:
name:windows2012-snap
namespace:vm-windows-12
spec:
volumeSnapshotClassName:ceph-rbd-class
source:
persistentVolumeClaimName:windows2012
创建volumesnapt
kubectlapply-fsnapshotclass.yaml
kubectlapply-fwindows-snapshot.yaml
获取volumesnapshot 状态
Kubectl get volumesnapshot -n vm-windows
•创建VM
创建数据磁盘DATA(win12-snap2-data.yaml)
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:win12-snap2-data
namespace:vm-windows-12
spec:
accessModes:
-ReadWriteOnce
volumeMode:Block
resources:
requests:
storage:200Gi
storageClassName:csi-rbd-sc
创建系统镜像OS(win12-snap2-os.yaml)
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:win12-snap2-os
namespace:vm-windows-12
spec:
storageClassName:csi-rbd-sc
dataSource:
name:windows2012-snap
kind:VolumeSnapshot
apiGroup:snapshot.storage.k8s.io
accessModes:
-ReadWriteOnce
resources:
requests:
storage:129Gi
构建VM模板(win12-snap2.yaml)
apiVersion:kubevirt.io/v1
kind:VirtualMachine
metadata:
name:win12-snap2
namespace:vm-windows-12
labels:
network:fixedip#vm设置固定IP,基于calico二次开发
spec:
running:true
template:
metadata:
labels:
kubevirt.io/vm:win12-snap2cc
network:fixedip
spec:
terminationGracePeriodSeconds:30
domain:
resources:
requests:
memory:24Gi
cpu:
cores:16
sockets:1
threads:1
devices:
networkInterfaceMultiqueue:true#开启网卡多队列模式
blockMultiQueue:true#开启磁盘多队列模式
disks:
-disk:
bus:virtio
name:win12-snap2-os#定义基于snap快速构建OS镜像
-disk:
bus:virtio
name:win12-snap2-data#定义RBD数据盘
interfaces:
-bridge:{}
name:default
networks:
-name:default
pod:{}
nodeSelector:
node-role.kubernetes.io/BIZ-Kubevirt:"true"
volumes:
-name:win12-snap2-os
persistentVolumeClaim:
claimName:win12-snap2-os
-name:win12-snap2-data
persistentVolumeClaim:
claimName:win12-snap2-data
启动VM
kubectlapply-fwin12-snap2-data.yaml
kubectlapply-fwin12-snap2-os.yaml
kubectlapply-fwin12-snap2.yaml
•VNC 部署(暴漏VM控制台)
wget
设置virtvnc namespace kubevirt
启动vnc服务
Kubectl apply -f virtvnc.yaml
•针对测试环境POD为暴漏,可通过ingress 提供服务
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:virtvnc
namespace:kubevirt
spec:
ingressClassName:nginx
rules:
-host:kubevnc.xxx.xxx.com
http:
paths:
-path:/
pathType:Prefix
backend:
service:
name:virtvnc
port:
number:8001
4.未来展望
深入k8s技术探索,推进kubevirt在非典型的容器化场景中解决用户棘手问题,帮助业务全面容器化,实现虚拟化技术栈统一,实现之家技术全面容器化最后一公里。