0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

m8i.16xlargeを使う前に、aws EC2のm8i.largeでNestedVirtを有効にしてみた

0
Posted at

■aws EC2を「on KVM」にするため、ネストされた仮想化のサポートを試してみる
 個人的には、そもそもネステッドにできないものは「仮想化基盤」とは言わないと思っている。
 metalは高額なので、砂場にするのももったいない。
 ネステッド要件のインスタンスタイプについて今回、制限範囲が分かったので、常用も「あり」ですね。
 特にコンテナじゃだめだけど、EC2立てるほどじゃないという使い捨て環境の構築がはかどる印象
 カスタムAMI作るためのrawディスクの作成環境としても良いかも(?)

 Amazon EC2 は仮想 Amazon EC2 インスタンス上でネストされた仮想化のサポートを開始
https://aws.amazon.com/jp/about-aws/whats-new/2026/02/amazon-ec2-nested-virtualization-on-virtual/

この機能は、すべての商用リージョンの C8i、M8i、および R8i インスタンスでご利用いただけます

■現状のインスタンス確認
 「NestedVirt」に対応していないと「None」、無効なら「disabled」。
 ここを「enabled」にする方法とも言いかえられる。

$ # Get instance IDs for nested-virt-*
INSTANCE_IDS=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=nested-virt-*" "Name=instance-state-name,Values=running,pending" \
  --query "Reservations[].Instances[].InstanceId" \
  --output text \
  --region ap-northeast-1)

# Check CPU Options with the retrieved IDs
aws ec2 describe-instances \
  --instance-ids ${INSTANCE_IDS} \
  --query "Reservations[].Instances[].{Name:Tags[?Key=='Name'].Value|[0],InstanceId:InstanceId,NestedVirt:CpuOptions.NestedVirtualization}" \
  --output table \
  --region ap-northeast-1
----------------------------------------------------------------
|                       DescribeInstances                      |
+----------------------+-------------------------+-------------+
|      InstanceId      |          Name           | NestedVirt  |
+----------------------+-------------------------+-------------+
|  i-XXXXXXXXXXXXXXXXX |  ec2winSV2025-20260129  |  None       |
+----------------------+-------------------------+-------------+

■us-east-1で、[cmr]8iの料金で$0.9〜1.2の範囲で選択可能なインスタンスタイプの調査
 最終的にはap-northeast-1に置くとしても、これ以上は下がらないという最安環境を見ておきたい。
 以下、過去に作ったスクリプトを流用。

 awscliでAWSリージョンとAZの一覧を取得する
https://labunix.hateblo.jp/entry/20180918/1537269823

■インスタントタイプは「インスタンスタイプ: m8i.16xlarge, r8i.16xlarge, c8id.16xlarge, m8id.16xlarge, r8id.16xlarge」が候補
 ※「c8i」はメモリ128GB、「m8i」だと256GB、「r8i」なら512GBの違い。
 vCPU 32C(x2T)、NIC 30 Gigabit、GPU,FPGA なし
 「ssd 3800GB」があると「d」が付くようだ。
 ※「c8i.metal-48xl,r8i.metal-48xl,m8i.metal-48xl」は約3倍の上位性能なので料金の参考値のみ
 ここで人によっては「metalで良い」と、なるかも知れないので。

