一、使用iso镜像、qcow2或raw文件创建虚拟机
注意:此方案需要部署CDI、Hostpath-provisioner以及virtctl,安装详见部署章节
镜像相关链接:
- raw与qcow2的区别: https://lhw-tyut.github.io/2019/05/27/raw%E4%B8%8Eqcow2%E7%9A%84%E5%8C%BA%E5%88%AB
- ISO 转换qcow2:http://www.ahanwhite.com/archives/qemu-convert-iso-to-qcow2-or-raw
- QCOW2/RAW/qemu-img 概念浅析:https://developer.aliyun.com/article/237275
进入正题,要想使用镜像启动虚拟机首先需要将镜像转换为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