kubevirt存储

五、KubeVirt存储

KubeVirt提供了很多种存储方式,存储就决定了你使用虚拟机镜像到底什么内核、什么版本,三种比较常用的形式虚拟机镜像(磁盘)是启动虚拟机必不可少的部分,目前KubeVirt中提供多种方式的虚拟机磁盘。

◎cloudInitNoCloud/cloudInitConfigDrive:用于提供 cloud-init 初始化所需要的 user-data,使用 configmap 作为数据源,此时VMI 内部将出现第二块大约为356KB的第二块硬盘

◎dataVolume:虚拟机启动流程中自动将虚拟机磁盘导入 pvc 的功能,在不使用 DataVolume 的情况下,用户必须先准备带有磁盘映像的 PVC,然后再将其分配给 VM 或 VMI。dataVolume 拉取镜像的来源可以是HTTP、PVC。

◎PersistentVolumeClaim: PVC 做为后端存储,适用于数据持久化,即在虚拟机重启或关机后数据依然存在。PV 类型可以是 block 和 filesystem,为 filesystem 时,将使用 PVC 上的 disk.img,格式为 RAW 格式的文件作为硬盘。block 模式时,使用 block volume 直接作为原始块设备提供给虚拟机。缺点在于仅支持RAW格式镜像,若镜像较大CDI 导入镜像会比较慢(如果是QCW2 CDI 内部机制qemu.go 会将其进行格式转换为RAW并导入PVC中),因此降低快速创建 VMI 体验感

◎ephemeral、containerDisk: 数据是无法持久化,故在存储选型上,我们采用 CEPH 作为后端存储,通过调用Ceph CSI 插件创建 PVC 卷方式管理虚机磁盘设备。Ceph CSI 插件实现了容器存储编排与Ceph集群交互的接口,它可以为容器应用分配 存储集群中的存储空间,同时在选择 Ceph-CSI 版本需要考虑到当前 K8S 版本、及 CEPH 版本号

◎registryDisk

定义image来创建虚拟机的root disk。 virt-controller会在pod定义中创建registryVolume的container,container中的entry服务负责 将spec.volumes.registryDisk.image转化为qcow2格式,路径为pod根目录。

创建默认存储

我们知道创建PV,PVC有两种方法,一个是静态,一个是动态

静态就是手动编写PV,PVC资源清单,然后再将他们进行绑定

动态就是创建一个存储类:StorageClass,然后我们只需要编写PVC的资源清单即可,它会给我们自动创建PV,然后和PVC进行绑定

5.1部署NFS服务(动态)

# 在每个机器。

yum install -y nfs-utils

# 在master 执行以下命令

echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

# 执行以下命令,启动 nfs 服务;创建共享目录

mkdir -p /nfs/data

# 在master执行

systemctl enable rpcbind

systemctl enable nfs-server

systemctl start rpcbind

systemctl start nfs-server

# 使配置生效

exportfs -r

#检查配置是否生效

exportfs

5.2配置存储类

只需修改两部分:就是把NFS服务端的IP修改为自己的即可

## 创建了一个存储类

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

  name: nfs-storage

  annotations:

    storageclass.kubernetes.io/is-default-class: "true"

provisioner: k8s-sigs.io/nfs-subdir-external-provisioner

parameters:

  archiveOnDelete: "true"  ## 删除pv的时候,pv的内容是否要备份

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: nfs-client-provisioner

  labels:

    app: nfs-client-provisioner

  # replace with namespace where provisioner is deployed

  namespace: default

spec:

  replicas: 1

  strategy:

    type: Recreate

  selector:

    matchLabels:

      app: nfs-client-provisioner

  template:

    metadata:

      labels:

        app: nfs-client-provisioner

    spec:

      serviceAccountName: nfs-client-provisioner

      containers:

        - name: nfs-client-provisioner

          image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2

          # resources:

          #    limits:

          #      cpu: 10m

          #    requests:

          #      cpu: 10m

          volumeMounts:

            - name: nfs-client-root

              mountPath: /persistentvolumes

          env:

            - name: PROVISIONER_NAME

              value: k8s-sigs.io/nfs-subdir-external-provisioner

            - name: NFS_SERVER

              value: 172.31.0.4 ## 指定自己nfs服务器地址

            - name: NFS_PATH  

              value: /nfs/data  ## nfs服务器共享的目录

      volumes:

        - name: nfs-client-root

          nfs:

            server: 172.31.0.4

            path: /nfs/data

---

apiVersion: v1

kind: ServiceAccount

metadata:

  name: nfs-client-provisioner

  # replace with namespace where provisioner is deployed

  namespace: default

---

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: nfs-client-provisioner-runner