$ aws ec2 describe-spot-price-history \
  --start-time $(date -d '1 days ago' -u '+%Y-%m-%dT%H:%M:%S.000Z') \
  --product-description "Linux/UNIX" --region us-east-1 | \
  jq -r '.SpotPriceHistory[] | [ .InstanceType , .ProductDescription , .AvailabilityZone , .SpotPrice ] | @csv' | \
  tr '"' ' ' | awk -F\, '{if($1 ~ /[cmr]8id.metal-48xl|[cmr]8i.16xlarge|[cmr]8id.16xlarge/){a[$1]=a[$1]_$4}}END{for(n in a){print n,a[n]}}' | sort -k 1 -V
 c8id.16xlarge   1.043300  0.877900  0.835600  0.773600  0.891600  0.952300  0.785200  0.828800  0.929500  0.895900  1.037700  0.799900  0.826300  0.897700  0.924800  1.036500  0.831500  0.814600  0.907200  0.908300  0.833800  1.040000  0.819200  0.914600 
 c8id.metal-48xl   3.153600  3.414100  3.191300  2.514100  3.527300  3.428700  2.546900  3.215100  3.343800  3.444100  3.559200  2.548500  3.219200  3.332500  2.562900  3.449400  3.564700  3.228500  3.347100  2.586500  3.472100  3.578700 
 c8i.16xlarge   1.470200  1.026100  1.158800  1.029400  1.052300  1.002900  1.455900  1.030300  1.159900  0.999500  1.041000  1.034400  1.439200  1.023500  1.038500  1.159600  0.998900  1.166400  1.426000  1.005100  1.019500  1.044500  1.004300  1.418500  1.165300 
 m8id.16xlarge   1.568400  0.930400  1.762700  0.928300  1.471600  2.653900  1.532500  0.925900  1.466500  2.619800  1.746800  1.496900  1.462600  1.704700  0.931100  2.574000  1.482000  2.562400  0.941900  1.678100  1.466900  1.471300  2.556100  0.942500  1.676300 
 m8id.metal-48xl   2.183500  2.842200  2.518600  1.461300  2.187100  3.251600  2.536300  2.852300  1.474700  3.233200  2.216800  2.574600  2.842700  3.190400  2.197600  1.498600  2.871700  2.621100  3.142600  1.503300  2.893000  2.205600  2.654900 
 m8i.16xlarge   1.193100  1.213400  1.024500  1.102500  1.046800  1.191900  1.042900  1.216800  1.193400  1.105600  1.019300  1.031100  1.014800  1.228500  1.196700  1.105500  1.034700  1.015100  1.233300  1.212100  1.116500  1.018500  1.012400 
 r8id.16xlarge   4.125100  4.206100  2.497200  4.150400  1.233100  4.218800  2.542900  4.189400  4.285400  1.236900  5.322200  4.197700  1.244900  2.526600  4.345100  4.252700  4.269000  4.353500  2.482500  1.255400  5.322200 
 r8id.metal-48xl   2.487000  2.778200  4.119700  2.186700  2.445300  3.500500  2.826800  2.217600  3.526100  4.145300  2.420600  2.255600  2.827200  3.533100  2.416500  4.158400  2.873200  2.267700  2.378700  3.567400  2.925400  2.348400  2.282200  4.165100  3.610000 
 r8i.16xlarge   1.096000  1.884300  1.298000  1.351800  1.353300  1.884200  1.350600  1.276300  1.091200  1.897400  1.355600  1.246800  1.347900  1.080600  1.909500  1.379600  1.255800  1.345500  1.070200  1.383100  1.338100  1.258000  1.060500  1.930400 

■「m8id」が「バランスのとれたワークロード」とのことなので、とりあえずこれで。
 ※「m8id.metal-48xl」は3倍の性能、NICだけ3倍の90でなく75Gigabitなくらい。
 「m8id.16xlarge」は逆に1/3の性能なので、料金も1/3を期待したいところ。

C8id インスタンスは、高性能ウェブサーバー、バッチ処理、分散分析、広告配信、動画エンコーディング、ゲームサーバーなど、コンピューティング負荷の高いワークロードに最適です。

M8id インスタンスは、アプリケーションサーバー、マイクロサービス、エンタープライズアプリケーション、小規模から中規模のデータベースなど、バランスの取れたワークロードに適しています。

R8id インスタンスは、インメモリデータベース、リアルタイムビッグデータ分析、大規模インメモリキャッシュ、科学計算アプリケーションなど、メモリ負荷の高いワークロードに最適です。 

■「m8i.large」vCPU 2C(x2T)、メモリ8GB、NIC 12.5 Gigabit、GPU,FPGA なしで確認
 「ssd 118GB」がある「m8id」ではネステッドを「有効」にする選択肢がグレーアウトしていた
 一応ドキュメント上は「etc」となっていたが、m8iまたはm8idかつxlarge,metal以外のインスタンスタイプを抽出するとlargeがあるので、「使えるかどうかすら分からなくても」この料金なら気軽に手が出せる。

$ aws ec2 describe-spot-price-history \
  --start-time $(date -d '1 days ago' -u '+%Y-%m-%dT%H:%M:%S.000Z') \
  --product-description "Linux/UNIX" --region us-east-1 | \
  jq -r '.SpotPriceHistory[] | [ .InstanceType , .ProductDescription , .AvailabilityZone , .SpotPrice ] | @csv' |   tr '"' ' ' | awk -F\, '{if($1 ~ /m8id|m8i\./&& $1 !~ /xlarge|metal/){a[$1]=a[$1]_$4}}END{for(n in a){print n,a[n]}}' | sort -k 1 -V
 m8id.large   0.046100  0.035100  0.050700  0.064000  0.064800  0.045500  0.050200  0.035300  0.038000  0.065200  0.045100  0.050400  0.035200  0.044600  0.037900  0.050300  0.066200  0.044300  0.035100  0.049600  0.037800 
 m8i.large   0.042700  0.044500  0.048000  0.044600  0.046600  0.042800  0.041600  0.047800  0.041800  0.043000  0.044700  0.041900  0.043100  0.046500  0.044600  0.047700 

