KubeVirt创建虚拟机

一、使用iso镜像、qcow2或raw文件创建虚拟机

注意:此方案需要部署CDI、Hostpath-provisioner以及virtctl,安装详见部署章节

镜像相关链接:

进入正题,要想使用镜像启动虚拟机首先需要将镜像转换为kubevirt可以识别的的磁盘(.img),并存储在指定位置

1.1 镜像上传转换

使用virtctl image-upload上传镜像到pvc

virtctl提供了image-upload上传镜像功能,上传的镜像文件会转化为img格式提供给虚拟机使用

virtctl image-upload \
  --image-path='CentOS-7-x86_64-DVD-2009.iso' \
  --storage-class hostpath-csi \
  --pvc-name=iso-centos \
  --pvc-size=5Gi \
  --uploadproxy-url=https://<cdi-uploadproxy_svc_ip> \
  --insecure \
  --wait-secs=240
  • –-image-path : 操作系统镜像的本地地址
  • –-pvc- : 指定存储运行镜像的PVC过程,这个PVC不需要提前准备好自动上传中会创建。
  • –-pvc-size:PVC大小,根据镜像大小来设置,一般略大一个G就行
  • –uploadproxy-url : cdi-uploadproxy 的Service IP,可以通过命令kubectl -n cdi get svc -l cdi.kubevirt.io=cdi-uploadproxy来查看。
[root@192 home]# virtctl image-upload   --image-path='CentOS-7-x86_64-GenericCloud-2009.qcow2'   --storage-class hostpath-csi   --pvc-name=iso-centos2009   --uploadproxy-url=https://10.245.68.78   --insecure   --pvc-size=100Gi --wait-secs=240 -n vlan
PVC default/iso-centos2009 not found
PersistentVolumeClaim default/iso-centos2009 created
Waiting for PVC iso-centos2009 upload pod to be ready...
Pod now ready
Uploading data to https://10.245.68.78

 847.81 MiB / 847.81 MiB [======================================================================================================================] 100.00% 14s

Uploading data completed successfully, waiting for processing to complete, you can hit ctrl-c without interrupting the progress

使用virtctl上传镜像会自动创建一个pod,该pod会将差上传的镜像转换为img

注意:virtctl可以使用-n创建pvc到指定命名空间下

创建转换镜像流程:

  • 执行上传命令,自动创建PV、PVC(以上面创建为例:iso-centos2009、iso-centos2009-scratch)其中iso-centos2009-scratch这个PVC会保存上传的镜像文件,iso-centos2009存储转换后的img
  • 自动创建POD(cdi-upload-iso-centos2009)挂载上述PVC进行镜像转换和存储
  • 完毕后自动删除POD以及iso-centos2009-scratch的PVC

PVC自动创建

[root@192 vlan]# kubectl get pvc
NAME                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
iso-centos2009           Bound    pvc-2bd2449b-0007-4c7b-932b-6ee692b968f2   406Gi      RWO            hostpath-csi   4s
iso-centos2009-scratch   Bound    pvc-02311cf9-78f0-49c5-9a4e-9df7328e18b6   406Gi      RWO            hostpath-csi   4s

POD内日志

I0111 07:29:32.151184       1 uploadserver.go:74] Running server on 0.0.0.0:8443
I0111 07:29:36.539835       1 uploadserver.go:325] Content type header is ""
I0111 07:29:36.539883       1 data-processor.go:379] Calculating available size
I0111 07:29:36.539934       1 data-processor.go:391] Checking out file system volume size.
I0111 07:29:36.540026       1 data-processor.go:399] Request image size not empty.
I0111 07:29:36.540119       1 data-processor.go:404] Target size 100Gi.
I0111 07:29:36.540221       1 data-processor.go:282] New phase: TransferScratch
I0111 07:29:36.540394       1 util.go:192] Writing data...
I0111 07:29:49.912632       1 data-processor.go:282] New phase: ValidatePause
I0111 07:29:49.912695       1 data-processor.go:288] Validating image
I0111 07:29:50.489733       1 data-processor.go:282] New phase: Pause
I0111 07:29:50.489849       1 uploadserver.go:368] Returning success to caller, continue processing in background
I0111 07:29:50.490286       1 data-processor.go:193] Resuming processing at phase Convert
I0111 07:29:50.490335       1 data-processor.go:288] Validating image
使用qemu-img工具进行转换

此方案不依赖于kubevirt,转换完成后可使用任意形式的存储方式提供给kubevirt。如HostDisk或PVC等,这里不做过多说明,参见文章:https://blog.csdn.net/cloudvtech/article/details/105590034

1.2 编写VM文件

这里的VM文件是指创建kubevirt自定义CRD(VirtualMachine)的CR声明文件

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
  name: centos2009
  namespace: vlan
