背景と目的
Azure Linux VM の規定のディスクサイズは 30GB です。たまにしか起動しない VM でもディスクサイズに応じたディスク利用料はかかり続けます。自分が以前書いた「パブリックプレビューの Azure Managed Disk ライブ拡張(ディスクをマウントしたまま容量を増やすやつ)をやってみた」のように、データディスクのディスクサイズをライブ拡張出来るようになりました。OS 領域は最低限のディスクサイズでデータ領域をライブ拡張していく使い方を想定したいと思います。Azure に用意されているディスクイメージは、ディスクサイズを小さくすることが出来ないため、あらかじめ小さいディスクサイズの OS イメージを用意する必要があります。そこで今回は Hyper-V 環境で CentOS をインストールして VHD を Azure にアップロードして Azure Linux VM を作ってみました。
前提条件
- Hyper-V 環境があること
- azcopy がインストール済みであること
Hyper-V 環境にディスクサイズ 8GB の CentOS を作る
こちらのドキュメントを参考に、仮想マシンを作成します。
# 環境変数をセットします
$VMName = 'testvm'
$Switch = 'Default Switch'
$InstallMedia = 'C:\Users\Public\Documents\ISO\CentOS-7-x86_64-Minimal-1611.iso'
# 仮想マシンを作成します
New-VM -Name $VMName `
-MemoryStartupBytes 1GB `
-Generation 1 `
-NewVHDPath "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhdx" `
-NewVHDSizeBytes 8GB `
-Path "C:\Users\Public\Documents\Hyper-V\Virtual Machines\$VMName" `
-SwitchName $Switch
# インストールメディアをセットします
Set-VMDvdDrive -VMName $VMName -Path $InstallMedia
次に、画面を開いて VM を起動し OS をインストールします。私の場合、ディスクは標準パーティションで SWAP なしで作成しました。
固定サイズの VHD を作る
# 仮想マシンを停止します
Stop-VM -Name $VMName
# 固定サイズの VHD に変換します
Convert-VHD `
-Path "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhdx" `
-DestinationPath "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhd" `
-VHDType Fixed
# 固定サイズの VHD で別の仮想マシンを作成します
New-VM -Name ${VMName}2 `
-MemoryStartupBytes 1GB `
-Generation 1 `
-VHDPath "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhd" `
-Path "C:\Users\Public\Documents\Hyper-V\Virtual Machines\${VMName}2" `
-SwitchName $Switch
次に、固定サイズの VHD で起動した仮想マシンに SSH ログインします。コンソールログインでも良いです。
Azure 用に OS をカスタマイズ
インストールメディアで使用した CentOS のバージョンを固定したい場合、今回の例では 7.3 なので、以下のようにします。
echo 7.3.1611 > /etc/yum/vars/releasever
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/create-upload-centos#centos-70
こちらのドキュメントを参考に、以下のようにカスタマイズしてみました。また、今回はディスクを一般化(イメージ化)しないでインストール時に作成した root ログイン情報もそのまま Azure に持って行きたいと思います。イメージ化したい場合は、「リリース前の Ubuntu 22.04 イメージを Azure に持ち込み VM 作成までやってみた」を参考にしてみてください。
cat << EOF > /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOF
cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=dhcp
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no
EOF
ln -s /dev/null /etc/udev/rules.d/75-persistent-net-generator.rules
cat << "EOF" > /etc/yum.repos.d/CentOS-Base.repo
[openlogic]
name=CentOS-$releasever - openlogic packages for $basearch
baseurl=http://olcentgbl.trafficmanager.net/openlogic/$releasever/openlogic/$basearch/
enabled=1
gpgcheck=0
[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
baseurl=http://ftp.riken.jp/Linux/centos-vault/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
baseurl=http://ftp.riken.jp/Linux/centos-vault/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
baseurl=http://ftp.riken.jp/Linux/centos-vault/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
baseurl=http://ftp.riken.jp/Linux/centos-vault/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
EOF
yum clean all
yum -y update
sed -i 's/GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet"/GRUB_CMDLINE_LINUX="rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0"/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
sed -i 's/#add_drivers+=""/add_drivers+=" hv_vmbus hv_netvsc hv_storvsc "/' /etc/dracut.conf
dracut -f -v
yum -y install python-pyasn1 WALinuxAgent
systemctl enable waagent
poweroff
固定サイズの VHD をマネージドディスクに直接アップロード
# 変数をセットします
$region = "japaneast"
$prefix = "mnrcent"
$filesize = (Get-VHD "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhd").FileSize
# リソースグループを作成します
az group create `
--name ${prefix}-rg `
--location $region
# 空のマネージドディスクを作成します
az disk create `
--name ${prefix}-vmOSDisk `
--resource-group ${prefix}-rg `
--os-type Linux `
--for-upload `
--upload-size-bytes $filesize `
--sku Standard_LRS `
--hyper-v-generation V1
# マネージドディスクに書き込み出来るようにします
$sasurl = $(az disk grant-access `
--name ${prefix}-vmOSDisk `
--resource-group ${prefix}-rg `
--access-level Write `
--duration-in-seconds 86400 `
--query accessSas `
--output tsv)
# 固定サイズの VHD をマネージドディスクに直接アップロードします
azcopy copy "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\$VMName.vhd" $sasurl --blob-type PageBlob
# マネージドディスクへのアクセスを閉じます
az disk revoke-access `
--name ${prefix}-vmOSDisk `
--resource-group ${prefix}-rg
# 仮想マシンを作成します
az vm create `
--resource-group ${prefix}-rg `
--name ${prefix}-vm `
--os-type linux `
--attach-os-disk ${prefix}-vmOSDisk `
--size Standard_B1ls `
--nsg-rule NONE `
--public-ip-address-dns-name ${prefix}
# 自身の IP から SSH アクセス出来るようにします
az network nsg rule create `
--resource-group ${prefix}-rg `
--name Allow-SSH `
--nsg-name ${prefix}-vmNSG `
--priority 100 `
--source-address-prefixes $((curl -UseBasicParsing inet-ip.info/ip).Content) `
--destination-port-ranges 22 `
--access Allow `
--protocol Tcp
# root ユーザーで SSH 接続します
ssh root@${prefix}.$region.cloudapp.azure.com
参考
作成したリソースを削除します。
# リソースグループを削除します
az group delete `
--name ${prefix}-rg
参考サイトです。
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/disks-upload-vhd-to-managed-disk-cli