■インスタンスの作成画面で以下が選べればOKで、m8idはグレーアウトしていたのでm8i.*で検証

image.png

■NestedVirtが「Enabled」になっている

$ # Get instance IDs for nested-virt-*
INSTANCE_IDS=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=nested-virt-*" "Name=instance-state-name,Values=running,pending" \
  --query "Reservations[].Instances[].InstanceId" \
  --output text \
  --region ap-northeast-1)

# Check CPU Options with the retrieved IDs
aws ec2 describe-instances \
  --instance-ids ${INSTANCE_IDS} \
  --query "Reservations[].Instances[].{Name:Tags[?Key=='Name'].Value|[0],InstanceId:InstanceId,NestedVirt:CpuOptions.NestedVirtualization}" \
  --output table \
  --region ap-northeast-1
-----------------------------------------------------------------
|                       DescribeInstances                       |
+----------------------+--------------------------+-------------+
|      InstanceId      |          Name            | NestedVirt  |
+----------------------+--------------------------+-------------+
|  i-XXXXXXXXXXXXXXXXX |  ec2winSV2025-20260129   |  None       |
|  i-XXXXXXXXXXXXXXXXY |  debian-nested-m8i       |  enabled    |
+----------------------+--------------------------+-------------+

■debianはSSM Agentを入れてIAMはいつもどおりアサイン、踏み台EC2からssh接続する方針
 ここはKVMホスト要件を満たせるなら、awsのお作法は好きなようにしてもらえれば。

■これでNestedが使える。見た感じCPUフラグをパススルーしてるっぽい。
 余談だけど、それが良いのかは置いといて、EC2のNICはNetworkManager管理。

$ lscpu | grep -A 2 "Model name:\|Virtualization:"
Model name:                              Intel(R) Xeon(R) 6975P-C
CPU family:                              6
Model:                                   173
--
Virtualization:                          VT-x
Hypervisor vendor:                       KVM
Virtualization type:                     full

$ grep flags /proc/cpuinfo | awk '{for(a=1;a<=NF;a++){if($a ~ /vmx|svm/){print $a | "sort | uniq -c"}}}'
      4 vmx

sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-daemon virtinst bridge-utils libosinfo-bin

$ lsmod | grep kvm
kvm_intel             413696  0
kvm                  1376256  1 kvm_intel
irqbypass              12288  1 kvm

$ virsh list --all
 Id   Name   State
--------------------

$ ls /sys/class/net/
enp39s0  lo

$ nmcli device status 
DEVICE   TYPE      STATE                   CONNECTION         
enp39s0  ethernet  connected               Wired connection 1 
lo       loopback  connected (externally)  lo

■NetworkManagerの管理外として、virshで管理するvirbr1を作成

$ cat kvm-nat.xml 
<network>
  <name>kvm-nat</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.128' end='192.168.100.254'/>
    </dhcp>
  </ip>
</network>

$ sudo virsh net-define kvm-nat.xml 
Network kvm-nat defined from kvm-nat.xml

$ sudo virsh net-start kvm-nat 
Network kvm-nat started

$ nmcli device status 
DEVICE   TYPE      STATE                   CONNECTION         
enp39s0  ethernet  connected               Wired connection 1 
lo       loopback  connected (externally)  lo                 
virbr1   bridge    connected (externally)  virbr1     

■小さめ(400MB未満)のqcow2を持って来てrootパスワードを設定
 ※genericcloudは様々なクラウドベンダ向けに使われている

# cloudイメージのダウンロード
$ wget https://cdimage.debian.org/cdimage/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2
--2026-05-03 13:09:29--  https://cdimage.debian.org/cdimage/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2

$ du debian-13-genericcloud-amd64.qcow2 
331584	debian-13-genericcloud-amd64.qcow2

# cloud-initのカスタマイズでrootのパスワードをdebianにする(※デフォルトはrootパスワードなし)
$ sudo apt install -y libguestfs-tools

