OCI Computeでブロックボリュームをマウントする
マニュアルやチュートリアルにも書かれているテーマだけれど、その内容がイマイチなので、ここで整理したい。
0. 対象環境
1. なぜブロックボリュームのマウントについて書くのか
ブロックボリュームのマウントはCompute(IaaS)を利用する際に、もっとも基本的な操作の1つである。ところがOCIのマニュアルやチュートリアルを読むと、心配になるほど貧弱な記述であることに気付く。
具体的には
- OCIのブロックボリュームはgptだし、最大32TBまで可能なのに、なぜfdisk使ってるの?
今どき論理ボリュームマネージャ(LVM)は使わないの?
追記:クラウドではボリュームを簡単に拡張できるので、LVMを使わないことも多い。fdiskのgpt対応については、Oracle Linux 7でもexperimental(実験的)フェーズなのでpartedを推奨。
さらに「チュートリアル : Oracle Cloud Infrastructure を使ってみよう」の「ブロック・ボリュームをインスタンスにアタッチする - Oracle Cloud Infrastructureを使ってみよう(その4)」では、下記のように作成中でごまかしている始末。うーん。
3. (オプション) ボリュームのフォーマットおよびマウント(作成中)以下のように修正された。その後、実際にボリューム上にデータを配置する際には、各OS上で適切なファイルシステムを構築して利用してください。
ということで、次にわたしが理想的と考えている方法を説明する。
今回は「Oracle Linux 6」「Oracle Linux 7」「Oracle Linux 8」を使用しているが、CentOS 6/7/8は当然のこと、RHEL系のディストリビューションでも同じハズだ。さらに純粋なLinuxコマンド部分だけについて言えば、AWSやAzureでも通用する内容にしたつもりである。
またLVMを使わない方法は、別エントリーに差分だけを書くことにする。クラウドではLVMを使わないほうが一般的だ。
2. デフォルトのディスク情報を確認する
実際にコマンドを実行する箇所ではOracle Linux 7を使用する。7と8では、ほぼ同じ操作だ。またOracle Linux 6は大きく違うときに限り併記する。
2-1. ディスク構成を確認する
まずデフォルトのディスク構成を確認する。するとブートボリュームとして/dev/sdaがあり、UEFI構成になっていることがわかる。
# lsblk -o +UUID NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT UUID sda 8:0 0 46.6G 0 disk ├─sda2 8:2 0 8G 0 part [SWAP] 8c83c999-ef07-40b5-b001-9658556502d3 ├─sda3 8:3 0 38.4G 0 part / eb7fd29b-a114-4e5e-8926-a6f4a541d605 └─sda1 8:1 0 200M 0 part /boot/efi 52AE-1880
2-2. パーティション構成を確認する
続いてパーティション構成を確認する。するとパーティションテーブルは従来のMBRではなくgptになっている。またファイルシステムは、Oracle Linux 7=xfs、Oracle Linux 6=ext4になっている。
表示だけならばfdisk -l
で確認できるが、fdiskのgpt対応はexperimentalフェーズなので推奨しない。partedやgdiskが推奨である。とくにpartedは対話的に実行しない方法が提供されているのでオススメである。gdiskはgpt対応のfdiskクローン。
# parted -l Model: ORACLE BlockVolume (scsi) Disk /dev/sda: 50.0GB Sector size (logical/physical): 512B/4096B Partition Table: gpt★ Disk Flags: Number Start End Size File system Name Flags 1 1049kB 211MB 210MB fat16 EFI System Partition boot 2 211MB 8801MB 8590MB linux-swap(v1) 3 8801MB 50.0GB 41.2GB xfs★
# parted -l Model: ORACLE BlockVolume (scsi) Disk /dev/sda: 50.0GB Sector size (logical/physical): 512B/4096B Partition Table: gpt★ Number Start End Size File system Name Flags 1 1049kB 211MB 210MB fat16 boot 2 211MB 8801MB 8590MB linux-swap(v1) 3 8801MB 50.0GB 41.2GB ext4★
また上記の結果からもわかるが、pvsで確認すると、論理ボリュームマネージャ(以降LVM)が構成されていないことがわかる。
# pvs ★何も表示されない★
3. コンシステンス・デバイス・パスとは
ブロックボリュームをマウントする方法には、デバイス名として従来通りUUIDを指定する方法と、コンシステンス・デバイス・パスを指定する方法がある。コンシステンス・デバイス・パスは以下の条件を満たすときに使用できる。
筆者が調べた限りでは、LVM環境ではコンシステンス・デバイス・パスは利用できなかった。パーティション内の論理ボリュームを認識できないためだと思われる(2019/5)。
3-1. リブートするとデバイス名が変わる問題
Linuxでリモートストレージを使用する場合、デバイス追加などが発生すると、再起動時にデバイス名が変わる可能性がある。そのために導入されたのがコンシステンス・デバイス・パスだ。コンシステンス・デバイス・デバイス名はリブートしても変わらないので、安心して/etc/fstabに指定できる。
また従来の方法でもUUIDを指定すれば、リブートによるデバイス名変更の影響は受けない。コンシステンス・デバイス・パスは、UUIDよりも人間にリーダブルな方法と考えていいだろう。ただし制限事項もあるので、どちらを利用するかは使用しているイメージやLVM使用の有無、既存環境との互換性などを考慮したうえで選択して欲しい。
3-2. コンシステンス・デバイス・パスの確認方法
コンシステンス・デバイス・パスはブロックボリュームアタッチ時に指定でき、管理コンソールでも確認できる。以下のようなDevice Pathになっているときは/etc/fstabで/dev/oracleoci/oraclevdc1のようなデバイス名を使用できる。
3-3. 従来のUUIDを使用する
今回はLVMを使用するので従来のUUIDを使った方法を主体に説明する。コンシステンス・デバイス・パスについては補足にとどめる。マニュアルの参考箇所は以下の通り。
- fstab Options for Block Volumes Using Consistent Device Paths
- Traditional fstab Options
- 一貫性のあるデバイス・パスを使用したBlock Volumesの/etc/fstabオプション
- /etc/fstabオプション
4. インスタンスにブロックボリュームを追加する
実際にブロックボリュームを作成し、Computeインスタンスにアタッチする。アタッチとは、オンプレミスで言うところの「ケーブル接続」という感覚に近い。
4-1.ブロックボリュームを作成する
Computeと同じADにブロックボリュームを作成する。今回はvolume-phx-ad-t-orcl01-ol7というブロックボリュームを作成する。
4-2. ブロックボリュームをアタッチする
コンソールやCLIなどで、以下の条件でボリュームをアタッチする。
- ATTACHMENT TYPE : Paravirtualized
- BLOCK VOLUE NAME: volume-phx-ad-t-orcl01-ol7
- DEVICE PATH: /dev/oracleoci/oraclevdb
- IN-TRANSIT ENCRYPTION: not check(disable)
- Access: Read/Write
ヒント ブロックボリュームのアタッチ方法には、ParavirtualizedとiSCSIの2種類がある。現在払い出すインスタンスは「仮想マシンはParavirtualizedもしくはiSCSI」「ベアメタルはiSCSI」を使用できる。
Paravirtualizedのほうが手順は簡単だが、iSCSIのほうがIOPS性能に優れている。どちらを使用するかは、以下のマニュアルを読んで決めて欲しい。
「iSCSIのほうが性能がいい」ということだったが、筆者がテストしたところ大きな差はみられなかった。ただしiSCSI接続は、Enterprise SLA(Performance)を適用する前提条件になっている。
手順は以下のエントリを参照のこと。
4-3. 追加したブロックボリュームを確認する
再びディスク情報を確認すると/dev/sdbがアタッチされている。
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb 8:16 0 50G 0 disk★追加したボリューム sda 8:0 0 46.6G 0 disk ├─sda2 8:2 0 8G 0 part [SWAP] ├─sda3 8:3 0 38.4G 0 part / └─sda1 8:1 0 200M 0 part /boot/efi
またコンシステンス・デバイス・パスを指定したので、/dev/sdbに対し/dev/oracle/oraclevdbというシンボリックリンクが作成されている。
# ls -l /dev/oracle* total 0 lrwxrwxrwx. 1 root root 6 May 13 04:22 oraclevda -> ../sda lrwxrwxrwx. 1 root root 7 May 13 04:22 oraclevda1 -> ../sda1 lrwxrwxrwx. 1 root root 7 May 13 04:22 oraclevda2 -> ../sda2 lrwxrwxrwx. 1 root root 7 May 13 04:22 oraclevda3 -> ../sda3 lrwxrwxrwx. 1 root root 6 May 13 04:37 oraclevdb -> ../sdb★
5. 作成したブロックボリュームをインスタンスで使えるようにする
今回はアタッチしたボリュームを以下の構成で設定する。
/dev/sdbの代わりにコンシステンス・デバイス・パス(/dev/oracleoci/oraclevdb)も利用できる。ただしLVMでは使用できないので、今回は/dev/sdbを使用する。
5-1. 手順全体の流れ
手順全体は以下の通り。LVMを使うと、それなりに手順が複雑になる。逆にLVMを使わないときは、2から4の手順を省略できる。
- ディスクパーティションを作成する
- LVMのPV(物理ボリューム)を作成する
- LVMのVG(ボリュームグループ)を作成する
- LVMのLV(論理ボリューム)を作成する
- ファイルシステムを作成する
- インスタンスにマウントする
LVMについては一定の知識が必要になる。詳細は以下のマニュアルを参考にすること。
- Oracle Linux 8ストレージデバイスの管理「Logical Volume Managerの操作」
- Oracle Linux 7 管理者ガイド「論理ボリューム・マネージャについて」
- Oracle Linux 6 管理者ガイド「論理ボリューム・マネージャについて」
- 論理ボリュームの設定および管理(RHEL8)
- 論理ボリュームマネージャーの管理(RHEL7)
- 論理ボリュームマネージャーの管理(RHEL6)
5-2. ディスクパーティションを作成する
partedを使ってLVM用のディスクパーティションを作成する。/dev/sdbに対し、gptフラグとLVMフラグを付け、ディスクの全サイズを割り当てている。
またset 1の行は「1番目のパーティションにLVMのフラグを付ける」という意味である。そのためLVMを使用しないときは最後の"set 1 lvm on"が不要である。partedの詳細はpartedチートシートなどを参照のこと。
1回実行バージョン (末尾の\は改行を入れる目的で付けている。削除して1行で実行してもよい)
# parted -s -a optimal /dev/sdb \ mklabel gpt \ mkpart primary 0% 100% \ set 1 lvm on
分割実行バージョン
parted /dev/sdb mklabel gpt parted -a optimal /dev/sdb mkpart primary 0% 100% parted /dev/sdb set 1 lvm on
再び確認するとパーティションが作成されている。
# parted /dev/sdb print Model: ORACLE BlockVolume (scsi) Disk /dev/sdb: 53.7GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 53.7GB 53.7GB primary lvm
次の手順は省略してよいが、作成したパーティションに対応した、コンシステンス・デバイス・パスも作成されていることがわかる。
# ls -l /dev/oracleoci/oraclevd* lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/oracleoci/oraclevdb1 -> ../sdb1lrwxrwxrwx. 1 root root 6 May 13 04:22 /dev/oracleoci/oraclevda -> ../sda lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda1 -> ../sda1 lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda2 -> ../sda2 lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda3 -> ../sda3 lrwxrwxrwx. 1 root root 6 May 13 07:01 /dev/oracleoci/oraclevdb -> ../sdb lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/oracleoci/oraclevdb1 -> ../sdb1★これ
5-3. LVMの物理ボリュームを作成する
作成したパーティション/dev/sdb1にLVMの物理ボリューム(PV)を作成する。
# pvcreate /dev/sdb1 Physical volume "/dev/sdb1" successfully created.
pvsで物理ボリューム確認すると、物理ボリューム/dev/sdb1が作成されている。
# pvs PV VG Fmt Attr PSize PFree /dev/sdb1 lvm2 --- <50.00g <50.00g
5-4. LVMのボリュームグループを作成する
ボリュームグループ(VG)vg01を作成し、前のステップで作成した物理ボリューム/dev/sdb1を割り当てる。
# vgcreate vg01 /dev/sdb1 Volume group "vg01" successfully created
vgsでボリュームグループを確認すると、ボリュームグループvg01が作成され、空き容量50GBになっている。
# vgs VG #PV #LV #SN Attr VSize VFree vg01 1 0 0 wz--n- <50.00g <50.00g
5-5. LVMの論理ボリュームを作成する
論理ボリューム(LV)lv_dataを作成し、ボリュームグループvg01の全サイズを割り当てる。サイズを指定するときはlvcreate -L 20G -n lv_data vg01
のように指定する。
# lvcreate -l 100%FREE -n lv_data vg01 Logical volume "lv_data" created.
lvsで論理ボリューム確認すると、論理ボリュームlv_dataが作成されている。
# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert lv_data vg01 -wi-a----- <50.00g
再びボリュームグループを確認すると、lv_dataに全サイズを割り当てたため、空きはゼロになっている。
# vgs VG #PV #LV #SN Attr VSize VFree vg01 1 1 0 wz--n- <50.00g 0 ★VFreeがゼロになっている
また以下のデバイスファイルが作成されている。/dev/vg01/lv_dataと/dev/mapper/vg01-lv_dataは共に/dev/dm-0のシンボリックリンクである。
# ls -l /dev/vg01/lv_data lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/vg01/lv_data -> ../dm-0 # ls -l /dev/mapper/vg01-lv_data lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/mapper/vg01-lv_data -> ../dm-0
今回はpvsやvgs、lvsを使用しているが、pvdisplay、vgdisplay、lvdisplayなどを使用すると、もっと詳しい情報を表示できる。
/dev/oracleoci/oraclevd*を確認すると、論理ボリュームlv_dataに対応したデバイスファイルが追加されていない。そのためコンシステンス・デバイス・パスはLVMに対応していないと判断した。
# ls -l /dev/oracleoci/oraclevd* lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/oracleoci/oraclevdb1 -> ../sdb1lrwxrwxrwx. 1 root root 6 May 13 04:22 /dev/oracleoci/oraclevda -> ../sda lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda1 -> ../sda1 lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda2 -> ../sda2 lrwxrwxrwx. 1 root root 7 May 13 04:22 /dev/oracleoci/oraclevda3 -> ../sda3 lrwxrwxrwx. 1 root root 6 May 13 07:01 /dev/oracleoci/oraclevdb -> ../sdb lrwxrwxrwx. 1 root root 7 May 13 07:39 /dev/oracleoci/oraclevdb1 -> ../sdb1
5-6. ファイルシステムを作成する
Oracle Linux 6ではext4、Oracle Linux 7 / 8ではxfsのファイルシステムを作成する。
# mkfs.xfs /dev/vg01/lv_data meta-data=/dev/vg01/lv_data isize=256 agcount=4, agsize=3276544 blks = sectsz=4096 attr=2, projid32bit=1 = crc=0 finobt=0, sparse=0, rmapbt=0, reflink=0 data = bsize=4096 blocks=13106176, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=6399, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
# mkfs.ext4 /dev/vg01/lv_data mke2fs 1.43-WIP (20-Jun-2013) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=256 blocks 3276800 inodes, 13106176 blocks 655308 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4294967296 400 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
ext4では、デフォルトで5%のリザーブ領域を確保する。データ領域にリザーブ領域は不要なのでゼロに変更する。心配性ならば1で。xfsには同じ仕組みが無いので実行しない。
# tune2fs -m0 /dev/vg01/lv_data tune2fs 1.43-WIP (20-Jun-2013) Setting reserved blocks percentage to 0% (0 blocks)
ここまででブロックボリューム側の準備ができた。次に作成したブロックボリュームをマウントする。
5-7. ブロックボリュームをマウントする
残りの作業はあとわずかだ。マウントポイントを作成して、マウントするだけである。ただし、UUIDもしくはコンシステンス・デバイス・パスのどちらかで/etc/fstab
の記述が異なる。利用環境に応じて設定すること。
5-7-1. マウントポイントを作成する
マウントポイント用のディレクトリを作成し、オーナーをopcに変更する。各自の環境に読み替えて適宜変更して欲しい。
# mkdir /mnt/vol01 # chown opc:opc /mnt/vol01
5-7-2. UUID用の/etc/fstabを作成する
UUIDでデバイス名を指定するので、lsblkで該当デバイスのUUIDを調べる。
# lsblk -o +UUID NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT UUID sdb 8:16 0 50G 0 disk └─sdb1 8:17 0 50G 0 part Lobmfv-K3tR-2lzz-Zizs-eQx4-iF8E-9nmeca └─vg01-lv_data 252:0 0 50G 0 lvm f451d63f-1692-44ea-ad37-82ffa3313226 ★これがlv_dataのUUID sda 8:0 0 46.6G 0 disk ├─sda2 8:2 0 8G 0 part [SWAP] 8c83c999-ef07-40b5-b001-9658556502d3 ├─sda3 8:3 0 38.4G 0 part / eb7fd29b-a114-4e5e-8926-a6f4a541d605 └─sda1 8:1 0 200M 0 part /boot/efi 52AE-1880
UUIDはlsblkで確認するが、次のように逆引きもできる。
# findfs UUID=f451d63f-1692-44ea-ad37-82ffa3313226 /dev/mapper/vg01-lv_data
以下のように/etc/fstabを作成する。
# vi /etc/fstab ★末尾に以下の行を追加する UUID=f451d63f-1692-44ea-ad37-82ffa3313226 /mnt/vol01 xfs defaults,_netdev,nofail 0 2
それぞれの意味は次の通り。 1番目:デバイス名 2番目:マウントポイント 3番目:ファイルシステムのタイプ 4番目:ファイルシステムのマウントオプション 5番目:dumpコマンド実行時に対象にするか。対象にするときは1 6番目:fsckの実行順序。ルートファイルシステムは1。それ以外は2。対象外にするときは0
この中でもっとも重要なのが「_netdev」と「nofail」である。_netdevはネットワーク系のサービスが起動してからマウントするオプションで、リモートストレージでは必須。またnofailはディスク障害などでマウントできないときは、マウントをスキップして起動するオプションである。
「nofail」を指定しないとリモートディスク障害時にOSが起動できなくなる。また/etc/fstabに追加エントリがあるカスタムイメージを作成すると、そのカスタムイメージを使ってComputeインスタンスを作成してもOSが起動できない。
5-7-3. コンシステンス・デバイス・パス用の/etc/fstabを作成する
LVMを使用しないときは、コンシステンス・デバイス・パスとUUIDのどちらも使用できる。コンシステンス・デバイス・パスを使用するときは以下のように/etc/fstabを作成する。
# vi /etc/fstab ★末尾に以下の行を追加する /dev/oracleoci/oraclevdb1 /mnt/vol01 xfs defaults,_netdev,nofail 0 2
5-8. ファルシステムをマウントする
ファイルシステムをマウントすると/mnt/vol01に約50GBのブロックボリュームが追加されていることがわかる。
# mount -a # df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 7.2G 0 7.2G 0% /dev tmpfs 7.3G 0 7.3G 0% /dev/shm tmpfs 7.3G 8.6M 7.3G 1% /run tmpfs 7.3G 0 7.3G 0% /sys/fs/cgroup /dev/sda3 39G 2.1G 37G 6% / /dev/sda1 200M 9.7M 191M 5% /boot/efi tmpfs 1.5G 0 1.5G 0% /run/user/1000 /dev/mapper/vg01-lv_data 50G 33M 50G 1% /mnt/vol01 ★この行が追加
6. おわりに
「partedやLVMを使おうぜ」って、つもりで書き始めたのだが、新機能のコンシステンス・デバイス・パスに少し苦戦。従来通りUUIDを使用することにした。またLVMを利用するとレイヤが増えるのでパフォーマンスが低下するという人もいるが、微々たるものだろう。結局のところ利便性とのトレードオフだ。
今回はデータ領域用に新しくブロックボリュームを追加したが、既存のボリュームを拡張する方法もある。これはオンプレミスのベアメタルサーバでは難しい芸当だろう。
- ブートボリュームを拡張
- 既存のブロックボリュームを拡張
拡張時の操作はLVMよりも複雑になるが、LVMを使いたくないユーザにとっては便利な選択肢になる。詳しくは以下のマニュアルやエントリを参照のこと。賢いLinuxライフを!
7. まとめ
- ディスクサイズを増やす方法には、ブロックボリュームを追加する方法と、既存のボリュームを拡張する方法がある
- partedを使うと、gptパーティションや非対話的にパーティションを作成できる
- マウントオプションに「_netdev」と「nofail」は絶対指定する
- ブロックストレージを追加するとデバイス名が変わる可能性があるので、コンシステンス・デバイス・パスかUUIDを使用するべし
- コンシステンス・デバイス・パスは便利な機能だがLVMでは使えない(使う方法があるってかたがいたら教えて)
8. コピペ用まとめバージョン
コピペ用の手順は以下の通り。7/8系OSでの利用を想定しているが、6系OSでも実行可能。ext4
がいいときには変更すること。最後の/etc/fstab
への追加はシェルスクリプトにすれば可能だが、コピペでだけで実現したかったので元ネタを提供。
- 追加したディスク:
/dev/sdb
- ファイルシステム:
xfs
- マウントポイント:
/mnt/vol01
LVMを使わないときのサンプルコピペはコチラのリンク先を参照のこと。
# パーティション作成 parted -s -a optimal /dev/sdb mklabel gpt mkpart primary 0% 100% set 1 lvm on # LVM設定 pvcreate /dev/sdb1 vgcreate vg01 /dev/sdb1 lvcreate -l 100%FREE -n lv_data vg01 # ファイルシステム作成 mkfs.xfs /dev/vg01/lv_data # マウントポイント作成 mkdir /mnt/vol01 chown opc:opc /mnt/vol01 # /etc/fstab元ネタ。次の3行をマージして末尾に追加する echo UUID= ; lsblk -o +UUID | grep vg01-lv_data | awk '{print $NF}' ; echo " /mnt/vol01 xfs defaults,_netdev,nofail 0 2"