なにかの技術メモ置き場

なにかの技術メモ置き場

@インフラエンジニア

自作キーボード「exmp」を作ってみた

f:id:none06:20220113020602j:plain

目次

概要

自作キーボード(マクロパッド)「exmp」のビルドログ。

経緯

  • 自作キーボード「sphh jp」のはんだ付けに失敗した際に、実は練習用に購入していた。 none06.hatenadiary.org
  • 結局「sphh jp」が無事完成したため本来の役割を果たせなかったが、純粋に表面実装の練習としてビルドすることにした。

構成

今回作成したキーボードの主要パーツは以下。

  • Keyboard: exmp
  • Keyswitch: Kailh BOX スイッチ 黒
  • Keycap: DSA 無刻印キーキャップ 水晶

準備

以下の工具一式を揃えた。 none06.hatenadiary.org

部材購入

部材 製品名 価格 入力先 備考
キット 【委託】exmp 基本キット 3,960 https://shop.yushakobo.jp/products/2928 -
スイッチソケット(MX用) スイッチ用PCBソケット(10個入り) 165(165*1) https://shop.yushakobo.jp/products/a01ps?variant=37665172521121 -
キースイッチ(MX互換) Kailh BOX スイッチ(10個) 黒 462(462*1) https://shop.yushakobo.jp/products/kailh-box?variant=37665170587809 -
キーキャップ(MX互換) DSA 無刻印キーキャップ(1個) 水晶 440(55*8) https://shop.yushakobo.jp/products/dsa-blank-keycaps?variant=37665598668961 -
USB ケーブル(TypeA to micro) - - 家に転がっていたもの -
合計 - 5,027(+α) - -

手順書(ビルドガイド)

製作者であるa bit keysさまのビルドガイドを参照。 abitkeys.com

作業ログ(ビルドログ)

開封

f:id:none06:20220113015354j:plain

はんだ付け

今回は完了した写真だけ。
使われる素子は「sphh jp」と全く同じ。まさに練習用にうってつけ。 f:id:none06:20220113015425j:plain

PCとの接続確認

micro USBケーブルでPCに接続する。今回は一発で認識した!
前回「sphh jp」をインストールした際にドライバがインストールされたためか、デバイスマネージャでは「libusb-win32 devices」配下に表示された。 f:id:none06:20220113203956p:plain

ファームウェアの書き込み

「exmp_rev1_via.hex」をダウンロードし、QMK Toolboxでインストールする。 f:id:none06:20220113021909p:plain

トッププレートにネジとスペーサーを固定

f:id:none06:20220113020405j:plain

トッププレートにキースイッチを固定

この素材なら割れない。 f:id:none06:20220113020417j:plain

トッププレートとキースイッチを基盤に固定

f:id:none06:20220113020428j:plain

各キーの認識確認

https://config.qmk.fm/#/test/
デフォルトキーマップは12345678f:id:none06:20220113021921p:plain

エッジプレートとゴム足の取り付け

むき出しの基盤が良い。 f:id:none06:20220113020528j:plain

キーキャップの取り付け

キースイッチの軸が見えるクリアなキャップを選定。素材はABS。 f:id:none06:20220113020547j:plain

キーマップのカスタマイズ

VIAを使用する。以下のサイトを参考にした。 salicylic-acid3.hatenablog.com 今回は「BASIC」だけで。「MACRO」や「LAYERS」もいずれ使いたい。
なんとなく移動キーを詰め込んでみた。 f:id:none06:20220113204517p:plain 動作確認をして完了。 f:id:none06:20220113210122p:plain

完成!

f:id:none06:20220113020602j:plain f:id:none06:20220113020608j:plain f:id:none06:20220113020613j:plain f:id:none06:20220113020558j:plain ベゼルが極限まで薄い。この点がa bit keysさまの製品の魅力だと思っている。

あとがき

今回は楽しんで表面実装のはんだ付けができた。マクロパッドとしての使い道が未定だが、おもむろにカチャカチャ触っているだけでも心地良いので満足している。

参考記事

abitkeys.com

自作キーボード「sphh jp」を作ってみた

f:id:none06:20220116195827j:plain

目次

概要

自作キーボード「sphh jp」のビルドログ。

経緯

  • デスクワークの姿勢が悪く、首に負担になっていた。
  • 調べたら分割キーボードが見つかったが、日本語配列の製品はキー配列が好みとマッチしない。さらに市販されている製品が少ないため、選択肢が限られる。

※カーソルキーと一番右の列のキーがしっくり来ない。

  • さらに調べると自作キーボードの世界にたどり着いた。ここでも結局ほとんどが英字配列だが、1つだけ要件を満たすキーボードに出会った。
    • 分割キーボードであること。
    • 日本語配列であること。
    • テンキーレスであること(コンパクトであること)。
    • カーソルキーがあると嬉しい。
  • はんだ付け未経験なのがネックだったが、この機にトライしてみた。なお、このキーボードを自作する前にはんだ付けを3日ほど練習した。

構成

今回作成したキーボードの主要パーツは以下。

  • Keyboard: sphh jp
  • Keyswitch: Gateron Caps V2 Switches 3 Pins Milkey Brown
  • Keycap: Majestouch (P/N: FKCS108BB)

準備

  • はんだ付けに必要な工具一式として以下を揃えた。 none06.hatenadiary.org
  • こちらがたいへん参考になった。 salicylic-acid3.hatenablog.com
  • 遊舎工房さんの工作室(有料)を利用することで、工具一式も借りることができる。さらにどうしてもうまくいかないときは技術サポートもお願いできる(追加料金)。 yushakobo.jp

部材購入

部材 製品名 価格 入力先 備考
キット 【委託】sphh jp 14,850 https://shop.yushakobo.jp/products/consign_sphh-jp -
スイッチソケット(MX用) スイッチ用PCBソケット(10個入り) 1,155(165*7) https://shop.yushakobo.jp/products/a01ps?variant=37665172521121 -
キースイッチ(MX互換) Gateron Caps V2 Switches 3 Pins(10個) Milkey Brown 3,465(495*7) https://shop.yushakobo.jp/products/2808?variant=40821007286433 -
キーキャップ(MX互換) Majestouch 交換用キーキャップセット 日本語108キー・無刻印 FKCS108BB 5,920(2,960*2) https://www.biccamera.com/bc/item/3050564/ -
USB ケーブル(TypeA to micro) - - 家に転がっていたもの -
USB ケーブル(micro to micro) USB AUDIOケーブル (micro B-micro B/0.8m) DH-MBMB08 840 https://www.biccamera.com/bc/item/3352626/ -
合計 - 26,230(+α) - -

手順書(ビルドガイド)

製作者であるa bit keysさまのビルドガイドを参照。 abitkeys.com

作業ログ(ビルドログ)

はんだ付け

