目次
概要
QEMU+KVM環境でゲストマシンの多重起動を防止する。virtlockdの排他ロック機能を導入する。
経緯
前回の記事でライブマイグレーションの環境を構築したが、共有ディスクがiSCSIのため排他ロックの概念がなく、複数のホストマシンから同一ゲストマシンの多重起動ができてしまうリスクがあった。今回の記事ではそのリスクに対処する。
環境
概要図
構成
ホスト名 | 管理NWのIP | ストレージNWのIP | OS | H/W | 備考 |
---|---|---|---|---|---|
kvm02 | 172.16.0.206 | 172.16.1.206 | CentOS 8.4.2105 | Fujitsu TX1320 M1 | KVMホスト(移行元) |
kvm03 | 172.16.0.207 | 172.16.1.207 | CentOS 8.4.2105 | Fujitsu TX120 S3 | KVMホスト(移行先) |
guest01 | 172.16.0.253 | - | CentOS 8.4.2105 | - | KVMゲスト |
linux01 | 任意 | - | CentOS 7.9.2009 | - | KVMゲストへの疎通確認用Linux |
file01 | 172.16.0.5 | 172.16.1.5 | RAIDiator 4.2.31 | NETGEAR ReadyNAS Pro 2 | iSCSIターゲット、NFSサーバ |
前提
- NFSサーバを構築済みとする。
手順
1.NFSサーバの設定
1-1.NFS領域の公開
以下のディレクトリを作成し公開する。設定方法は環境に依る。
/nfs/virt-lockd
2.ホストマシンの設定
注意
両方のホストマシンに対して実施すること。
2-1.fstabの編集
fstabにNFS領域のマウント定義を追記する。
[root@kvm02 ~]# ls -l /etc/fstab* -rw-r--r--. 1 root root 734 10月 6 20:24 /etc/fstab
[root@kvm02 ~]# cp -p /etc/fstab{,_$(date +%Y%m%d)}
[root@kvm02 ~]# ls -l /etc/fstab* -rw-r--r--. 1 root root 734 10月 6 20:24 /etc/fstab -rw-r--r-- 1 root root 734 10月 6 20:24 /etc/fstab_20211012
[root@kvm02 ~]# cat << EOF >> /etc/fstab > > # virtlockd > file012:/nfs/virt-lockd /var/lib/libvirt/lockd nfs vers=3,defaults 0 0 > EOF
[root@kvm02 ~]# diff /etc/fstab{,_$(date +%Y%m%d)} 19,21d18 < < # virtlockd < file012:/nfs/virt-lockd /var/lib/libvirt/lockd nfs vers=3,defaults 0 0
※当環境のNFSサーバはNFSv3のためvers=3
オプションを付与している。
2-2.マウントポイントの作成
マウントポイントを作成する。
[root@kvm02 ~]# mkdir /var/lib/libvirt/lockd
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd 合計 0
2-3.マウントの実行
マウントする。マウントポイント名だけを指定することで、マウント元はfstabから読み取らせてfstabの動作確認を兼ねる。
[root@kvm02 ~]# df -hT | grep /var/lib/libvirt/lockd
[root@kvm02 ~]# mount /var/lib/libvirt/lockd
[root@kvm02 ~]# df -hT | grep /var/lib/libvirt/lockd file012:/nfs/virt-lockd nfs 7.3T 5.0T 2.3T 69% /var/lib/libvirt/lockd
2-4.ロック機能の有効化
qemu.confを編集し、ロック機能を有効化する。
[root@kvm02 ~]# ls -l /etc/libvirt/qemu.conf* -rw-r--r-- 1 root root 31778 8月 11 05:57 /etc/libvirt/qemu.conf
[root@kvm02 ~]# cp -p /etc/libvirt/qemu.conf{,_$(date +%Y%m%d)}
[root@kvm02 ~]# ls -l /etc/libvirt/qemu.conf* -rw-r--r-- 1 root root 31778 8月 11 05:57 /etc/libvirt/qemu.conf -rw-r--r-- 1 root root 31778 8月 11 05:57 /etc/libvirt/qemu.conf_20211012
[root@kvm02 ~]# sed -i -e '/^#lock_manager/s/#//g' /etc/libvirt/qemu.conf
[root@kvm02 ~]# diff /etc/libvirt/qemu.conf{,_$(date +%Y%m%d)} 668c668 < lock_manager = "lockd" --- > #lock_manager = "lockd"
qemu-lockd.confを編集し、ロックファイルの作成先を定義する。
[root@kvm02 ~]# ls -l /etc/libvirt/qemu-lockd.conf* -rw-r--r-- 1 root root 2169 8月 11 05:59 /etc/libvirt/qemu-lockd.conf
[root@kvm02 ~]# cp -p /etc/libvirt/qemu-lockd.conf{,_$(date +%Y%m%d)}
[root@kvm02 ~]# ls -l /etc/libvirt/qemu-lockd.conf* -rw-r--r-- 1 root root 2169 8月 11 05:59 /etc/libvirt/qemu-lockd.conf -rw-r--r-- 1 root root 2169 8月 11 05:59 /etc/libvirt/qemu-lockd.conf_20211012
[root@kvm02 ~]# sed -i \ > -e '/^#require_lease_for_disks/s/#//g' \ > -e '/^#file_lockspace_dir/s/#//g' \ > -e '/^#lvm_lockspace_dir/s/#//g' \ > -e '/^#scsi_lockspace_dir/s/#//g' \ > /etc/libvirt/qemu-lockd.conf
[root@kvm02 ~]# diff /etc/libvirt/qemu-lockd.conf{,_$(date +%Y%m%d)} 17c17 < require_lease_for_disks = 1 --- > #require_lease_for_disks = 1 39c39 < file_lockspace_dir = "/var/lib/libvirt/lockd/files" --- > #file_lockspace_dir = "/var/lib/libvirt/lockd/files" 53c53 < lvm_lockspace_dir = "/var/lib/libvirt/lockd/lvmvolumes" --- > #lvm_lockspace_dir = "/var/lib/libvirt/lockd/lvmvolumes" 67c67 < scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes" --- > #scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes"
virtlockdサービスが停止していることを確認する。
[root@kvm02 ~]# systemctl is-active virtlockd.service inactive
ロックファイル格納ディレクトリが存在しないことを確認する。
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd 合計 0
libvirtdサービスを再起動する。
[root@kvm02 ~]# systemctl is-active libvirtd.service active
[root@kvm02 ~]# systemctl restart libvirtd.service
[root@kvm02 ~]# systemctl is-active libvirtd.service active
連動してvirtlockdサービスも起動される。
[root@kvm02 ~]# systemctl is-active virtlockd.service active
ロックファイル格納ディレクトリが作成されていることを確認する。数秒かかる可能性がある。
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd 合計 12 drwx------ 2 nobody nobody 4096 10月 13 19:50 files drwx------ 2 nobody nobody 4096 10月 13 19:50 lvmvolumes drwx------ 2 nobody nobody 4096 10月 13 19:50 scsivolumes
[root@kvm02 ~]# ls -lR /var/lib/libvirt/lockd /var/lib/libvirt/lockd: 合計 12 drwx------ 2 nobody nobody 4096 10月 13 19:50 files drwx------ 2 nobody nobody 4096 10月 13 19:50 lvmvolumes drwx------ 2 nobody nobody 4096 10月 13 19:50 scsivolumes /var/lib/libvirt/lockd/files: 合計 0 /var/lib/libvirt/lockd/lvmvolumes: 合計 0 /var/lib/libvirt/lockd/scsivolumes: 合計 0
※所有者・所有グループがnobody nobody
なのはNASの設定。
3.動作確認
3-1.ゲストマシンの起動
1台目のホストマシンでゲストマシンを起動する。
[root@kvm02 ~]# virsh start guest01 ドメイン guest01 が起動されました
ロックファイルが作成されていることを確認する。なお、今回はiSCSIディスクなのでscsivolumesにしか作成されない。
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd/scsivolumes/ 合計 0 -rw------- 1 nobody nobody 0 10月 13 19:51 360014052e1170401087d041000000000
3-2.排他ロックの動作確認
2台目のホストマシンからロックファイルが見えていることを確認する。
[root@kvm03 ~]# ls -l /var/lib/libvirt/lockd/scsivolumes/ 合計 0 -rw------- 1 nobody nobody 0 10月 13 19:51 360014052e1170401087d041000000000
2台目のホストマシンからゲストマシンを多重起動する。
[root@kvm03 ~]# virsh list Id 名前 状態 -------------------
[root@kvm03 ~]# virsh start guest01 エラー: ドメイン guest01 の起動に失敗しました エラー: resource busy: ロック空間のリソース '360014052e1170401087d041000000000' がロックされています
[root@kvm03 ~]# virsh list Id 名前 状態 -------------------
排他ロックが機能し、ゲストマシンの多重起動を防止することができた。
補足1
ゲストマシンを停止するとロックファイルが削除される。
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd/scsivolumes/ 合計 0 -rw------- 1 nobody nobody 0 10月 13 20:05 360014052e1170401087d041000000000
[root@kvm02 ~]# virsh shutdown guest01 ドメイン guest01 はシャットダウン中です
[root@kvm02 ~]# virsh list Id 名前 状態 -------------------
[root@kvm02 ~]# ls -l /var/lib/libvirt/lockd/scsivolumes/ 合計 0
補足2
ロックファイルのファイル名はディスクのデバイスIDに由来している。ディスク側で値を持っているため、ホストマシンが異なってもファイル名が変わることはない。
[root@kvm02 ~]# ls -l /dev/disk/by-id/ | grep 360014052e1170401087d041000000000 lrwxrwxrwx 1 root root 9 10月 13 20:08 scsi-360014052e1170401087d041000000000 -> ../../sdl lrwxrwxrwx 1 root root 10 10月 13 20:08 scsi-360014052e1170401087d041000000000-part1 -> ../../sdl1 lrwxrwxrwx 1 root root 10 10月 13 20:08 scsi-360014052e1170401087d041000000000-part2 -> ../../sdl2 lrwxrwxrwx 1 root root 10 10月 13 20:08 scsi-360014052e1170401087d041000000000-part3 -> ../../sdl3
[root@kvm02 ~]# ls -l /dev/disk/by-path/ | grep sdl lrwxrwxrwx 1 root root 9 10月 13 20:08 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0 -> ../../sdl lrwxrwxrwx 1 root root 10 10月 13 20:08 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part1 -> ../../sdl1 lrwxrwxrwx 1 root root 10 10月 13 20:08 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part2 -> ../../sdl2 lrwxrwxrwx 1 root root 10 10月 13 20:08 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part3 -> ../../sdl3
/etc/libvirt/qemu-lockd.conf
にちゃんと書いてあった。
# # When using SCSI volumes that can be visible across # multiple, it is desirable to do locking based on # the unique UUID associated with each volume, instead # of their paths. Setting this path causes libvirt to # do UUID based locking for SCSI. # # Typically this directory would be located on a shared # filesystem visible to all hosts accessing the same # storage. # scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes"
参考記事
https://soar.keizof.com/wp/?p=157
今回の設定方法はググっても上記記事しか見つからなかった。RHELの公式ドキュメントもgoogleの検索対象なのでそこにもないと思われる。貴重な情報に感謝する。
併せて、公式ドキュメントを読む姿勢と、ドキュメントがない場合はmanや定義ファイルのコメントを読む姿勢、いずれも不足していたと痛感した。