spec:
  running: true   # 此处设置为true创建vm后即自动创建vmi启动虚拟机
  template:
    metadata:
      labels:
        kubevirt.io/domain: centos2009
      annotations:
        ovn.kubernetes.io/logical_switch: mail263
        ovn.kubernetes.io/ip_address: 192.168.10.190
    spec:
      domain:
        cpu:
          cores: 1
        devices:
          disks:
          - disk:
              bus: virtio
            name: cdromiso
          - disk:
              bus: virtio
            name: cloudinitdisk
          interfaces:
          - masquerade: {}
            model: e1000
            name: default
        machine:
          type: q35
        resources:
          requests:
            memory: 2Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - name: cdromiso
        persistentVolumeClaim:
          claimName: iso-centos2009
      - cloudInitNoCloud:
          networkData: |-
            network:
              version: 1
              config:
                - type: physical
                  name: eth0
                  subnets:
                    - type: dhcp
          userData: |-
            #cloud-config
            disable_root: false
            ssh_pwauth: true
            users:
              - default
              - name: root
                lock_passwd: false
                hashed_passwd: $1$4t.w.u.X$BkdPjEOi30r85GpIaTZ8C1  # 密码:12345678
        name: cloudinitdisk

二、使用容器镜像创建虚拟机

此方案使用了kubevirt的containerDisk存储方案,需要额外注意,改方案创建的虚拟机每次重启系统盘都会重置,系统盘的数据不能持久化,每一次重启都是一个全新的虚拟机。

2.1 构建系统镜像image

官方文档:https://kubevirt.io/user-guide/virtual_machines/disks_and_volumes/#containerdisk

下载系统qcow2或raw文件

cat << END > Dockerfile
FROM kubevirt/registry-disk-v1alpha
ADD --chown=107:107 fedora25.qcow2 /disk/
END

docker build -t xxx .
docker push xxx

2.2 使用docker image 创建虚拟机系统

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  labels:
  name: centos
  namespace: vlan
spec:
  running: true
  template:
    metadata:
      annotations:
        ovn.kubernetes.io/logical_switch: mail263
        ovn.kubernetes.io/ip_address: 192.168.10.181
    spec:
      domain:
        devices:
          disks:
          - disk:
              bus: virtio
            name: cdromiso
          - disk:
              bus: virtio
            name: cloudinitdisk
          interfaces:
          - bridge: {}
            name: default
        machine:
          type: q35
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: "1"
            memory: 2Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - name: cdromiso
        containerDisk:
          image: harbor.mrlch.cn/kubevirt/centos:1805-1
      - cloudInitNoCloud:
          networkData: |-
            network:
              version: 1
              config:
                - type: physical
                  name: eth0
                  subnets:
                    - type: dhcp
          userData: |-
            #cloud-config
            disable_root: false
            ssh_pwauth: true
            users:
              - default
              - name: root
                lock_passwd: false
                hashed_passwd: $1$4t.w.u.X$BkdPjEOi30r85GpIaTZ8C1
        name: cloudinitdisk

使用该方式创建的虚拟机启动的pod包含2个Init Containers和2个Containers

 initContainers:
    - name: container-disk-binary
      image: quay.io/kubevirt/virt-launcher:v0.58.0
      command:
        - /usr/bin/cp
        - /usr/bin/container-disk
        - /init/usr/bin/container-disk
...
      volumeMounts:
        - name: virt-bin-share-dir
          mountPath: /init/usr/bin
      securityContext:
        privileged: false
        runAsUser: 0
        runAsNonRoot: false
    - name: volumecdromiso-init
      image: home.mrlch.cn:8888/kubevirt/centos:1805-1
      command:
        - /usr/bin/container-disk
      args:
        - '--no-op'