すべて表面実装。苦労した。

  • MCU
    後にはんだ不足が発覚した。フラックスがあればブリッジは防ぎやすい。 f:id:none06:20220109224211p:plain:w800
  • 水晶発振子
    後にはんだ不足が発覚した。素子を基盤に置くとランドがわずかしか見えなくなり、細いこて先でもランドを温めるのが難しかった。 f:id:none06:20220109224222p:plain:w800
  • USB micro Type-Bコネクタ
    後にブリッジが発覚した。個人的に最難関のはんだ付け。 f:id:none06:20220109224703p:plain:w800
  • チップ抵抗
    ここまでの素子と比べるとやや易しい。 f:id:none06:20220109224237p:plain:w800 f:id:none06:20220109224256p:plain:w800
  • チップコンデンサ
    チップ抵抗と同じ難易度かと思いきや難しかった。 f:id:none06:20220109224308p:plain:w800 f:id:none06:20220109224318p:plain:w800 f:id:none06:20220109224424p:plain:w800
  • ショットキーバリアダイオード
    ここまでの素子と比べるとさらに易しい。極性があるので向きに注意。 f:id:none06:20220109224433p:plain:w800
  • スイッチングダイオード
    同上。数が多い(70個)。 f:id:none06:20220109224442p:plain:w800
  • スイッチソケット
    簡単。数が多い(70個)。 f:id:none06:20220109224448p:plain:w800

はんだ付けは以上。記念に動画も撮っておいた。


www.youtube.com

PCとの接続確認

ビルドガイドの流れと異なるが、この時点でPCとの接続確認をしておいた。はんだ付けの修正が必要な場合に手戻りをなくすのが目的。

・・・がしかし、認識しない!
原因の切り分けをするにはテスターの使い方や回路図の理解が必要だが、その時間が惜しい。遊舎工房さんの技術サポート(有料)に切り分けを依頼した。基盤を見て不具合を指摘・修正してもらったらあっさり解決した。不具合は以下。

  • USB micro Type-Bコネクタのブリッジ
  • MCUのはんだ不足
  • 水晶振動子のはんだ不足

ということで、PCに接続するといつもの軽快なサウンドが鳴り、認識した!
バイスマネージャで「ATm32U4DFU」と表示される。 f:id:none06:20220109233252p:plain

ファームウェアの書き込み

QMK Toolboxをインストールする。 f:id:none06:20220109233703p:plain よくわからないがドライバもインストールする。 f:id:none06:20220109233712p:plain 起動する。「sphhjp_rev1_via.hex」をダウンロードし、「Local file」に指定する。 f:id:none06:20220109233735p:plain 基盤上の「Reset」端子を1秒ほどピンセットでショートさせ、「Flash」ボタンを押下する。 f:id:none06:20220109233747p:plain ファームウェアの書き込みが完了するとデバイスマネージャの「ATm32U4DFU」がなくなる。 f:id:none06:20220109233801p:plain

キースイッチの仮取り付け

キーの認識テストのため、キースイッチを基盤に仮で取り付ける。すべて取り付けも良いし、写真のように1個を使い回すことも可能。ちなみにここは遊舎工房さんの工作室。 f:id:none06:20220110013809j:plain

各キーの認識テスト

以下のサイトを開いた状態で、キーを押下していく。すべて反応したらOK。
https://config.qmk.fm/#/test/ f:id:none06:20220109233810p:plain

注意点1

Fnキーは単体では反応しないので注意。例えば、Fnキー+1キーでF1が反応すればOK。

キースイッチをトッププレートに固定

仮で取り付けたキースイッチを外し、トッププレートにキースイッチを固定していく。 f:id:none06:20220112001809j:plain

注意点1

割れた・・・
ビルドガイドに『トッププレートの破損に注意して下さい。特に端に近いキースイッチの作業時にご注意下さい。』と書いてあるが、力加減は体験しないとわからなかった。はんだ付けと違って取り返しがつかないぞこれ、どうすんだ・・・ f:id:none06:20220112001821j:plain

2022/1/13追記

ビルドログを公開して半日も経たずして、なんと製作者さまから連絡が!補修用のトッププレートをご準備くださった。諦めていた課題だったため、たいへん助かった。 f:id:none06:20220113193440j:plain f:id:none06:20220113193458j:plain f:id:none06:20220113193452j:plain f:id:none06:20220113193446j:plain

注意点2

左側だとAキーとSキー、右側だと*キーと}キーだけ上下逆なので注意。トッププレートには逆でも固定できてしまうが、後ほど基盤に入らなくて気づいた。 f:id:none06:20220112001835j:plain

トッププレートを基盤に固定

キースイッチの端子を折らないように注意。事前に真っ直ぐにしておいたら思ったよりすんなり入った。 f:id:none06:20220112001852j:plain

ボトムプレートを基盤に固定&ゴム足の取り付け

キットには4個のみのため、まずは上側に取り付け。キーボードの高さと傾きを調整する機能も兼ねるため意外と重要。 f:id:none06:20220110022103j:plain

キーキャップの取り付け

Majestouchの無刻印版を2セット用意。入手に時間がかかった。 f:id:none06:20220116195737j:plain f:id:none06:20220116195742j:plain OEMプロファイルと呼ばれており、列ごとにキー高さが異なる。 f:id:none06:20220116195748j:plain まずは刻印と機能が一致するキーをはめていく。
1個だけフライングしたが、左Shiftキーはテンキーの0キーを使用する。 f:id:none06:20220116195753j:plain 次に刻印は無視して高さと長さが一致するものをはめていく。 f:id:none06:20220116195801j:plain 残念ながら3キーだけ不足するため、2セット目を使用する。なるほどこうしてキーキャップが余っていくのか・・・ f:id:none06:20220116195808j:plain 取り付け完了!美しい・・・ f:id:none06:20220116195813j:plain f:id:none06:20220116195822j:plain 最下段の中央付近だけキーの向きを上下逆に変えた。こうすることで親指を自然に乗せることができる。このアイデアは他の自作キーボード(名前を出してしまうと7sPro)を参考にした。 f:id:none06:20220116195836j:plain f:id:none06:20220116195843j:plain

キーマップのカスタマイズ

ひとまずデフォルトキーマップとする。

キーボードの接続

左右のキーボードを内側のmicro USBコネクタで接続する。左右どちらかのキーボードの外側のmicro USBコネクタでPCに接続する。
f:id:none06:20220116195832j:plain

完成!

f:id:none06:20220116195827j:plain

今後について

  • HHKB日本語配列のキーマップに慣れる。もしくは、自由にキーマップをカスタマイズする。
  • ゴム足でキーボードの高さを調整する。奥側(上側)をもっと高くしたい。なお、手前側(下側)にはアクリル板の劣化を防ぐために低めのゴム足を追加した。

