akam1oの日記

クラウドを作るお仕事をしています

Proxmox VE に AlmaLinux の VM テンプレートを Cloud Image から作成

概要

AlmaLinux の VM テンプレートを Cloud Image から作成する方法です。

Cloud Image のダウンロード

公式 Repo から必要なイメージをダウンロードしてください。

# wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-9.7-20251118.x86_64.qcow2

VM テンプレートの作成

ワンライナー

IMG_ID=9001 \
IMG_FILE="AlmaLinux-9-GenericCloud-9.7-20251118.x86_64.qcow2" \
STORAGE="local-lvm" \
BRIDGE="vmbr0" \
&& qm create $IMG_ID --memory 2048 --net0 virtio,bridge=${BRIDGE} \
&& qm importdisk $IMG_ID ${IMG_FILE} ${STORAGE} \
&& qm set $IMG_ID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:vm-${IMG_ID}-disk-0 \
&& qm set $IMG_ID --ide2 ${STORAGE}:cloudinit \
&& qm set $IMG_ID --boot c --bootdisk scsi0 \
&& qm set $IMG_ID --serial0 socket --vga serial0 \
&& qm template $IMG_ID

変数について

変数 説明
IMG_ID Proxmox 内でユニークな VM ID
IMG_FILE ダウンロード済みの qcow2 ファイル名
STORAGE インポート先ストレージ
BRIDGE ネットワークブリッジ名

変数定義

IMG_ID=9001
IMG_FILE="AlmaLinux-9-GenericCloud-9.7-20251118.x86_64.qcow2"
STORAGE="local-lvm"
BRIDGE="vmbr0"

テンプレート用 VM 作成

# qm create $IMG_ID --memory 2048 --net0 virtio,bridge=${BRIDGE}

ダウンロードしたイメージをインポート

# qm importdisk $IMG_ID ${IMG_FILE} ${STORAGE}

scsi で attach

# qm set $IMG_ID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:vm-${IMG_ID}-disk-0

cloud-init 用の CD ドライブを用意

# qm set $IMG_ID --ide2 ${STORAGE}:cloudinit

attach したディスクを boot disk に設定

# qm set $IMG_ID --boot c --bootdisk scsi0

シリアルコンソールに接続

# qm set $IMG_ID --serial0 socket --vga serial0

テンプレートに変換

# qm template $IMG_ID

テンプレートからのデプロイ

作成したテンプレートから Clone して VM を起動します。

参考

Proxmox VE と Archer TXE70UH で 6GHz の無線 AP を作る

0. 目次

1. 概要

  • 6GHz の無線 AP を自作したいという技術的興味から、6GHz に対応する無線 LAN カードで最安であった TP-Link Archer TXE70UH を用いて無線 LAN AP の自作を試みた
    • なお TP-Link Archer TXE70UH 購入時点では 6GHz でのクライアントでの動作実績はあるので AP もすぐ問題なく動くと思っていた
  • また可搬性の観点から VM 上で hostapd を構成し、無線 LAN カードは USB デバイスをパススルーで見せる構成とした

1.1 モチベーション

  • 6GHz の無線 AP が急に欲しくなった
    • 実家で無線 LAN の実験環境的な運用をしているのだが、そこに自作 AP で 6GHz も吹きたいと考えた
  • 気軽な気持ちでヤフーショッピングで調べてみると、Wi-Fi 6E 対応でポイント還元込みで3000円程度で買えることを発見 -> 即購入
  • これが地獄の始まりだった

1.2 技術的課題

  • 無線モジュール届いて調べ始めたら早々になんか動かんらしいという GitHub Issue を見つける
  • そもそもドライバの実装で 6GHz を吹く上で必要な機能が呼び出せなかったり、なんならホスト kernel 巻き込んで死んだりする
  • とはいえ丁寧にデバッグしていったら動くやろ!くらいの気持ちで実装を始める

1.3 構成コンセプト

  • 構成としては非常にシンプルで、PCI passthrough で Wi-Fi モジュールを見せているだけ
    構成概要

2. システム構成と環境