rules:

  - apiGroups: [""]

    resources: ["nodes"]

    verbs: ["get", "list", "watch"]

  - apiGroups: [""]

    resources: ["persistentvolumes"]

    verbs: ["get", "list", "watch", "create", "delete"]

  - apiGroups: [""]

    resources: ["persistentvolumeclaims"]

    verbs: ["get", "list", "watch", "update"]

  - apiGroups: ["storage.k8s.io"]

    resources: ["storageclasses"]

    verbs: ["get", "list", "watch"]

  - apiGroups: [""]

    resources: ["events"]

    verbs: ["create", "update", "patch"]

---

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: run-nfs-client-provisioner

subjects:

  - kind: ServiceAccount

    name: nfs-client-provisioner

    # replace with namespace where provisioner is deployed

    namespace: default

roleRef:

  kind: ClusterRole

  name: nfs-client-provisioner-runner

  apiGroup: rbac.authorization.k8s.io

---

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  # replace with namespace where provisioner is deployed

  namespace: default

rules:

  - apiGroups: [""]

    resources: ["endpoints"]

    verbs: ["get", "list", "watch", "create", "update", "patch"]

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  # replace with namespace where provisioner is deployed

  namespace: default

subjects:

  - kind: ServiceAccount

    name: nfs-client-provisioner

    # replace with namespace where provisioner is deployed

    namespace: default

roleRef:

  kind: Role

  name: leader-locking-nfs-client-provisioner

  apiGroup: rbac.authorization.k8s.io

5.3应用,并查看StorageClass(sc)

上传镜像

KubeVirt 可以使用 PVC 作为后端磁盘,使用 filesystem 类型的 PVC 时,默认使用的时 /disk.img 这个镜像,用户可以将镜像上传到 PVC,在创建 VMI 时使用此 PVC。使用这种方式需要注意下面几点:

一个 PVC 只允许存在一个镜像,只允许一个 VMI 使用,要创建多个 VMI,需要上传多次

/disk.img 的格式必须是 RAW 格式

CDI 提供了使用使用 PVC 作为虚拟机磁盘的方案,在虚拟机启动前通过下面方式填充 PVC:

通过 URL 导入虚拟机镜像到 PVC,URL 可以是 http 链接,s3 链接

Clone 一个已经存在的 PVC

通过 container registry 导入虚拟机磁盘到 PVC,需要结合 ContainerDisk 使用

通过客户端上传本地镜像到 PVC

通过命令行 virtctl,结合 CDI 项目,可以上传本地镜像到 PVC 上,支持的镜像格式有:

.img

.qcow2

.iso

压缩为 .tar,.gz,.xz 格式的上述镜像

kubevirt 提供了registryDIsk的基础镜像: registry-disk-v1alpha, 根据Dockerfile形式去创建虚拟机镜像,以下是window镜像demo Dockerfile

FROM kubevirt/registry-disk-v1alpha

COPY Windows---server-2012-datacenter-64bit-cn-syspreped---2018-01-15.qcow2 /disk/windows2012dc.img

这个是最终构建成镜像名:windows2012dc:lastest,最终在CRD表现形式如下所示

kind: VirtualMachineInstance

...

spec:

 domain:

   devices:

     disks:

     - disk:

         bus: virtio

       name: registrydisk

       volumeName: registryvolume

... - name: registryvolume

   registryDisk:

     image: windows2012dc:latest

案例:(安装windows10虚拟机)

因为目标是安装windows10虚拟机,所以需要将上面下载好的windows镜像上传到PVC:

#参数讲解

--image-path='Win10_20H2_Chinese(Simplified)_x64.iso'    #指定Win镜像的路径,我们是在/root目录下,因此就这个路径即可。

--pvc-name=iso-win10         #指定PVC的名字

--pvc-size=7G                #指定PVC的大小,根据操作系统镜像大小来设定,一般略大一个G就行。

--uploadproxy-url=https://10.96.237.3         #cdi-uploadproxy 的 Service IP,可以通过命令 kubectl -n cdi get svc -l cdi.kubevirt.io=cdi-uploadproxy 来查看。

增加hostDisk支持

KubeVirt默认没有开启对hostDisk的支持,需要手动开启,这里我们直接editKubeVirt1的ConfigMap

apiVersion: v1

data:

  debug.useEmulation: "true"

  feature-gates: HostDisk              #添加这一行即可

kind: ConfigMap

metadata:

  creationTimestamp: "2022-04-17T01:19:05Z"

  name: kubevirt-config

  namespace: kubevirt

  resourceVersion: "46074"

  uid: 56ff5d51-1ce5-4c0e-bef2-7c2d24525306

5.4创建虚拟机

编写vm.yaml文件