$ sudo virt-customize -a debian-13-genericcloud-amd64.qcow2 --root-password password:debian
[   0.0] Examining the guest ...
[  12.5] Setting a random seed
[  12.5] Setting passwords
[  13.1] SELinux relabelling
[  13.1] Finishing off

■どうでもいい余談として、genericcloudの初期ユーザはdebianだがパスワードログイン禁止なので、何もしないとログインできずに詰むというcloud-initの記載箇所をピックアップ

$ sudo modprobe nbd
$ lsmod | grep nbd
nbd                    65536  0
$ sudo qemu-nbd -c /dev/nbd0 debian-13-genericcloud-amd64.qcow2
$ lsblk -l /dev/nbd0
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
nbd0     43:0    0    3G  0 disk 
nbd0p1   43:1    0  2.9G  0 part 
nbd0p14  43:14   0    3M  0 part 
nbd0p15  43:15   0  124M  0 part 

$ sudo mount /dev/nbd0p1 /mnt
$ sudo grep -A 20 ^system_info:  /mnt/etc/cloud/cloud.cfg
system_info:
   # This will affect which distro class gets used
   distro: debian
   # Default user name + that default users groups (if added/used)
   default_user:
     name: debian
     lock_passwd: True
     gecos: Debian
     groups: [adm, audio, cdrom, dialout, dip, floppy, plugdev, sudo, video]
     sudo: ["ALL=(ALL) NOPASSWD:ALL"]
     shell: /bin/bash
   # Other config here will be given to the distro class and/or path classes
   paths:
      cloud_dir: /var/lib/cloud/
      templates_dir: /etc/cloud/templates/
   package_mirrors:
     - arches: [default]
       failsafe:
         primary: https://deb.debian.org/debian
         security: https://deb.debian.org/debian-security
   ssh_svcname: ssh

$ sudo umount /mnt
$ sudo qemu-nbd -d /dev/nbd0

■話を戻して、virbr1を使えるようにしてvirsh管理下のKVM-QEMUで起動
 ※virsh管理下のネットワークについては、本題から逸れるので「動くだけ」で雑に進める

# virbr1 の使用許可
$ sudo mkdir -p /etc/qemu;echo "allow virbr1" | sudo tee /etc/qemu/bridge.conf

$ cat debian13.xml 
<domain type='kvm'>
  <name>debian13</name>
  <memory unit='MiB'>4096</memory>
  <vcpu>2</vcpu>

  <os>
    <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type>
  </os>

  <cpu mode='host-passthrough'/>

  <devices>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/debian-13-genericcloud-amd64.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>

    <interface type='bridge'>
      <source bridge='virbr1'/>
      <model type='virtio'/>
    </interface>

    <serial type='pty'>
      <target port='0'/>
    </serial>

    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
  </devices>
</domain>


$ sudo virsh define debian13.xml
$ sudo virsh start debian13

$ sudo virsh list
 Id   Name       State
--------------------------
 2    debian13   running


$ sudo virsh console debian13
...
Debian GNU/Linux 13 debian ttyS0

debian login: root
Password: 
Linux debian 6.12.85+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.85-1 (2026-04-30) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

root@debian:~# lscpu | grep -A 3 "Model name\|Virtualization:"
Model name:                              Intel(R) Xeon(R) 6975P-C
CPU family:                              6
Model:                                   173
Thread(s) per core:                      1
--
Virtualization:                          VT-x
Hypervisor vendor:                       KVM
Virtualization type:                     full
L1d cache:                               32 KiB (1 instance)

root@debian:~# hostnamectl | grep -v ID
 Static hostname: debian
       Icon name: computer-vm
         Chassis: vm 🖴
  Virtualization: kvm
Operating System: Debian GNU/Linux 13 (trixie)
          Kernel: Linux 6.12.85+deb13-cloud-amd64
    Architecture: x86-64
 Hardware Vendor: QEMU
  Hardware Model: Standard PC _i440FX + PIIX, 1996_
Firmware Version: 1.16.3-debian-1.16.3-2
   Firmware Date: Tue 2014-04-01
    Firmware Age: 12y 1month 2d

■vCPUが2、メモリは4GB、ディスクは余談のlsblkで見た通り3GB(qcow2としては400MB未満)

root@debian:~# grep flags /proc/cpuinfo | awk '{for(a=1;a<=NF;a++){if($a ~ /vmx|svm/){print $a | "sort | uniq -c"}}}'
      2 vmx