2.1 ハードウェア構成

  • ハイパーバイザー: Proxmox VE
  • ゲスト OS: Ubuntu 24.04.2 LTS(kernel: 6.8.0-53-generic)
  • 無線アダプタ: TP-Link Archer TXE70UH(RTL8852CU チップセット
  • 接続方式: USB passthrough *(前述のコンセプトでは PCI passthrough になっているが、ドライバが上手く走らなかったため USB passthrough になっている)

2.2 設計思想

  • 可搬性と実験性を重視し、VM 環境での構築
    • 将来的には実家での稼働を想定
    • 何度か OS が起動しなくなるような破滅的な場面もあったため、やはり VM 環境推奨

2.3 ネットワーク構成

  • 純粋な無線 AP(ブリッジ)として実装
    • DHCP は上位のルータが行うため

3. ホスト側作業

3.1 Proxmox で Archer TXE70UH が WLAN モードで読み込まれるようにする

Windows 向けに無線 LAN ドライバを自動インストールするための仕組みがあるため、USB モードの切り替えが必要

// CDROM モードになっている

# lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 0bda:c821 Realtek Semiconductor Corp. Bluetooth Radio
Bus 003 Device 002: ID 0573:1573 Zoran Co. Personal Media Division (Nogatech) USB Audio and HID
Bus 003 Device 004: ID 0bda:1a2b Realtek Semiconductor Corp. RTL8188GU 802.11n WLAN Adapter (Driver CDROM Mode)
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

# apt install usb-modeswitch

# usb_modeswitch -KW -v 0bda -p 1a2b
Take all parameters from the command line


 * usb_modeswitch: handle USB devices with multiple modes
 * Version 2.6.1 (C) Josua Dietze 2017
 * Based on libusb1/libusbx

 ! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor=  0x0bda
DefaultProduct= 0x1a2b

StandardEject=1

Look for default devices ...
  found USB ID 1d6b:0003
  found USB ID 0bda:c821
   vendor ID matched
  found USB ID 0573:1573
  found USB ID 35bc:0102
  found USB ID 1d6b:0002
  found USB ID 1d6b:0003
  found USB ID 1d6b:0002
 No devices in default mode found. Nothing to do. Bye!

設定の永続化

# cat /etc/usb_modeswitch.d/0bda\:1a2b
DefaultVendor=0x0bda
DefaultProduct=0x1a2b
TargetVendor=0x35bc
TargetProduct=0x0102
StandardEject=1

3.2 VM への USB デバイスの割り当て

モードを切り替えると WLAN Adapter として TXE70UH が見えているので、これを VM にアタッチする

USB デバイスの割り当て

IOMMU の設定していない場合はする

iommu=pt intel_iommu=on

エミュレーションモデルは q35 にする pc-i440fx には USB が実装されていないので注意

4. 基本環境構築

4.1 RTL8852CUドライバーの構築

4.1.1 ドライバーソースの取得
  • GitHub上のmorrownr版RTL8852CUドライバーを使用
# ドライバーソースの取得
git clone https://github.com/morrownr/rtl8852cu-20240510.git
cd rtl8852cu-20240510

# 対応デバイスの確認
# supported-device-IDs ファイルで以下を確認
# ID 35bc:0102 - TP-Link Archer TXE70UH(EU) V1
4.1.2 依存関係のインストール
sudo apt update
sudo apt install -y build-essential git dkms bc bridge-utils hostapd
sudo apt install -y linux-modules-extra-6.8.0-53-generic
4.1.3 ドライバーのビルドとインストール
# ドライバーのビルド
sudo make clean
sudo make

# モジュールの手動インストール
sudo mkdir -p /lib/modules/6.8.0-53-generic/kernel/drivers/net/wireless/
sudo cp 8852cu.ko /lib/modules/6.8.0-53-generic/kernel/drivers/net/wireless/
sudo depmod -a

# ドライバーの段階的ロード
sudo modprobe cfg80211
sudo modprobe mac80211
sudo modprobe 8852cu

無線インターフェイス wlx98038eddc01f が正常に認識された

$ ip l
~~~
4: wlx98038eddc01f: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 98:03:8e:dd:c0:1f brd ff:ff:ff:ff:ff:ff

5. ブリッジネットワークの構築

5.1 systemd-networkd設定

linuxbridge を作り、そこに VM の eth デバイスをぶら下げるが、このとき bridge で IP 終端する必要があるため、起動時にそのような構成になるようにする

5.1.1 ブリッジデバイス定義
cat > /etc/systemd/network/10-br0.netdev << EOF
[NetDev]
Name=br0
Kind=bridge
EOF
5.1.2 ブリッジネットワーク設定
cat > /etc/systemd/network/20-br0.network << EOF
[Match]
Name=br0

[Network]
Address=192.168.1.29/24
Gateway=192.168.1.1
DNS=192.168.1.1
IPForward=yes
EOF
5.1.3 eth0のブリッジ接続
cat > /etc/systemd/network/30-eth0.network << EOF
[Match]
Name=eth0

[Network]
Bridge=br0
EOF

5.2 ブリッジの設定

# ブリッジインターフェイスの作成
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo ip link set br0 up

eth0をブリッジに接続する際、IPアドレスが eth0 から br0 に移行するため、ネットワーク接続が一時的に切断される このため、事前にコンソールアクセスを確保しておくと良い

6. 5GHz帯での動作確認

6.1 基準設定の構築

6GHz 帯に着手する前に、動作するであろう 5GHz 帯での AP 動作を確認を行った

# /etc/hostapd/hostapd.conf
interface=wlx98038eddc01f
bridge=br0
driver=nl80211

ssid=AP_5GHz
hw_mode=a
channel=36
ieee80211n=1
ieee80211ac=1
ieee80211ax=1

# セキュリティ設定
wpa=2
wpa_key_mgmt=WPA-PSK SAE
wpa_passphrase=hogehoge
wpa_pairwise=CCMP
rsn_pairwise=CCMP
ieee80211w=1

# 地域設定
country_code=JP
ieee80211d=1
ieee80211h=1
wmm_enabled=1

# 管理設定
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
max_num_sta=32

6.2 動作確認結果

5GHz帯(チャンネル36、5180 MHz)での安定動作を確認し、問題なく動作することを確認した

7. 6GHz 帯 AP 構築

7.1 最初の技術的障壁

7.1.1 HE 6GHz Max MPDU lengthエラー

6GHz 帯での設定を試みた際、即座に下記のエラーが発生した

The driver does not support the configured HE 6 GHz Max MPDU length

この「HE 6 GHz Max MPDU length」エラーは、RTL8852CU ドライバーで 6GHz AP 機能が完全に実装されていないことを示しており、最大の障壁でした これを解決するにはドライバーに機能を実装、仮に実装したとしてもファームにその機能をキックする実装があるか、そもそもモジュールに物理的実装があるか、などなどそもそも解決できない問題にぶつかる可能性があり、この機能を回避して AP を実装することに注力することになる

7.1.2 GitHub Issue

6GHZ Not Working On Realtek 8832cu. · Issue #408 · morrownr/USB-WiFi · GitHub によると

  1. ドライバー制限: RTL8852CU ドライバーの 6GHz AP 機能は部分的実装
  2. HE 6GHz 機能: High Efficiency 6GHz 特有の機能が不完全対応

となっており、やはりここを解決して進むのは難しそう

7.2 Realtek ドライバーの特殊要件

有識者からの情報により、Realtekモジュールはiw reg setを実行してからでないと6GHz帯が正しく動作しないことが判明した

# 正しい起動順序(必須)
sudo modprobe 8852cu     # ドライバーロード
sudo iw reg set JP       # レギュラトリードメイン設定
sudo hostapd config      # hostapd起動

この順序を守らないと6GHz帯でチャンネル設定エラーが発生する

7.3 技術的ブレークスルーの実現

7.3.1 決定的な設定の発見

数十パターンの設定アプローチを試行し、エラーが段階的に変化することを確認:

  1. 初期: HE 6 GHz Max MPDU length エラー
  2. 第1段階: Failed to set beacon parameters エラー
  3. 第2段階: Could not determine operating frequency エラー
  4. 最終段階: 起動成功

最終的に、下記の設定でドライバー制限を突破

# 6GHz制限回避のキー設定
he_6ghz_max_mpdu=0
he_6ghz_max_ampdu_len_exp=0
he_6ghz_rx_ant_pat=0
he_6ghz_tx_ant_pat=0

値を明示的に 0(最小値)に設定することで、ドライバーの未対応機能を回避できることを確認

7.3.2 成功時のログ
# 成功ログ
wlx98038eddc01f: interface state UNINITIALIZED->ENABLED
wlx98038eddc01f: AP-ENABLED

衝動的に Archer TXE70UH をポチって数日、2025年7月10日に 6GHz 帯の AP として利用できることを確認

8. Windows接続問題の解決

8.1 接続エラーの詳細分析

6GHz AP が見えるようになった後、Windows クライアントから接続しようとしたときに「このネットワークに接続できません」エラーが発生した

8.1.1 クライアント環境の確認
ドライバー: Qualcomm FastConnect 6900 Wi-Fi 6E Dual Band Simultaneous (DBS) WiFiCx Network Adapter
バージョン: 2.0.0.1292 (2025/03/20)
サポートされる認証: WPA3-パーソナル CCMP
サポートされるバンド: 6 GHz [ 5935 MHz - 7115 MHz]

クライアント側は 6GHz / WPA3-SAE に完全対応していることを確認

8.1.2 認証ログの分析
# プローブリクエスト/レスポンスは正常
nl80211: RX frame da=xx:xx:xx:xx:xx:xx sa=yy:yy:yy:yy:yy:yy freq=5570 stype=4 (WLAN_FC_STYPE_PROBE_REQ)

# しかし認証フレームが来ない
# AUTH (stype=11) フレームが全く受信されていない

8.2 SAE設定の最適化

8.2.1 問題の根本原因

RTL8852CUドライバーの6GHz APモードでのSAE実装に制限があることが判明:

  • クライアントモード: 正常動作
  • APモード: SAE認証に制限あり
8.2.2 成功した設定

十数パターンの設定を試行した結果、下記の設定で接続に成功:

# 6GHz Final Working Configuration
interface=wlx98038eddc01f
bridge=br0
driver=nl80211
ssid=AP_6GHz

# 6GHz band
hw_mode=a
op_class=131
channel=5  # 5975 MHz

# 802.11ax
ieee80211ax=1
he_oper_chwidth=0

# Required driver settings for RTL8852CU
he_6ghz_max_mpdu=0
he_6ghz_max_ampdu_len_exp=0
he_6ghz_rx_ant_pat=0
he_6ghz_tx_ant_pat=0

# Country
country_code=JP
ieee80211d=1
ieee80211h=1

# WPA3-SAE (Required for 6GHz)
wpa=2
wpa_key_mgmt=SAE
wpa_passphrase=hogehoge
rsn_pairwise=CCMP
ieee80211w=2
sae_require_mfp=1

# SAE compatibility settings (Critical for Windows)
sae_groups=19 20 21
sae_pwe=2
sae_anti_clogging_threshold=10

# Additional settings
wpa_pairwise=CCMP
wpa_group_rekey=3600

# Basic settings
wmm_enabled=1
beacon_int=100
dtim_period=2

8.3 接続成功の技術的分析

8.3.1 SAE PWE (Password Element) の重要性

sae_pwe パラメータがポイントだった

  • sae_pwe=0: Hash-to-Element(デフォルト)
  • sae_pwe=1: Looping method
  • sae_pwe=2: Hash-to-Element with optional Looping method(互換性最高)

Windows / Qualcomm クライアントは sae_pwe=2 で最も安定して動作した

8.3.2 成功時の認証シーケンス
# SAE認証成功ログ
WPA: Received EAPOL-Key from yy:yy:yy:yy:yy:yy key_info=0x108 type=2
wlx98038eddc01f: STA yy:yy:yy:yy:yy:yy WPA: received EAPOL-Key frame (2/4 Pairwise)
WPA: PTK derivation - A1=xx:xx:xx:xx:xx:xx A2=yy:yy:yy:yy:yy:yy
wlx98038eddc01f: STA yy:yy:yy:yy:yy:yy WPA: sending 3/4 msg of 4-Way Handshake
wlx98038eddc01f: STA yy:yy:yy:yy:yy:yy WPA: received EAPOL-Key frame (4/4 Pairwise)
wlx98038eddc01f: AP-STA-CONNECTED yy:yy:yy:yy:yy:yy
wlx98038eddc01f: EAPOL-4WAY-HS-COMPLETED yy:yy:yy:yy:yy:yy

9. 永続化と運用設定

9.1 systemdサービスの作成

# サービスファイルの作成
sudo systemctl edit --full --force hostapd-6ghz.service
[Unit]
Description=6GHz WiFi Access Point
After=network.target
Wants=network.target

[Service]
Type=forking
PIDFile=/run/hostapd-6ghz.pid
Restart=on-failure
RestartSec=2
Environment=DAEMON_CONF=/etc/hostapd/hostapd-6ghz.conf
EnvironmentFile=-/etc/default/hostapd
ExecStartPre=/bin/bash -c 'modprobe -r 8852cu; sleep 2; modprobe 8852cu; sleep 2; iw reg set JP'
ExecStart=/usr/sbin/hostapd -B -P /run/hostapd-6ghz.pid $DAEMON_CONF
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

9.2 自動起動設定

# サービスの有効化
sudo systemctl enable hostapd-6ghz.service
sudo systemctl start hostapd-6ghz.service

10. その他技術メモ

10.1 一般的な問題と解決策

10.1.1 HE 6GHz Max MPDU length エラー
he_6ghz_max_mpdu=0
he_6ghz_max_ampdu_len_exp=0
he_6ghz_rx_ant_pat=0
he_6ghz_tx_ant_pat=0
10.1.2 Windows 接続エラー
sae_groups=19 20 21
sae_pwe=2
sae_anti_clogging_threshold=10
10.1.3 周波数許可エラー
sudo iw reg set JP

10.2 デバッグ手法

10.2.1 最大詳細度でのデバッグ
sudo hostapd -ddd /etc/hostapd/hostapd-6ghz.conf
10.2.2 無線インターフェイス状態の確認
iw dev wlx98038eddc01f info
iw reg get

11. 技術仕様と制限事項

11.1 実現した Wi-Fi AP の技術仕様

  • SSID: 設定可能
  • 動作周波数: 5955-6415 MHz(日本の6GHz帯)
  • 帯域幅: 20 MHz
  • セキュリティ: WPA3-SAE
  • 動作モード: ブリッジモード(L2透過)

11.2 現在の制限事項

  • 帯域幅制限: 20 MHzのみ対応(40/80/160 MHzは未対応)
  • HE 機能制限: 高度な HE 6GHz 機能は最小値設定が必要
  • ビームフォーミング: 無効化が必要
  • MU-MIMO: 未対応
  • FILS Discovery: RTL8852CUドライバーは未対応

12. 今後について

12.1 帯域幅 40/80/160 MHz への対応

一旦 6GHz で吹くことを優先したため手が回っていないが、40/80/160MHz 幅の構成も設定の針の穴を通していけば実現できる可能性がある

12.2 ドライバーの改善

今後の RTL8852CU ドライバーの改善により下記が実現できる可能性がある

  • HE 機能向上: より多くの 6GHz 特有機能の実装
  • FILS Discovery 対応: 6GHz Discovery 機構の実装

12.3 代替モジュールの検討

Intel AX210 や MediaTek MT7921K 等の他の 6GHz 対応モジュールを利用することで、安定した 6GHz Wi-Fi AP を実現できる可能性が高い 少なくとも RTL8852CU よりはマシな結果が得られると考える

13. まとめ

  • RTL8852CU での 6GHz AP 構築は実現可能(ただし制限はあり)
  • hostapd を使えばすぐに実現するだろう程度に考えていたが、思っていた以上にドライバやファームウェア、デバイスといった要素が複雑に絡み合っており、一筋縄ではいかない
    • 特にドライバ・ファームウェア・デバイスの足並みがしっかり揃っていないと余分な苦労をたくさんすることになる
    • Wi-Fi ルータを作っている企業やエンジニアの苦労がわかるので、一度作ってみることはおすすめしたい
  • RTL8852CU で構築を考えているなら考え直して Intel AX210 など他の先駆者がいるモジュールでの構築をすべき
    • 少なくとも現時点で RTL8852CU のドライバは 6GHz AP を完全に運用できるレベルにない
    • ドライバやファームウェアを独自で改善したい人にはちょうど良い題材かもしれない

14. 参考資料

15. チップセット別 USB-WiFI

15.1 Realtek RTL8852CU

15.2 MediaTek MT7921AUN

15.3 Realtek RTL8912AU

Wi-Fi 7 に対応したモジュール

15.4 Intel AX210

アリエクで探したほうが選択肢があるかも?

Proxmox で NUMA チューニングされた VM を作成する

0. 目次

1. 概要

Proxmox で NUMA チューニングをする方法についてまとめます。

2. 目的

2 socket 以上を持つコンピュータ上での仮想化において、NUMA を考慮した VM 配置にすることはパフォーマンスを改善する上で重要です。 しかしながら Proxmox の設定だけで完結した NUMA チューニングについてはインターネット上の情報が乏しかったため、備忘録として記事に残します。

3. 手順

3.1 grub の変更

kernel cmdline に default_hugepagesz を追加します。 今回はより TLB miss を減らしたかったため 1GB hugepage を用意しています。

# cat /etc/default/grub
~~~
GRUB_CMDLINE_LINUX_DEFAULT="quiet elevator=deadline cpufreq.default_governor=performance default_hugepagesz=1G"
~~~

# update-grub
# reboot

3.2 hugepage の設定

https://github.com/akam1o/hugepages-reserve-service

deb パッケージをインストール

設定ファイルを書き換え

# cat /etc/hugepages.conf
node0   1G  72
node1   1G  72

hugepage service enable/start

# systemctl enable hugepages-reserve.service
# systemctl start hugepages-reserve.service

確認

# cat /proc/meminfo | grep Huge
AnonHugePages:     24576 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:     144
HugePages_Free:        144
HugePages_Rsvd:        0
HugePages_Surp:      0
Hugepagesize:    1048576 kB
Hugetlb:        150994944 kB

3.3 VM への設定

qm set コマンドを用いて NUMA チューニングを入れていく

対象の VM は 6core 24GB

node0 側

# qm set 101 --numa 1 --numa0 cpus=0-5,memory=24576,hostnodes=0,policy=preferred --cpu host --hugepages 1024 

node1 側

# qm set 102 --numa 1 --numa0 cpus=0-5,memory=24576,hostnodes=1,policy=preferred --cpu host --hugepages 1024

引数の説明 --numa: VM の NUMA node の数、SMP としたいので 1 としている --numa0: VM の numa0 側の設定 cpus: node あたりの cpu 数 memory: node あたりの memory GB hostnodes: VM の起動させるホストの NUMA node を設定する policy: メモリの割当ポリシー、通常は preferred で問題ない --cpu: host passthrough としたいので host を指定 --hugepages: hugepage サイズ、今回は 1GB なので 1024 を指定

3.5 VM を pinning したい場合

さらに CPU コアで pinning したい場合、affinity の設定を行う

affinity を設定する場合は、CPU の sibling や NUMA を意識して設定する

sibling の確認
# cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort -n | uniq
0,24
1,25
2,26
3,27
4,28
5,29
6,30
7,31
8,32
9,33
10,34
11,35
12,36
13,37
14,38
15,39
16,40
17,41
18,42
19,43
20,44
21,45
22,46
23,47
NUMA の確認
# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 24 25 26 27 28 29 30 31 32 33 34 35
node 0 size: 96256 MB
node 0 free: 52015 MB
node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23 36 37 38 39 40 41 42 43 44 45 46 47
node 1 size: 96756 MB
node 1 free: 93321 MB
node distances:
node   0   1
  0:  10  21
  1:  21  10

今回の例では numa0 側は 3-5,27-29, numa1 側は 15-17,39-41 として設定

qm set コマンド

numa0 側の VM

# qm set 101 --affinity 3-5,27-29

numa1 側の VM

# qm set 102 --affinity 15-17,39-41

まとめて下記のように設定もできる

# qm set 101 --numa 1 --numa0 cpus=0-5,memory=24576,hostnodes=0,policy=preferred --cpu host --hugepages 1024 --affinity 3-5,27-29
# qm set 102 --numa 1 --numa0 cpus=0-5,memory=24576,hostnodes=1,policy=preferred --cpu host --hugepages 1024 --affinity 15-17,39-41
⚠️ 注記

通常、VM を CPU pinning をする場合には isolcpus, nohz_full, rcu_nocbs を設定することが多いが、Proxmox でこの設定を入れたところ、VM に不具合が出たため意図的に設定していません

4. 結果

起動してくるマシン構成

numa0 側

# cat /etc/pve/qemu-server/101.conf
affinity: 3-5,27-29
boot: order=scsi0
cipassword: xxxxxx
ciuser: xxxxxx
cores: 6
cpu: host
hugepages: 1024
ide2: data1:vm-101-cloudinit,media=cdrom,size=4M
ipconfig0: ip=xxxxxx,gw=xxxxxx
memory: 24576
meta: creation-qemu=9.2.0,ctime=1750411305
name: xxxxxx
net0: virtio=xxxxxx,bridge=xxxxxx
numa: 1
numa0: cpus=0-5,memory=24576,hostnodes=0,policy=preferred
scsi0: data1:vm-101-disk-0,size=100G
scsihw: virtio-scsi-pci
smbios1: uuid=xxxxxx
sockets: 1
vmgenid: xxxxxx

numa1 側

# cat /etc/pve/qemu-server/102.conf
affinity: 15-17,39-41
boot: order=scsi0
cipassword: xxxxxx
ciuser: xxxxxx
cores: 6
cpu: host
hugepages: 1024
ide2: data2:vm-102-cloudinit,media=cdrom,size=4M
ipconfig0: ip=xxxxxx,gw=xxxxxx
memory: 24576
meta: creation-qemu=9.2.0,ctime=1750411305
name: xxxxxx
net0: virtio=xxxxxx,bridge=xxxxxx
numa: 1
numa0: cpus=0-5,memory=24576,hostnodes=1,policy=preferred
scsi0: data2:vm-102-disk-0,size=100G
scsihw: virtio-scsi-pci
smbios1: uuid=xxxxxx
sockets: 1
vmgenid: xxxxxx

Proxmox VE で Windows 11 VM を立てる

0. 目次

1. 概要

Windows 11 の VM が必要になったので、Proxmox で Windows 11 の VM を立てる手順をまとめる

2. ISO のダウンロード

3. VM 作成

VirtIO Driver 用の ISO を追加しています

VirtIO SCSI を選択しています

Intel N100 の iGPU の SR-IOV デバイスPCI Passthrough しています

4. OS インストール

起動してすぐに何かしらキーを押さないと PXE boot になるので、起動後速やかにコンソール画面を出してキーを連打します

あとは基本的には Windows のインストール手順と変わりないですが、インストール先のデバイスがデフォルトだと見えません

そのためドライバーの読み込みを押下し、バージョンと一致する driver (今回の場合は w11/vioscsi.inf)を選択します

正常にドライバが当たれば VirtIO SCSI のディスクが表示されます

ネットワークデバイスに VirtIO を選択している場合は、この時点で VirtIO ドライバをインストールしておかないとこの後のセットアップで詰むので、忘れずにインストールします

5. 起動

無事起動したら完了です

6. 参考

Proxmox VE で Intel N100 の iGPU を SR-IOV で VM に PCI Passthrough する

0. 目次

1. 概要

Intel Processor N100 の内蔵 GPU を SR-IOV で分割し、Proxmox VE 上の VM に PCI Passthrough します。

この記事では、Proxmox VE ホスト側で i915-sriov-dkms を導入し、iGPU の Physical Function(PF) から Virtual Function(VF) を作成して、VM に割り当てるところまでをまとめます。

2. 環境

本文中のログは、以下の環境で取得したものです。

  • CPU: Intel Processor N100
  • GPU: Intel UHD Graphics(Alder Lake-N)
  • Hypervisor: Proxmox VE 8 系
  • Kernel: 6.5.11-8-pve
  • Bootloader: GRUB

BIOS/UEFI 側では、事前に Intel VT-d を有効化しておきます。

i915-sriov-dkms は out-of-tree の DKMS モジュールです。カーネルバージョンやリリースによって導入方法が変わるため、実際に作業する場合は利用するカーネルに対応した release / branch を確認してください。

また、Secure Boot を有効にしている環境では、モジュール署名または MOK 登録が必要になります。検証目的であれば Secure Boot を無効化しておくほうが切り分けしやすいです。

3. 背景

もともとは Ryzen Renoir 世代のホストで、AMD iGPU を vfio-mdev 経由で VM に見せる構成を試そうとしていました。

ただ、検証に時間がかかりそうだったため、まずは SR-IOV に対応している Intel iGPU を使って VM に GPU を割り当てることにしました。今回の対象は Intel N100(Alder Lake-N) の iGPU です。

Intel の iGPU 仮想化対応状況については、以下の Intel 公式資料が参考になります。

AMD iGPU を vfio-mdev で VM に見せる構成については、別途検証する予定です。

4. ホスト側の準備

以降のコマンドは Proxmox VE ホストの root shell で実行します。

4.1 build 環境を入れる

まず、カーネルヘッダと DKMS の build に必要なパッケージを入れます。

apt update
apt install pve-headers-$(uname -r) build-essential dkms mokutil sysfsutils git

4.2 i915-sriov-dkms を取得する

cd ~
git clone https://github.com/strongtz/i915-sriov-dkms.git
cd i915-sriov-dkms

今回の環境では、DKMS の package version を Proxmox のカーネルバージョンに合わせました。

KERNEL="$(uname -r)"
DKMS_VERSION="${KERNEL%-pve}"

sed -i 's/"@_PKGBASE@"/"i915-sriov-dkms"/g' dkms.conf
sed -i 's/"@PKGVER@"/"'"${DKMS_VERSION}"'"/g' dkms.conf

編集後の dkms.conf は以下のようになります。

PACKAGE_NAME="i915-sriov-dkms"
PACKAGE_VERSION="6.5.11-8"

MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build KVER=${kernelver}"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build KVER=${kernelver} clean"

BUILT_MODULE_NAME[0]="i915"
DEST_MODULE_LOCATION[0]=/kernel/drivers/gpu/drm/i915

AUTOINSTALL=yes

4.3 DKMS に登録して install する

dkms add .
dkms status
dkms install -m i915-sriov-dkms -v "$DKMS_VERSION" -k "$KERNEL" --force -j "$(nproc)"

install 時の出力例です。

Sign command: /lib/modules/6.5.11-8-pve/build/scripts/sign-file
Signing key: /var/lib/dkms/mok.key
Public certificate (MOK): /var/lib/dkms/mok.pub

Building module:
Cleaning build area...
make -j4 KERNELRELEASE=6.5.11-8-pve -C /lib/modules/6.5.11-8-pve/build M=/var/lib/dkms/i915-sriov-dkms/6.5.11-8/build KVER=6.5.11-8-pve
Signing module /var/lib/dkms/i915-sriov-dkms/6.5.11-8/build/i915.ko
Cleaning build area...

i915.ko:
Running module version sanity check.
 - Original module
   - This kernel never originally had a module by this name
 - Installation
   - Installing to /lib/modules/6.5.11-8-pve/updates/dkms/
depmod...

5. kernel parameter を設定する

/etc/default/grubGRUB_CMDLINE_LINUX に、IOMMU と i915 SR-IOV 用のパラメータを追加します。

iommu=pt intel_iommu=on i915.enable_guc=3 i915.max_vfs=7

私の環境では、以下のように設定しました。

GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX="intel_idle.max_cstate=1 processor.max_cstate=1 cpufreq.default_governor=performance iommu=pt intel_iommu=on i915.enable_guc=3 i915.max_vfs=7"

現在の i915-sriov-dkms では i915xe の両方に関する案内があるため、xe ドライバが読み込まれる環境では module_blacklist=xe の追加も検討してください。

設定後、GRUB と initramfs を更新します。

update-grub
update-initramfs -u -k all

6. 起動時に VF を作成する

起動時に VF が作成されるように、/etc/sysfs.confsriov_numvfs を設定します。

今回は 2 つの VF を作成します。

echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = 2" >> /etc/sysfs.conf

> で書くと既存の /etc/sysfs.conf を上書きしてしまうため、既存設定がある場合は >> で追記するか、エディタで追加するのが安全です。

設定後、ホストを再起動します。

reboot

7. ホスト再起動後の確認

再起動後、dmesg で i915 が SR-IOV PF mode で動いていることを確認します。

dmesg | grep i915

確認したいポイントは以下です。

i915 0000:00:02.0: Running in SR-IOV PF mode
i915 0000:00:02.0: 7 VFs could be associated with this PF

このログが出ていれば、iGPU が PF として認識され、最大 7 個の VF を作成できる状態になっています。

私の環境では、以下のようなログが出ました。

[    4.115709] i915 0000:00:02.0: Running in SR-IOV PF mode
[    4.116313] i915 0000:00:02.0: [drm] VT-d active for gfx access
[    4.130395] i915 0000:00:02.0: [drm] GT0: GuC firmware i915/tgl_guc_70.bin version 70.13.1
[    4.135982] i915 0000:00:02.0: [drm] GT0: HuC: authenticated for all workloads!
[    4.136431] i915 0000:00:02.0: [drm] GT0: GUC: submission enabled
[    4.197366] [drm] Initialized i915 1.6.0 20201103 for 0000:00:02.0 on minor 0
[    4.199682] i915 0000:00:02.0: 7 VFs could be associated with this PF

lspci でも VF が増えていることを確認できます。

lspci -vnn | grep VGA

出力例です。

00:02.0 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [UHD Graphics] [8086:46d1] (prog-if 00 [VGA controller])
00:02.1 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [UHD Graphics] [8086:46d1] (prog-if 00 [VGA controller])
00:02.2 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [UHD Graphics] [8086:46d1] (prog-if 00 [VGA controller])

00:02.0 が PF、00:02.100:02.2 が VF です。PF と VF は PCI device ID が同じに見えるため、VM に渡すときは PCI address を確認してください。

8. VF を VM に割り当てる

Proxmox VE の GUI から、対象 VM の Hardware を開き、Add -> PCI Device で VF を追加します。

このとき、ホスト側の PF である 00:02.0 ではなく、VF の 00:02.100:02.2 を選びます。

PF を VM に渡すと、ほかの VF も含めて不安定になる可能性があります。VM に割り当てるのは VF のみにします。

CLI で設定する場合は、VMID と VF の PCI address を指定します。

qm set <VMID> -machine q35
qm set <VMID> -hostpci0 0000:00:02.1,pcie=1

Linux ゲストで利用する場合は、ゲスト側にも対応する i915 / xe ドライバが必要です。Windows ゲストの場合は、ゲスト OS 側で Intel Graphics Driver を導入します。

9. VM 起動

VM を起動し、ゲスト OS 側から Intel UHD Graphics として認識されれば成功です。

10. トラブルシュートのメモ

VF が作成されない

まず、kernel parameter が反映されているか確認します。

cat /proc/cmdline

intel_iommu=oni915.enable_guc=3i915.max_vfs=7 が入っていることを確認します。

次に、PF 側で作成可能な VF 数を確認します。

cat /sys/bus/pci/devices/0000:00:02.0/sriov_totalvfs
cat /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs

ホストが起動しなくなった

GRUB の起動画面で対象 kernel を選び、e で kernel parameter を一時編集します。

module_blacklist=i915,xe を追記して起動できれば、i915 / xe ドライバまわりの設定を戻して切り分けできます。

VM に渡す PCI device に注意する

Intel iGPU の PF と VF は同じ device ID に見えます。00:02.0 が PF、00:02.1 以降が VF です。

VM に渡すのは VF だけです。PF はホスト側に残します。

参考

Proxmox VE に CentOS Stream の VM テンプレートを Cloud Image から作成

概要

CentOS Stream の VM テンプレートを Cloud Image から作成する方法です。

Cloud Image のダウンロード

公式 Repo から必要なイメージをダウンロードしてください。

# wget https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2

VM テンプレートの作成

テンプレート用 VM 作成

# qm create 9000 --memory 2048 --net0 virtio,bridge=vmbr0

ダウンロードしたイメージをインポート

# qm importdisk 9000 CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2 local-lvm

scsi で attach

# qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0

cloud-init 用の CD ドライブを用意

# qm set 9000 --ide2 local-lvm:cloudinit

attach したディスクを boot disk に設定

# qm set 9000 --boot c --bootdisk scsi0

シリアルコンソールに接続

# qm set 9000 --serial0 socket --vga serial0

テンプレートに変換

# qm template 9000

テンプレートからのデプロイ

作成したテンプレートから Clone して VM を起動します。

参考

Proxmox VE に Rocky Linux の VM テンプレートを Cloud Image から作成

概要

Rocky LinuxVM テンプレートを Cloud Image から作成する方法です。

Cloud Image のダウンロード

公式 Repo から必要なイメージをダウンロードしてください。

# wget https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2

VM テンプレートの作成

ワンライナー

IMG_ID=9000 \
IMG_FILE="Rocky-8-GenericCloud.latest.x86_64.qcow2" \
STORAGE="local-lvm" \
BRIDGE="vmbr0" \
&& qm create $IMG_ID --memory 2048 --net0 virtio,bridge=${BRIDGE} \
&& qm importdisk $IMG_ID ${IMG_FILE} ${STORAGE} \
&& qm set $IMG_ID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:vm-${IMG_ID}-disk-0 \
&& qm set $IMG_ID --ide2 ${STORAGE}:cloudinit \
&& qm set $IMG_ID --boot c --bootdisk scsi0 \
&& qm set $IMG_ID --serial0 socket --vga serial0 \
&& qm template $IMG_ID

変数について

変数 説明
IMG_ID Proxmox 内でユニークな VM ID
IMG_FILE ダウンロード済みの qcow2 ファイル名
STORAGE インポート先ストレージ
BRIDGE ネットワークブリッジ名

変数定義

IMG_ID=9000
IMG_FILE="Rocky-8-GenericCloud.latest.x86_64.qcow2"
STORAGE="local-lvm"
BRIDGE="vmbr0"

テンプレート用 VM 作成

# qm create $IMG_ID --memory 2048 --net0 virtio,bridge=${BRIDGE}

ダウンロードしたイメージをインポート

# qm importdisk $IMG_ID ${IMG_FILE} ${STORAGE}

scsi で attach

# qm set $IMG_ID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:vm-${IMG_ID}-disk-0

cloud-init 用の CD ドライブを用意

# qm set $IMG_ID --ide2 ${STORAGE}:cloudinit

attach したディスクを boot disk に設定

# qm set $IMG_ID --boot c --bootdisk scsi0

シリアルコンソールに接続

# qm set $IMG_ID --serial0 socket --vga serial0

テンプレートに変換

# qm template $IMG_ID

テンプレートからのデプロイ

作成したテンプレートから Clone して VM を起動します。

参考