あとがき

はんだ付けの表面実装がキツかった。遊舎工房さんの技術サポートがなかったら気持ちが折れそうだったが、完遂すると大きな自信になった。これで他のキーボードは余裕で自作できる・・・!

参考記事

abitkeys.com salicylic-acid3.hatenablog.com

CentOSのレスキューモードでsshサーバを起動できた

目次

概要

CentOSのレスキューモードでsshサーバを起動できたのでメモ。

経緯

レスキューモードに関して以下の理解だった。

  • ネットワークを使用できない。↓
    • ssh接続できない。↓
      • コマンドのコピペができない。
      • 操作ログをテキストで回収できない。

このうち「ネットワークを使用できない」は明確に誤り。RHEL公式ドキュメントに設定手順があった(はず)。
一方、「ssh接続できない」については公式ドキュメントに情報が見当たらなかったため、試してみた。

環境

概要図

TBD

構成

ホスト名 IPアドレス OS 用途 備考
localhost 172.16.0.253 CentOS 8.4.2105 レスキューモード起動対象 KVMゲスト
linux01 任意 CentOS 7.9.2009 sshクライアント -

手順

1.レスキューモードの起動

インストールメディアからマシンを起動する。
Troubleshootingを選択。 f:id:none06:20211016025713p:plain

Rescue a CentOS Linux systemを選択。 f:id:none06:20211016025715p:plain

13を選択。
ENTERキーを押下。 f:id:none06:20211016025723p:plain shに入れた。

2.IPアドレスの設定

レスキューモード起動直後はIPアドレスが設定されていないため、設定した。当環境では固定IPにしたが、DHCPサーバがいる環境ならDHCPでも良い。

ip a
nmcli con sh
nmcli con mod <デバイス名> ipv4.method manual ipv4.addr <IPアドレス>/<PREFIX>
nmcli con up <デバイス名>
nmcli con sh
ip a

f:id:none06:20211016034531p:plain

3.sshdサービスの起動(失敗)

レスキューモード起動直後はsshdサービスも起動していない。おもむろに起動してみたが、失敗した。

systemctl status sshd
systemctl start sshd
systemctl status sshd
journalctl -u sshd

f:id:none06:20211016030158p:plain

原因はjournalctlのログに出ていた。/etc/ssh/sshd_configが存在しないと言っている。

Oct 15 17:50:15 localhost sshd[2070]: /etc/ssh/sshd_config: No such file or directory

4.sshdサービスの設定

確認したところ確かに存在しなかった。
一方、sshd_config.anacondaという怪しいファイルがあり、内容からして使えそうだったので(後述)リネームしてみた。

ls -l /etc/ssh/sshd_config*
cp -p /etc/ssh/sshd_config.anaconda /etc/ssh/sshd_config
ls -l /etc/ssh/sshd_config*

f:id:none06:20211016030733p:plain

5.sshdサービスの起動(成功)

sshdサービスを起動したらあっさり起動した。

systemctl start sshd
systemctl status sshd

f:id:none06:20211016031051p:plain

6.接続確認

別のサーバからssh接続できることを確認した。ユーザはroot。パスワード認証はなかった。

[root@linux01 ~]# ssh root@172.16.0.253
Warning: Permanently added '172.16.0.253' (ECDSA) to the list of known hosts.
[anaconda root@localhost ~]#

参考

sshd_config.anacondaの内容は以下のとおり。最低限のコンフィグだけが記載されていた。

[anaconda root@localhost ~]# cat /etc/ssh/sshd_config.anaconda
PermitRootLogin yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd yes
SyslogFacility AUTHPRIV
PasswordAuthentication yes
PermitEmptyPasswords yes
PermitUserEnvironment yes

・・・あ、PermitEmptyPasswords yesか、なるほど。

参考記事

なし

QEMU+KVM+iSCSI環境でゲストマシンの多重起動を防止する

f:id:none06:20211013220931p:plain

目次

概要

QEMU+KVM環境でゲストマシンの多重起動を防止する。virtlockdの排他ロック機能を導入する。

経緯

前回の記事でライブマイグレーションの環境を構築したが、共有ディスクがiSCSIのため排他ロックの概念がなく、複数のホストマシンから同一ゲストマシンの多重起動ができてしまうリスクがあった。今回の記事ではそのリスクに対処する。

環境

概要図

f:id:none06:20211013220931p:plain

構成

