ITPub博客

首页 > 云计算 > Docker/K8 > 浅谈kubevirt在之家落地

浅谈kubevirt在之家落地

Docker/K8 作者:ITPUB社群 时间:2023-07-20 09:32:13 0 删除 编辑

来源:之家技术

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

组件说明

  1. Virt-api:是一个 RESTful API 服务器,提供了一系列的 API 接口来管理和操作 KubeVirt 中的虚拟机资源,virt-api 支持多种虚拟机资源类型,基于API 进行管理和操作

  2. Virt-controller: 负责监控 k8s集群中的虚拟机资源,并根据用户定义的规则自动调整资源分配,负责管理虚拟机生命周期管理,它通过自动化资源分配、弹性扩展、监控和报警等功能

  3. Virt-handler: 是 KubeVirt 的一个核心组件,它运行在 k8s 集群中每个节点上,并负责管理和监控节点上的虚拟机资源,监控虚拟机事件,维护节点状态,实现自动化管理和部署

  4. Virt-launcher: 负责在 k8s集群中启动和管理虚拟机实例, 通过管理虚拟机生命周期、支持多种虚拟化技术、提供安全性和高可用性等功能

  5. Virt-vnc: 是 KubeVirt的一个核心组件,它提供了一种 VNC 远程访问虚拟机的方式,使得用户可以通过 VNC 客户端远程访问和操作虚拟机, 支持多种虚拟化技术、提供安全性和高可用性等功能

  6. CDI: (Containerized Data Importer)是 KubeVirt 的一个组件,它提供了一种在 k8s 集群中导入、管理和使用虚拟机镜像的方式

  7. Ceph-csi: 是k8s存储插件,它可以将 Ceph 存储集成到 k8s 集群中,并提供了一系列的 API 接口来管理和操作 Ceph 存储并集成到k8s集群中,实现了高效、可靠的存储服务。

  8. External-snapshotter:是 k8s 的一个存储插件,它可以将外部存储系统的快照(Snapshot)集成到 k8s 集群中,并通过 API 接口提供了快照管理和操作功能。

  9. 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 
(2)镜像启动
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配置


• 针对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镜像地址设置为私有镜像仓库地址

      创建服务

Kubectl apply -f cdi-operator.yaml
Kubectl apply -f cdi-cr.yaml

      检查服务

• Kubevirt 部署

       下载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-csi 部署

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

• ceph csi 相关配置


  下载ceph-csi包

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

             Csi-rbd-sc配置
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 
              Csi rbd secret 配置,userKey 可通过ceph auth获取
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"

             Csi-rbdplugin kms 配置去除
#- 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

 服务检查


• External-snapshotter 部署  

  下载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

• 创建系统镜像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

kubectl apply -f snapshotclass.yaml
kubectl apply -f windows-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

kubectl apply -f win12-snap2-data.yaml
kubectl apply -f win12-snap2-os.yaml
kubectl apply -f win12-snap2.yaml


•  VNC 部署(暴漏VM控制台) 

wget https://github.com/wavezhang/virtVNC/raw/master/k8s/virtvnc.yaml

设置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在非典型的容器化场景中解决用户棘手问题,帮助业务全面容器化,实现虚拟化技术栈统一,实现之家技术全面容器化最后一公里。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024420/viewspace-2965242/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2022-11-21

  • 博文量
    1090
  • 访问量
    546620