この記事の内容
KubeVirtでVMを作るときの流れは、ざっくり、
- 仮想ディスクを作る
- VMを作る
です。この仮想ディスクの作り方について、バリエーションが多いため整理し、役に立つと思われるパターンについて、実施例を示してみます。
環境
マシン一覧
- 物理PCを2台使用。KVMの仮想化環境を作成。
- KVMで3VM(AlmaLinux 9.5)作り、Masterノードx1、Workerノードx2にしてk8sクラスタを構成。
k8sクラスタ環境
-
k8sクラスタに対し、以下をインストール済み。
-- MetalLB(ロードバランサ用)
-- kubernetes-dashboard(k8sクラスタの各リソース表示確認など)
-- NFS Subdir External Provisioner(NFSのStorageClass用。名前はnfs-client)
-- KubeVirt(VM作成用) -
また、k8sクラスタ内のMasterノード、k8sクラスタ外のwindows11とAlmaLinux9.5(al9host)には、kubectlコマンドとkubectl virtコマンドをインストール済みであり、k8sクラスタの操作が可能。
-
KubeVirtで3VM(RockyLinux 9.5)作成済み。
1. 試すパターン
仮想ディスクの作り方として、(あまり意味のない方法を含めて)パターン的に、このような方法が挙げられます(他にもあるかもですが、思いつくところで)。
-
VMから見た仮想ディスク
-- PVCを使う
-- DataVolumeを使う(実体はPVC) -
PVの作り方
-- StorageClassから切り出す
-- PVのyamlから作る -
disk.imgの作り方
-- WebのファイルURLを指定
-- ローカルファイルを指定
これらの方法は、
(1) PVCのyamlを作成。PVはStorageClassから切り出す。disk.imgはWebURL指定。
(2) (1)の内、PVはyamlから作る。
(3) PVCをコマンドで作成。PVはStorageClassから切り出す。disk.imgはローカルファイル指定。
(4) DataVolumeのyamlを作成。基本的に(1)と同じ。
のやり方が分かれば、一通り網羅的に、仮想ディスクの作り方を把握できるのではないかと思います。
以降、この(1)~(4)の方法で、仮想ディスクを作り、VMを作る方法を、それぞれ、示してみます。いずれも、RockyLinux9.5のマシンイメージから、VMを作ります。
2. (1)の方法(PVCのyamlを作成/PVはStorageClassから切り出す/disk.imgはWebURL指定)
この(1)の方法は、以下で示した方法そのものです(名前などは違いますがやり方は同じ)。
以下、要点だけ示します。
(1) 実施前のPVC/PV確認
PVCリソースはありません。
[root@master1 kubevirt-test]# kubectl get pvc
No resources found in kubevirt-test namespace.
[root@master1 kubevirt-test]#
PVリソースは、これまでに作った3VMの4つのPVが表示されています(ルートディスク3つとISOディスク1つ)。
[root@master1 kubevirt-test]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-074aba38-5b71-4b55-9d79-8910430cf271 30Gi RWO Delete Bound default/rl95vm-3cockpit nfs-client <unset> 25h
pvc-d02a3efe-c6b7-4ea7-8ee4-0d14268615b0 15Gi RWO Delete Bound default/rocky-iso-9.5 nfs-client <unset> 28h
pvc-e6774427-e7b7-48de-921d-f04604076125 18Gi RWO Delete Bound default/rl95vm-2-rootdisk nfs-client <unset> 28h
pvc-f5fcfd71-0604-4476-aebe-8f93f007b1b3 16Gi RWO Delete Bound default/rocky-9.5-20241118 nfs-client <unset> 7d4h
[root@master1 kubevirt-test]#
なお、kubevirt-testのnamespaceを作りセットしています。以下のように、namespaceのyamlファイルを作って適用し、
[root@master1 kubevirt-test]# vim kubevirt-test-namespace.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat kubevirt-test-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: kubevirt-test
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./kubevirt-test-namespace.yaml
namespace/kubevirt-test created
[root@master1 kubevirt-test]#
これで、作成したnamespaceに切り替わりました。
[root@master1 kubevirt]# kubectl config set-context --current --namespace=kubevirt-test
Context "kubernetes-admin@kubernetes" modified.
[root@master1 kubevirt]#
[root@master1 kubevirt-test]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin kubevirt-test
[root@master1 kubevirt-test]#
(2) PVCをyamlから作成(StorageClass、URL)
PVCリソースのyamlを作り、適用します。
[root@master1 kubevirt-test]# vim test1-1-yaml-sc-url-pvc.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-1-yaml-sc-url-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test1-1-yaml-pv-url-pvc
labels:
app: containerized-data-importer
annotations:
cdi.kubevirt.io/storage.import.endpoint: "https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2"
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 11Gi
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-1-yaml-sc-url-pvc.yaml
persistentvolumeclaim/test1-2-yaml-pv-url-pvc created
[root@master1 kubevirt-test]#
(3) 実施後のPVC/PV確認
PVCリソースが作られました。
[root@master1 kubevirt-test]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test1-1-yaml-pv-url-pvc Bound pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO nfs-client <unset> 4m55s
[root@master1 kubevirt-test]#
PVリソースも、StorageClassから切り出されて作られています。
[root@master1 kubevirt-test]# kubectl get pv | grep -e NAME -e kubevirt-test
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO Delete Bound kubevirt-test/test1-1-yaml-pv-url-pvc nfs-client <unset> 4m53s
[root@master1 kubevirt-test]#
PV(実体はNFSサーバのディレクトリ)には、disk.imgが作られています。
[root@al9host sc-nfs]# qemu-img info kubevirt-test-test1-1-yaml-pv-url-pvc-pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f/disk.img
image: kubevirt-test-test1-1-yaml-pv-url-pvc-pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f/disk.img
file format: raw
virtual size: 10.4 GiB (11161042944 bytes)
disk size: 1.27 GiB
Child node '/file':
filename: kubevirt-test-test1-1-yaml-pv-url-pvc-pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f/disk.img
protocol type: file
file length: 10.4 GiB (11161042944 bytes)
disk size: 1.27 GiB
[root@al9host sc-nfs]#
(4) VM起動
Vmリソースのyamlを作り、適用して、VMを起動します。
[root@master1 kubevirt-test]# vim test1-1-vm.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-1-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
labels:
kubevirt.io/os: linux
name: test1-1-vm
spec:
runStrategy: Always
template:
metadata:
creationTimestamp: null
labels:
kubevirt.io/domain: test1-1-vm
spec:
domain:
cpu:
cores: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- cdrom:
bus: sata
readonly: true
name: cloudinitdisk
machine:
type: q35
resources:
requests:
memory: 1024M
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: test1-1-yaml-pv-url-pvc
- cloudInitNoCloud:
userData: |
#cloud-config
hostname: test1-1guest
users:
- name: myuser
ssh_pwauth: true
chpasswd:
list: |
root:initpasswd
myuser:initpasswd
expire: False
name: cloudinitdisk
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl create -f ./test1-1-vm.yaml
virtualmachine.kubevirt.io/test1-1-vm created
[root@master1 kubevirt-test]#
(5) VMへのsshログイン
Vmiリソースの情報を表示してIPアドレスを確認します。
[root@master1 kubevirt-test]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
test1-1-vm 23s Running 10.244.1.95 worker1.internal True
[root@master1 kubevirt-test]#
VMのIPアドレスを指定して、sshでログインできました。
[root@master1 kubevirt-test]# ssh myuser@10.244.1.95
The authenticity of host '10.244.1.95 (10.244.1.95)' can't be established.
ED25519 key fingerprint is SHA256:NvEdt7uQJglFs70a5iptHoaZ86nmYfoXVP6UuTw3GNE.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.244.1.95' (ED25519) to the list of known hosts.
myuser@10.244.1.95's password:
[myuser@test1-1-vm ~]$
3. (2)の方法(PVCのyamlを作成/PVはyamlから作る/disk.imgはWebURL指定)
正直、StorageClassからPVを切り出す方が便利だし、特にStorageClassを使うことにデメリットがあるわけでもないため、こういうやり方も一応ありますよ、程度で。
(1) PVをyamlから作成(StorageClass)
PVリソースのyamlを作り、適用します。
[root@master1 kubevirt-test]# vim test1-2-yaml-pv-url-pv.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-2-yaml-pv-url-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test1-2-yaml-pv-url-pv
spec:
storageClassName: nfs-client
capacity:
storage: 12Gi
accessModes:
- ReadWriteOnce
nfs:
path: /root/sc-nfs/test1-2-yaml-pv-url-pv
server: 192.168.11.103
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-2-yaml-pv-url-pv.yaml
persistentvolume/test1-2-yaml-pv-url-pv created
[root@master1 kubevirt-test]#
この場合、StorageClassのNFSサーバのディレクトリには、「path: /root/sc-nfs/test1-2-yaml-pv-url-pv」で指定したディレクトリが自動的に作られないため、手動で作る必要があります。
ここだけ、NFSサーバのal9hostでやります。
[root@al9host sc-nfs]# mkdir test1-2-yaml-pv-url-pv; chmod 777 test1-2-yaml-pv-url-pv
[root@al9host sc-nfs]#
(2) 実施後のPV確認
PVリソースが作られました。PVCにバインドされていないため、STATUSがAvailableです。あと、上のyamlの場合、RECLAIM POLICYがRetainになっています(バインドしたPVCを消しても、PVのSTATUSがReleasedになり残る)
[root@master1 kubevirt-test]# kubectl get pv | grep -e NAME -e test
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO Delete Bound kubevirt-test/test1-1-yaml-pv-url-pvc nfs-client <unset> 143m
test1-2-yaml-pv-url-pv 12Gi RWO Retain Available nfs-client <unset> 58s
[root@master1 kubevirt-test]#
(3) PVCをyamlから作成(StorageClass、URL)
PVCリソースのyamlを作り、適用します。
[root@master1 kubevirt-test]# vim ./test1-2-yaml-pv-url-pvc.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat ./test1-2-yaml-pv-url-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test1-2-yaml-pv-url-pvc
labels:
app: containerized-data-importer
annotations:
cdi.kubevirt.io/storage.import.endpoint: "https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2"
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 12Gi
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-2-yaml-pv-url-pvc.yaml
persistentvolumeclaim/test1-2-yaml-pv-url-pvc created
[root@master1 kubevirt-test]#
(4) 実施後のPVC/PV確認
PVCリソースが作られました。先に作成しておいたPVがバインドされています。
[root@master1 kubevirt-test]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test1-1-yaml-pv-url-pvc Bound pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO nfs-client <unset> 152m
test1-2-yaml-pv-url-pvc Bound test1-2-yaml-pv-url-pv 12Gi RWO nfs-client <unset> 33s
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl get pv | grep -e NAME -e test
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO Delete Bound kubevirt-test/test1-1-yaml-pv-url-pvc nfs-client <unset> 151m
test1-2-yaml-pv-url-pv 12Gi RWO Retain Bound kubevirt-test/test1-2-yaml-pv-url-pvc nfs-client <unset> 9m8s
[root@master1 kubevirt-test]#
PV(実体はNFSサーバのディレクトリ)には、disk.imgが作られています。
[root@al9host sc-nfs]# qemu-img info test1-2-yaml-pv-url-pv/disk.img
image: test1-2-yaml-pv-url-pv/disk.img
file format: raw
virtual size: 11.3 GiB (12176064512 bytes)
disk size: 1.26 GiB
Child node '/file':
filename: test1-2-yaml-pv-url-pv/disk.img
protocol type: file
file length: 11.3 GiB (12176064512 bytes)
disk size: 1.26 GiB
[root@al9host sc-nfs]#
(5) VM起動
Vmリソースのyamlを作り、適用して、VMを起動します。
[root@master1 kubevirt-test]# vim test1-2-vm.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-2-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
labels:
kubevirt.io/os: linux
name: test1-2-vm
spec:
runStrategy: Always
template:
metadata:
creationTimestamp: null
labels:
kubevirt.io/domain: test1-2-vm
spec:
domain:
cpu:
cores: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- cdrom:
bus: sata
readonly: true
name: cloudinitdisk
machine:
type: q35
resources:
requests:
memory: 1024M
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: test1-2-yaml-pv-url-pvc
- cloudInitNoCloud:
userData: |
#cloud-config
hostname: test1-2guest
users:
- name: myuser
ssh_pwauth: true
chpasswd:
list: |
root:initpasswd
myuser:initpasswd
expire: False
name: cloudinitdisk
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-2-vm.yaml
virtualmachine.kubevirt.io/test1-2-vm created
[root@master1 kubevirt-test]#
(6) VMへのsshログイン
Vmiリソースの情報を表示してIPアドレスを確認します。
[root@master1 kubevirt-test]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
test1-1-vm 159m Running 10.244.1.95 worker1.internal True
test1-2-vm 11s Running 10.244.1.98 worker1.internal True
[root@master1 kubevirt-test]#
VMのIPアドレスを指定して、sshでログインできました。
[root@master1 kubevirt-test]# ssh myuser@10.244.1.98
The authenticity of host '10.244.1.98 (10.244.1.98)' can't be established.
ED25519 key fingerprint is SHA256:jmq1aRkz8nthQSd1LoSOlCW5OovbQ/74j5dxJtqkeiI.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.244.1.98' (ED25519) to the list of known hosts.
myuser@10.244.1.98's password:
[myuser@test1-2-vm ~]$
4. (3)の方法(PVCはコマンドで作成/PVはStorageClassから切り出す/disk.imgはローカルファイルを指定)
この(3)の方法は、以下で示した方法です(ISOファイル、KVMで作ったimgファイル、でやっています)。
kubectl virt image-uploadコマンドを使います。コマンドを使ってリソースを操作するのは、k8sで重要な宣言的設定を使う方針に反するので、あまり気が進みません。
しかし、そもそも、yamlファイルに記述して、CDIでローカルファイルをアップロードする方法は、見つけられませんでした(無いと書いてる情報は見つけられていませんが、できるという情報が見つけられない)。
また、ISOファイルは特に、認証なしに取得できるURLを示せるとは限りませんし、同じ581MiBのマシンイメージファイルをアップロードするにしても、Webから落とさせるより、ローカルファイルをアップロードする方が、圧倒的に早いです。
以上から、恐らく、(1)よりも使いやすい方法ではないかと思います。
以下、要点だけ示します。
(1) cdi-uploadproxyのIPアドレス確認
アップロード先として指定する必要があるので、IPアドレスを確認します。以下の場合、「10.111.218.50」です。
[root@master1 kubevirt-test]# kubectl get service -n cdi
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cdi-api ClusterIP 10.110.82.60 <none> 443/TCP 12d
cdi-prometheus-metrics ClusterIP 10.105.9.213 <none> 8080/TCP 12d
cdi-uploadproxy ClusterIP 10.111.218.50 <none> 443/TCP 37h
[root@master1 kubevirt-test]#
(2) ローカルファイルのPVへのアップロードとPVC作成
このコマンドで、
- PVC作成
- PV作成
- disk.img作成
が、まとめて行われます。
[root@master1 kubevirt-test]# kubectl virt image-upload pvc test1-3-cmd-pv-file-pvc --storage-class nfs-client --size 13Gi --uploadproxy-url=10.111.218.50 --image-path=/root/kubevirt/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2 --insecure
PVC kubevirt-test/test1-3-cmd-pv-file-pvc not found
PersistentVolumeClaim kubevirt-test/test1-3-cmd-pv-file-pvc created
Waiting for PVC test1-3-cmd-pv-file-pvc upload pod to be ready...
Pod now ready
Uploading data to https://10.111.218.50
581.56 MiB / 581.56 MiB [---------------------------------------------------------------] 100.00% 52.53 MiB p/s 11s
Uploading data completed successfully, waiting for processing to complete, you can hit ctrl-c without interrupting the progress
Processing completed successfully
Uploading /root/kubevirt/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2 completed successfully
[root@master1 kubevirt-test]#
(3) 実施後のPVC/PV確認
作られています。
[root@master1 kubevirt-test]# kubectl get pv | grep -e NAME -e test
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47 13Gi RWO Delete Bound kubevirt-test/test1-3-cmd-pv-file-pvc nfs-client <unset> 4m16s
pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO Delete Bound kubevirt-test/test1-1-yaml-pv-url-pvc nfs-client <unset> 10h
test1-2-yaml-pv-url-pv 12Gi RWO Retain Bound kubevirt-test/test1-2-yaml-pv-url-pvc nfs-client <unset> 8h
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test1-1-yaml-pv-url-pvc Bound pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO nfs-client <unset> 10h
test1-2-yaml-pv-url-pvc Bound test1-2-yaml-pv-url-pv 12Gi RWO nfs-client <unset> 8h
test1-3-cmd-pv-file-pvc Bound pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47 13Gi RWO nfs-client <unset> 4m20s
[root@master1 kubevirt-test]#
PV(実体はNFSサーバのディレクトリ)には、disk.imgが作られています。
[root@al9host sc-nfs]# qemu-img info kubevirt-test-test1-3-cmd-pv-file-pvc-pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47/disk.img
image: kubevirt-test-test1-3-cmd-pv-file-pvc-pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47/disk.img
file format: raw
virtual size: 12.3 GiB (13190037504 bytes)
disk size: 1.13 GiB
Child node '/file':
filename: kubevirt-test-test1-3-cmd-pv-file-pvc-pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47/disk.img
protocol type: file
file length: 12.3 GiB (13190037504 bytes)
disk size: 1.13 GiB
[root@al9host sc-nfs]#
(4) VM起動
Vmリソースのyamlを作り、適用して、VMを起動します。
[root@master1 kubevirt-test]# vim test1-3-vm.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-3-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
labels:
kubevirt.io/os: linux
name: test1-3-vm
spec:
runStrategy: Always
template:
metadata:
creationTimestamp: null
labels:
kubevirt.io/domain: test1-3-vm
spec:
domain:
cpu:
cores: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- cdrom:
bus: sata
readonly: true
name: cloudinitdisk
machine:
type: q35
resources:
requests:
memory: 1024M
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: test1-3-cmd-pv-file-pvc
- cloudInitNoCloud:
userData: |
#cloud-config
hostname: test1-3guest
users:
- name: myuser
ssh_pwauth: true
chpasswd:
list: |
root:initpasswd
myuser:initpasswd
expire: False
name: cloudinitdisk
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-3-vm.yaml
virtualmachine.kubevirt.io/test1-3-vm created
[root@master1 kubevirt-test]#
(5) VMへのsshログイン
Vmiリソースの情報を表示してIPアドレスを確認します。
[root@master1 kubevirt-test]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
test1-1-vm 10h Running 10.244.1.95 worker1.internal True
test1-2-vm 7h50m Running 10.244.1.98 worker1.internal True
test1-3-vm 47s Running 10.244.1.100 worker1.internal True
[root@master1 kubevirt-test]#
VMのIPアドレスを指定して、sshでログインできました。
[root@master1 kubevirt-test]# ssh myuser@10.244.1.100
The authenticity of host '10.244.1.100 (10.244.1.100)' can't be established.
ED25519 key fingerprint is SHA256:iXd23rRWVJ6Ann/kxgc2x92e/OHc/rOLLUUvdB52cUc.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.244.1.100' (ED25519) to the list of known hosts.
myuser@10.244.1.100's password:
[myuser@test1-3-vm ~]$
5. (4)の方法(DataVolumeのyamlを作成/PVはStorageClassから切り出す/disk.imgはWebURL指定)
正直、(1)と(3)の方法で、事足りていると思いますが、KubeVirtのマニフェストファイルの例を探すと、結構、「kind: DataVolume」が出てくるので、どういうものか把握しておくことは必要です。
DataVolumeとはなにかは、以下に説明があります。
dataVolume
DataVolumes are a way to automate importing virtual machine disks onto PVCs during the virtual machine's launch flow. Without using a DataVolume, users have to prepare a PVC with a disk image before assigning it to a VM or VMI manifest. With a DataVolume, both the PVC creation and import is automated on behalf of the user.
つまり、DataVolumeリソースは、VMを作成するときに、仮想ディスクをPVCにインポートする、ということをしてくれるリソースです。これによって、VM作成前にPVCを作っておく手間を省けます、とのこと。
ということで、これを使ってやってみます。
(1) DataVolumeをyamlから作成(StorageClass、URL)
DataVolumeリソースのyamlを作り、適用します。
[root@master1 kubevirt-test]# vim test1-4-yaml-dv.yaml
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# cat test1-4-yaml-dv.yaml
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: test1-4-datavolume
namespace: kubevirt-test
spec:
source:
http:
url: "https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2"
pvc:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 14Gi
storageClassName: nfs-client
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-4-yaml-dv.yaml
datavolume.cdi.kubevirt.io/test1-4-datavolume created
[root@master1 kubevirt-test]#
(2) 実施後のPVC/PV確認
PVCリソースが作られました。先に作成しておいたPVがバインドされています。
[root@master1 kubevirt-test]# kubectl get pv | grep -e NAME -e test
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-193f1361-921c-48bf-9944-2b8fe85fefe3 14Gi RWO Delete Bound kubevirt-test/test1-4-datavolume nfs-client <unset> 4m51s
pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47 13Gi RWO Delete Bound kubevirt-test/test1-3-cmd-pv-file-pvc nfs-client <unset> 36m
pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO Delete Bound kubevirt-test/test1-1-yaml-pv-url-pvc nfs-client <unset> 11h
test1-2-yaml-pv-url-pv 12Gi RWO Retain Bound kubevirt-test/test1-2-yaml-pv-url-pvc nfs-client <unset> 8h
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test1-1-yaml-pv-url-pvc Bound pvc-d9ea4023-50f8-4ae0-9029-a9edfcc38d5f 11Gi RWO nfs-client <unset> 11h
test1-2-yaml-pv-url-pvc Bound test1-2-yaml-pv-url-pv 12Gi RWO nfs-client <unset> 8h
test1-3-cmd-pv-file-pvc Bound pvc-c2b70d42-2cc6-4e91-bd64-e1ab59caec47 13Gi RWO nfs-client <unset> 36m
test1-4-datavolume Bound pvc-193f1361-921c-48bf-9944-2b8fe85fefe3 14Gi RWO nfs-client <unset> 4m54s
[root@master1 kubevirt-test]#
PV(実体はNFSサーバのディレクトリ)には、disk.imgが作られています。
[root@al9host sc-nfs]# qemu-img info kubevirt-test-test1-4-datavolume-pvc-193f1361-921c-48bf-9944-2b8fe85fefe3/disk.img
image: kubevirt-test-test1-4-datavolume-pvc-193f1361-921c-48bf-9944-2b8fe85fefe3/disk.img
file format: raw
virtual size: 13.2 GiB (14205059072 bytes)
disk size: 1.13 GiB
Child node '/file':
filename: kubevirt-test-test1-4-datavolume-pvc-193f1361-921c-48bf-9944-2b8fe85fefe3/disk.img
protocol type: file
file length: 13.2 GiB (14205059072 bytes)
disk size: 1.13 GiB
[root@al9host sc-nfs]#
(3) 実施後のDataVolume確認
datavolumeリソースも作られています。
[root@master1 kubevirt-test]# kubectl get datavolume
NAME PHASE PROGRESS RESTARTS AGE
test1-4-datavolume Succeeded 100.0% 6m2s
[root@master1 kubevirt-test]#
describeは以下です。
[root@master1 kubevirt-test]# kubectl describe datavolume test1-4-datavolume
Name: test1-4-datavolume
Namespace: kubevirt-test
Labels: <none>
Annotations: cdi.kubevirt.io/storage.usePopulator: false
API Version: cdi.kubevirt.io/v1beta1
Kind: DataVolume
Metadata:
Creation Timestamp: 2025-02-23T14:32:24Z
Generation: 1
Resource Version: 1342794
UID: f9518349-f314-4f5c-b328-2238fc7dce43
Spec:
Pvc:
Access Modes:
ReadWriteOnce
Resources:
Requests:
Storage: 14Gi
Storage Class Name: nfs-client
Source:
Http:
URL: https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2
Status:
Claim Name: test1-4-datavolume
Conditions:
Last Heartbeat Time: 2025-02-23T14:32:24Z
Last Transition Time: 2025-02-23T14:32:24Z
Message: PVC test1-4-datavolume Bound
Reason: Bound
Status: True
Type: Bound
Last Heartbeat Time: 2025-02-23T14:36:55Z
Last Transition Time: 2025-02-23T14:36:55Z
Status: True
Type: Ready
Last Heartbeat Time: 2025-02-23T14:36:54Z
Last Transition Time: 2025-02-23T14:36:54Z
Message: Import Complete
Reason: Completed
Status: False
Type: Running
Phase: Succeeded
Progress: 100.0%
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pending 6m32s datavolume-import-controller PVC test1-4-datavolume Pending
Normal Bound 6m32s datavolume-import-controller PVC test1-4-datavolume Bound
Normal ImportInProgress 6m30s datavolume-import-controller Import into test1-4-datavolume in progress
Warning Completed 2m2s datavolume-import-controller Import Complete
Normal ImportSucceeded 2m1s datavolume-import-controller Successfully imported into PVC test1-4-datavolume
[root@master1 kubevirt-test]#
(5) VM起動
Vmリソースのyamlを作り、適用して、VMを起動します。
[root@master1 kubevirt-test]# cat test1-4-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: test1-4-vm
namespace: kubevirt-test
labels:
kubevirt.io/os: linux
spec:
runStrategy: Always
template:
metadata:
labels:
kubevirt.io/domain: test1-4-vm
spec:
domain:
cpu:
cores: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- cdrom:
bus: sata
readonly: true
name: cloudinitdisk
machine:
type: q35
resources:
requests:
memory: 1024M
volumes:
- name: rootdisk
dataVolume:
name: test1-4-datavolume
- cloudInitNoCloud:
userData: |
#cloud-config
hostname: test1-4guest
users:
- name: myuser
ssh_pwauth: true
chpasswd:
list: |
root:initpasswd
myuser:initpasswd
expire: False
name: cloudinitdisk
[root@master1 kubevirt-test]#
[root@master1 kubevirt-test]# kubectl apply -f ./test1-4-vm.yaml
virtualmachine.kubevirt.io/test1-4-vm created
[root@master1 kubevirt-test]#
(6) VMへのsshログイン
Vmiリソースの情報を表示してIPアドレスを確認します。
[root@master1 kubevirt-test]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
test1-1-vm 11h Running 10.244.1.95 worker1.internal True
test1-2-vm 8h Running 10.244.1.98 worker1.internal True
test1-3-vm 34m Running 10.244.1.100 worker1.internal True
test1-4-vm 37s Running 10.244.3.141 worker2.internal True
[root@master1 kubevirt-test]#
VMのIPアドレスを指定して、sshでログインできました。
[root@master1 kubevirt-test]# ssh myuser@10.244.3.141
The authenticity of host '10.244.3.141 (10.244.3.141)' can't be established.
ED25519 key fingerprint is SHA256:tb1S999xrHjGrtM2o5AiqXFEcMHqBqX9cohbB48E5LM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.244.3.141' (ED25519) to the list of known hosts.
myuser@10.244.3.141's password:
[myuser@test1-4-vm ~]$
ということで、DataVolumeを使ってみましたが、(1)のPVCとの違いは、特に無いように思います。CDIのアップロードの進捗を、kubectl get datavolumeで確認できること、くらいでしょうか(別にそれだって、kubectl logs -fで確認できますが)。
まとめ
KubeVirtでVMを作るときにバリエーションの多い、仮想ディスクの作り方について、4つのパターンについて比較し、それぞれ、試しました。
このような4VMを作りました。