ホスト名 管理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サーバ
NWアドレス NW名 用途
172.16.0.0/24 管理NW ssh接続、Web管理画面接続
172.16.1.0/24 ストレージNW ストレージ接続(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や定義ファイルのコメントを読む姿勢、いずれも不足していたと痛感した。

QEMU+KVM+iSCSIでライブマイグレーションをする

f:id:none06:20211010153636p:plain

目次

概要

QEMU+KVM+iSCSIな環境でライブマイグレーションを実行する。

経緯

OpenStackのライブマイグレーション機能を試す前に、OpenStack内部で使われているQEMU+KVMで設定と検証をしてみたかった。

環境

概要図

f:id:none06:20211010153636p:plain

構成

ホスト名 管理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ターゲット
NWアドレス NW名 用途
172.16.0.0/24 管理NW ssh接続、Web管理画面接続
172.16.1.0/24 ストレージNW ストレージ接続(iSCSI)

前提

  • ホストマシンは構築済みとする。
  • ゲストマシンは共有ディスク上にインストールする必要がある。当記事ではiSCSIディスク上を用いる。
  • 共有ディスクの排他ロック機能は使用しない。
    • ゲストOSの多重起動ができてしまう。ファイルシステム破損などが起こりうる。
    • オペミスさえしなければ問題ないが、あまりよろしくないため実装後に追記予定。→こちらで実施済み。

手順

1.ホストマシンの設定

注意

移行元と移行先の双方のホストマシンに対して実施すること。

1-1.ファイアウォールの設定

ライブマイグレーションで使用するポート番号に対して通信を許可する。

[root@kvm02 ~]# firewall-cmd --list-ports
[root@kvm02 ~]# firewall-cmd --add-port=49152-49215/tcp --permanent
success
[root@kvm02 ~]# firewall-cmd --reload
success
[root@kvm02 ~]# firewall-cmd --list-ports
49152-49215/tcp
[root@kvm02 ~]#
補足.ポート番号

ポート番号は以下で定義されている。コメントアウトされているがデフォルト設定だとこの値で動作しているっぽい。

[root@kvm02 ~]# grep migration_port /etc/libvirt/qemu.conf
#migration_port_min = 49152
#migration_port_max = 49215
補足.ゲストマシンへの接続にssh以外を使用している場合

環境に依るが、サービスlibvirtlibvirt-tlsの許可が必要。当環境は該当しないため割愛する。

[root@kvm02 ~]# cat /usr/lib/firewalld/services/libvirt.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Virtual Machine Management</short>
  <description>Enable this option if you want to allow remote virtual machine management with SASL authentication and encryption (digest-md5 passwords or GSSAPI/Kerberos). The libvirtd service is needed for this option to be useful.</description>
  <port protocol="tcp" port="16509"/>
</service>
[root@kvm02 ~]# grep -R 16509 /etc/
/etc/libvirt/libvirtd.conf:#tcp_port = "16509"
/etc/libvirt/virtproxyd.conf:#tcp_port = "16509"
[root@kvm02 ~]# lsof -i:16509
[root@kvm02 ~]# cat /usr/lib/firewalld/services/libvirt-tls.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Virtual Machine Management (TLS)</short>
  <description>Enable this option if you want to allow remote virtual machine management with TLS encryption, x509 certificates and optional SASL authentication. The libvirtd service is needed for this option to be useful.</description>
  <port protocol="tcp" port="16514"/>
</service>
[root@kvm02 ~]# grep -R 16514 /etc/
/etc/libvirt/libvirtd.conf:#tls_port = "16514"
/etc/libvirt/virtproxyd.conf:#tls_port = "16514"
[root@kvm02 ~]# lsof -i:16514

2.ゲストマシンの準備

2-1.ゲストマシンの準備

ゲストマシンを準備する。

  • すでにiSCSIディスク上にゲストマシンが存在する場合は不要。
  • ローカルディスク上に存在するゲストマシンをiSCSIディスク上に移行する場合はこちらを参照。
  • ゲストマシンをiSCSIディスク上に新規作成する場合はこちらを参照。
2-2.iSCSIディスクへの接続(ホストマシン)

ゲストマシンの準備の副産物として、ホストマシンからiSCSIディスクへの接続設定がホストマシン上に残る。この設定はライブマイグレーションされないものの必要なため、もう1台のホストマシンでも同様に設定(iSCSIプールの作成と起動)をする。

3.ライブマイグレーション

3-1.ライブマイグレーションの実行

ライブマイグレーションを実行する。オプションの意味は以下。*3

・ --persistent - ドメインを移動先ホスト物理マシンでもそのまま永続的な状態に維持します。
・ --undefinesource - ソースのホスト物理マシンのゲスト仮想マシンを削除します。
・ --verbose - 移行実施中の進捗状況を表示します。

移行元画面:

ライブマイグレーションを実行する。

[root@kvm02 ~]# virsh migrate --domain guest01 --live --persistent --undefinesource qemu+ssh://kvm03/system --verbose
マイグレーション: [100 %]

ゲストマシンが消える。

[root@kvm02 ~]# virsh list --all
 Id   名前           状態
-----------------------------------

定義ファイルも消える。

[root@kvm02 ~]# ls -l /etc/libvirt/qemu/guest01.xml
ls: '/etc/libvirt/qemu/guest01.xml' にアクセスできません: そのようなファイルやディレクトリはありません
移行先画面:

ライブマイグレーション実行後、ゲストマシンが起動する。

[root@kvm03 ~]# virsh list
 Id   名前      状態
------------------------
 1    guest01   実行中

定義ファイルも生成される。

[root@kvm03 ~]# ls -l /etc/libvirt/qemu/guest01.xml
-rw------- 1 root root 5617 10月 10 11:30 /etc/libvirt/qemu/guest01.xml
疎通確認用サーバ画面:

事前にpingを実行しておく。ライブマイグレーション中は応答がなくなる。

[root@linux01 ~]# ping 172.16.0.253
PING 172.16.0.253 (172.16.0.253) 56(84) bytes of data.
--- snip ---
64 bytes from 172.16.0.253: icmp_seq=12 ttl=64 time=2.52 ms
64 bytes from 172.16.0.253: icmp_seq=13 ttl=64 time=2.30 ms
64 bytes from 172.16.0.253: icmp_seq=14 ttl=64 time=2.57 ms # ここでしばらく止まる
64 bytes from 172.16.0.253: icmp_seq=39 ttl=64 time=1.23 ms # ここから再開する
64 bytes from 172.16.0.253: icmp_seq=40 ttl=64 time=0.729 ms
64 bytes from 172.16.0.253: icmp_seq=41 ttl=64 time=0.710 ms
3-2.ライブマイグレーションの実行(逆方向)
移行先画面:
[root@kvm03 ~]# virsh migrate --domain guest01 --live --persistent --undefinesource qemu+ssh://kvm02/system --verbose

マイグレーション: [100 %]
[root@kvm03 ~]# virsh list --all
 Id   名前   状態
-------------------
[root@kvm03 ~]# ls -l /etc/libvirt/qemu/guest01.xml
ls: '/etc/libvirt/qemu/guest01.xml' にアクセスできません: そのようなファイルやディレクトリはありません
移行先画面:
[root@kvm02 ~]# virsh list
 Id   名前      状態
------------------------
 10   guest01   実行中
[root@kvm02 ~]# ls -l /etc/libvirt/qemu/guest01.xml
-rw------- 1 root root 5617 10月 10 11:30 /etc/libvirt/qemu/guest01.xml
疎通確認用サーバ画面:
[root@linux01 ~]# ping 172.16.0.253
PING 172.16.0.253 (172.16.0.253) 56(84) bytes of data.
--- snip ---
64 bytes from 172.16.0.253: icmp_seq=47 ttl=64 time=2.42 ms
64 bytes from 172.16.0.253: icmp_seq=48 ttl=64 time=2.64 ms
64 bytes from 172.16.0.253: icmp_seq=49 ttl=64 time=2.91 ms # ここでしばらく止まる
64 bytes from 172.16.0.253: icmp_seq=72 ttl=64 time=1041 ms # ここから再開する
64 bytes from 172.16.0.253: icmp_seq=73 ttl=64 time=1.19 ms
64 bytes from 172.16.0.253: icmp_seq=74 ttl=64 time=0.872 ms
補足.移行元と移行先のホストマシンのCPUが異なる場合

当環境では以下のエラーが出た。

[root@kvm02 ~]# virsh migrate --domain guest01 --live qemu+ssh://kvm03/system --verbose
エラー: 操作は失敗しました: guest CPU doesn't match specification: missing features: vmx,fma,movbe,bmi1,avx2,bmi2,invpcid,pdpe1gb,abm

ひとまず以下の対処によりエラーを回避できた。

[root@kvm02 ~]# virsh shutdown guest01
ドメイン guest01 はシャットダウン中です
[root@kvm02 ~]# virsh list
 Id   名前   状態
-------------------
[root@kvm02 ~]# virsh edit guest01
ドメイン guest01 XML の設定は編集されました
  • 変更前
  <cpu mode='host-model' check='partial'/>
  • 変更後
  <cpu mode='host-model' check='partial'>
    <feature policy='disable' name='vmx'/>
    <feature policy='disable' name='fma'/>
    <feature policy='disable' name='movbe'/>
    <feature policy='disable' name='bmi1'/>
    <feature policy='disable' name='avx2'/>
    <feature policy='disable' name='bmi2'/>
    <feature policy='disable' name='invpcid'/>
    <feature policy='disable' name='pdpe1gb'/>
    <feature policy='disable' name='abm'/>
  </cpu>
[root@kvm02 ~]# virsh start guest01
ドメイン guest01 が起動されました
[root@kvm02 ~]# virsh list
 Id   名前      状態
------------------------
 9    guest01   実行中

不足しているfeaturesをfeature policy='disable'としてひたすら登録しただけなので暫定対処としか思えない。恒久対処は、/usr/share/libvirt/cpu_map/にCPUのモデルの定義が格納されているため、双方のホストマシンが対応するモデルを特定してゲストマシンに設定するべきだと思う。

補足

ゲストマシンへのping結果を見ると30secほどのダウンタイムが発生しているように見える。これを"ライブ"マイグレーションと呼べるのかと疑念を抱かれかねないため、追加で検証した。

結論

  • OSはダウンタイムなしに稼働している(すごい)。
  • TCPセッションは維持されている。一時的にレスポンスがなくなるが、TCP再送により復帰する(すごい)。
  • UDPやICMPはロストする。ICMPの結果はpingにて確認済み。

検証1.TCP

ゲストマシンにssh接続した状態でライブマイグレーションを実行した。レスポンスの可視化のためにゲストマシン上で1sec間隔でuptimeコマンドを実行した。

[root@guest01 ~]# while :; do uptime; sleep 1; done
 10:07:53 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:54 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:55 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:56 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:57 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:58 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:07:59 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00 # ここでしばらく表示が止まる
 10:08:00 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00 # sshセッション復帰後一気に表示される
 10:08:01 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00
 10:08:02 up 9 min,  1 user,  load average: 0.00, 0.00, 0.00

マイグレーション中はsshクライアントへの出力が止まったが、sshセッション復帰後に止まっていた部分も含めて一気に出力が再開した。

検証2.UDP

ゲストマシンに1sec間隔でsnmpwalkを実行しながらライブマイグレーションを実行した。

[root@linux01 ~]# while :; do snmpwalk -cpublic -v2c 172.16.0.253 uptime; sleep 1; done
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (44539) 0:07:25.39
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (44687) 0:07:26.87
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (44834) 0:07:28.34
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (44982) 0:07:29.82
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (45130) 0:07:31.30
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (45279) 0:07:32.79
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (45427) 0:07:34.27
Timeout: No Response from 172.16.0.253
Timeout: No Response from 172.16.0.253
Timeout: No Response from 172.16.0.253
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (48018) 0:08:00.18
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (48165) 0:08:01.65
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (48313) 0:08:03.13

参考サイト

https://soar.keizof.com/wp/?p=169 www.server-world.info blogger.fastriver.net access.redhat.com access.redhat.com access.redhat.com access.redhat.com

KVMゲストのストレージをイメージファイルからiSCSIディスクに移行する

f:id:none06:20211007000548p:plain

目次

概要

QEMU+KVM環境のゲストマシンのストレージを、イメージファイル(.img)からiSCSIディスクに移行する。移行といってもddで複製するだけだが、その前後の作業が煩雑だったため記録した。
移行なので既存のゲストマシンが作業対象となる。新規ゲストマシンをiSCSIディスクにインストールする方法は前回記事を参照。 none06.hatenadiary.org

経緯

  • KVMホストのローカルディスクの容量が逼迫してきた。恒久対処としてゲストマシンのイメージファイルをKVMホストの外で管理することにした。
  • データの管理場所はNASとした。
  • 接続インターフェース(プロトコル)はiSCSIとした。

環境

概念図

f:id:none06:20211007000548p:plain

構成

ホスト名 管理NWのIP ストレージNWのIP OS H/W 備考
file01 172.16.0.5 172.16.1.5 RAIDiator 4.2.31 NETGEAR ReadyNAS Pro 2 iSCSIターゲット
kvm01 172.16.0.205 172.16.1.205 CentOS 8.4.2105 HP DL360 G7 KVMホスト
guest01 172.16.0.253 - CentOS 8.4.2105 - KVMゲスト
NWアドレス NW名 用途
172.16.0.0/24 管理NW ssh接続、Web管理画面接続
172.16.1.0/24 ストレージNW ストレージ接続(iSCSI)

前提

  • iSCSIターゲットの作成手順は各自確認のこと。
  • ゲストマシンを作成済みとする。ディスクイメージはファイル(.img)とする。

手順

1.iSCSIターゲット/LUNの作成

1-1.移行元ディスク容量の確認

手順の汎用化のため、ゲストマシンのホスト名を変数_NODEに格納しておく。

[root@kvm01 ~]# _NODE=guest01
[root@kvm01 ~]# echo $_NODE
guest01

移行元ディスクの容量を確認する。

[root@kvm01 ~]# qemu-img info /var/lib/libvirt/images/${_NODE}.img
image: /var/tmp/images/guest01.img
file format: qcow2
virtual size: 20 GiB (21474836480 bytes)
disk size: 2.15 GiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
1-2.iSCSIターゲット/LUNの作成

iSCSIターゲット/LUNを作成する。手順は各自の環境に依存。 |ターゲット名|LUN番号|ディスク容量| |:--|:--|:--| |iqn.2020-09.file01:guest01|0|20GB|

ディスク容量について。移行元ディスクと比較して

  • 同一:無駄もなく作業もわかりやすい
  • 大きい:ディスク複製は可能だが作業後に必要に応じて拡張が必要(当記事のスコープ外)
  • 小さい:当記事の手順では移行不可(※)

パーティション作成、バックアップ(xfsdump)、リストア(xfsrestore)、grub更新、fstab更新、などを行なえば可能。

2.事前作業

2-1.ゲストマシンの定義ファイルのバックアップ

ゲストマシンの定義ファイルをバックアップする。

[root@kvm01 ~]# ls -l /etc/libvirt/qemu/${_NODE}.xml*
-rw------- 1 root root 4316 10月  8 20:25 /etc/libvirt/qemu/guest01.xml
[root@kvm01 ~]# cp -p /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)}
[root@kvm01 ~]# ls -l /etc/libvirt/qemu/${_NODE}.xml*
-rw------- 1 root root 4316 10月  8 20:25 /etc/libvirt/qemu/guest01.xml
-rw------- 1 root root 4316 10月  8 20:25 /etc/libvirt/qemu/guest01.xml_20211009

3.移行元ディスクの接続

3-1.nbdモジュールの読み込み

nbdモジュールを読み込む。

[root@kvm01 ~]# modprobe nbd
[root@kvm01 ~]# lsmod | grep nbd
nbd                    49152  0

nbdデバイスが作成されていることを確認する。

[root@kvm01 ~]# ls -l /dev/nbd*
brw-rw---- 1 root disk 43,   0 10月  9 13:26 /dev/nbd0
brw-rw---- 1 root disk 43,  32 10月  9 13:18 /dev/nbd1
brw-rw---- 1 root disk 43, 320 10月  9 13:18 /dev/nbd10
brw-rw---- 1 root disk 43, 352 10月  9 13:18 /dev/nbd11
brw-rw---- 1 root disk 43, 384 10月  9 13:18 /dev/nbd12
brw-rw---- 1 root disk 43, 416 10月  9 13:18 /dev/nbd13
brw-rw---- 1 root disk 43, 448 10月  9 13:18 /dev/nbd14
brw-rw---- 1 root disk 43, 480 10月  9 13:18 /dev/nbd15
brw-rw---- 1 root disk 43,  64 10月  9 13:18 /dev/nbd2
brw-rw---- 1 root disk 43,  96 10月  9 13:18 /dev/nbd3
brw-rw---- 1 root disk 43, 128 10月  9 13:18 /dev/nbd4
brw-rw---- 1 root disk 43, 160 10月  9 13:18 /dev/nbd5
brw-rw---- 1 root disk 43, 192 10月  9 13:18 /dev/nbd6
brw-rw---- 1 root disk 43, 224 10月  9 13:18 /dev/nbd7
brw-rw---- 1 root disk 43, 256 10月  9 13:18 /dev/nbd8
brw-rw---- 1 root disk 43, 288 10月  9 13:18 /dev/nbd9
3-2.nbdデバイスへの接続

ディスクイメージをnbdデバイスに接続する。

[root@kvm01 ~]# blkid | grep nbd0
[root@kvm01 ~]# qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/${_NODE}.img
[root@kvm01 ~]# blkid | grep nbd0
/dev/nbd0: PTUUID="417f0ae5" PTTYPE="dos"
/dev/nbd0p1: UUID="41619de3-6f19-40cf-b088-27e34d842a53" BLOCK_SIZE="1024" TYPE="ext4" PARTUUID="417f0ae5-01"
/dev/nbd0p2: UUID="64849620-bd0d-48ad-93e3-a2861530fc2e" TYPE="swap" PARTUUID="417f0ae5-02"
/dev/nbd0p3: UUID="2a90a8c7-1221-435d-8a8b-b9e660a70c67" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="417f0ae5-03"

パーティションが見えた。すごい。

4.移行先ディスクの接続

4-1.iSCSIプールの定義

iSCSIプールを定義する。

[root@kvm01 ~]# virsh pool-list --all
 名前       状態       自動起動
-----------------------------------
[root@kvm01 ~]# virsh pool-define-as --name ${_NODE} --type iscsi --source-host 172.16.1.5 --source-dev iqn.2020-09.file01:${_NODE} --target /dev/disk/by-path/
プール guest01 が定義されました
[root@kvm01 ~]# virsh pool-list --all
 名前       状態       自動起動
------------------------------------
 guest01    停止状態   いいえ (no)
4-2.iSCSIプールの起動

iSCSIプールを起動する。裏でiSCSIターゲットへのログインが行われるので前後で状態を確認しておく。

[root@kvm01 ~]# iscsiadm --mode node
iscsiadm: No records found
[root@kvm01 ~]# iscsiadm --mode session
iscsiadm: No active sessions.
[root@kvm01 ~]# virsh pool-start ${_NODE}
プール guest01 が起動されました
[root@kvm01 ~]# virsh pool-autostart ${_NODE}
プール guest01 が自動起動としてマークされました
[root@kvm01 ~]# virsh pool-list --all
 名前       状態       自動起動
-----------------------------------
 guest01    動作中     はい (yes)
[root@kvm01 ~]# iscsiadm --mode node
172.16.1.5:3260,1 iqn.2020-09.file01:guest01
[root@kvm01 ~]# iscsiadm --mode session
tcp: [78] 172.16.1.5:3260,1 iqn.2020-09.file01:guest01 (non-flash)
4-3.ディスクの認識確認

ディスクを認識できていることを確認する。

[root@kvm01 ~]# ls -l /dev/disk/by-path | grep ${_NODE}
lrwxrwxrwx 1 root root  9 10月  9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0 -> ../../sdb
lrwxrwxrwx 1 root root 10 10月  9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 10月  9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part2 -> ../../sdb2
lrwxrwxrwx 1 root root 10 10月  9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part3 -> ../../sdb3

上記よりデバイス名は/dev/sdbだと特定できる。手順の汎用化のため変数_TARGET_DEVに格納しておく。

[root@kvm01 ~]# _TARGET_DEV=$(ls -l /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 | sed 's#.*../../#/dev/#')
[root@kvm01 ~]# echo $_TARGET_DEV
/dev/sdb
[root@kvm01 ~]# fdisk -l ${_TARGET_DEV}
ディスク /dev/sdb: 20 GiB, 21474837504 バイト, 41943042 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 524288 バイト
[root@kvm01 ~]# blkid | grep ${_TARGET_DEV}

※blkidではまだ見えない。

5.ディスクの移行

5-1.ディスクの複製

ディスクを複製する。原始的なddを使う。

[root@kvm01 ~]# dd if=/dev/nbd0 of=${_TARGET_DEV} bs=1024 status=progress
2429779968 bytes (2.4 GB, 2.3 GiB) copied, 6 s, 405 MB/s
--- snip ---
21439167488 bytes (21 GB, 20 GiB) copied, 242 s, 88.6 MB/s
20971520+0 レコード入力
20971520+0 レコード出力
21474836480 bytes (21 GB, 20 GiB) copied, 297.242 s, 72.2 MB/s
[root@kvm01 ~]# blkid | grep ${_TARGET_DEV}
/dev/sdb1: UUID="81e8e85e-f169-443b-a525-2294f0c3e1ed" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="000a8874-01"
/dev/sdb2: UUID="ee5a595f-3bf7-48bd-9ba4-b02468b60eab" TYPE="swap" PARTUUID="000a8874-02"
/dev/sdb3: UUID="828fc91e-fa92-4dfc-944c-c4c70ec43cb7" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="000a8874-03"
5-2.nbdデバイスからの切断

移行元ディスクをnbdデバイスから切断する。

[root@kvm01 ~]# qemu-nbd --disconnect /dev/nbd0
/dev/nbd0 disconnected
[root@kvm01 ~]# blkid | grep nbd0

6.ゲストマシンの定義変更

6-1.ゲストマシンからの移行元ディスクの切断

ゲストマシンから移行元ディスクを切断する。

[root@kvm01 ~]# virsh dumpxml guest01
--- snip ---
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/tmp/images/guest01.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </disk>
--- snip ---

バイス名は上記よりvdaだと特定できる。手順の汎用化のために変数_GUEST_DEVに格納する。

[root@kvm01 ~]# _GUEST_DEV=$(virsh dumpxml ${_NODE} | grep .img -2 | grep "target dev" | sed "s/.*dev='\(.*\)' bus.*/\1/g")
[root@kvm01 ~]# echo $_GUEST_DEV
vda
[root@kvm01 ~]# virsh detach-disk ${_NODE} --target ${_GUEST_DEV} --config
ディスクが正常に切断されました
6-2.ゲストマシンへの移行先ディスクの接続

ゲストマシンへ移行先ディスクを接続する。

[root@kvm01 ~]# virsh attach-disk --domain ${_NODE} --source /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 --target vda --io native --cache none --config
ディスクが正常に接続されました
6-3.定義ファイルの差分確認

定義ファイルの差分箇所がディスク関連のみであることを確認する。

[root@kvm01 ~]# diff /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)}
27c27,29
<   <cpu mode='host-model' check='partial'/>
---
>   <cpu mode='host-model' check='partial'>
>     <model fallback='allow'/>
>   </cpu>
42,44c44,46
<     <disk type='block' device='disk'>
<       <driver name='qemu' type='raw' cache='none' io='native'/>
<       <source dev='/dev/disk/by-path/ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0'/>
---
>     <disk type='file' device='disk'>
>       <driver name='qemu' type='qcow2'/>
>       <source file='/var/lib/libvirt/images/guest01.img'/>

※cpuのmodelの差分は不明だが無影響。

6-4.ゲストマシンの起動

ゲストマシンを起動する。

[root@kvm01 ~]# virsh list
 Id   名前   状態
-------------------
[root@kvm01 ~]# virsh start ${_NODE}
ドメイン guest01 が起動されました
[root@kvm01 ~]# virsh list
 Id   名前      状態
------------------------
 1    guest01   実行中
6-5.ゲストマシンの正常性確認

ログインするなどしてOSが正常に起動していることを確認する。

おまけ

当記事の手順をスクリプト化したものを貼っておく。

#!/bin/sh
#
# img2iscsi.sh
#
#   Usage: img2iscsi.sh <_NODE>
#

# 引数チェック
if [ "$1" = "" ]; then
        echo "Usage: $0 <_NODE>"
        exit 1
fi
_NODE=$1

# 1.iSCSIターゲット/LUNの作成
# 完了している前提とする

# 2.事前作業
ls -l /etc/libvirt/qemu/${_NODE}.xml*
if [ ! -f /etc/libvirt/qemu/${_NODE}.xml_$(date +%Y%m%d) ]; then
        cp -p /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)}
        ls -l /etc/libvirt/qemu/${_NODE}.xml*
