はじめに
こんにちは。
この記事は、Microsoft Azure Tech Advent Calendar 2022 22日目の記事です。
Azure Linux VM にデータディスクを複数接続したとき、Linux に認識されているディスク (/dev/sdX) が Azure のどのディスクなのか識別したいときがあります。この記事では、Linux VM デバイス名の変更トラブルシューティング に書いてあることをもう少し具体的に見ていきます。
準備
おもむろに 4GB のデータディスクを3つ接続した Gen1 Ubuntu VM を作成します。
az group create -g diskgroup -l japaneast
for i in `seq 1 3`; do az disk create -g diskgroup -n data$i -l japaneast --size-gb 4 --sku Standard_LRS; done
az vm create -g diskgroup -n diskvm --image UbuntuLTS --attach-data-disks data1 data2 data3
lsblk
コマンド
SSH 接続後、lsblk
でブロックデバイスを表示してみます。
root@diskvm:~# lsblk -i
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 30G 0 disk
|-sda1 8:1 0 29.9G 0 part /
|-sda14 8:14 0 4M 0 part
`-sda15 8:15 0 106M 0 part /boot/efi
sdb 8:16 0 7G 0 disk
`-sdb1 8:17 0 7G 0 part /mnt
sdc 8:32 0 4G 0 disk
sdd 8:48 0 4G 0 disk
sde 8:64 0 4G 0 disk
sr0 11:0 1 628K 0 rom
sda1
が /
にマウントされているので、sda
が OS ディスク、sdb1
が /mnt
にマウントされているので、sdb1
が一時ディスク、sdc
, sdd
, sde
がデータディスクっ ぽい という事はわかります。また、Azure 上に限らず Linux においてはこのデバイス名の一貫性が保証されていないため、デバイス名だけを見て判断するのは軽率です。
lsscsi
コマンド
ディスクを識別する一つの方法は、lsscsi
コマンドで SCSI アドレス ([Host:Bus:Target:Lun]) をみることです。
VM の世代により SCSI アドレスが若干異なるため、後述の /dev/disk/azure
をみる方が確実ですが、少なくともデータディスクの LUN を見分けることが可能です。
root@diskvm:~# lsscsi
[0:0:0:0] disk Msft Virtual Disk 1.0 /dev/sda
[1:0:1:0] disk Msft Virtual Disk 1.0 /dev/sdb
[3:0:0:0] disk Msft Virtual Disk 1.0 /dev/sdc
[3:0:0:1] disk Msft Virtual Disk 1.0 /dev/sde
[3:0:0:2] disk Msft Virtual Disk 1.0 /dev/sdd
[5:0:0:0] cd/dvd Msft Virtual CD/ROM 1.0 /dev/sr0
今回の Gen1 の場合は SCSI アダプター番号 (Host) が 0
のものが OS ディスク、1
のものが一時ディスク、3
のものがデータディスクとなり、さらにその Lun が、Azure VM の LUN に一致しています。
つまり、このコマンド結果からは、/dev/sdc
が LUN 0, /dev/sde
が LUN 1, /dev/sdd
が LUN 2 という事が確認できます。
/sys/block/*/device
のシンボリックリンクでも SCSI アドレスが確認できます。
root@diskvm:~# ls -l /sys/block/*/device
lrwxrwxrwx 1 root root 0 Dec 21 14:44 /sys/block/sda/device -> ../../../0:0:0:0
lrwxrwxrwx 1 root root 0 Dec 21 14:44 /sys/block/sdb/device -> ../../../1:0:1:0
lrwxrwxrwx 1 root root 0 Dec 21 14:44 /sys/block/sdc/device -> ../../../3:0:0:0
lrwxrwxrwx 1 root root 0 Dec 21 14:44 /sys/block/sdd/device -> ../../../3:0:0:2
lrwxrwxrwx 1 root root 0 Dec 21 14:44 /sys/block/sde/device -> ../../../3:0:0:1
lrwxrwxrwx 1 root root 0 Dec 21 14:48 /sys/block/sr0/device -> ../../../5:0:0:0
/dev/disk/azure
/dev/disk/azure
ができている場合、このディレクトリ配下のシンボリックリンクにより識別が可能です。
ls -l
や tree
を使って確認してみます。
root@diskvm:~# ls -l /dev/disk/azure/*
lrwxrwxrwx 1 root root 9 Dec 21 14:44 /dev/disk/azure/resource -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 21 14:44 /dev/disk/azure/resource-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 9 Dec 21 14:44 /dev/disk/azure/root -> ../../sda
lrwxrwxrwx 1 root root 10 Dec 21 14:44 /dev/disk/azure/root-part1 -> ../../sda1
lrwxrwxrwx 1 root root 11 Dec 21 14:44 /dev/disk/azure/root-part14 -> ../../sda14
lrwxrwxrwx 1 root root 11 Dec 21 14:44 /dev/disk/azure/root-part15 -> ../../sda15
/dev/disk/azure/scsi1:
total 0
lrwxrwxrwx 1 root root 12 Dec 21 14:44 lun0 -> ../../../sdc
lrwxrwxrwx 1 root root 12 Dec 21 14:44 lun1 -> ../../../sde
lrwxrwxrwx 1 root root 12 Dec 21 14:44 lun2 -> ../../../sdd
root@diskvm:~# apt install tree
root@diskvm:~# tree /dev/disk/azure/
/dev/disk/azure/
├── resource -> ../../sdb
├── resource-part1 -> ../../sdb1
├── root -> ../../sda
├── root-part1 -> ../../sda1
├── root-part14 -> ../../sda14
├── root-part15 -> ../../sda15
└── scsi1
├── lun0 -> ../../../sdc
├── lun1 -> ../../../sde
└── lun2 -> ../../../sdd
1 directory, 9 files
resource
が一時ディスク、root
が OS ディスク、scsi1/lunX
がデータディスクの LUN X に対応することを意味しています。
それらに続く -part
はパーティション番号です。
このディレクトリやシンボリック リンクは、udev
によって生成されています。udev ルールは VM エージェント (WALinuxAgent) パッケージに含まれているため、Azure MarketPlace のイメージから導入した Linux VM では殆どの場合に利用できるはずです。
なお、WALinuxAgent は GitHub 上で開発されいるため、最新のルールは下記リンク先から取得が可能です。
Azure IMDS から Azure Disk の情報を得る
実は前述の udev ルールを改造し、Azure IMDS から得た情報を基にシンボリックリンクを作成しようと思っていたのですが、udevd が実行されるタイミングではネットワークが使用できないため断念しました。
今回は、LUN 番号からディスクのリソース情報を得るための方法だけ紹介します。
IMDS は JSON 形式のデータを返すため、jq をインストールします。
root@diskvm:~# apt install jq
.compute.storageProfile.dataDisks[]
にデータディスク情報が含まれていますので、LUN で select
することで、LUN に接続されているデータディスクのリソース情報を得ることができます。以下は LUN "0"
のクエリ例です。
root@diskvm:~# /usr/bin/curl -s -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | /usr/bin/jq -r '.compute.storageProfile.dataDisks[] | select(.lun=="0")'
{
"caching": "None",
"createOption": "Attach",
"diskSizeGB": "4",
"image": {
"uri": ""
},
"lun": "0",
"managedDisk": {
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/diskgroup/providers/Microsoft.Compute/disks/data1",
"storageAccountType": "Standard_LRS"
},
"name": "data1",
"vhd": {
"uri": ""
},
"writeAcceleratorEnabled": "false"
}
これで、リソース名 data1
のデータディスクが、VM の LUN 0 に接続されており、/dev/sdc として認識されている事が確認できました。
まとめ
- デバイス名 (/dev/sdX) は変わることがあるので注意が必要
-
/dev/disk/azure
のシンボリックリンクを見ると、LUN との対応がわかる - Azure IMDS を使うと、ディスク リソース情報が VM 内から見れる