ConnectX-3 VPIなんですが、uefi の rom はあるだろうと思っていたのですが、調べた所、どうやら Legacy rom しかないらしく、セキュアーブートはできないのですが、ipoib 経由で iSCSI root はできたので、備忘録として挙げてみることにしました。uefi rom がこちらにありましたが、本稿はレガシーブートの例として残しておくことにしました。
まず、大まかな流れですが、iSCSI target 上で disk イメージを作成し targetcli をつかってアクセスできるようにしておきます。 なお disk imageは uefiクライントも共有できるように gptでパーティションを作成し grub(uefi) を設定していますが、今回は pxelinux が kernel と initrd を直接読み込むので問題はありません。
次に、ConnectX-3の場合 ブートデバイスとして起動すると、flexboot ( iPXE ) が立ち上がるのですが、Legacy ブート なのでサーバ側は 前述のように grub ではなく、 pxelinux を tftp サーバ上で設定します。なお今回は menu.ipxe 経由で disk イメージを iSCSIデバイスとしてフックして iBFT を登録させておいてから、 pxelinux にhttpでチェーンするようにしました。( http server ( apache2 ) の設定は前回を参照してください。)
次に、dhcp サーバを設定し、menu.ipxe を取得できるようにしておきます。なお、dhcpサーバーについては、残念ながら Debian 12 の isc-dhcp-server 場合 ipoib での bootp/dhcp には対応しておらず、今回は Ubuntu 24.04 LTS で構成しました。また今回はiSCSIターゲットは 別セグメントにありますが、dhcpd.conf が正しく default gw を指定しルーティングが機能していれば問題はありません。
以下設定詳細です。iSCSI イニシエータ(クライアント) が 10.1.40.112/sv112, iSCSI ターゲット(サーバ)が10.1.56.106/sv106, tftp/httpサーバが10.1.40.50/i50としています。
まず、iSCSI ターゲット上で disk imageを作成しておきます。
最後は isc-dhcp-server ( /etc/dhcp/dhcpd.conf ) です。ここでは 固定アドレス、 iscsi-initiator-iqn、取得する file を指定します。
作業は以上です。ConnectX-3 VPIをブートデバイスにし、menu.ipxe -> pxelinux.cfg -> iSCSI root の順に起動できれば OK です。
ConnectX-3 は uefiに対応していないのは残念ですが、ConnextX-4以降は対応しているので、これで大丈夫そうです。
今回は以上です。それでは。
まず、大まかな流れですが、iSCSI target 上で disk イメージを作成し targetcli をつかってアクセスできるようにしておきます。 なお disk imageは uefiクライントも共有できるように gptでパーティションを作成し grub(uefi) を設定していますが、今回は pxelinux が kernel と initrd を直接読み込むので問題はありません。
次に、ConnectX-3の場合 ブートデバイスとして起動すると、flexboot ( iPXE ) が立ち上がるのですが、Legacy ブート なのでサーバ側は 前述のように grub ではなく、 pxelinux を tftp サーバ上で設定します。なお今回は menu.ipxe 経由で disk イメージを iSCSIデバイスとしてフックして iBFT を登録させておいてから、 pxelinux にhttpでチェーンするようにしました。( http server ( apache2 ) の設定は前回を参照してください。)
次に、dhcp サーバを設定し、menu.ipxe を取得できるようにしておきます。なお、dhcpサーバーについては、残念ながら Debian 12 の isc-dhcp-server 場合 ipoib での bootp/dhcp には対応しておらず、今回は Ubuntu 24.04 LTS で構成しました。また今回はiSCSIターゲットは 別セグメントにありますが、dhcpd.conf が正しく default gw を指定しルーティングが機能していれば問題はありません。
以下設定詳細です。iSCSI イニシエータ(クライアント) が 10.1.40.112/sv112, iSCSI ターゲット(サーバ)が10.1.56.106/sv106, tftp/httpサーバが10.1.40.50/i50としています。
まず、iSCSI ターゲット上で disk imageを作成しておきます。
# on iSCSI target (10.1.56.106 106)
apt-get install targetcli-fb qemu-utils
mkdir -p /srv/deb01
cd /srv/deb01
dd if=/dev/zero of=deb12.disk.img bs=1024k count=32768
NBD=nbd0
modprobe -av nbd
qemu-nbd -f raw -c /dev/${NBD} deb12.grub.img
# パーティションの作成
fdisk
############################
g
n
enter
enter
1050623
t
uefi
n
enter
enter
enter
w
############################
mkfs.vfat /dev/${NBD}p1
# debian 10 の場合
# mkfs.xfs -m crc=0,finobt=0 -f /dev/${NBD}p2
# debian 12 の場合
mkfs.xfs -f /dev/${NBD}p2
P2_UUID=`xfs_admin -u /dev/${NBD}p2 | cut -d' ' -f 3`
# uefi クライアントと共通で使うので efi ファイルと grub をインストール
mount /dev/${NBD}p2 /mnt
mkdir -p /mnt/boot/efi
mount /dev/${NBD}p1 /mnt/boot/efi
cd /mnt/boot/efi
mkdir -p /mnt/boot/efi/EFI/debian
cd /srv/deb01
mkdir netboot
cd netboot
wget https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz
tar xzpf netboot.tar.gz
cp -a debian-installer/amd64/bootnetx64.efi /mnt/boot/efi/EFI/debian/
cat > /mnt/boot/efi/EFI/debian/grub.cfg <<EOF
search.fs_uuid $P2_UUID root hd0,gpt2
set prefix=(\$root)/boot/grub
configfile \$prefix/grub.cfg
EOF
cat > /mnt/boot/grub/grub.cfg <<EOF
menuentry 'Debian 12 iSCSI root'{
linux /boot/vmlinuz-6.1.0-29-amd64 root=UUID=$P2_UUID rw ip=::::::dhcp iscsi_auto rootfstype=xfs rootwait
initrd /boot/initrd.img-6.1.0-29-amd64.ib
}
EOF
grub-install --target=x86_64-efi --efi-directory=/mnt/boot/efi --boot-directory=/mnt/boot --uefi-secure-boot /dev/${NBD}
# disk image の population
# on iscsi target ( 10.1.56.106 sv106 )
cd /mnt
# debian 10 busterの場合
# debootstrap buster .
# debian 12 boookworm の場合
debootstrap bookworm .
# debootstrap では足りないパッケージ等を半自動でインストール・設定
cat > root/and-so-on.sh <<EOF
apt-get install -y --no-install-recommends linux-image-amd64 linux-image-6.1.0-29-amd64 busybox xfsprogs openssh-server open-iscsi zstd
apt-get install -y --no-install-recommends locales console-setup fbterm fonts-vlgothic fonts-courier-prime
# set root password
passwd
# add user
adduser YourUserName
# change hostname
echo deb12a > /etc/hostname
# add ipv4 nameservers
echo nameserver 10.1.1.64 >> /etc/resolv.conf
echo nameserver 10.1.1.65 >> /etc/resolv.conf
# setup locales
dpkg-reconfigure locales
# setup keyboard layout
dpkg-reconfigure keyboard-configuration
exit
EOF
mount -t proc proc proc/
mount -t sysfs sysfs sys/
chroot . bash root/and-so-on.sh
umount proc/
umount sys/
# カーネル等を tftp/http サーバにコピー
scp /mnt/boot/*6.1.0-29* 10.1.56.50:/srv/tftp/boot/
disk imageの作成が済んだら targetcliでアクセスできるようにしておきます。
apt-get install targetcli-fb targetcli /backstores/fileio create deb12-amd64-01 /srv/deb01/deb12.disk.img targetcli /iscsi create iqn.1868-01.com.example:sv106.deb12-amd64-01 targetcli /iscsi/iqn.1868-01.com.example:sv106.deb12-amd64-01/tpg1/luns create /backstores/fileio/deb12-amd64-01 targetcli /iscsi/iqn.1868-01.com.example:sv106.deb12-amd64-01/tpg1/acls create iqn.1868-01.com.example:sv112続いて menu.ipxeとpxelinux.cfg/sv112 (sv112は今回のiSCSIイニシエータ) を作成します。
# on tftp server (10.1.40.50 i50)
cat > /srv/tftp/menu.ipxe <<EOF
#!ipxe
:start
menu MENU
item --gap -- --------------
item pxelinux boot from http://10.1.40.50/pxelinux.0
item --gap -- --------------
item shell Drop to iPXE shell
item --gap -- --------------
choose selected
goto ${selected}
:pxelinux
set root-path iscsi:10.1.56.106::::iqn.1868-01.com.example:sv106.deb12-amd64-01
sanhook ${root-path}
set 209:string pxelinux.cfg/${hostname}
set 210:string http://${next-server}/
chain http://${next-server}/pxelinux.0 || goto start
:shell
echo Type 'exit' to get back to the menu
shell
set menu-timeout 0
goto start
EOF
# on tftp server (10.1.40.50 i50)
apt-get install syslinux pxelinux tftpd-hpa
cd /srv/tftp
cp -a /usr/lib/syslinux/modules/bios/menu.c32 .
cp -a /usr/lib/syslinux/modules/bios/ldlinux.c32 .
cp -a /usr/lib/syslinux/modules/bios/libutil.c32 .
cp -a /usr/lib/PXELINUX/pxelinux.0 .
mkdir pxelinux.cfg
# pxelinux の menu を作成
cat > pxelinux.cfg/sv112 <<EOF
PROMPT 1
TIMEOUT 100
UI menu.c32
SERIAL 0 115200
MENU TITLE PXE Boot Menu
MENU DEFAULT 6.1.0-29
LABEL 6.1.0-29
kernel /boot/vmlinuz-6.1.0-29-amd64
append initrd=/boot/initrd.img-6.1.0-29-amd64.ib root=UUID=72cd4ba4-d447-4118-8e35-xxxxxxxxxxxx ip=::::::dhcp iscsi_auto net.ifnames=0 rootfstype=xfs rw console=tty0 console=ttyS0,115200n1
EOF
つづいて initrd を 作成し配置します。(今回はiSCSIターゲット sv106 が Debian 12 なのでこちらで作業)
# edit /etc/initramfs-tools/modules
cat >> /etc/initramfs-tools/modules EOF
iscsi_ibft
ib_core
ib_cm
ib_uverbs
ib_umad
iw_cm
rdma_cm
rdma_ucm
mlx4_core
mlx4_ib
ib_mthca
ib_ipoib
EOF
# patch for /usr/share/initramfs-tools/scripts/local-top/iscsi
## -----------------------------------------------------------
--- iscsi.orig 2025-03-18 07:16:13.081164264 +0900
+++ iscsi.ok.02.2 2025-03-26 22:37:00.263868546 +0900
@@ -99,7 +99,7 @@
# try to auto-configure network interface based
# on firmware values
modprobe iscsi_ibft
- iscsistart -N
+ iscsistart -N || echo "Unable to configure network"
# write out /run/net-$IFACE.conf based on what
# was in the firmware
@@ -182,7 +182,7 @@
# also, if we set up DHCP iBFT, we need ipconfig to run so it creates
# a proper /run/net-${DEVICE}.conf file that includes the DNS search
# domain, which we don't get in our iBFT data (see LP: #1806777)
- configure_networking
+ true || configure_networking
if [ -n "$IBFT_DHCP_DEVICE" ]; then
if ! [ -e "/run/net-${DEVICE}.conf" ] ; then
@@ -192,7 +192,7 @@
# though that will not include the DNS search domain
mv "/run/net-${DEVICE}.conf.ibft" "/run/net-${DEVICE}.conf"
# need to re-run configure_networking to process conf file
- configure_networking
+ true || configure_networking
fi
fi
@@ -330,8 +330,58 @@
exit 0
fi
+modprobe iscsi_ibft
+iscsistart -f | grep -v \# > /run/iscsi-vars
+iface=`cat /run/iscsi-vars | grep iface.net_ifacename | cut -d' ' -f3`
+
+if [ "$iface" == "$DEVICE" ]; then
+ iscsistart -N || echo Failed to bring up the network as specified by iBFT
+else
+ i=$DEVICE
+ if [ -e /sys/class/net/$i/carrier ]; then
+ ip link set dev $i up && interface_up=`cat /sys/class/net/$i/carrier`
+ else
+ interface_up=""
+ fi
+ echo awainting for interface $i up
+ count=0
+ while [ "$interface_up" == "0" -o ! -n "$interface_up" ] && [ $count -lt 30 ]
+ do
+ echo interface_up: $interface_up
+ if [ -e /sys/class/net/$i/carrier ]; then
+ ip link set dev $i up && interface_up=`cat /sys/class/net/$i/carrier`
+ else
+ interface_up=""
+ fi
+ if [ "$interface_up" == "1" ];then
+ echo $i is up
+ fi
+ count=$((count + 1))
+ sleep 1
+ done
+
+ address=`cat /run/iscsi-vars | grep iface.ipaddress | cut -d' ' -f3`
+ netmask=`cat /run/iscsi-vars | grep iface.subnet_mask | cut -d' ' -f3`
+ gateway=`cat /run/iscsi-vars | grep iface.gateway | cut -d' ' -f3`
+ plength=`cat /run/iscsi-vars | grep iface.prefix_len | cut -d' ' -f3`
+ dns=`cat /run/iscsi-vars | grep iface.primary_dns | cut -d' ' -f3`
+
+ ip addr del $address/$plength dev $iface
+ ip addr add $address/$plength dev $DEVICE
+ ip rout add default via $gateway
+
+ initiatorname=`cat /run/iscsi-vars | grep iface.initiatorname | cut -d' ' -f3`
+ targetname=`cat /run/iscsi-vars | grep node.name | cut -d' ' -f3`
+ targetaddr=`cat /run/iscsi-vars | grep node | grep address | grep 0 | cut -d' ' -f3`
+ iscsistart --param iface.net_ifacename=ib0 -i $initiatorname -g 1 -t $targetname -a $targetaddr || true
+fi
+
do_iscsi_login
+if [ "$iface" != "$DEVICE" ]; then
+ ip addr del $address/$plength dev $iface
+fi
+
udevadm settle
# The second check is to allow us to use multiple root= parameters. That way##
-----------------------------------------------------------
# create a config file
cat > /etc/iscsi/iscsi.initramfs <<EOF
ISCSI_AUTO=true
EOF
# edit /etc/initramfs-tools/initramfs.conf
--- /etc/initramfs-tools/initramfs.conf.orig 2022-06-20 20:54:17.000000000 +0000
+++ /etc/initramfs-tools/initramfs.conf 2025-03-25 04:03:02.511800529 +0000
@@ -63,7 +63,7 @@
# Overridden by optional ip= or BOOTIF= bootarg
#
-DEVICE=
+DEVICE=ib0
#
# NFSROOT: [ auto | HOST:MOUNT ]
# initrd の作成と tftp/http サーバへの配置
mkdir ~/initrd_ib
cd ~/initrd_ib
update-initramfs -k 6.1.0-29-amd64 -c -b .
mv initrd.img-6.1.0-29-amd64 initrd.img-6.1.0-29-amd64.ib
scp initrd.img-6.1.0-29-amd64.ib root@10.1.56.50:/srv/tftp/boot/
追記:シングルインターフェースの場合問題ないのですが、デュアルインターフェースの場合、ib0ではなくib1が選択される場合があります。initramfs の local-top/iscsi スクリプトを追ったのですがどうやら iBFT の値の受け渡しに問題があるようなので、local-top/iscsi スクリプトに簡易ワークアラウンドを追加しました。最後は isc-dhcp-server ( /etc/dhcp/dhcpd.conf ) です。ここでは 固定アドレス、 iscsi-initiator-iqn、取得する file を指定します。
allow booting;
allow bootp;
option iscsi-initiator-iqn code 203 = string;
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;
set vendorclass = option vendor-class-identifier;
option pxe-system-type code 93 = unsigned integer 16;
set pxetype = option pxe-system-type;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;
log-facility-local7;
subnet 10.1.40.0 netmask 255.255.255.0 {
option domain-name-servers 10.1.1.64;
option domain-name "example.com";
option routers 10.1.40.50;
option broadcast-address 10.1.40.255;
next-server 10.1.40.50;
if substring(vendorclass, 0, 9)="PXEClient" {
if pxetype=00:06 or pxetype=00:07 {
filename "ipxe-signed/ipxe.efi";
# filename "ipxe-signed/snponly.efi";
} else {
filename "menu.ipxe";
}
}
pool {
range 10.1.40.200 10.1.40.250;
}guid (00:02:c9:03:00:18:2f:91)
}
host sv112 {
option host-name "sv112";
hardware ethernet 02:02:c9:18:2f:91;
option dhcp-client-identifier=ff:00:00:00:00:00:02:00:00:02:c9:00:00:02:11:22:33:44:55:66;
fixed-address 10.1.40.112;
next-server 10.1.40.50;
filename "menu.ipxe";
# filename "pxelinux.0";
# option pxelinux.configfile "pxelinux.cfg/sv112";
option iscsi-initiator-iqn "iqn.1868-01.com.example:sv112";
# option root-path "iscsi:10.1.56.106::::iqn.1868-01.com.example:sv106.deb12-amd64-01";
}
dhcp-client-identifierは 接頭 ff:00:00:00:00:00:02:00:02:c9:00: + GUID 8バイト(00:02:11:22:33:44:55:66)です。編集が済んだら、systemctl restart isc-dhcp-server とします。作業は以上です。ConnectX-3 VPIをブートデバイスにし、menu.ipxe -> pxelinux.cfg -> iSCSI root の順に起動できれば OK です。
ConnectX-3 は uefiに対応していないのは残念ですが、ConnextX-4以降は対応しているので、これで大丈夫そうです。
今回は以上です。それでは。
コメント
コメントを投稿