fi

# 3.移行元ディスクの接続
lsmod | grep nbd; if [ $? -ne 0 ]; then modprobe nbd; lsmod | grep nbd; fi
ls -l /dev/nbd0
blkid
qemu-nbd --connect=/dev/nbd0 /var/tmp/images/${_NODE}.img
blkid

# 4.移行先ディスクの接続
virsh pool-list --all
virsh pool-define-as --name ${_NODE} --type iscsi --source-host 172.16.1.5 --source-dev iqn.2020-09.file01:${_NODE} --target /dev/disk/by-path/
virsh pool-start ${_NODE}
virsh pool-autostart ${_NODE}
virsh pool-list --all

_TARGET_DEV=$(ls -l /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 | sed 's#.*../../#/dev/#')
echo "_TARGET_DEV: $_TARGET_DEV"

# 5.ディスクの移行
tune2fs -l /dev/nbd0p1 | grep "Block size"
xfs_info /dev/nbd0p3
dd if=/dev/nbd0 of=${_TARGET_DEV} bs=1024 status=progress
blkid
tune2fs -l ${_TARGET_DEV}1 | grep "Block size"
xfs_info ${_TARGET_DEV}3

qemu-nbd --disconnect /dev/nbd0
blkid

# 6.ゲストマシンの定義変更
_GUEST_DEV=$(virsh dumpxml ${_NODE} | grep .img -2 | grep "target dev" | sed "s/.*dev='\(.*\)' bus.*/\1/g")
virsh detach-disk ${_NODE} --target ${_GUEST_DEV} --config