root@debian:~# free -m
               total        used        free      shared  buff/cache   available
Mem:            3922         251        3750           0          76        3671
Swap:              0           0           0

root@debian:~# lsblk 
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda     254:0    0    3G  0 disk 
├─vda1  254:1    0  2.9G  0 part /
├─vda14 254:14   0    3M  0 part 
└─vda15 254:15   0  124M  0 part /boot/efi

root@debian:~# fdisk -l
Disk /dev/vda: 3 GiB, 3221225472 bytes, 6291456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: A6A14BD2-2D1F-4065-9CC0-D3983F38D8AF

Device      Start     End Sectors  Size Type
/dev/vda1  262144 6289407 6027264  2.9G Linux root (x86-64)
/dev/vda14   2048    8191    6144    3M BIOS boot
/dev/vda15   8192  262143  253952  124M EFI System

Partition table entries are not in disk order.

■一時的な確認だけで、メインはNestedVirtなので、ネットワークの確認はサラッと。

root@debian:~# sudo ip addr add 192.168.100.2/24 dev enp0s2
root@debian:~# sudo ip link set enp0s2 up
root@debian:~# ping 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_seq=1 ttl=64 time=0.013 ms
64 bytes from 192.168.100.2: icmp_seq=2 ttl=64 time=0.012 ms

--- 192.168.100.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.012/0.012/0.013/0.000 ms
root@debian:~# ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.197 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.075 ms

--- 192.168.100.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.075/0.136/0.197/0.061 ms
root@debian:~# sudo ip route add default via 192.168.100.1

■とはいえ、pingだけでは信用できないので、socatでechoサーバ立ててクライアントからの応答を確認
 ※最後は[Ctrl]+[c]でシグナル「2」で落とした

root@debian:~# socat -d -d -v TCP4-LISTEN:8007,reuseaddr,fork PIPE
2026/05/03 15:25:02 socat[1279] N listening on AF=2 0.0.0.0:8007
2026/05/03 15:25:35 socat[1279] N accepting connection from AF=2 192.168.100.1:50490 on AF=2 192.168.100.2:8007
2026/05/03 15:25:35 socat[1280] N writing to and reading from unnamed pipe
2026/05/03 15:25:35 socat[1279] N forked off child process 1280
2026/05/03 15:25:35 socat[1280] N starting data transfer loop with FDs [6,6] and [5,7]
2026/05/03 15:25:35 socat[1279] N listening on AF=2 0.0.0.0:8007
> 2026/05/03 15:25:37.000259439  length=2 from=0 to=1
\r
< 2026/05/03 15:25:37.000262284  length=2 from=0 to=1
\r
> 2026/05/03 15:25:37.000560655  length=2 from=2 to=3
\r
< 2026/05/03 15:25:37.000563169  length=2 from=2 to=3
\r
> 2026/05/03 15:25:39.000005191  length=6 from=4 to=9
echo\r
< 2026/05/03 15:25:39.000008686  length=6 from=4 to=9
echo\r
2026/05/03 15:29:09 socat[1279] N socat_signal(): handling signal 2
2026/05/03 15:29:09 socat[1279] N exiting on signal 2
2026/05/03 15:29:09 socat[1280] N socat_signal(): handling signal 2
2026/05/03 15:29:09 socat[1280] N exiting on signal 2
2026/05/03 15:29:09 socat[1279] N socat_signal(): finishing signal 2
2026/05/03 15:29:09 socat[1279] N exit(130)
2026/05/03 15:29:09 socat[1280] N socat_signal(): finishing signal 2
2026/05/03 15:29:09 socat[1280] N exit(130)

■上記のsocatサーバのechoログは、ec2NestedVirtのホストからtelnetクライアントで与えたもの
 ※KVMホストとなったEC2と、KVMゲストのgenericcloud間の通信が正常なので、DNSとかルーティングとかまでの確認に手を伸ばさないことにする。

$ telnet 192.168.100.2 8007
Trying 192.168.100.2...
Connected to 192.168.100.2.
Escape character is '^]'.




echo
echo
Connection closed by foreign host.

■ちなみにインスタントタイプは後からでも変えられる。
 インスタントタイプが対応している範囲にリセットされるのは当然として、「前の設定は一旦リセットで」というパターンもあるようなので、インスタントタイプを変える前後のNestedVirtの状態はきちんと確認しておくと良さそう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?