...
      volumeMounts:
        - name: container-disks
          mountPath: >-
            /var/run/kubevirt-ephemeral-disks/container-disk-data/c3dcbe96-165f-4f07-9b79-836e5669abd1
        - name: virt-bin-share-dir
          mountPath: /usr/bin
      securityContext:
        runAsUser: 107
        runAsNonRoot: true
  containers:
    - name: compute
      image: quay.io/kubevirt/virt-launcher:v0.58.0
      command:
        - /usr/bin/virt-launcher-monitor
        - '--qemu-timeout'
        - 301s
        - '--name'
        - centos
        - '--uid'
        - c3dcbe96-165f-4f07-9b79-836e5669abd1
        - '--namespace'
        - vlan
        - '--kubevirt-share-dir'
        - /var/run/kubevirt
        - '--ephemeral-disk-dir'
        - /var/run/kubevirt-ephemeral-disks
        - '--container-disk-dir'
        - /var/run/kubevirt/container-disks
        - '--grace-period-seconds'
        - '45'
        - '--hook-sidecars'
        - '0'
        - '--ovmf-path'
        - /usr/share/OVMF
      env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
      volumeMounts:
        - name: private
          mountPath: /var/run/kubevirt-private
        - name: public
          mountPath: /var/run/kubevirt
        - name: ephemeral-disks
          mountPath: /var/run/kubevirt-ephemeral-disks
        - name: container-disks
          mountPath: /var/run/kubevirt/container-disks
          mountPropagation: HostToContainer
        - name: libvirt-runtime
          mountPath: /var/run/libvirt
        - name: sockets
          mountPath: /var/run/kubevirt/sockets
        - name: data
          mountPath: /var/run/kubevirt-private/vmi-disks/data
        - name: hotplug-disks
          mountPath: /var/run/kubevirt/hotplug-disks
          mountPropagation: HostToContainer
      securityContext:
        capabilities:
          add:
            - NET_BIND_SERVICE
            - SYS_PTRACE
            - SYS_NICE
          drop:
            - NET_RAW
        privileged: false
        runAsUser: 0
        runAsNonRoot: false
    - name: volumecdromiso
      image: home.mrlch.cn:8888/kubevirt/centos:1805-1
      command:
        - /usr/bin/container-disk
      args:
        - '--copy-path'
        - >-
          /var/run/kubevirt-ephemeral-disks/container-disk-data/c3dcbe96-165f-4f07-9b79-836e5669abd1/disk_0
      volumeMounts:
        - name: container-disks
          mountPath: >-
            /var/run/kubevirt-ephemeral-disks/container-disk-data/c3dcbe96-165f-4f07-9b79-836e5669abd1
        - name: virt-bin-share-dir
          mountPath: /usr/bin
      securityContext:
        seLinuxOptions:
          type: virt_launcher.process
        runAsUser: 107
        runAsNonRoot: true

三、使用dataVolumeTemplates+docker镜像创建虚拟机

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: bigdata-01
  namespace: vlan
spec:
  dataVolumeTemplates:
  - metadata:
      name: bigdata-01-rootfs
    spec:
      pvc:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: hostpath-csi
      source:
        registry:
          url: docker://harbor.mrlch.cn/kubevirt/opencloudos:v8.6-latest  # 需要使用https协议的仓库
  running: true   # 此处设置为true创建vm后即自动创建vmi启动虚拟机
  template:
    metadata:
      annotations:
        ovn.kubernetes.io/ip_pool: 192.168.10.191  # kube-ovn固定IP方法,参见kube-ovn文档
    spec:
      domain:
        devices:    # 磁盘
          disks:
          - disk:
              bus: virtio
            name: rootfs
          - disk:
              bus: virtio
            name: cloudinitdisk
          interfaces:
          - bridge: {}
            name: default
        machine:
          type: q35
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: "1"
            memory: 2Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - dataVolume:
          name: bigdata-01-rootfs
        name: rootfs
      - cloudInitNoCloud:
          networkData: |-
            network:
              version: 1
              config:
                - type: physical
                  name: eth0
                  subnets:
                    - type: dhcp
          userData: |-
            #cloud-config
            disable_root: false
            ssh_pwauth: true
            users:
              - default
              - name: root
                lock_passwd: false
                hashed_passwd: $1$4t.w.u.X$BkdPjEOi30r85GpIaTZ8C1
        name: cloudinitdisk

注意:registry的镜像地址需要使用https协议

挂载数据盘

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: bigdata-01
  namespace: vlan
spec:
  dataVolumeTemplates:
  - metadata:
      name: bigdata-01-rootfs
    spec:
      pvc:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: hostpath-csi
      source:
        registry:
          url: docker://harbor.mrlch.cn/kubevirt/opencloudos:v8.6-latest
  - metadata:
      name: bigdata-01-data
    spec:
      pvc:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: hostpath-csi
      source:
        blank: {}
  running: true
  template:
    metadata:
      annotations:
        ovn.kubernetes.io/ip_pool: 192.168.10.191
    spec:
      domain:
        devices:
          disks:
          - disk:
              bus: virtio
            name: rootfs
          - disk:
              bus: virtio
            name: bigdata-01-data
          - disk:
              bus: virtio
            name: cloudinitdisk
          interfaces:
          - bridge: {}
            name: default
        machine:
          type: q35
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: "1"
            memory: 2Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - dataVolume:
          name: bigdata-01-rootfs
        name: rootfs
      - dataVolume:
          name: bigdata-01-data
        name: bigdata-01-data
      - cloudInitNoCloud:
          networkData: |-
            network:
              version: 1
              config:
                - type: physical
                  name: eth0
                  subnets:
                    - type: dhcp
          userData: |-
            #cloud-config
            disable_root: false
            ssh_pwauth: true
            users:
              - default
              - name: root
                lock_passwd: false
                hashed_passwd: $1$4t.w.u.X$BkdPjEOi30r85GpIaTZ8C1
        name: cloudinitdisk

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code