virsh attach-disk --domain ${_NODE} --source /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 --target vda --io native --cache none --config

diff /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)}

virsh list
virsh start ${_NODE}
virsh list

#EOF

参考サイト

oplern.hatenablog.com

iSCSI boot on QEMU+KVM case3

f:id:none06:20211007000548p:plain

目次

概要

QEMU+KVM環境でゲストマシンをiSCSIブートする。

case1,case2との違い

case1,cese2は結局のところPXE+DHCPで頑張っていたに過ぎず、QEMU+KVMの機能を使っていなかった。今回はQEMU+KVMの機能を活用する。 大きな違いはゲストマシンとiSCSIディスクとの接続方法。case1,case2は直接接続していたが、case3はホストマシンを介して接続する。 個人的にはcase1,case2のゲストマシンがホストマシンから独立してストレージに直接接続するあたりが疎結合で好み。しかし、設定がやや大変。その点case3は設定が非常に楽だったので捨てがたい。

DHCPサーバ 必要 必要 不要 case1のほうがやや設定が多い
HTTPサーバ 必要 不要 不要 -
iPXEスクリプト 必要 不要 不要 -
メンテナンス性 良い 悪い 良い -
機能間の結合度 なるべく疎にしたい

経緯

  • KVMホストのローカルディスクの容量が逼迫してきた。恒久対処としてゲストマシンのイメージファイルをKVMホストの外で管理することにした。
  • データの管理場所はNASとした。
  • 接続インターフェース(プロトコル)はiSCSIとした。