apiVersion: kubevirt.io/v1alpha3

kind: VirtualMachine

metadata:

  name: win10

spec:

  running: false

  template:

    metadata:

      labels:

        kubevirt.io/domain: win10

    spec:

      domain:

        cpu:

          cores: 4

        devices:

          disks:

          - bootOrder: 1

            cdrom:

              bus: sata

            name: cdromiso

          - disk:

              bus: virtio

            name: harddrive

          - cdrom:

              bus: sata

            name: virtiocontainerdisk

          interfaces:

          - masquerade: {}

            model: e1000

            name: default

        machine:

          type: q35

        resources:

          requests:

            memory: 16G

      networks:

      - name: default

        pod: {}

      volumes:

      - name: cdromiso

        persistentVolumeClaim:

          claimName: iso-win10

      - name: harddrive

        hostDisk:

          capacity: 50Gi

          path: /data/disk.img

          type: DiskOrCreate

      - containerDisk:

          image: kubevirt/virtio-container-disk

        name: virtiocontainerdisk

这里用到了 3 个 Volume:

◎cdromiso : 提供操作系统安装镜像,即上文上传镜像后生成的 PVC iso-win10。

◎harddrive : 虚拟机使用的磁盘,即操作系统就会安装在该磁盘上。这里选择 hostDisk 直接挂载到宿主机以提升性能,如果使用分布式存储则体验非常不好。

◎containerDisk : 由于 Windows 默认无法识别 raw 格式的磁盘,所以需要安装 virtio 驱动。containerDisk 可以将打包好 virtio 驱动的容器镜像挂载到虚拟机中。

关于网络部分,spec.template.spec.networks 定义了一个网络叫 default,这里表示使用 Kubernetes 默认的 CNI。spec.template.spec.domain.devices.interfaces 选择定义的网络 default,并开启 masquerade,以使用网络地址转换 (NAT) 来通过 Linux 网桥将虚拟机连接至 Pod 网络后端。

  1. 使用模版文件创建虚拟机

kubectl apply -f win10.yaml

virtctl start win10

#查看VM,VMI,Pod状态

示例:创建本地存储

创建一个本地存储目录

[root@k8s-master ~]# sudo mkdir -p /mnt/local-storage

[root@k8s-master ~]# sudo chmod 777 /mnt/local-storage

创建一个 PersistentVolume (PV) 配置文件 local-pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

  name: local-pv

spec:

  capacity:

    storage: 10Gi

  accessModes:

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  storageClassName: local-storage

  local:

    path: /mnt/local-storage

  nodeAffinity:

    required:

      nodeSelectorTerms:

      - matchExpressions:

        - key: kubernetes.io/hostname

          operator: In

          values:

          - <NODE_NAME>

应用配置

[root@k8s-master ~]# kubectl apply -f  local-pv.yaml

创建一个 StorageClass 配置文件 local-storage-class.yaml

[root@k8s-master ~]# vi local-storage-class.yaml

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

  name: local-storage

provisioner: kubernetes.io/no-provisioner

volumeBindingMode: WaitForFirstConsumer

应用配置

[root@k8s-master ~]# kubectl apply -f local-storage-class.yaml

创建PVC

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: test-pvc

spec:

  accessModes:

    - ReadWriteOnce

  storageClassName: local-storage

  resources:

    requests:

      storage: 5Gi

创建文件后,应用配置

[root@k8s-master ~]# kubectl apply -f pvc.yaml

查看PV和PVC是否绑定成功

如果绑定成功,STATUS 应该显示为 Bound

[root@k8s-master ~]# kubectl get pv my-pv

[root@k8s-master ~]# kubectl get pvc my-vm-pvc

创建虚拟机并绑定PVC

创建vmq.yaml文件定义一个 KubeVirt 虚拟机,并将刚创建的 PVC 挂载为虚拟机的磁盘

[root@k8s-master ~]# vi vmq-yaml

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

  name: testvm

spec:

  running: false

  template:

    spec:

      domain:

        resources:

          requests:

            memory: 1024M

        devices:

          disks:

          - name: containerdisk

            disk:

              bus: virtio

          - name: datavolumedisk1

            disk:

              bus: virtio

      volumes:

      - name: containerdisk

        containerDisk:

          image: kubevirt/cirros-container-disk-demo:latest

      - name: datavolumedisk1

        persistentVolumeClaim:

          claimName: test-pvc

应用yaml文件并启动虚拟机,验证虚拟机的状态

[root@k8s-master ~]# kubect apply -f vmq-yaml

[root@k8s-master ~]# virtctl start testvmq

进入虚拟机控制台,查看磁盘情况

[root@k8s-master ~]# virtctl console testvm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值