首页 > 云计算 > Docker/K8 > 浅谈kubevirt在之家落地
来源:之家技术
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 -n windows2012 -f /data/centos74.img -s 120 -r 16384 -v --vcpus=16 --vnc ---cdrom=/mnt/windows2012
virt-install -n windows2012 -f /data/centos74.img -s 120 -r 16384 -v --vcpus=16 --vnc ---cdrom=/mnt/windows2012
(3)系统标准化
完善系统基础服务安装包定制、系统分区、系统安全、内核参数等标准化定制
开机启动(init)脚本:实现系统启动后网络配置自动生成,Salt Agent网络可达
数据盘格式化:虚拟机交付后可实现PVC 卷格式化并自动挂载/data目录
因kubevirt 采用组件较多,验证较稳定版本,可上传至内部镜像(harbor)仓库,实现组件版本统一,避免线上自动更新最新版本引起不可逆问题

选择版本是需经过多维度测试,建议选择较新且稳定版,避免出现未知问题影响生产业务
(1)CDI 部署(采用v1.55.0版本)
下载cdi yaml文件
https://github.com/kubevirt/containerized-data-importer/releases/download/v1.55.0/cdi-cr.yaml
https://github.com/kubevirt/containerized-data-importer/releases/download/v1.55.0/cdi-operator.yaml核心cdi-cry配置
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
创建服务
Kubectl apply -f cdi-operator.yaml
Kubectl apply -f cdi-cr.yaml检查服务

下载yaml文件
https://github.com/kubevirt/kubevirt/releases/download/v0.55.2/kubevirt-cr.yaml
https://github.com/kubevirt/kubevirt/releases/download/v0.55.2/kubevirt-operator.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 私有镜像地址
创建服务
Kubectl apply -f kubevirt-operator.yaml
Kubectl apply -f kubevirt-cr.yaml检查服务

Ceph RBD 集群环境部署暂且不在论述,通过ceph csi实现Ceph 存储并集成到k8s集群,管理 pod/vmi pvc存储应用
Kubevirt pool 创建
ceph osd pool create kubevirt 1024
创建Ceph rbd Key 实现k8s对RBD 管理
ceph auth get-or-create client.kubevirt mon 'profile rbd' osd 'profile rbd pool=kubevirt' mgr 'profile rbd pool=kubevirt'
获取kubevirt key
ceph auth ls |grep kubevirt -A 1
wget https://github.com/ceph/ceph-csi/archive/refs/tags/v3.7.2.tar.gz
tar -xzvf v3.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
kubectl apply -f cm-ceph-config.yaml
kubectl apply -f csi-config-map.yaml
kubectl apply -f csi-rbd-sc.yaml
kubectl apply -f secret-csi-rbd.yaml
kubectl apply -f csi-nodeplugin-rbac.yaml
kubectl apply -f csi-provisioner-rbac.yaml
kubectl apply -f csi-rbdplugin-provisioner.yaml
kubectl apply -f csi-rbdplugin.yaml
服务检查

wget 1. https://github.com/kubernetes-csi/external-snapshotter/archive/refs/tags/v6.1.0.tar.gz
tar -xzvf v6.1.0.tar.gz
cd ./external-snapshotter-6.1.0/client/config/crd
kubectl apply -f snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -f snapshot.storage.k8s.io_volumesnapshotclasses.yaml
cd ./kubevirt/external-snapshotter-6.1.0/deploy/Kubernetes/
kubectl create -f csi-snapshotter/
kubectl create -f snapshot-controller/检查服务
https://github.com/kubevirt/kubevirt/releases/download/v0.55.2/virtctl-v0.55.2-linux-amd64
cp -fr virtctl-v0.55.2-linux-amd64 /usr/bin//virtctl 获取cdi upload proxy 地址
kubectl get all -n kubevirt |grep 'cdi-uploadproxy'|grep 'ClusterIP'|awk '{print $3}'
上传镜像
virtctl image-upload --namespace=vm-windows-12 --pvc-size=129G --storage-class=csi-rbd-sc --pvc-name=windows2012 --image-path=/data/windows2012.qcow2 --uploadproxy-url=https://uploadproxy:ip –insecure

构建 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
kubectl apply -f snapshotclass.yaml
kubectl apply -f windows-snapshot.yaml获取volumesnapshot 状态
Kubectl get volumesnapshot -n vm-windows

创建数据磁盘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
kubectl apply -f win12-snap2-data.yaml
kubectl apply -f win12-snap2-os.yaml
kubectl apply -f win12-snap2.yaml
wget https://github.com/wavezhang/virtVNC/raw/master/k8s/virtvnc.yaml
启动vnc服务
Kubectl apply -f virtvnc.yaml
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在非典型的容器化场景中解决用户棘手问题,帮助业务全面容器化,实现虚拟化技术栈统一,实现之家技术全面容器化最后一公里。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024420/viewspace-2965242/ ,如需转载,请注明出处,否则将追究法律责任。