環境

概念図

f:id:none06:20211007000548p:plain

構成

ホスト名 管理NWのIP ストレージNWのIP OS H/W 備考
file01 172.16.0.5 172.16.1.5 RAIDiator 4.2.31 NETGEAR ReadyNAS Pro 2 iSCSIターゲット
kvm02 172.16.0.206 172.16.1.206 CentOS 8.4.2105 Fujitsu TX1320 M1 KVMホスト
guest03 172.16.0.253 - CentOS 8.4.2105 - KVMゲスト
NWアドレス NW名 用途
172.16.0.0/24 管理NW ssh接続、Web管理画面接続
172.16.1.0/24 ストレージNW ストレージ接続(iSCSI)

前提

  • iSCSIターゲットの作成手順は各自確認のこと。
  • ゲストマシンのOSは新規インストールする。
  • OSのインストールメディアを用意していること。

手順

1.iSCSIターゲット/LUNの作成

1-1.以下の要領で作成する。

ターゲット名 LUN番号 ディスク容量
guest03 0 20GB

f:id:none06:20211006231616p:plain

2.iSCSIディスクのプール化

2-1.ホストマシンでiSCSIターゲットにログインし、ディスクを認識させる。

[root@kvm02 ~]# iscsiadm -m node -T iqn.2020-09.file01:guest03 -p file012 --login
Logging in to [iface: default, target: iqn.2020-09.file01:guest03, portal: 172.16.1.5,3260]
Login to [iface: default, target: iqn.2020-09.file01:guest03, portal: 172.16.1.5,3260] successful.
[root@kvm02 ~]# iscsiadm -m session
tcp: [2] 172.16.1.5:3260,1 iqn.2020-09.file01:guest03 (non-flash)
[root@kvm02 ~]# fdisk -l /dev/sdb
ディスク /dev/sdb: 20 GiB, 21474837504 バイト, 41943042 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 524288 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0xff4b72b7

デバイス   起動 開始位置 終了位置   セクタ サイズ Id タイプ
/dev/sdb1  *        2048  2099199  2097152     1G 83 Linux
/dev/sdb2        2099200  6293503  4194304     2G 82 Linux スワップ / Solaris
/dev/sdb3        6293504 41943039 35649536    17G 83 Linux

2-3.ディスクをQEMU+KVMのプールに登録する。

[root@kvm02 ~]# virsh pool-list --all
 名前      状態       自動起動
----------------------------------
[root@kvm02 ~]# virsh pool-define-as --name pool_guest03 --type iscsi --source-host file012 --source-dev iqn.2020-09.file01:guest03 --target /dev/disk/by-path/
プール pool_guest03 が定義されました
[root@kvm02 ~]# virsh pool-list --all
 名前           状態       自動起動
----------------------------------------
 pool_guest03   停止状態   いいえ (no)
[root@kvm02 ~]# virsh pool-start pool_guest03
プール pool_guest03 が起動されました
[root@kvm02 ~]# virsh pool-autostart pool_guest03
プール pool_guest03 が自動起動としてマークされました
[root@kvm02 ~]# virsh pool-list --all
 名前           状態       自動起動
---------------------------------------
 pool_guest03   動作中     はい (yes)
[root@kvm02 ~]# virsh pool-info pool_guest03
名前:         pool_guest03
UUID:           242b198b-69a2-45b0-8b89-a2411ac4e23c
状態:         実行中
永続:         はい (yes)
自動起動:   はい (yes)
容量:         20.00 GiB
割り当て:   20.00 GiB
利用可能:   0.00 B

2-4.プール内のボリュームを確認する。

[root@kvm02 ~]# virsh vol-list pool_guest03
 名前         パス
-------------------------------------------------------------------------------------------
 unit:0:0:0   /dev/disk/by-path/ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest03-lun-0

3.ゲストマシンの構築

3-1.ゲストマシンを作成する。
ポイントは、--diskプール名/ボリューム名を指定する点。

[root@kvm02 ~]# virt-install \
> --hvm \
> --name guest03 \
> --vcpus 4 \
> --ram 4096 \
> --disk vol=pool_guest03/unit:0:0:0 \
> --os-type linux \
> --os-variant centos8 \
> --network bridge=br0 \
> --graphics none \
> --location "/tmp/CentOS-8.4.2105-x86_64-dvd1.iso" \
> --console pty,target_type=serial \
> --extra-args "console=tty0 console=ttyS0,115200n8"

インストールの開始中...
ファイル vmlinuz を読出中...                                                                          | 9.6 MB  00:00:00
ファイル initrd.img を読出中...                                                                       |  72 MB  00:00:00
ドメイン guest03 に接続しました
エスケープ文字は ^] です
[    0.094429] pci 0000:00:1f.2: reg 0x20: [io  0xc040-0xc05f]
[    0.095857] pci 0000:00:1f.2: reg 0x24: [mem 0xfdc07000-0xfdc07fff]
[    0.097168] pci 0000:00:1f.3: [8086:2930] type 00 class 0x0c0500
### snip ###

3-2.OSをインストールする。
特段考慮する点はない。ゲストマシンから見たディスクはただのローカルディスクに見える。case1,case2ではiSCSIディスクに見えていたのでこの点が大きな違い。

Starting installer, one moment...
anaconda 33.16.4.15-1.el8.0.2 for CentOS Linux 8 started.
 * installation log files are stored in /tmp during the installation
 * shell is available on TTY2
 * if the graphical installation interface fails to start, try again with the
   inst.text bootoption to start text installation
 * when reporting a bug add logs from /tmp as separate text/plain attachments
13:25:21 Not asking for VNC because we don't have a network
================================================================================
================================================================================
Installation

1) [x] Language settings                 2) [x] Time settings
       (English (United States))                (America/New_York timezone)
3) [!] Installation source               4) [!] Software selection
       (Processing...)                          (Processing...)
5) [!] Installation Destination          6) [x] Kdump
       (Processing...)                          (Kdump is enabled)
7) [!] Network configuration             8) [!] Root password
       (Not connected)                          (Root account is disabled.)
9) [!] User creation
       (No user will be created)

Please make a selection from the above ['b' to begin installation, 'q' to quit,
'r' to refresh]:
[anaconda]1:main* 2:shell  3:log  4:storage-log >Switch tab: Alt+Tab | Help: F1

3-3.OSインストールを完了させる。

4.ゲストマシンの状態確認

4-1.ゲストマシンにログインする。

[root@kvm02 ~]# virsh list
 Id   名前      状態
------------------------
 5    guest03   実行中
[root@kvm02 ~]# virsh console guest03
ドメイン guest03 に接続しました
エスケープ文字は ^] です

CentOS Linux 8
Kernel 4.18.0-305.3.1.el8.x86_64 on an x86_64

localhost login: root
パスワード:
前回のログイン: Wed Oct  6 22:40:15 端末: ttyS0
[root@localhost ~]#

4-2.ディスクの状態を確認する。

[root@localhost ~]# fdisk -l
ディスク /dev/vda: 20 GiB, 21474837504 バイト, 41943042 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0xff4b72b7

デバイス   起動 開始位置 終了位置   セクタ サイズ Id タイプ
/dev/vda1  *        2048  2099199  2097152     1G 83 Linux
/dev/vda2        2099200  6293503  4194304     2G 82 Linux スワップ / Solaris
/dev/vda3        6293504 41943039 35649536    17G 83 Linux
[root@localhost ~]# iscsiadm -m session
-bash: iscsiadm: コマンドが見つかりません

ゲストマシンからはあたかもローカルディスクのように見える。iSCSIプロトコルはストレージとホストマシンとの間で終端しているため。

参考サイト

https://soar.keizof.com/wp/?p=157 access.redhat.com