えんでぃの技術ブログ

えんでぃの技術ブログ

ネットワークエンジニアの視点で、IT系のお役立ち情報を提供する技術ブログです。

GNS3・QEMU上でvEOSを起動する

お伝えしたいこと

Arista vEOSをGNS3上で起動するためのセットアップ手順を紹介します。
Arista vEOSとは、Arista社が提供するL3SWの仮想アプライアンス (VM版) です。

今回は仮想化ドライバにQEMUを使います。
QEMUは、GNS3をLinux上で動かしている方に向いています。

Arista vEOSのダウンロード

Arista Software Downloadのページからダウンロードします。
(※) URLの通り、トップページからSupport > Software DownloadのリンクでSoftware Downloadページにアクセスできます

このページにアクセスするには、Arista社にユーザー登録する必要があります。
vEOSを利用するだけであれば、Arista社から製品を購入していなくてもアカウント登録できます。
アカウント登録完了から実際にログインできるまで、数十分ほどラグがあったと思います。

ログインできたら下の方へスクロールし、vEOS-lab配下の以下2ファイルをダウンロードしてください。

  • Aboot-veos-serial-x.x.x.iso (最新版を選択)
  • vEOS64-lab-x.xx.xM.vmdk (Mがつく中で最新版を選択)

download_veos

(参考) AbootとAboot-serial

AbootはvEOSのBootloaderです。
Aboot-veosはシリアルコンソール非対応版、Aboot-veos-serialはシリアルコンソール対応版です。

vEOSをGNS3上で動かす場合はシリアルコンソールに対応していたほうが便利なので、Aboot-veos-serialを使いましょう。

(参考) vEOSの推奨バージョンの選び方

Arista Software DownloadRecommended Releasesタブに記載がありますが、Arista vEOSの推奨バージョンはMがつく中での最新版です。

MはMaintenance Releaseという意味であり、いわゆる安定版です。
基本的にはM付きの最新版を選ぶのが無難です。

Fというフラグがついたバイナリもありますが、これはFeatureの略です。
最新版の機能を追加したリリースであることを意味しています。
どうしても試したい機能が最新版でリリースされたときのみ、最新版のF付きリリースを試しても良いかもしれません。

vEOSをGNS3に登録する

手順の大半はGNS3・QEMU上でLinuxを起動すると同様です。
したがって、今回はややシンプルに手順を説明します。

詳細が気になった方は、上記記事をご確認ください。

(参考) vEOSの動作要件

CloudEOS and vEOS Router - Using the vEOS Router on KVM and ESXiによると、vEOSの動作要件は以下のとおりです。

項目 推奨値
vCPUコア数 最低2コア、最大16コア
RAMサイズ 最低4GiB
ディスクサイズ 最低8GiB
仮想NIC 最大8まで

仮想ディスクファイルの格納

#Arista vEOSのダウンロードでダウンロードした2ファイルを~/GNS3/images/QEMU/配下に格納してください。
これらのファイルは、現在のユーザーが読み書きできる必要があります。
(正確には、gns3serverプロセスが読み書きできる必要があります)

ls -l ~/GNS3/images/QEMU/Aboot-veos-serial*.iso ~/GNS3/images/QEMU/vEOS64-lab*.vmdk
# -rw-r--r--. 1 endy endy   6291456 Apr 29 12:06 /home/endy/GNS3/images/QEMU/Aboot-veos-serial-8.0.1.iso
# -rw-r--r--. 1 endy endy 473235456 Apr 29 12:07 /home/endy/GNS3/images/QEMU/vEOS64-lab-4.26.5M.vmdk

GNS3にQEMU仮想マシンとして登録する

本セクションでは、準備した仮想ディスクファイルをGNS3に登録します。

まずはGNS3を起動し、Edit > Preferences (Ctrl+Shift+P) から設定画面を開きます。

左のメニューからQEMU VMsを選択し、NewボタンからQEMUで再生する仮想マシンを新規登録します。

create_qemu_vm1

わかりやすい仮想マシン名を入力します。
今回はvEOSとします。

register_veos1

QEMUコマンドのパスを指定します。
今回は/usr/bin/qemu-kvmとします。

RAMサイズはvEOSの動作要件に合わせて4096 MiBとします。

register_veos2

コンソールタイプを選択します。
シリアルコンソールが便利なので、telnetを選択します。

register_veos3

セットするディスクファイルを選択します。
ここではAboot-veos-serial-x.x.x.isoを選択します。
vEOS64-lab-x.xx.xM.vmdkは、後ほどVMの編集画面でセットします。

register_veos4

QEMU仮想マシンをカスタマイズする

前セクションで登録した仮想マシンを更にカスタマイズします。
作成した仮想マシンを選択し、Editから更に設定変更します。

edit_veos1

以降のセクションでは、変更した箇所をピンクの枠で囲みます。

General settings

アイコンはL3SWに近い印象のswitch_multilayerを選択しました。
CPUコア数は、ホストマシンのスペックに応じてご検討ください。

edit_veos2

HDD

Disk interfaceはvirtioを選択します。

また、ディスクファイルは以下のようにセットしてください (※)
ディスクファイルは~/GNS3/images/QEMU/配下に格納されています。
(※) CloudEOS and vEOS Router - Launching vEOS in LinuxBridge ModeによるとISOファイルをHDCに、ディスクファイル (qcow2)をHDAにセットしていますが、これでは動きません。Abootを先に起動し、Abootからディスクファイル内のEOSを起動するのが本来の起動順序なので、Abootの方が起動の優先順位を高くする必要があります。LinuxQuestions.org - IDE master/slaveの情報も踏まえ、起動デバイスであるAbootをPrimary Masterに配置するのが良いでしょう

接続先 ディスクファイル
HDA
(Primary Master)
Aboot-veos-serial-x.x.x.iso
HDB
(Primary Slave)
vEOS64-lab-x.xx.xM.vmdk

edit_veos3

CD/DVD

CD/DVDは特にいじりません。

edit_veos4

Network

Arista vEOSを含め、多くのNW機器の仮想アプライアンスは先頭ポートがManagement、2ポート目以降がサービスポートという扱いになります。
Arista vEOSの場合、ポートアサインは下表のようになります。
(※) ポートアサインは実機にログインして確認しました

VMNIC番号 vEOS上のinterface#
0 Management1
1 Ethernet1
2 Ethernet2
3 Ethernet3
4 Ethernet4
5 Ethernet5
6 Ethernet6
7 Ethernet7

GNS3上も上記のような表示名で見せるために、下図のような設定としました。
Ma1のような省略表記にした理由は、トポロジ上のNIC番号は短い表記の方が扱いやすいためです。

NIC数は動作要件に合わせて8に、性能向上のためにドライバはvirtioにしました。

edit_veos5

Advanced

Advancedは特にいじりません。

edit_veos6

Usage

最低限のコメントのみ書いておきました。

edit_veos7

vEOSの起動

登録したvEOSをGNS3上で起動します。

SwitchのカテゴリからvEOSをドラッグ&ドロップで追加します。

launch_veos1

vEOSのアイコンを右クリックし、Startを選択して起動します。

launch_veos2

vEOSのアイコンをダブルクリックしてシリアルコンソール接続します。
ターミナルが起動しない場合は、GNS3・QEMU上でLinuxを起動する - #Console applicationsを参考にしつつ、GNS3が既定で呼び出すコンソールアプリケーションを設定してください。

(参考) Arista vEOSへのログイン

起動には数分かかります。

大量のsyslogメッセージが見えてきた頃にEnterキーを押すとログインプロンプトが出てきます。

adminユーザーでログインします。
パスワードは不要です。

ログイン後、以下のコマンドを実行してZTP (※) を停止します。
ZTPを停止しないとstartup-configを生成できないためです。

zerotouch cancel

zerotouch cancelを実行すると、vEOSが再起動します。
起動してきたら再びログインし、以下のコマンドを実行します。

enable
copy running-config startup-config

これでZTPが恒久的に停止します。

(参考) ZTPとは

ZTPとは、Zero Touch Provisioningの略語です。
LinuxでいうPXE Bootと似たような概念です。

ZTPを利用すれば、Aristaの管理ポートを接続して電源投入するだけでコンフィグ投入が自動的に完了します。
ZTPの原理は、専用のZTP用サーバからDHCPIPアドレスを受け取り、startup-configかスクリプトをダウンロードしてセットアップを行うというものです。

(参考) ZTPを無効化する方法

参考: YouTube - Networking Institute - Implementing Zero Touch Provisioning(ZTP) on Arista Switches
(※) 無料ユーザーではArista公式情報から詳細な情報を得られませんでした。Networking Instituteは、非公式ながらAristaの情報について正確かつ詳細に解説しているので、今回こちらを情報源とさせていただきました

Arista EOSの起動時、以下の2つの条件を満たせばZTPが開始されます。
(※) zerotouch cancelという例外パターンもありますが、この後説明します

  • /mnt/flash/startup-configが存在しないこと
  • /mnt/flash/zerotouch-configDISABLE=Trueと書かれていないこと

初期状態のArista EOSは、上記のどちらのファイルも存在しないためZTPを開始する条件が揃っています。

ZTPを停止する方法は大きく分けて2つあります。

  • zerotouch cancelを実行し、再起動後にcopy running-config startup-configを実行する
  • zerotouch disableを実行する

zerotouch cancelを実行すると、直後にEOSが再起動します。
そしてZTPが無効化された状態でEOSが起動します。

zerotouch cancelによるZTPの無効化は一時的なものです。
copy running-config startup-configによって/mnt/flash/startup-configを生成すれば、ZTPの無効化が永続的なものとなります。
startup-config生成前に再び再起動すると、ZTPが有効化されて起動してきます。

zerotouch disableによるZTPの有効化は永続的なものです。
このコマンドの実行により/mnt/flash/zerotouch-configDISABLE=Trueが書き込まれます。
これにより、startup-configの有無に関わらずZTPが永続的に無効化されます。

(任意) ZTPを予め無効化しておく

ZTPを使わない場合、毎回zerotouch cancelを実行するのは面倒だと思います。
そこで、本セクションでは予めZTPを無効化した上でテンプレート化するための手順を紹介します。

まず、~/GNS3/images/QEMU/配下にあるvEOSのvmdkファイルをコピーしておきます。

cd ~/GNS3/images/QEMU/
cp -pi vEOS64-lab-4.26.5M.vmdk vEOS64-lab-4.26.5M_zerotouch_disable.vmdk

続いて、GNS3を起動して設定画面を開きます (Ctrl+Shift+P)
QEMU VMsセクションにて、作成済みのvEOSの設定をコピーします。
新しいVMの名前を求められるので、vEOS (ZTP Disabled)としておきます。

copy_veos_vm_settings

続いてEditからvEOS (ZTP Disabled)の設定をカスタマイズします。

edit_veos_ztp_disabled1

General settingsタブで、Default name format{name}-{0}からvEOS-{0}に変更します。

edit_veos_ztp_disabled2

HDDタブで、HDBに先ほどコピー作成したvmdkファイルをセットします。
(※) vEOS64-lab-x.xx.xM_zerotouch_disable.vmdk

edit_veos_ztp_disabled3

Advancedタブで、Use as a linked base VMのチェックを外します。
これにより、GNS3上にVMを追加した際のVMクローン処理が無効化され、VMテンプレートを直接書き換えることができます。

edit_veos_ztp_disabled4

作成したvEOS (ZTP Disabled)をGNS3上で起動します。

launch_veos2

起動したvEOSにシリアルコンソールで接続し、adminユーザーでログインします。
そして以下のコマンドを実行することでZTPを恒久的に無効化します。

zerotouch disable

vEOSの再起動後、再びadminユーザーでログインします。
そして、以下のコマンドによってOSをシャットダウンします。

enable
bash
sudo shutdown -h now

vEOSをGNS3上で右クリックして削除します。
これによってvEOS (ZTP Disabled)はGNS3のトポロジ上からは消えますが、実際にはZTPが無効化された設定込のデータが~/GNS3/images/QEMU/vEOS64-lab-x.xx.xM_zerotouch_disable.vmdkに残っています。

delete_veos_on_gns3

最後に、vEOS (ZTP Disabled)の設定を開き、AdvancedタブからUse as a linked base VMを再び有効化します。

edit_veos_ztp_disabled5

以上の操作により、ZTPが無効化されたvEOSテンプレートを作成できました。

まとめ

Arista vEOSをGNS3上にQEMU VMとして追加する手順を紹介しました。
前回記事LinuxVPCSと組み合わせれば、vEOSを使った一通りのハンズオンができると思います。

参考サイト

ネットワークチェンジニアとして - Arista vEOSの基本的な使い方

Arista vEOSのダウンロード方法について、本ブログよりも更に丁寧に解説されています。
またGNS3ではありませんが、ESXiへのvEOS登録手順が解説されています。

vEOSのダウンロードとセットアップ手順を調べる際、大いに参考にさせていただきました。

記事内のリンクにvEOSでよく使いそうなMLAGやVXLAN、EVPNの解説もあります。
こちらは、GNS3セットアップ後の検証を行う上で大変役に立ちます。

GNS3・QEMU上でLinuxを起動する

お伝えしたいこと

LinuxをGNS3上で動作させる手順を紹介します。

GNS3上でQEMUベースのLinux VMを登録する手順を扱います。
Linux上でGNS3 Serverを動作させる構成において役に立つと思います。

本記事は、ホストマシンがGNS3とKVM環境をセットアップ済みのLinuxであることを前提にしています。
KVMのセットアップ手順については、KVMの初期設定、及びvirsh, virt-installによるVM作成を参照してください。

Linuxの準備

GNS3上でQEMU仮想マシンを動作させるには、GNS3に仮想ディスクファイル (※qcow2など) を登録する必要があります。
もちろん、その仮想マシンファイルにはLinuxがインストールされている必要があります。

シリアルコンソールに対応したい場合は、Linuxインストール後に#(任意) シリアルコンソールへの対応も実施しておいてください。
シリアルコンソールに対応しておいた方が使い勝手が向上するため、任意とは言いつつも実施しておくことをおすすめします。

(参考) Linux VMの作成手順

ご参考までに、KVMLinux VMを作成するための簡易手順を示します。

CLIで行う場合は、以下のようなコマンドでLinuxマシンを新規作成、及び起動します。
以下のコマンドはCentOS Stream 8の例です。

virt-install \
--name centos_stream8 \
--memory 1024 \
--vcpus 2 \
--disk size=20 \
--cdrom /home/shared/libvirt/images/isos/centos/CentOS-Stream-8-x86_64-latest-dvd1.iso \
--os-variant centos-stream8 &

やり直し用に、VMの強制終了、及び削除のコマンドサンプルも示します。

virsh destroy centos_stream8 ; virsh undefine centos_stream8 --storage vda

CockpitなどのGUIによるVM作成手順については、KVMの基本操作集 - #VMの作成を参考にしてください。

(任意) シリアルコンソールへの対応

本セクションの作業は任意です。
この手順によって、Linuxにシリアルコンソール接続できるようにします。

GNS3上でLinuxを操作する場合はシリアルコンソールに対応させたほうが便利なので、本セクションの手順も含めて実施することを推奨します。

(参考) シリアルコンソールとは

GNS3にKVMベースのLinux VMを追加したとき、管理アクセスの選択肢としてデフォルトでは主に以下の選択肢が挙げられます。

  1. GNS3上のネットワーク経由でログインする
    • SSHHTTPSを初めとして各種プロトコルが使える
    • ファイル転送もできる (SCPやFTPなど)
    • GNS3上の配線に依存する
    • 管理IPアドレスの設定が必要
  2. グラフィカルコンソール経由でログインする
    • サーバー本体に直接キーボード、マウス、ディスプレイを接続するのと同等
    • GUIにも対応可能
    • ホストマシンからコピペしづらいのが不便

グラフィカルコンソールとは、以下の画面のことです。

graphical_console

上記2つの方式にはそれぞれ弱点があります。
1はネットワークアクセスのために配線と初期設定が必要です。
2はホストマシンからのコピペがしづらいです。

そこで、本セクションでは第三の選択肢としてシリアルコンソール経由でのログインを使えるように設定変更します。

シリアルコンソールとは、例えばネットワーク機器にロールオーバーケーブルで接続してアクセス可能な画面のことです。
シリアルコンソールを使えば、ネットワーク接続性がなくてもコピペに対応したCLIアクセスが可能です。
その代わり、ファイル転送やGUI表示はできませんので、そこは他の方式と使い分けが必要です。
CLIベースのLinuxであれば、グラフィカルコンソールよりもシリアルコンソールの方が便利です。

Linuxをシリアルコンソールに対応させるには、Linux側で初期設定が必要です。
その手順は次のセクションで紹介します。

Linuxの設定変更

対象のLinuxマシンにログインして、GRUB 2の設定を変更することでシリアルコンソールを有効化します。

まずは、変更前の設定を事前に確認しておきます。

# (更新行のみ抜粋)

sudo grubby --info=ALL

# index=0
# args="ro crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet $tuned_params"

# index=1
# args="ro crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet"

sudo cat /etc/default/grub

# GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet"

続いて設定を変更します。

sudo grubby --update-kernel=ALL --args="console=tty0 console=ttyS0,115200"

設定を確認します。
grubby --info=ALLargsと、/etc/default/grubGRUB_CMDLINE_LINUXのそれぞれに、console=tty0 console=ttyS0,115200が追記されていることがわかります。

# (更新行のみ抜粋)

sudo grubby --info=ALL

# index=0
# args="ro crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet console=tty0 console=ttyS0,115200 $tuned_params"

# index=1
# args="ro crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet console=tty0 console=ttyS0,115200"

sudo cat /etc/default/grub 

# GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/cs-swap rd.lvm.lv=cs/root rd.lvm.lv=cs/swap rhgb quiet console=tty0 console=ttyS0,115200"

OS再起動して更新を反映します。

sudo reboot

ご参考までに、consoleオプションを削除して元の値に戻したい場合は以下のコマンドを実行します。
今回の手順ではもちろん実行する必要はありませんので、コメントアウトしてあります。

# sudo grubby --update-kernel=ALL --remove-args="console"

(参考) 実施した手順の意味

上記のgrubbyコマンドで一体何を変更したのかを補足します。
気になる方のみお読みください。

(参考) grubbyとは

grubbyとは、Boot Entryの設定値を表示、変更するコマンドラインツールです。
RHELではこのコマンドによってGRUB 2の設定変更をすることが推奨されています。1

grubbyコマンドを使用するパターンも含めて、GRUB 2の設定を変更する方法は3つあります。
興味のある方は、以下のリンクもご確認ください。
参考: RHEL7 - System Administrator’s Guide - 26.2. Configuring GRUB 2

(参考) Boot Entryとは

過去記事を参照してください。

(参考) consoleオプション

今回書き換えたのは、GRUB 2からLinux Kernelに渡すパラメータの1つです。
consoleオプションの仕様は、以下のLinuxカーネルのドキュメントに記載があります。
参考: The Linux kernel user’s and administrator’s guide - Linux Serial Console

Linuxのデフォルトではグラフィカルコンソール (/dev/ttyX) のみが有効化され、シリアルコンソール (/dev/ttySX) は有効化されません。
今回はconsoleオプションを2回指定することで、グラフィカルコンソールとシリアルコンソールをそれぞれ有効化しています。

シリアルコンソールの指定ではconsole=ttyS0,115200を指定していますが、これは以下のような意味を持ちます。

  • /dev/ttyS0バイスを生成する (※ttyS0は、COM1と同義)
  • ボーレートを115200に指定している (※デフォルトは9600。115200に変更することで表示速度を上げている)

RHEL7のSystem Administrator’s Guideでもconsoleオプションについて言及されています。2,3
ここで言いたいことは、今回実施した手順はRHELのドキュメントでもある程度裏打ちされたものであるということです。

LinuxをGNS3に登録する

VM設定の全体像

先に設定の全体像を示しておきます。
GNS3に既に慣れている方は、以下の画面だけで手の動かし方が十分に伝わると思います。

先にCentOS Stream8の例を示します。

centos_stream_8CentOS Stream 8の設定

CentOS Stream 9のVMを建てる場合のみ、QEMUのオプションに-cpu hostを追加で指定する必要があります。
このパラメータを指定するのは、CentOS Stream 9とQEMUの相性問題を回避するためです。
詳細は#Advancedを参照してください。

centos_stream_9CentOS Stream 9の設定

仮想ディスクファイルの格納

ここまでの手順で、Linux VMの作成が完了しているはずです。
作成した仮想マシンから、仮想ディスクファイルを取り出しましょう。

KVM環境の場合は、virsh domblklist 仮想マシン名で仮想ディスクファイルのパスを確認できます。

virsh domblklist centos_stream8

#  Target  Source
# ---------------------------------------------------
#  vda     /home/shared/libvirt/images/centos_stream8.qcow2

作成した仮想マシンから仮想ディスクファイルを取り出し、~/GNS3/images/QEMU/に格納しておきます。

cp /home/shared/libvirt/images/centos_stream8.qcow2 ~/GNS3/images/QEMU/

取り出した仮想ディスクファイルが現在のユーザーから読み書きできることを確認してください。
権限が足りていない場合は、chmodchownで変更しておきましょう。

sudo chown $USER:$USER ~/GNS3/images/QEMU/centos_stream8.qcow2
chmod 644 ~/GNS3/images/QEMU/centos_stream8.qcow2

ls -lh ~/GNS3/images/QEMU/centos_stream8.qcow2
# -rw-r--r--. 1 endy endy 11G Apr 13 21:06 /home/endy/GNS3/images/QEMU/centos_stream8.qcow2

この段階で仮想ディスクファイルは既に取り出せたので、#Linuxの準備で作成したVMは削除しても問題ありません。

GNS3にQEMU仮想マシンとして登録する

本セクションでは、準備した仮想ディスクファイルをGNS3に登録します。

まずはGNS3を起動し、Edit > Preferences (Ctrl+Shift+P) から設定画面を開きます。

左のメニューからQEMU VMsを選択し、NewボタンからQEMUで再生する仮想マシンを新規登録します。

create_qemu_vm1

仮想マシン名を入力します。
今回はCentOS Stream 8とします。

create_qemu_vm2

QEMU Binaryとメモリ容量を設定します。

QEMU Binaryは、/usr/bin/qemu-kvmを選択します。
ただ、ほとんどの方はデフォルトのまま/bin/qemu-system-x86_64を選んでも同じ意味になります (※)
RAMにはLinux VMに割り当てたいメモリ容量を指定します。
(※) Fedoraの環境では/bin/usr/bin/へのシンボリックリンクです。/usr/bin/qemu-kvmは、KVMに対応したCPUアーキテクチャのバイナリに対するシンボリックリンクとなっており、x86_64アーキテクチャのCPUを使っているなら/usr/bin/qemu-system-x86_64と同じ意味になります。ここで大事なのは、ホストマシンのCPUアーキテクチャに対応したQEMUバイナリを選択することです。CPUアーキテクチャuname -mコマンドなどで確認できます。ARMなど他アーキテクチャのCPUを使っている方は選択肢が変わることもあります。わからない方は/usr/bin/qemu-kvmを選んでおけばほぼ間違いないと思います

create_qemu_vm3

最後に、GNS3からコンソール接続するときの方式を選択します。

シリアルコンソールを使いたい場合は、telnetを選択してください。
グラフィカルコンソールを使いたい場合は、vncspiceを選択してください。
今回、私はtelnetを指定しました。

create_qemu_vm4

最後に、QEMUにセットする仮想ディスクファイルを決定します。
今回は予め用意しておいたcentos_stream8.qcow2を指定します。

create_qemu_vm5

QEMU仮想マシンをカスタマイズする

前のセクションの手順により、GNS3上にQEMU仮想マシンが登録されました。
作成した仮想マシンを選択し、Editから更に設定変更します。

edit_qemu_vm1

General settings

まずはGeneral settingsタブです。
変更した箇所をピンクの枠で囲いました。
vCPUs以外はほぼ見た目にしか影響のない変更です。
お好みに合わせてカスタマイズしてください。

edit_qemu_vm2

各設定の意味を下表にまとめました。

設定項目、デフォルト値、意味 今回の設定値
Template name
デフォルト: なし

  • VMテンプレート名
  • わかりやすい名前をつける
CentOS Stream 8
(※) デフォルトと同じ
Default name format
デフォルト: {name}-{0}

  • GNS3トポロジに追加後のノード名
  • 短い方が扱いやすい
  • {}で変数が使える
    • {name}: Template nameの値
    • {0}: 0から始まる連番
cs8-{0}
Symbol
デフォルト: :/symbols/qemu_guest.svg

  • アイコン
  • お好みで選択する
:/symbols/affinity/circle/blue/server.svg
Category
デフォルト: End devices

  • VMのカテゴリを選択
  • 見た目にのみ影響する
  • わかりやすいものを選択する
End devices
(※) デフォルトと同じ
RAM
デフォルト: なし

  • VMのメモリ容量
2048 MB
(※) デフォルトと同じ
vCPUs
デフォルト: 1

  • VMのCPUコア数
4
Qemu binary
デフォルト: 環境依存

  • VM起動用のQEMUコマンドを指定する
/usr/bin/qemu-kvm
(※) デフォルトと同じ
Boot priority
デフォルト: HDD

HDD
(※) デフォルトと同じ
On close
デフォルト: Power off the VM

  • GNS3上でVMを "Stop" したときの動作
  • Power offが最も確実で早い
  • shutdownは、OSハング時は使えない
Power off the VM
(※) デフォルトと同じ
Console type
デフォルト: なし

  • VMへのコンソールアクセス方法
  • telnet: シリアルコンソール
  • vnc: グラフィカルコンソール
  • spice: グラフィカルコンソール
  • spice+agent: グラフィカルコンソール
  • none: 表の下に記載 (※1)
telnet
Auto start console
デフォルト: OFF

  • ON: VM起動時にコンソールを開く
  • OFF: コンソールを自動起動しない
OFF
(※) デフォルトと同じ

(※1) Console typeでnoneを指定すると、QEMUコマンドラインオプションに-serial, -vnc, -spiceなどのオプションを指定しない。Auto start consoleの設定に関わらず、VM起動と同時にQEMUの内蔵コンソールが起動する。内蔵コンソールは、グラフィカルコンソールとシリアルコンソールを切り替える機能を持つ。ウィンドウを閉じるとVMを停止する

HDD

HDDタブでは、HDA (Primary Master)のDisk interfaceをvirtioに変更します。

デフォルトのnoneが選択されている場合、VM起動時に自動的にideに変更されます。
このハードウェアの値がideでもvirtioでもVMは問題なく起動しますが、virtioの方が性能が出やすいようなのでここで変更しています4

edit_qemu_vm3

CD/DVD

特に何も変更せず、空欄のままです。

今回は既にLinuxをインストール済みのため、CD/DVD (ISOファイル) をセットする必要はありません。

edit_qemu_vm4

Network

Networkタブは下図のように設定しました。
変更した箇所を枠線で強調してあります。

edit_qemu_vm5

設定値を下表にまとめます。

設定項目、デフォルト値、意味 今回の設定値
Adapters
デフォルト: 1

  • NIC
  • 後から変更できるのでお好みで
3
First port name
デフォルト: なし

なし
(※) デフォルトと同じ
Name format
デフォルト: Ethernet{0}

  • NIC番号の命名を変更する
  • First port nameが未設定の場合、
    1番目以降のNIC番号を設定する
  • First port nameが設定済の場合、
    2番目以降のNIC番号を設定する
  • {}で囲うことで変数を使える
  • {port0}: 0から始まる連番
  • {port3}: 3から始まる連番
  • Eth{segment0}/{port0}: (※2)
  • 参考: GNS3 - Port name formatting
ens{port3}
(※3)
Segment size
デフォルト: 0

  • Name formatに影響するパラメータ (※2)
  • 0は、1と同じ意味になる
0
(※) デフォルトと同じ
Base MAC
デフォルト: __:__:__:__:__:__

  • 1つ目のNICMACアドレスを指定する
  • 2つ目以降は、Base MACの値に1を足して生成
  • __:__:__:__:__:__: Base MACを自動生成する
  • 11:11:11:11:11:11: 左記のBase MACを利用
__:__:__:__:__:__
(※) デフォルトと同じ
Type
デフォルト: Intel Gigabit Ethernet (e1000)

Paravirtualized
Network I/O
(virtio-net-pci)
Custom adapters
デフォルト: 設定なし

  • NICに対して番号とドライバを個別指定する
設定なし
(※) デフォルトと同じ
Replicate network connection states in Qemu
デフォルト: ON

  • 正確な意味は不明だが、検証により以下を観測した
  • ON: GNS3の配線によって実機上でlink up/downする
  • OFF: 実機上で常にlink upする
ON
(※) デフォルトと同じ
Use the legacy networking mode
デフォルト: OFF

  • QEMU 2.9.0未満でのみ使用可能なモード
  • 現在のQEMUは6.1.0以上
  • このオプションを使うことはない
OFF
(※) デフォルトと同じ

(※1) ネットワーク機器の仮想アプライアンスの場合、1番目のNICがしばしば管理インターフェースとして扱われる。そして2番目のNICからサービスポートとなる。その場合、First port nameをmgmt0、Name formatをEth1/{port1}と設定すると、先頭ポートから順にmgmt0, Eth1/1, Eth1/2, ...という番号付けができる。このようにポート番号付けの規則をチューニングすることで、GNS3上の表示と実機のshow interface出力の間で整合性を取ることができる

(※2) {segment0}は、Segment sizeと共に使う。Segment sizeが3だった場合、Eth{segment0}/{port0}Eth0/0, Eth0/1, Eth0/2, Eth1/0, Eth1/2, ...のように3ポート周期でセグメント番号が変わる。{segment1}と指定することで、1から始まる連番を指定することも可能。ネットワーク機器の仮想アプライアンスに対して有効

(※3) GNS3上でLinux VMQEMUで動作させた場合、Linux実機上でポート番号がens3, ens4, ...アサインされた。したがって、Name formatens{port3}に設定した

Advanced

Advancedタブについては、よく使うオプションにのみ言及しています。

特にCentOS Stream 9を使う場合は、Aditional settings > Optionsに追加設定が必要であるため、忘れないようにしてください。

Use as a linked base VMオプションについても念のため補足します。
このオプションが有効の場合、GNS3のトポロジにVMを追加する前に内部的にVMクローンするようになります。
つまり、このオプションが有効である限りはテンプレートVMを書き換える心配がありません。
テンプレートVMを書き換えたい場合には一時的にOFFにします。

edit_qemu_vm6

設定項目、デフォルト値、意味 今回の設定値

Aditional settings > Options
デフォルト: なし
  • 原則、なし
  • CentOS Stream 9のみ
    -cpu host (※1)

Aditional settings > Use as a linked base VM
デフォルト: ON
  • ON: 仮想ディスクをコピーしてVM起動する
  • OFF: オリジナルのディスクでVM起動する
ON
(※) デフォルトと同じ

(※1) CentOS Stream 9をQEMUで起動する時、-cpu hostオプションを指定しないとKernel Panicになるという事象が報告されています5。私の環境においても2022/3/28リリース版のCentOS Stream 9のISOファイルにて再現しました。virt-installやCockpitなど、libvirtを介する環境で作成したVMはオプションが正しく設定されているためか再現しませんでした。GNS3はlibvirtを介さずQEMUコマンドを直接実行してVMを起動するため、CentOS Stream 9 VMを起動する場合は-cpu hostを指定するワークアラウンドが必要です。-cpu host自体はQEMUの推奨オプションであり、CentOS Stream 9以外のホストに対して同様に指定しても特に悪影響はありません

Usage

Usageタブにはコメントを自由に書けます。
お好みで、VMの説明を簡単にメモすると便利です。

空欄のままでも問題ありません。

edit_qemu_vm7

共通設定

Generalセクションで特定のVMに閉じない一般的な設定ができます。
今回作成したLinux VMに関連する設定もあるので、ここで触れておきます。

Console applications

#General settingsConsole typetelnetに設定している場合、電源起動済みのVMをダブルクリックすることでシリアルコンソール接続できます。
以下の画面で、シリアルコンソール接続に使用するアプリケーションを指定します。

console_applications1

console_applications2

デフォルトはXtermになっていますが、環境によってはXtermが入っていないこともあると思います。
Xtermから変更する場合、お使いのターミナルソフトウェアに合わせてGnome TerminalKonsoleなど選択してください。

シリアルコンソール起動時のコマンドは自分自身で指定することも可能です。
私はTilixを使っているため、以下のように設定しました。

tilix -t "%d" -a session-add-down --focus-window -e "telnet %h %p"

%dはコンソール画面のタイトル、%hはコンソール接続先のIPアドレス%pはコンソール接続先のポート番号です (※)
組み込み変数の意味について、詳細は上記スクリーンショットを参照してください。
(※) GNS3のシリアルコンソール接続は、内部的にtelnet通信を使用します

VNC

#General settingsConsole typeVNCに設定している場合、VNCプロトコルによるコンソール接続になります。
以下の画面で、VNCコンソール接続に使用するアプリケーションを指定します。

vnc1

デフォルトはTightVNC (vncviewer) が選択されています。
私の環境ではRemote Viewer (remote-viewer)がインストール済みなので、それを選択しました。
Remote Viewerは、sudo dnf install remote-viewerでインストールできます。

Spice

#General settingsConsole typeSpiceに設定している場合、Spiceプロトコルによるコンソール接続になります。
以下の画面で、Spiceコンソール接続に使用するアプリケーションを指定します。

spice1

デフォルトはRemote Viewer (remote-viewer) が選択されています。
私の環境としてはこのままで問題ないので、特に変更しませんでした。

Linuxの起動

いよいよ、GNS3上でLinuxを起動します。

まず、作成したCentOS Stream 8をGNS3上に追加します。

add_vm

GNS3トポロジ上のVMを右クリックし、Startを選択することでVMを起動します。

start_vm

VMをダブルクリックするか、右クリックしてConsoleを選択することでコンソールを起動します。
ログインプロンプトが確認できれば、無事成功です。

connect_to_console

後はケーブル配線して好きなトポロジを組んでみましょう。
作成したVMSSHログインする方法は別の記事で紹介します。

(参考) GNS3で起動したVMKVMを使っているか?

GNS3で起動したVMは、KVMを使うようになっています。

GNS3からQEMUVMを起動した後にps -ef | grep qemuコマンドを実行すると、-enable-kvmを指定していることがわかります。

また、VM起動前後でlsmod | grep kvmを実行して値を比較することでもKVMの利用を確認できます。
VM起動後は、intel_kvm行、またはkvm_amd行の右端にあるカウントが増加しています。
これは、VMKVMカーネルモジュールを利用していることを表しています。
以下のコマンドでは、VM起動前では0だったものが、VM起動後では6に増加しています。
参考: KVMの初期設定、及びvirsh, virt-installによるVM作成 - #KVMの動作確認 (2/2)

################
# VM起動前
################
lsmod | grep kvm
# kvm_intel             360448  0
# kvm                  1028096  1 kvm_intel
# irqbypass              16384  1 kvm


################
# VM起動後
################
lsmod | grep kvm
# kvm_intel             360448  6
# kvm                  1028096  1 kvm_intel
# irqbypass              16384  5 kvm

まとめ

GNS3にLinux VMを追加し、コンソール接続する手順を紹介しました。

手順に書き起こすと長いですが、要点にまとめると3ステップなシンプルな手順です。

  1. Linux VMをインストール済みのqcow2ファイルを用意する
  2. qcow2ファイルをGNS3に登録する
  3. GNS3上で起動する

一度登録すれば、Use as a linked base VM機能によって同じVMを何台でも作り放題になります。
GNS3によるネットワーク検証に役に立ちますので、ぜひお試しください。

FedoraへのGNS3インストール

gns3_topology

前の記事

お伝えしたいこと

FedoraにGNS3クライアントとGNS3サーバをインストールする手順をお伝えします。
ここでご紹介する手順は、以下サイトの内容を元にしています。

Computing for Geeks - How To Install GNS3 on Fedora 35/34/33/32/31

ただし、本ブログの手順は一部アレンジを加えています。
具体的には、以下の通りです。

  • VPCSの最新版をインストールする手順に変更
  • 最小限のパッケージのみをインストールする手順に変更

本ブログでご紹介した手順は、Fedora35、GNS3 2.2.29にて動作確認済みです。

GNS3のインストール

GNS3サーバとGNS3クライアントは導入必須です。
以下のコマンドでインストールします。

sudo dnf install gns3-gui gns3-server

RPMパッケージ版はGNS3公式サイトで直接配布されているものよりも多少バージョンは古いですが、全く問題なく動作します。

外部ツールのインストール

GNS3のインストールに必要なのは、GNS3本体のみです。

しかし、GNS3本体は各種機能を提供するために、様々な外部ツールと連携します。
それらの外部ツールを使う場合には、追加のインストールが必要になります。

全てのツールを一旦入れるか、必要なツールに絞って入れるかはユーザーの好み次第です。
今回、私はWireshark、VPCS、Dynamipsのみ導入することにしました。
仮想マシンを動作させるため、KVMも別途インストールしました。

IOU、Dockerについては、今回はインストールしませんでした。
これらのツールについては、ツールの概要とインストールしなかった理由を中心に紹介します。

Wireshark

(参考) Wiresharkとは

Wiresharkとは、パケットキャプチャの実施と、結果のGUI表示機能を持つアプリケーションです。
GNS3においては、ケーブルを右クリックして該当箇所のパケットキャプチャを取得/確認するためにWiresharkを使います。

一般に、物理的なネットワーク環境では以下の手順でパケットキャプチャを行います。

GNS3においてはそのような面倒な操作は一切不要です。
ケーブルを右クリックしてキャプチャを開始するのみです。

WiresharkとGNS3の組み合わせは非常に便利です。
Wiresharkはぜひインストールしましょう。

Wiresharkのインストール

以下のコマンドでインストールします。

sudo dnf install wireshark

VPCS

(参考) VPCSとは

VPCS (Virtual PC Simulator) は、仮想パソコンのことです。

ネットワークの検証をする際、ネットワーク機器に端末を接続してpingなどの疎通確認を行いたい場面はあると思います。
そんなときに、Linuxの代わりに使えるのがVPCSです。

VPCSは以下の特徴を持ちます。

WEB通信を試したい場合、サーバー役はLinuxを用意しても良いと思いますが、クライアント役をVPCSに任せることでメモリ容量を節約できます。
起動/停止も高速で、あると何かと便利です。
VPCSは、ぜひインストールしましょう。

VPCSは独特のCLIを持ちますが、ネットワーク機器のように?でヘルプを確認しながら使っていればすぐに使い方を理解できるでしょう。

VPCS依存パッケージのインストール

VPCSをインストールするために、gccとmakeをインストールしておきます。

sudo dnf install gcc make

VPCSのインストール

VPCSの公式版はSource Forgeにて配布されていますが、現在はメンテナンスされていないようです。
GNS3 ProjectがVPCSの開発を引き継いでメンテナンスしたものがGitHub上に存在するので、そちらをダウンロードします。
GitHub - GNS3/vpcs - Releases

2022年3月時点の最新版は0.8.2であるため、そちらをダウンロードします。
ブラウザ上でダウンロードリンクのURLを右クリック・コピーし、curlコマンドでtar.gzファイルをダウンロードします。
(※) git clone https://github.com/GNS3/vpcsでダウンロードしても良いですが、厳密にはmasterブランチとv0.8.2タグを持つリリース版には差がある可能性があるのでご注意ください

curl -LO https://github.com/GNS3/vpcs/archive/refs/tags/v0.8.2.tar.gz

tar.gzファイルを展開し、シェルスクリプトを実行することでC言語ソースコードをビルドします。
ビルドの結果、vpcsの実行ファイルが生成します。
このシェルスクリプトが行うのは、基本的にmakegccによるビルドのみです。
カレントディレクトリに*.oファイルとvpcsファイルを生成しますが、他には何もしません。

tar xzf v0.8.2.tar.gz
cd vpcs-0.8.2/src
./mk.sh

生成したvpcs実行ファイルを適切なパスに格納します。
今回は/usr/local/binに格納します(※)
(※) RPMインストールされたときの実行ファイルは、/usr/bin/配下に格納されます。make installpip installなど、他の手段でインストールされた場合は私の知る限り/usr/local/binに格納されます

また、vpcsのmanファイルも用意されているのでこちらも適切なパスに格納します。

sudo cp -i vpcs /usr/local/bin
sudo cp -i ../man/vpcs.1 /usr/local/share/man/man1/

動作確認します。

vpcs -v
# バージョンが表示されること

man vpcs
# manが表示されること

インストールが完了した後は、不要なファイルは削除して問題ありません。

cd ../..
rm -rf vpcs-0.8.2/ v0.8.2.tar.gz

(参考) VPCSのアンインストール

VPCSのインストール時に行った変更は、実行ファイルとmanファイルの配置のみです。
これらのファイルを削除すれば、VPCSをアンインストールしたことになります。

sudo rm /usr/local/share/man/man1/vpcs.1 /usr/local/bin/vpcs

Dynamips

(参考) Dynamipsとは

Dynamipsは、GNS3においては以下の機能を持ちます。

  • Cisco IOSエミュレーター
    • Cisco IOSイメージファイルを持っていれば、仮想Ciscoルータを再現できる
    • イメージファイルの入手が一番のハードル
  • ソフトウェアベースのハブ、L2スイッチが使える

今回は、後者の機能を目的としてDynamipsを導入します。

DynamipsがサポートするL2スイッチはメモリ消費が少なく、気軽に追加できる点が一番の長所です。
また、VLANやDot1Q Trunkingにも対応します。

Dynamipsのインストール

基本的な流れはVPCSの時と同じです。
まず、依存パッケージをインストールします。

sudo dnf install make gcc
sudo dnf install cmake elfutils-libelf-devel libpcap-devel

続いて、以下のコマンドを実行してインストールします。
curlコマンドに指定しているURLは、GitHub上のGNS3/DynamipsのReleaseページ上の "Source code (tar.gz)" のリンクからコピーしたものです。

curl -LO https://github.com/GNS3/dynamips/archive/refs/tags/v0.2.21.tar.gz
tar xzf v0.2.21.tar.gz
cd dynamips-0.2.21/
mkdir build
cd build
cmake ..
sudo make install

任意ですが、ここでinstall_manifest.txtをどこかのディレクトリにバックアップしておきます。
このファイルはDynamipsをインストールした時に配置したファイルパスを記録したもので、Dynamipsをアンインストールする時に必要となります。

とはいえ、install_manifest.txtが手元にない場合ももう一度インストール手順を実行することで再び生成できます。
そのため、バックアップを取ることは必須ではありません。

install_manifest.txtの中身は以下のとおりです。

/usr/local/share/doc/dynamips/ChangeLog
/usr/local/share/doc/dynamips/COPYING
/usr/local/share/doc/dynamips/MAINTAINERS
/usr/local/share/doc/dynamips/README.md
/usr/local/share/doc/dynamips/README.hypervisor
/usr/local/share/doc/dynamips/RELEASE-NOTES
/usr/local/share/doc/dynamips/TODO
/usr/local/share/man/man1/dynamips.1
/usr/local/share/man/man1/nvram_export.1
/usr/local/share/man/man7/hypervisor_mode.7
/usr/local/bin/nvram_export
/usr/local/bin/dynamips

作業用のファイルやディレクトリを削除します。

cd ../..
rm -rf v0.2.21.tar.gz dynamips-0.2.21/

(参考) Dynamipsのアンインストール

Dynamipsのアンインストール手順は、途中まではインストール手順と同じです。

curl -LO https://github.com/GNS3/dynamips/archive/refs/tags/v0.2.21.tar.gz
tar xzf v0.2.21.tar.gz
cd dynamips-0.2.21/
mkdir build
cd build
cmake ..

このタイミングで、今いるbuild/ディレクトリにバックアップ済みのinstall_manifest.txtを配置しておきます。
このファイルがない場合、一旦sudo make installを実行し、install_manifest.txtを生成しましょう。

そして、以下のコマンドを実行することでアンインストールできます。

sudo make uninstall

アンインストール完了後、作業用のファイルやディレクトリを削除します。

cd ../..
rm -rf v0.2.21.tar.gz dynamips-0.2.21/

(参考) KVMのインストール

Linux仮想マシンを動かすために、QEMU/KVMVirtualBoxなどの仮想化エンジンを別途インストールする必要があります。

Linuxの場合は、オープンソースかつ軽快に動作するQEMU/KVMが良いのではないかと思います。
KVMは商用サービスにも利用されることがあり、品質の高さが伺えます。
また、CPUの仮想化支援機能や準仮想化ドライバなどを効率的に利用することから、VMが高速に動作します。

各種CLI/GUIツールも充実していて、操作性も良いです。

KVMのセットアップ手順は過去の記事で紹介していますので、よろしければ参考にしてください。

KVMの初期設定、及びvirsh, virt-installによるVM作成

快適なGUI操作を望む場合は、Cockpitをお試しください。
CockpitはRed Hat社が開発を支援しているオープンソースソフトウェアです。
Cockpit GUI によるKVM操作

一通りセットアップが終わったら、KVM仮想マシンを建ててみましょう。
基本操作の説明は以下の記事にまとまっています。
KVMの基本操作集

GNS3とKVMの連携方法については、別の記事にて紹介します。

(参考) その他のツール

本セクションで紹介するツールについては、今回はインストールを見送りました。
以下のセクションにて、各ツールをインストールしなかった理由について補足します。

これらのツールをインストールしたい場合は、以下の記事を参考にしてください。
Computing for Geeks - How To Install GNS3 on Fedora 35/34/33/32/31

Step 1にて依存パッケージをインストールの上、後は各ツールごとのインストール手順にしたがってご対応ください。

IOU

IOU (IOS on Unix) は、IOSv (Cisco IOSの仮想アプライアンス) とほぼ同等の機能性を持ちます。
IOL (IOS on Linux) とも呼ばれます。
噂によれば、Cisco IOSvよりもバグが少なく、パフォーマンスも良いと聞いたことがあります。

しかし、IOUはCisco社員、またはCisco社パートナーしか入手できないと言われています。
私達が手に入れることはかないませんので、IOUの動作環境を持っていても仕方ありません。

したがって、今回はIOU周りのセットアップも見送りました。

Docker

DockerのRPMパッケージ自体は、gns3-server RPMパッケージの依存関係として自動的にインストールされました。
しかし、私が現状VMしか使わず、コンテナを使っていないのでDockerのセットアップを見送りました。
ネットワーク検証を行うためには、Linuxやネットワーク仮想アプライアンスVMを建てられれば十分であるためです。

今後コンテナの軽量さを活かして何かする機会があれば、Dockerを使い始めることがあるかもしれません。

(参考) 他のOSへのGNS3インストール手順

GNS3が公式でインストールマニュアルを提供しているのは、WindowsMacUbuntuの3種です。
他にもArch LinuxやManjaroでもGNS3をインストールした実績があるそうです。

Fedora以外のOSに対するGNS3のインストール手順については、GNS3の概要 - GNS3のインストール方法も参考にしてください。

まとめ

FedoraにGNS3をインストールする手順を紹介しました。

GNS3本体はRPMパッケージで簡単にインストールできます。
GNS3と連携している外部ツールについては、個別にインストールする必要があります。

少々面倒かもしれませんが、手順さえわかってしまえば簡単です。
元の記事で情報提供してくださったJosphat Mutaiさんに感謝します。

GNS3の概要

gns3_topology

お伝えしたいこと

GNS3とはどんなソフトかを簡単にご紹介します。
また、GNS3のインストール手順についても軽く触れます。

GNS3の具体的な操作方法については、本記事では紹介しません。

GNS3とは

GNS3を略さず言うと、Graphical Network Simulator 3です。
その名の通り、GUIでネットワークをシミュレーションできるソフトウェアです。
https://www.gns3.com/

ネットワーク機器やLinux/Windowsなどの仮想版を起動し、GUI上で配線して通信させることができます。
内部的にはKVMVirtualBoxVMware Workstation PlayerやDockerと連携することで、仮想マシンやコンテナ版のネットワーク機器を再生する仕組みになっています。

GNS3の画面イメージは以下のとおりです。

gns3_ui

GNS3は、商用インフラにおけるネットワークサービス提供を想定したツールではありません。
ハンズオンを通してネットワーク機器のコマンドを試したり、プロトコルの動作を理解するための学習ツールです。

GNS3のユースケース

GNS3は、以下のような場面で役に立ちます。

  • 手を動かしながらネットワーク技術を学習する
  • お試しで構成を組んでみて、実際に動くか確認する
  • プロトコル、コマンド、API、自動化の動作を確認する

GNS3の良いところ

仮想マシンを起動するだけであれば、VirtualBoxKVMなどで十分です。
ではなぜGNS3を使うのが良いかと言うと、理由は以下が挙げられると思います。

複雑な物理構成を再現できる

GNS3は1:1のケーブル結線を容易に再現できます。
またGUIが物理構成図の役割を果たしており、ネットワークの全体像を俯瞰しながら操作できるので快適です。

これらの特徴により、GNS3であれば複雑な物理構成も容易に再現できます。

VirtualBoxを直接操作して、UDP Tunnel機能で複雑な構成を組むのはとても大変です。

安定した動作

GNS3が初めてリリースされてから10年以上経っています。
製品不具合や動作の重さなどは初期のバージョンから改善されており、GNS3そのものは安定して動作します。

もちろん注意すべき点はいくつかあります。

  • GNS3 GUI上の設定変更やケーブル結線は、必ず両側の電源をOFFにしてから行う
    • この手のトラブルは、大抵VM再起動、GNS3再起動、ホストマシン再起動のいずれかで直る
  • 文字化けの原因になるので、VM名やディレクトリパスの日本語表記は極力避ける
  • Windowsファイアウォールに必要な通信が拒否された場合は、許可ルールの追加が必要

数々の便利機能との連携

以下の機能は仮想アプライアンスを建てずに利用可能です。
主役がルータやファイアウォールロードバランサーの場合、L2スイッチや疎通確認用端末にあまりメモリリソースを割けない場合もあります。
そんなとき、以下のL2スイッチや仮想パソコン機能が役に立ちます。

  • 組み込みL2スイッチ
    • Dynamipsの機能
    • VLAN設定可能なソフトウェアベースのL2スイッチ
    • メモリ消費が少ない
  • VPCS (Virtual PC Simulator) との連携

Wiresharkとの連携

GNS3上でケーブルを右クリックして、該当箇所のパケットキャプチャを取得することができます。
これにより、プロトコルの詳細な動作の確認や、トラブルの切り分け調査を手軽に行うことができます。

物理ネットワークではネットワーク機器にトラフィックミラーリングのための設定を入れ、パケットキャプチャ用の端末を接続したりします。
GNS3では、そのような煩わしい操作は一切不要です。

マルチベンダー

GNS3は、仮想マシンやコンテナであれば何でも追加可能です。
GNS3は特定のネットワーク機器OSに縛られません。
それどころか、LinuxWindowsサーバなども追加可能です。

GNS3は、ブリッジ接続にも対応します。
すなわち、GNS3内部で動作している仮想アプライアンスを、ホストPCとケーブル結線された物理ネットワークと通信させることも可能です。
物理ネットワーク機器が検証の主役である場合にも、仮想アプライアンスとルーティングプロトコルなどをやり取りさせるような検証でGNS3を役立てることができます。

Linked base VM

GNS3上にArista vEOSを3台追加する場合、事前にVMを3台構築しておく必要はありません。
linked base VM機能を有効化すれば、GNS3トポロジ上にVMを追加するたびに、テンプレートとして事前登録したVMが自動的にクローンされます。

ユーザーは、同じVMを何台もGNS3トポロジに追加することができます。
その際、クローン操作を意識する必要はありません。

GNS3と似たソフトウェア

GNS3と似たような機能を持つソフトウェアとしては、Cisco Packet TracerやCML (Cisco Modeling Lab)などが挙げられます。
これらの製品と比較したGNS3の強みは、無料かつマルチベンダーであることだと思います。
詳細はGNS3の公式ドキュメントにも説明があります。

GNS3 Documentation - What is GNS3? - #GNS3 Comparisons

GNS3のアーキテクチャ

GNS3は、内部的にはクライアントとサーバーに分かれます。
GNS3クライアントがGUI画面を、GNS3サーバーが内部処理を担当します。

名称 役割
GNS3クライアント
(gns3-gui)
  • GUI画面を提供する
  • ユーザーの操作をGNS3サーバに伝える
  • GNS3サーバの処理結果をGUI画面に反映する
GNS3サーバ
(gns3-server)
  • デフォルトではTCP3080をリッスンする
  • GNS3の内部処理全般を担当する
  • 各種外部ツールとの連携を担当する

gns3_summary

GNS3の構成パターン

基本的には、GNS3クライアントとGNS3サーバを同じマシンにインストールしてしまうのが最も簡単です。
WindowsMacにインストールすると、こちらの構成になります。
マニュアル通りに操作すれば、難なくインストールできる簡単さが特徴です。

別の使い方として、LinuxマシンにGNS3サーバと連携ソフト (KVMやVPCSなど) のみをインストールして、GNS3クライアント複数台からネットワーク越しにアクセスさせる構成も可能です。
この構成の組み方はマニュアルに全て書いてあるわけではないので、多少は手順の検討が必要になります。
この構成のメリットは、私の理解では2つあると思います。

  • GNS3クライアント側の要求スペックが低くなる
  • GNS3サーバに配置した仮想マシンのテンプレート、GNS3プロジェクト (≒GNS3上で作成したトポロジ)などを複数のユーザー間で共有できる

個人学習においてGNS3を使う場合は、基本的には前者の「GNS3クライアントとGNS3サーバを同じマシンに同居させる構成」のほうが快適だと思います。
パソコンのスペックが小さい場合には、別途共用の物理サーバにGNS3サーバをインストールする構成を取ることもあると思います。

GNS3の動作要件

GNS3の動作要件は、以下のURLに書いてあります。
https://www.gns3.com/software

OS

Windows, Mac, Linuxに対応しています。

動作要件という観点では、Linuxのどのディストリビューションも含まれます。
しかしGNS3公式でパッケージリポジトリを管理し、インストール方法も公式ドキュメントで案内されているのはUbuntuDebian系のディストリビューションのみです。

Fedoraの場合、Fedora公式のリポジトリからdnfでインストール可能です。
Arch系の場合はAUR (Arch User Repository) 経由でインストール可能です。

しかしいずれの場合も、一部ソースコードビルドによるインストールも伴います。
Fedoraについては、次の記事で詳細な手順を示します。

その他ハードウェアスペック

CPUの仮想化支援機能が有効化されていることというのが重要です。
具体的には、AMD AMD-V/RVI, またはIntel VT-X/EPIのことです。
今どきのAMD、またはIntel製のCPUであれば問題ないと思います。
BIOS/UEFIの設定で仮想化支援機能が無効化されていないかをご確認ください。

他にもRAMサイズやディスク空き容量などに言及がありますが、基本的には大きければ大きいほど良いです。
仮想マシンを動かしますので、RAMサイズは8GiB以上ないと結構厳しいのではないかと思います。

GNS3のインストール方法

以下にOSごとのGNS3のインストール方法の概略を示します。
どのOSでも共通で、VirtualBoxやDockerなどの仮想化ソフトは別途インストールする必要があります。

Windows

以下公式サイトからAll-in-oneインストーラをダウンロードして実行します。
GNS3 - Download GNS3

Solar PuttyやSolarwindsのツールセットもおすすめされますが、これらのツールを導入する必要はありません。

Solar PuttyTeratermなどで置き換え可能です。
Teratermを使う場合の手順は、以下のサイトが参考になります。

なおWindowsでGNS3を動かす場合、WindowsファイアウォールによってGNS3の機能がブロックされないようご注意ください。
Windowsファイアウォールの規則にない通信が発生した場合、デフォルトではポップアップが表示されるはずです。
そのポップアップにおいて、GNS3やDynamipsなどのプログラムの通信が出たときは許可すれば、問題を回避できると思います。

ポップアップの画面で通信を拒否してしまった場合はファイアウォールにdenyルールが追加されてしまいます。
その場合は、手動でそのdenyルールを削除する必要があります。

公式のインストール手順はこちらです。
GNS3 Windows Install

Mac

以下公式サイトからGNS3のインストーラをダウンロードします。
GNS3 - Download GNS3

インストーラをダブルクリックで起動し、GNS3のアイコンをApplicationsフォルダにドラッグします。
Macのお作法として、初回起動時はApplicationsフォルダ内のGNS3アイコンをダブルクリックして起動する必要があります。

GNS3の初回起動時、uBridgeのアクセス権限を付与する旨のポップアップが出るので、許可するようにしてください。

Macのバージョンによっては、OSのセキュリティ機能によって追加の操作が必要になる場合があります。
何かつまづいた場合は、以下の公式手順をご確認ください。
GNS3 Mac Install

Linux

Ubuntu/Debianについては公式サイトにインストール方法があります。
Ubuntuの場合は、PPAを追加してapt installする手順になっています。
GNS3 Linux Install

他のディストリビューションについては、公式の説明はありません。
しかし、以下の記事を参考にすればインストールできると思います。

Fedora35については私も動作確認しました。
Fedoraに対するGNS3のインストール手順については、FedoraへのGNS3インストール手順でも詳しく説明します。

(参考) GNS3 VM

GNS3 VMは、GNS3公式で配布されているUbuntuのイメージです。
このUbuntuにはGNS3サーバが入っています。

GNS3 VMVMware Workstation PlayerやVirtualBoxなどにインポートし、GNS3クライアントの設定でGNS3 VMを有効化することで使えるようになります。

WindowsMacなどの非LinuxマシンでQEMUを使いたい場合には使うかもしれません。
ただ、多くの場合GNS3 VMは使わなくて良いのでは...と思います。
QEMUを使わなくても、VirtualBoxで事足りるためです。

むしろ、GNS3クライアント起動のたびに毎回GNS3 VMが自動で立ち上がり、GNS3 VMの起動が完了するまで待たされるようになります。

GNS3 VM上で仮想マシンを動かすために、GNS3 VMにCPU/RAM/ディスク等のリソースを割り当てる必要があります。
非力なマシンでは、このリソース消費が結構大きいです。

したがって、私個人としてはGNS3 VMの利用をあまりおすすめはしません。
公式ではおすすめしていますが、これはGNS3 VMを利用者が使うことで環境差異をなくし、動作不備を防止するためだと理解しています。
GNS3をローカルでトラブルなく動かせている方に関しては、GNS3 VMはほぼ必要ありません。

まとめ

GNS3の概要を紹介しました。
GNS3のインストール方法や使い方については、GNS3タグの記事をご確認ください。

次の記事

Fedoraに対するGNS3のインストール手順を紹介します。

virt-builderによるLinuxインストールの「省略」

virt-builder-image
The cloud icon is created by Freepik - flaticon.com

お伝えしたいこと

今回はvirt-builderというLinuxコマンドの紹介です。
LinuxをMinimal構成でインストール済みのディスクファイルを簡単に生成するコマンドです。

Linuxインストールを自動化するのではなく、Linuxインストール済みのテンプレートから仮想ディスクを作成します。

KVM仮想マシンを構成している場合に相性が良いです。
コマンド1行で、なおかつ短時間でLinuxマシンが手に入ります。

前回お伝えしたKickstartファイルと比較すると、得意/不得意があります。
詳細は次のセクションで紹介します。

virt-builderとは

virt-builderとは、libguestfsというツール群に含まれるコマンドの1つです。
Linux環境であれば、OS標準のパッケージマネージャで手軽にインストールして使い始めることができます。

このコマンドによって、LinuxをMinimal構成でインストールしたデータを格納した仮想ディスクファイル (raw, またはqcow2形式) を手軽に生成できます。
具体的な動作は、下図のとおりです。

virt-builder

virt-builderコマンドを実行したときの動作は2工程です。

  1. オンラインリポジトリからxz圧縮されたテンプレートを~/.cache/virt-builder/配下にダウンロードする
  2. テンプレートを加工し、Linuxインストール済みのディスクファイルを生成する

virt-builder実行時のコマンドラインオプションによって、2の工程における加工の内容を制御できます。
具体的にはディスクサイズや、ログインパスワードの変更などが挙げられます。

virt-builderコマンドは、Linuxのインストール処理を行いません。
そのため、テンプレートをダウンロード済みであれば高速に動作します。

一方で、Linuxを手動/自動インストールする場合と比較して細かなカスタマイズは効きません。
virt-builderはMinimal構成の検証用VMを手軽に作成する方法と割り切り、より細かな制御が必要な場合はKickstartファイルによる自動インストールなど自力でインストールすることをおすすめします。

virt-builderの使い方

インストール

virt-builderは、guestfs-tools RPMパッケージに含まれます。

RHEL系のディストリビューションであれば、以下のコマンドでインストールできます。

sudo dnf install guestfs-tools

virt-builderの実行

virt-builderのSyntaxは非常にシンプルです。

virt-builder os-version [options...]

最小限のコマンド例は、以下のとおりです。
以下のコマンドにより、6 GiBのディスク容量を持つCentOS Stream9をインストール済みの仮想ディスクファイルが生成します。
rootのパスワードはランダム文字列が生成され、標準出力に表示されます。
今回はrFdQIE0WFI8AHTRyでした。

virt-builder centosstream-9

# (一部抜粋)
#   Output file: centosstream-9.img
#   Output size: 6.0G
# Output format: raw

今回の例では、os-versioncentosstream-9を指定しました。
指定可能なOSバージョンの一覧は、virt-builder -lで確認できます。

virt-builder -l

# (一部のみ抜粋)
# centosstream-9  x86_64  CentOS Stream 9

実際に使う際は、以下のように複数のオプションを指定するのが一般的です。

virt-builder centosstream-9 \
-o /home/shared/libvirt/images/test.qcow2 \
--size 10G \
--format qcow2 \
--hostname test \
--root-password 'password:mypassword' \
--ssh-inject root \
--selinux-relabel

# (一部抜粋)
#   Output file: /home/shared/libvirt/images/test.qcow2
#   Output size: 10.0G
# Output format: qcow2

今回使用したコマンドラインオプションの意味は、下表のとおりです。
完全なリストはman virt-builderを参照してください。

--selinux-relabelSELinuxが有効なディストリビューションをビルドする場合のみ指定します (FedoraCentOS Streamなど)
他のオプションは、どのディストリビューションにおいても指定することをおすすめします。

オプション 意味
-o
--output
  • 出力する仮想ディスクファイルパスを指定
  • デフォルト:
    • raw形式の場合: OSイメージ名.img
    • qcow2形式の場合: OSイメージ名.qcow2
--size
  • 仮想ディスクのサイズを指定する
  • 単位のいずれかの指定が必須
    • b: Bytes
    • K: KiB
    • M: MiB
    • G: GiB
    • (※) Tという単位は認識されなかった
  • 最低でも6.0G以上を指定する必要がある
  • デフォルト: テンプレートのサイズを変更せず使う
    (※) デフォルト値は6.0Gのことが多い
--format
  • ディスクファイルのフォーマットを指定する
  • rawqcow2のいずれかを指定可能
  • (※) ディスク容量の効率が良いqcow2がおすすめ
  • デフォルト: raw
--hostname
  • ホスト名を指定する
  • デフォルト: テンプレートファイルの構成に従う
--root-password
  • rootユーザーのログインパスワードを指定する
  • password:PASSWORD: 指定した文字列を設定する
  • file:FILENAME: 指定したファイルの1行目の文字列を設定する
  • random: ランダム文字列を設定し、標準出力に表示する
  • disabled: パスワードを無効化する
  • locked: rootユーザーをロックする
  • 詳細はman virt-builderを参照
  • デフォルト: random
--ssh-inject (※1)
  • SSH公開鍵を指定したユーザーの~/.ssh/authorized_keysに登録する
  • ユーザー名のみ指定した場合、~/.ssh/から自動選択される
  • SELinuxが有効なVMをビルドする場合、--selinux-relabelも指定するべき (※2)
  • 詳細はman virt-builderを参照
--selinux-relabel
  • ビルドの最終工程でSELinuxのrelabelを行う
  • 以下の2つの条件を両方満たす場合は指定必須 (※3)
    • RHELCentOS StreamなどSELinuxが有効なOSをビルドするとき
    • virt-builderのオプションでファイル生成するとき

(※1) sshdはデフォルトでrootユーザーによるパスワード認証を拒否する設定になっているので、--ssh-injectによってSSH鍵をアップロードすることをおすすめします

(※2) --ssh-injectオプションによって、~/.ssh/authorized_keysファイルを生成します。このファイル生成はSELinuxが起動していない状態で行われるため、生成されるファイルはラベル無し (no label) になります

(※3) SELinuxが起動している時にファイルを生成すると、SELinuxは全てのファイルにラベル付けし、ファイルシステムメタデータとして記録します。その後、SELinuxはラベルに基づいてアクセス制御を行います。--ssh-injectオプションを利用すると、マシンが起動しておらずSELinuxも動作していないところに~/.ssh/authorized_keysを生成します。このとき当然ラベル付けされないので、そのままだとSELinuxの制御が正しく行われません。具体的にはsshdauthorized_keysを読み取れず、公開鍵認証に失敗します。この問題を回避するには、--selinux-relabelをセットで指定することで、SELinuxのラベル付けを行います。この対応はRHEL, CentOS, CentOS Stream, Fedoraなど、SELinuxが有効なディストリビューション全てに必要です。SELinuxについてもっと知りたい方は、Linuxプロセスアクセス制御の概要を始めとするSELinuxシリーズもぜひお読みください

(参考) 生成したディスクイメージファイルでVMを起動する

virt-builderで生成したディスクファイルをセットしてVMを起動すれば、インストール済みのLinuxを直ちに使うことができます。

例えば、KVM環境の場合は、以下のようなvirt-installコマンドでVMを作成・起動します。
今回はLinuxのインストールを行わないので--cdromのような起動順位を変更するオプションを指定せず、代わりに--importを指定します。

virt-install \
--name test \
--memory 1024 \
--vcpus 2 \
--os-variant centos-stream9 \
--disk path=/home/shared/libvirt/images/test.qcow2 \
--import
--noautoconsole

作成したVMを強制終了して削除するには、以下のコマンドを実行します。

virsh destroy test ; virsh undefine test --storage vda

詳細はKVMの基本操作集にあるVMの作成VMの削除を参考にしてください。

(参考) オンラインリポジトリのURL

virt-builderコマンドが参照するオンラインリポジトリのURLは、デフォルトで以下のとおりです。

  1. https://builder.libguestfs.org
  2. http://archive.libguestfs.org/builder
  3. https://download.opensuse.org/repositories/Virtualization:/virt-builder-images/images/

リポジトリのURLは、/etc/virt-builder/repos.d/*.confにて管理されています。

(参考) virt-builderに対応しているディストリビューション

2022/4現在で以下のとおりです。

virt-builderの引数に指定できるディストリビューション名は、virt-builder -lで確認できます。

virt-builder -l
# (一部のみ抜粋)

# opensuse-13.1        x86_64     openSUSE 13.1
# opensuse-42.1        x86_64     openSUSE Leap 42.1
# opensuse-tumbleweed  x86_64     openSUSE Tumbleweed
# alma-8.5             x86_64     AlmaLinux 8.5
# centos-6             x86_64     CentOS 6.6
# centos-7.0           x86_64     CentOS 7.0
# centos-8.2           x86_64     CentOS 8.2
# centosstream-8       x86_64     CentOS Stream 8
# centosstream-9       x86_64     CentOS Stream 9
# cirros-0.3.5         x86_64     CirrOS 0.3.5
# debian-6             x86_64     Debian 6 (Squeeze)
# debian-11            x86_64     Debian 11 (bullseye)
# fedora-33            x86_64     Fedora® 33 Server
# fedora-35            x86_64     Fedora® 35 Server
# fedora-35            aarch64    Fedora® 35 Server (aarch64)
# freebsd-11.1         x86_64     FreeBSD 11.1
# scientificlinux-6    x86_64     Scientific Linux 6.5
# ubuntu-10.04         x86_64     Ubuntu 10.04 (Lucid)
# ubuntu-20.04         x86_64     Ubuntu 20.04 (focal)

まとめ

Minimal構成でLinuxをインストール済みの仮想ディスクファイルをお手軽に入手する方法としてvirt-builderを紹介しました。
Kickstartよりも更に簡単に検証用マシンを作成することができます。

virt-builderで作成したLinuxは、構成がほぼ固定されます。
デフォルトの構成をカスタマイズしたい場合は、やはり自分でLinuxをインストールする必要があります。
Linuxインストールを自動化したいときは、Kickstartが便利です。

virt-builderVMクローン、Kickstart、またはその他の自動化をうまく使い分け、効率よくLinux検証環境を整備しましょう。

KickstartによるLinuxインストール自動化 (自動トリガー・PXEブート連携)

featured_image

Kickstartシリーズ

Kickstartとは、Linuxのインストールを自動化する機能です。
本シリーズではRHEL, Fedora, CentOS Streamをモデルに紹介します。

一連の記事でKickstartの構成を3パターン紹介します。
今回の記事では、3つ目の構成を紹介します。

  1. KickstartによるLinuxインストール自動化 (手動トリガー・HTTP連携)
  2. KickstartによるLinuxインストール自動化 (自動トリガー・ローカルディスク接続)
  3. KickstartによるLinuxインストール自動化 (自動トリガー・PXEブート連携) ← 今ココ

今回の記事については私が構成の内容を理解しきれておりません。
したがって、RHEL8のマニュアル通りの操作を抜粋して紹介するにとどめます。
詳しい原理や、使い勝手やセキュリティを踏まえた設計の吟味などはできませんが、ご了承ください。

今回の構成では、PXE BootやKickstartに必要なファイルをアップロードするサーバ (※) は、他にDHCPが動作していないネットワーク上で起動する必要があります。
(※) 本記事ではPXEサーバと呼びます

"他にDHCPが動作していないネットワーク" というのは、実はかなり大きな制約です。
VirtualBoxのようなローカル検証環境においてはDHCPを活用しているケースが多いと思うので、個人的にはローカル検証環境とPXE Bootはあまり相性が良くないと思います。

一方でPXE Boot用のネットワークが設計上分離されており、PXEサーバが常時起動しているようなインフラが整備されていればうまく活用できると思います。

構成概要

PXE (Preboot eXecution Environment) とは、ネットワークブートの一方式です。
ピクシー (/ˈpɪksiː/) と読まれることが多いようです1

ネットワーク越しにブートローダーやOSイメージ等の情報を取得して起動を開始します。
ブートローダーのパラメータにLinuxインストーラKickstartファイルのURLを指定することで、インストール作業の完全自動化まで可能となります。

kickstart3

環境構築は以下の手順で行います。
詳細は#環境構築にて説明します。

  1. DHCPサーバをインストールする
  2. DHCPサーバにTFTPサーバのIPアドレスなどを設定する
  3. TFTPサーバをインストールする
  4. ブートローダーの設定ファイルやバイナリファイルをTFTPサーバにアップロードする
  5. HTTP、FTP、またはNFSサーバを構築し、以下ファイルをアップロードする
    1. Kickstartファイル
    2. パッケージリポジトリ

Kickstartは以下の手順で開始します。
この構成では、イメージファイルの準備も不要です。
詳細は#Kickstartの実行にて説明します。

  1. インストール対象のマシンに空のディスクをセットする
  2. ネットワーク起動の優先順位を高くする
  3. マシンを起動する

環境構築

今回は、DHCPサーバ、TFTPサーバ、HTTPサーバを同じマシンに全て同居させた "PXEサーバ" を構築します。
今回の構成では、サーバは192.168.101.2/24というIPアドレスを持ちます。
デフォルトゲートウェイは、192.168.101.1であるとします。

手順はRHEL8 - Performing an advanced RHEL installationをベースとしています。
以降、各セクションに参照したセクションへのURLを記載します。

本記事の手順はCentOS Stream 9 (RHEL9相当) で動作を確認しました。

冒頭に記載しましたとおり、本記事では各設定内容の詳細までは吟味しません。
ただ、気になるポイントがあればSYSLINUX Wiki - PXELINUXが参考になると思います。

DHCPが動作していない仮想ネットワークを作成する

PXEサーバが動作するネットワークでは、他のDHCP機能が動作しないようにしてください。
VirtualBoxlibvirtなどの仮想ネットワークを使っている場合は、組み込みのDHCP機能がデフォルトで有効になっているので注意してください。

(参考) DHCPサーバが動作しない仮想ネットワークを作る理由

同じネットワーク内にDHCPサーバを複数台構築すると、DHCPサーバの動作が競合してしまいます。

同じネットワークにDHCPサーバが複数台存在すると、以下のような動きになってしまいます。
(※) DHCPサーバに冗長化機能があり、Active-Standby構成で動作しているようなケースは例外です

  • クライアントがブロードキャストでDHCPDISCOVERを出す
  • 複数台のDHCPサーバがDHCPDISCOVERを受け取り、DHCPOFFERを返す
  • クライアントは複数のDHCPサーバからDHCPOFFERを受け取るが、最初に届いたDHCPOFFERで後続の処理を進める

つまり、DHCPOFFERを先に届けたもの勝ちという動きになり、意図しないDHCPサーバがクライアントにIPアドレスを渡してしまいます。

今回の構成では、確実にPXEサーバが起動しているDHCPサーバからIPアドレスを受け取る必要があります。
PXEサーバ上で動作するDHCPサーバは、後続処理のためにTFTPサーバのIPやファイルパスを伝える特殊な役割を持つためです。

したがって、VirtualBoxKVM (libvirt) が起動している仮想ネットワークのDHCP機能と、PXEサーバのDHCP機能が競合しないように構成を組む必要があります。

(参考) KVMの場合の手順

KVM環境において、DHCP機能を無効化したネットワークを作る手順を紹介します。
操作方法はKVMの基本操作集 - #仮想ネットワークの作成が参考になります。

Cockpitの場合は以下のようなパラメータを指定します。

cockpit_add_nodhcp_network1

仮想ネットワーク作成後、ネットワーク起動し、自動起動も有効化しておきましょう。

cockpit_add_nodhcp_network2

コマンドで実行する場合は、やや煩雑な手順になります。
今回は少々手抜きですが、上記Cockpitで作成したXML形式の定義情報を貼っておきます。
ただし、MACアドレス、UUID情報、ブリッジ名は自動生成に任せたいので削除しておきました。

<network>
  <name>nodhcp</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <domain name='nodhcp' localOnly='yes'/>
  <dns>
    <host ip='192.168.101.1'>
      <hostname>gateway</hostname>
    </host>
  </dns>
  <ip address='192.168.101.1' netmask='255.255.255.0' localPtr='yes'>
  </ip>
</network>

以下のコマンドにより、作成したtmp.xmlを読み込んで新しい仮想ネットワークを作成します。

virsh net-define tmp.xml

ネットワークを起動し、自動起動を有効化します。

virsh net-start nodhcp
virsh net-autostart nodhcp

VMのネットワーク設定

KVMの構成におけるネットワーク設定を参考までに残しておきます。
以下の構成です。

sudo nmcli connection add ifname enp1s0 con-name enp1s0 type ethernet ipv4.method manual ipv4.addresses 192.168.101.2/24 ipv4.gateway 192.168.101.1 ipv4.dns 192.168.101.1 autoconnect yes

sudo nmcli connection up enp1s0

Linuxイメージファイルのマウント

今回のPXEサーバの構築にはLinuxインストール用のイメージファイルを使用します。

Linuxインストール用のISOファイルを接続した上でサーバを起動します。
Cockpitから仮想マシンに対してISOファイルを追加する際、BusをSCSIではなくSATAを指定しないとLinux上で/dev/cdromが生成しませんでした。

サーバ起動後、以下のコマンドでISOファイルをマウントします2

sudo mkdir /media/cdrom
sudo mount -t iso9660 -o ro,loop /dev/cdrom /media/cdrom

DHCPサーバの構築

参考元: 14. Preparing to install from the network using PXE
(14.2と14.3にそれぞれBIOSUEFI向けの設定方法が説明されていますが、DHCPの設定に関してはどちらも共通です)

DHCPサーバのインストール

以下のコマンドでDHCPサーバをインストールします。

sudo dnf install dhcp-server

DHCPサーバの設定

続いてDHCPサーバの設定を書き換えます。

sudo vi /etc/dhcp/dhcpd.conf

dhcpd.confの中身を以下のように編集します。
IPアドレスの値は環境によって調整してください。

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;
option architecture-type code 93 = unsigned integer 16;

subnet 192.168.101.0 netmask 255.255.255.0 {
    option routers 192.168.101.1;
    range 192.168.101.101 192.168.101.254;

    class "pxeclients" {
      match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
      next-server 192.168.101.2;

      if option architecture-type = 00:07 {
        filename "BOOTX64.efi";
        } else {
        filename "pxelinux/pxelinux.0";
      }
    }
}

中身について補足します。

DHCPサーバの起動

DHCPサーバを起動します。

# sudo systemctl enable dhcpd.service; sudo systemctl start dhcpd.service と同じ
sudo systemctl enable dhcpd.service --now

TFTPサーバの構築

参考元: 14. Preparing to install from the network using PXE

TFTPサーバのインストール

以下のコマンドでTFTPサーバをインストールします。

sudo dnf install tftp-server

firewalldによるTFTP通信許可

firewalldが有効な場合は、以下のコマンドでTFTP通信を許可しておきます。
重要なコマンドは「変更」と「設定反映」です。

# 事前確認。serviceにtftpがないこと
sudo firewall-cmd --list-all

# 変更
sudo firewall-cmd --add-service tftp --permanent

# 差分比較
diff -u <(sudo firewall-cmd --list-all) <(sudo firewall-cmd --list-all --permanent)
# -public (active)
# +public
#    target: default
#    icmp-block-inversion: no
# -  interfaces: enp1s0
# +  interfaces: 
#    sources: 
# -  services: cockpit dhcpv6-client ssh
# +  services: cockpit dhcpv6-client ssh tftp
#    ports: 
#    protocols: 
#    forward: yes

# 設定反映
sudo firewall-cmd --reload

# 事後確認。serviceにtftpがあること
sudo firewall-cmd --list-all

BIOS利用クライアント向けのブートローダー格納

参考元: 14.2. Configuring a TFTP server for BIOS-based clients

PXEBOOT用のブートローダーや設定ファイルをTFTPサーバに格納します。
本セクションで紹介するのは、BIOSベースのクライアント向けの手順です。
UEFIベースのクライアント向けの手順は、#UEFI利用クライアント向けのブートローダー格納にて別途紹介します。
理由がなければ、両方のセクションを対応しましょう。

作業ディレクトリに移動し、ブートローダRPMをISOイメージファイルから取り出します。
RPMファイルを展開し、中にあるブートローダーファイル群を/var/lib/tftpboot/pxelinux/ディレクトリに格納します。

mkdir ~/tmp/
cd ~/tmp/

# RHEL8の公式手順ではISOファイルから取り出している
  # RHEL8の場合: cp -p /media/cdrom/BaseOS/Packages/syslinux-tftpboot*.rpm .
  # CentOS Stream9場合: cp -p /media/cdrom/AppStream/Packages/syslinux-tftpboot-*.rpm .
dnf download syslinux-tftpboot

rpm2cpio syslinux-tftpboot*.rpm | cpio -dimv

sudo mkdir /var/lib/tftpboot/pxelinux
sudo cp -p tftpboot/* /var/lib/tftpboot/pxelinux/

作業用ディレクトリは不要になったので、このタイミングで消しておきます。

cd
rm -rf ~/tmp/

PXELINUXの設定ファイルを格納するディレクトリを作成します。

sudo mkdir /var/lib/tftpboot/pxelinux/pxelinux.cfg

PXELINUXの設定ファイルを作成します。

sudo vi /var/lib/tftpboot/pxelinux/pxelinux.cfg/default

defaultファイルには以下の内容を記述します。
IPアドレスや文言は環境に合わせてアレンジしてください。

default vesamenu.c32
timeout 50

display boot.msg

label linux_cs9
  menu label ^Install system
  menu default
  kernel images/centos_stream9/vmlinuz
  append initrd=images/centos_stream9/initrd.img ip=dhcp inst.repo=http://192.168.101.2/repositories/centos_stream9 inst.ks=http://192.168.101.2/kickstarts/centos_stream9
label vesa_cs9
  menu label Install system with ^basic video driver
  kernel images/centos_stream9/vmlinuz
  append initrd=images/centos_stream9/initrd.img ip=dhcp inst.xdriver=vesa nomodeset inst.repo=http://192.168.101.2/repositories/centos_stream9 inst.ks=http://192.168.101.2/kickstarts/centos_stream9
label rescue_cs9
  menu label ^Rescue installed system
  kernel images/centos_stream9/vmlinuz
  append initrd=images/centos_stream9/initrd.img rescue
label local
  menu label Boot from ^local drive
  localboot 0xffff

BIOS画面からPXE Bootを試みるとき、このdefaultファイルを参照してBoot Entryを選択します。
ファイル名は他にもUUIDやMACアドレスIPアドレスを元にした文字列も指定可能です。
上記のファイル名の条件に一致するようなクライアントから接続があった場合、defaultファイルよりも優先してそれらのファイルが読み込まれます。
詳細はSYSLINUX Wiki - PXELINUX - #Configuration filenameを参照してください。

設定ファイルの文法については、SYSLINUX Wiki - Configを参照してください。

今回はシンプルにdefaultファイルのみ作成しました。
MACアドレスIPアドレスごとのファイルを作成するかは設計思想に依存すると思いますが、手間がかかるので基本defaultのみで良いのではないかと思います。

defaultファイルは、RHEL8のマニュアルから以下の部分をアレンジしました。

変更前 変更後 詳細
prompt 1 行削除
  • prompt 1の場合、常にboot:プロンプトを表示する
  • prompt 0の場合、boot:プロンプトを表示しない
    (デフォルト)
  • boot:の表示によって起動が遅くなるので省いた
  • prompt
timeout 600 timeout 50
label linux label linux_cs9
  • 今後別OSの選択肢が増えたときのために名称変更
  • label
label vesa label vesa_cs9 同上
label rescue label rescue_cs9 同上

vesa_cs9, rescue_cs9, local_cs9については、不要であれば#コメントアウトしても問題ないと思います。

上表以外にも、各labelの配下に指定しているkernelinitrdinst.repoIPアドレスとファイルパスを適切な値に変更しました。

kernelinitrdについては、/var/lib/tftpboot/をrootとしたときの相対パスを指定します。
後続の#kernel, initrdファイルの格納において、ここで指定したパスにkernelinitrdを格納する必要があります。

inst.repoは、RPMパッケージリポジトリのURLです。
IPアドレスはHTTPサーバのものを指定します。
今回はDHCP/TFTP/HTTPサーバがすべて同じマシンに同居する構成のため、共通のIPアドレスである192.168.101.2を指定します。
後続の#RPMパッケージリポジトリの格納において、RPMパッケージリポジトリをここで指定したファイルパスに格納する必要があります。
inst.repoと同等のオプションはKickstartファイルのuriオプションでも指定しますが、これらはどちらも指定する必要があります。

inst.repoと同じ行にinst.ksを追記し、KickstartファイルのURLを指定しました。
後続の#Kickstartファイルの格納において、Kickstartファイルをここで指定したファイルパスに格納する必要があります。

UEFI利用クライアント向けのブートローダー格納

参考元: 14.3. Configuring a TFTP server for UEFI-based clients

前セクションではBIOSベースのクライアント用のブートローダーをTFTPサーバに格納しました。
本セクションでは、UEFIベースのクライアント用のブートローダーを格納します。

異なるバイナリファイルや設定ファイルを用意する必要がありますが、設定のポイントは基本的にBIOS向けの対応手順と変わりません。

まず、作業用ディレクトリを作成して移動します。

mkdir ~/tmp
cd ~/tmp

shim、grub2-efi RPMパッケージをISOファイルから取り出します。
これらのRPMはオンラインリポジトリには存在しなかったので、ISOファイルから取り出す必要がありました。

cp -p /media/cdrom/BaseOS/Packages/shim-x64-[0-9]*.rpm .
cp -p /media/cdrom/BaseOS/Packages/grub2-efi-x64-[0-9]*.rpm .

RPMファイルを展開して中身のファイルを取り出します。

rpm2cpio shim-x64-[0-9]*.rpm | cpio -dimv
rpm2cpio grub2-efi-x64-[0-9]*.rpm | cpio -dimv

EFIブートイメージファイルを取り出し、TFTPからアクセス可能な領域に格納します。

mkdir /var/lib/tftpboot/uefi

# RHELの場合は...
# sudo cp -p boot/efi/EFI/redhat/grubx64.efi
# sudo cp -p boot/efi/EFI/redhat/shimx64.efi
sudo cp -p boot/efi/EFI/centos/grubx64.efi
sudo cp -p boot/efi/EFI/centos/shimx64.efi

EFI用のBoot Entryを追記します。

sudo vi /var/lib/tftpboot/grub.cfg

以下のように記載します。

set timeout=5
menuentry 'CentOS Stream 9' {
  linuxefi images/centos_stream9/vmlinuz ip=dhcp inst.repo=http://192.168.101.2/repositories/centos_stream9/ inst.ks=http://192.168.101.2/kickstarts/centos_stream9
  initrdefi images/centos_stream9/initrd.img
}

grub.cfg環境変数やコマンドについては、GNU GRUB Manual - #16 The list of available commandsを参照してください。

grub.cfgファイルは、RHEL8のマニュアルから以下の部分をアレンジしました。

変更前 変更後 詳細
set timeout=60 set timeout=5
menuentry 'RHEL 8' menuentry 'CentOS Stream 9'

上表の他にも各種ファイルのパスやURLを環境に合わせて変更しました。

vmlinuzinitrd.imgについては、/var/lib/tftpboot/をrootとしたときの相対パスを指定します。
後続の#kernel, initrdファイルの格納において、ここで指定したパスにkernelinitrdを格納する必要があります。

inst.repoは、RPMパッケージリポジトリのURLです。
IPアドレスはHTTPサーバのものを指定します。
今回はDHCP/TFTP/HTTPサーバがすべて同じマシンに同居する構成のため、共通のIPアドレスである192.168.101.2を指定します。
後続の#RPMパッケージリポジトリの格納において、RPMパッケージリポジトリをここで指定したファイルパスに格納する必要があります。
inst.repoと同等のオプションはKickstartファイルのuriオプションでも指定しますが、これらはどちらも指定する必要があります。

inst.repoと同じ行にinst.ksを追記し、KickstartファイルのURLを指定しました。
後続の#Kickstartファイルの格納において、Kickstartファイルをここで指定したファイルパスに格納する必要があります。

kernel, initrdファイルの格納

PXE Bootで起動する際に必要なkernelイメージファイル、及びInit RAM DiskをISOファイルからコピーして格納します。
以下のコマンドを実行します。

mkdir -p /var/lib/tftpboot/pxelinux/images/centos_stream9
sudo cp -p /media/cdrom/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/pxelinux/images/centos_stream9/

TFTPサーバの起動

# sudo systemctl enable tftp.socket; sudo systemctl start tftp.socket と同じ
sudo systemctl enable tftp.socket --now

HTTPサーバの構築

参考元: RHEL8 - Performing an advanced RHEL installation - 6.4. Creating an installation source using HTTP or HTTPS

HTTPサーバにはKickstartファイルと、RPMパッケージリポジトリをアップロードします。

HTTPサーバのインストール

以下のコマンドでApache httpdをインストールします。

sudo dnf install httpd

firewalldによるHTTP通信許可

firewalldが有効な場合は、以下のコマンドでHTTP通信を許可しておきます。
重要なコマンドは「変更」と「設定反映」です。

# 事前確認。serviceにhttpがないこと
sudo firewall-cmd --list-all

# 変更
sudo firewall-cmd --add-service http --permanent

# 差分比較
diff -u <(sudo firewall-cmd --list-all) <(sudo firewall-cmd --list-all --permanent)
# -public (active)
# +public
#    target: default
#    icmp-block-inversion: no
# -  interfaces: enp1s0
# +  interfaces: 
#    sources: 
# -  services: cockpit dhcpv6-client ssh tftp
# +  services: cockpit dhcpv6-client http ssh tftp
#    ports: 
#    protocols: 
#    forward: yes

# 設定反映
sudo firewall-cmd --reload

# 事後確認。serviceにhttpがあること
sudo firewall-cmd --list-all

Kickstartファイルの格納

参考元: 5.3. Making a Kickstart file available on an HTTP or HTTPS server

KickstartファイルをHTTPサーバにアップロードします。
使用するファイルは、KickstartによるLinuxインストール自動化 (手動トリガー・HTTP連携) - #書き換え後のKickstartファイルとほぼ同じです。

ただし、cdromrepoの行のみ以下のように書き換えます。
RPMパッケージリポジトリをCDROMではなく、HTTPサーバ上のリポジトリに変更します。

# cdrom
url --url=http://192.168.101.2/repositories/centos_stream9

# repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream
repo --name="AppStream" --baseurl=http://192.168.101.2/repositories/centos_stream9/AppStream

cdromRPMパッケージリポジトリとしてISOイメージファイルを指定するコマンドです。
今回はRPMパッケージリポジトリとしてHTTPサーバを指定するので、これをurlコマンドに置き換えます。

repoは、baseなどデフォルトのRPMリポジトリに追加のリポジトリを指定するオプションです。
RHEL8以降は、インストール時にAppStreamというリポジトリを追加で指定する必要があります3

用意したKickstartファイルをHTTPサーバにアップロードします。

sudo mkdir /var/www/html/kickstarts
sudo vi /var/www/html/kickstarts/centos_stream9

今回使用するKickstartファイルは以下のとおりです。

# Generated by Anaconda 34.25.0.25
# Generated by pykickstart v3.32
#version=RHEL9
# Use graphical install
graphical
repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

# Keyboard layouts
keyboard --vckeymap=jp --xlayouts='jp'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=enp1s0 --ipv6=auto --activate
network  --hostname=cs

url --url=http://192.168.101.2/repositories/centos_stream9

%packages
@^minimal-environment

%end

# Run the Setup Agent on first boot
firstboot --enable

# Generated using Blivet version 3.4.0
ignoredisk --only-use=vda
# Partition clearing information
clearpart --none --initlabel
# Disk partitioning information
part pv.111 --fstype="lvmpv" --ondisk=vda --grow
part /boot --fstype="ext4" --ondisk=vda --size=1024
volgroup cs --pesize=4096 pv.111
logvol / --fstype="ext4" --percent=100 --name=root --vgname=cs
logvol swap --fstype="swap" --size=1024 --name=swap --vgname=cs

# System timezone
timezone Asia/Tokyo --utc

# Root password
rootpw --iscrypted $6$GMEsgHeNZwjJWb.d$BuP/sn9FX6xKEFGYo8KzNmLB5jPl7RhFQyHnklgrK2CkQntcsT2aOCz4Ozzcefc5J7gXO7IXVvj7KdQOddpv81
user --groups=wheel --name=endy --password=$6$qtY89ARpZJNqk8ap$1u6e3CplnSGpqBppAyd/.f9fheOt74TA.fqMdPsROa3kmSSlHuOyXurBWSr5EHksAemR.3HjDjkI1n6JIeJIk1 --iscrypted --gecos="endy"

過去記事と同様に、お好みでシンボリックリンクを作っておくとCentOS Streamのバージョン差異を抽象化できて便利になります。
よろしければ、以下のコマンドでcentos_streamというファイル名のシンボリックリンクを作成しておきましょう。

ln -s centos_stream9 centos_stream

RPMパッケージリポジトリの格納

参考元: 6.4. Creating an installation source using HTTP or HTTPS

ISOファイルからRPMパッケージリポジトリ情報をコピーします。
この部分の手順は、いわゆるリポジトリサーバの構築手順に近い内容かなと思います。

今回はLinuxの初期インストール用のパッケージを調達したいので、オンラインリポジトリではなくISOファイルからリポジトリデータをコピーします。

以下のコマンドでコピーします。
コピー元ディレクトリにある.treeinfoという隠しファイルが重要です。
*のようなワイルドカードを使うと隠しファイルのコピーが漏れてしまうので、以下の例のようにフォルダごとコピーしましょう。

sudo mkdir /var/www/html/repositories/
sudo cp -pr /media/cdrom/ /var/www/html/repositories/
sudo mv /var/www/html/repositories/cdrom /var/www/html/repositories/centos_stream9

HTTPサーバの起動

以下のコマンドでHTTPサーバを起動します。

# sudo systemctl enable httpd.service; sudo systemctl start httpd.service と同じ
sudo systemctl enable httpd.service --now

Kickstartの実行

ここまでの操作により、Kickstartに必要なPXEサーバの構築は完了しました。

では、いよいよ空のVMPXE Bootし、KickstartによってLinuxを自動インストールします。

(参考) 仮想マシンの作成

KVM配下に仮想マシンを作成する場合を例に、パラメータの例を示します。

詳細はKVMの基本操作集 - #VMの作成をご覧ください。

CockpitからVMを作成する際は、下図のようにパラメータを指定します。
今回はPXE Bootをするため、通常のCDROMからの起動ではなく、ネットワークからの起動を選択します。
また、PXEサーバと同じネットワークに接続するようにします。
今回の場合は、#DHCPが動作していない仮想ネットワークを作成するで作成したnodhcpというネットワークに接続します。

cockpit_vm_creation_with_network_boot_enabled

virt-installコマンドで仮想マシンを作成する場合は、例えば以下のようなコマンドを実行します。

Network bootを優先するため、普段指定している--cdromの代わりに--pxeを指定します。
また、今回は仮想ネットワークにdefault以外のものを指定するので、明示的に--network network=nodhcpによって指定します。

コンソール画面の自動起動を無効化したい場合は、--no-autoconsoleオプションも付けましょう。
--no-autoconsoleを指定する場合は、末尾の&は削除します。

virt-install \
--name test \
--memory 2048 \
--vcpus 2 \
--disk size=10 \
--graphics vnc \
--graphics spice \
--os-variant centos-stream9 \
--network network=nodhcp \
--pxe &

インストール手順を何度か試したいとも思いますので、作成したVMを停止して削除するコマンドも添えておきます。
--os-variantの指定を省いた場合は、--storage vdaの部分が--storage hdaになることもあります。
詳細はKVMの基本操作集 - #VMの削除を参照してください。

virsh destroy test ; virsh undefine test --storage vda --snapshots-metadata --managed-save

Kickstartによる自動インストール

VMを起動すると、以下の処理が自動的に走ります。

正しく動作すれば、以下のブートローダーの画面が表示されます。
無操作のまま5秒待つか、一番上のInstall systemを選択するとこの先のインストールに進みます。

pxe_bootloader

正しく処理が進めば、このままインストールが完了します。

(参考) トラブルのパターン

全てではありませんが、過去に踏んだことのあるトラブルを紹介します。

inst.repoの指定ミス

参考: 23.1. Configuring the Installation System at the Boot Menu - #Specifying the Installation Source

inst.repoに指定したパス配下の.treeinfoにHTTPアクセスできなかった場合、ブートローダーのグレーの画面を通過後、以下のようなエラー画面に遷移します。

.treeinfoの読み取りに失敗し、inst.repoinst.ksのパスに/images/install.imgを付与したパスから読み取る処理にフォールバックします。そのパスにもファイルが存在しないため、HTTP通信で404エラー応答が返り、処理に失敗します。

error_repository1

↓しばらく待つと、以下のようなエラーメッセージがしばらくループし続けた後、完全に処理を停止します。

error_repository2

このエラーが出た場合、inst.repoに指定したパスを中心に、HTTP通信がエラーになった原因を探って修正する必要があります。
確認するファイルは以下の2つです。

  • /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
  • /var/lib/tftpboot/grub.cfg

(参考) Kickstartでエラーが発生したときの対処法

1つ目の記事で紹介した(参考) Kickstartでエラーが発生したときの対処法を参照してください。

まとめ

PXE bootとKickstartを組み合わせて、ネットワーク越しに各種リソースにアクセスしてLinuxインストールを完全自動化する構成を紹介しました。

構成がなかなか複雑ですが、ネットワークに繋いでマシンの電源を入れるだけでLinuxのインストールが完了するというのは面白いと思います。

しかし、ローカル検証環境において活用するにはDHCPサーバの競合を回避する必要があります。
本番用途で活用するには、構築したサーバに何らかの方法で固定IPアドレスを割り振る工程も自動化するところで頭を使うと思います。

実際のユースケースと結びつけて正しく設計しようと考えると、今回紹介した構成は難易度が高いと思います。
他のKickstart構成やVMクローン、AnsibleなどのDevOpsツールなどの代替手段があるだけに、PXE bootの構成は中々採用されないかもしれません。

私も今のところ良いユースケースを思いつかない状況ですが、せっかく構築できたので本記事で紹介した次第です。
うまい使い方をご存知の方がいれば、ぜひコメントいただけますと幸いです。

関連記事

KickstartによるLinuxインストール自動化 (自動トリガー・ローカルディスク接続)

featured_image

Kickstartシリーズ

Kickstartとは、Linuxのインストールを自動化する機能です。
本シリーズではRHEL, Fedora, CentOS Streamをモデルに紹介します。

一連の記事でKickstartの構成を3パターン紹介します。
今回の記事では、2つ目の構成を紹介します。

私が普段Linuxをインストールするとき、この方法を使うことが一番多いです。

  1. KickstartによるLinuxインストール自動化 (手動トリガー・HTTP連携)
  2. KickstartによるLinuxインストール自動化 (自動トリガー・ローカルディスク接続) ← 今ココ
  3. KickstartによるLinuxインストール自動化 (自動トリガー・PXEブート連携)

構成概要

今回の構成は、Kickstartファイルを格納した専用の記憶デバイスをセットするだけでインストールを自動化します。

前回記事の構成と比較すると、初回起動時にinst.ks=...KickstartファイルのURLを手動入力しなくて良い点がメリットとして挙げられます。
一方でKickstart用ディスクを最初に接続し、インストール完了後に必要に応じて接続解除するという一手間が発生する点はデメリットとも言えます。

しかしながらコンソール上の文字入力が不要となるため、シェルスクリプトやAnsibleなどの外部ツールと連携して完全自動化したい場合は、今回の構成の方が実現が容易になります。

kickstart2

環境構築は以下の手順で行います。
詳細は#環境構築にて説明します。

  1. ファイルシステムOEMDRVとラベル付けする
  2. 上記ファイルシステムKickstartファイルを/ks.cfgというファイルパスで保存する

Kickstartは以下の手順で開始します。
詳細は#Kickstartの実行にて説明します。

  1. ISOファイル、インストール先ディスク、上記のキックスタート用ディスクをセットする
  2. ISOファイルから起動する
  3. 自動的にインストールが完了する

この構成は、特にLinuxを扱える環境においては採用しやすいと思います。
Linux環境であれば、mkisofsコマンドによって、Kickstartファイルだけを格納した専用のKickstartトリガー用ファイルをISO形式で簡単に作成できます。
(※) 本ブログでは、このKickstartトリガー用ファイルを「Kickstartイメージファイル」と呼びます

Windows環境でKickstartイメージファイルを作成するには、恐らくフリーソフトに頼る必要があります。
Macの場合はわかりません。

環境構築

Kickstartファイルの作成

前回記事で作成したファイルをそのまま使います。

ファイル名をks.cfgにリネームし、作業用ディレクトリに格納しておきます。

tree tmp
# tmp
# └── ks.cfg

Kickstart用ディスクの作成

mkisofsのインストール

Kickstart用ディスクの作成にはmkisofsコマンドを使います。

RHELディストリビューションであれば以下のコマンドでインストールできます。

sudo dnf install xorriso

Kickstartイメージファイルの作成

Kickstartイメージファイルの要件は以下のとおりです。

では、Kickstartイメージファイルを作成します。

まず、事前にks.cfgという名前のKickstartファイルをディレクトリに配置します。
サブディレクトリなどに含めず、必ずディレクトリ直下に配置するようにしてください。

ls tmp/
# ks.cfg

続いて、tmp/ディレクトリを引数にmkisofsによってISOファイルを作成します。

mkisofs -V OEMDRV -o ks_centos_stream9.iso tmp/

今回使用したmkisofsコマンドラインオプション、及び引数を下表に示します。

オプション / 引数 意味
-V OEMDRV
-o ks_centos_stream9.iso 出力ファイルパスをks_centos_stream9.isoと指定
tmp/ tmp/ディレクトリの中身をISOファイルシステムに含める

最後に、Kickstart用ディスクファイルをお好みの場所に格納します。
今回の例では、/home/shared/libvirt/images/kickstarts/ks_centos_stream9.isoに格納しました。

前回記事と同様に、お好みでシンボリックリンクを作っておくとCentOS Streamのバージョン差異を抽象化できて便利になります。
よろしければ、以下のコマンドでks_centos_stream.isoというファイル名のシンボリックリンクを作成しておきましょう。

ln -s ks_centos_stream9.iso ks_centos_stream.iso

Kickstartの実行

ここまでの作業で準備は整いました。
いよいよ初期状態の仮想マシンを用意してKickstartを開始します。

(参考) 仮想マシンの作成

KVM配下に仮想マシンを作成する場合を例に、パラメータの例を示します。
詳細はKVMの基本操作集 - #VMの作成をご覧ください。
VM作成時、Kickstart用ディスクファイルもセットするのがポイントです。

(参考) virt-installの場合

以下のコマンドを実行することで、Kickstartイメージファイルを搭載したVMを作成・起動できます。
基本的には前回記事と同じコマンドですが、以下の部分が差分です。

  • 末尾に--diskを追加指定することでKickstartイメージファイルを追加している
  • Kickstartイメージファイルの追加時、readonly=onを指定することでドライブを読み取り専用にしている (※)
  • --check path_in_use=offにより、Kickstartイメージファイルを搭載したVMが他に存在してもエラーにならないようにする
virt-install \
--name test \
--memory 2048 \
--vcpus 2 \
--disk size=10 \
--graphics vnc \
--graphics spice \
--os-variant centos-stream9 \
--cdrom /home/shared/libvirt/images/isos/centos/CentOS-Stream-9-latest-x86_64-dvd1.iso \
--disk path=/home/shared/libvirt/images/kickstarts/ks_centos_stream9.iso \
--check path_in_use=off &

VMを強制終了して削除するには、以下のコマンドを実行します。

virsh destroy test ; virsh undefine test --storage vda --snapshots-metadata --managed-save

Kickstartによる自動インストール

VMを起動し、インストールを開始すれば自動的にKickstartが始まります。

前回記事とは異なり、コンソール画面からinst.ks=...を指定する必要はありません。
これはOEMDRVラベルのついたファイルシステム/ks.cfgファイルがあるとき、ks.cfgファイルを自動的にKickstartファイルとして読み込む仕様があるためです1

(参考) Kickstartでエラーが発生したときの対処法

1つ目の記事で紹介した(参考) Kickstartでエラーが発生したときの対処法を参照してください。

(参考) ISO以外の形式でKickstartイメージファイルを作成する

本セクションで紹介する手順は非推奨です。
KickstartイメージファイルはISOファイルで作成するべきです。

Kickstartイメージファイルは、ISO以外のファイルシステムでも作成できます。
例えば、軽量なファイルシステムであるFATやEXT2でフォーマットすることも技術的には可能です。

例えば、以下のような手順でFATファイルシステムでフォーマットされたqcow2形式のディスクファイルを作成できます。

sudo dnf install guestfs-tools
virt-make-fs -t fat -F qcow2 --label OEMDRV tmp/ ks_centos_stream9.qcow2

しかしqcow2でKickstartイメージファイルを作成すると、紐づくVMを削除するときに巻き添えでKickstartイメージファイルも誤って削除するリスクが上がります。
したがって、冒頭のとおりKickstartイメージファイルをqcow2で作成することは推奨しません。

具体的なメカニズムを以下に補足します。

  • qcow2ディスクファイルは、デフォルトで読み書き可能ディスクとして/dev/vdXにマウントされる
    • (一方で、ISOファイルはデフォルトで読み取り専用かつ/dev/sdXにマウントされる)
  • CockpitでVMを削除するとき、読み取り専用ではないディスクはデフォルトで削除対象のチェックボックスにチェックが入る
  • virsh undefine --storage vdaを指定したとき、Kickstartイメージファイルが読み書き可能ディスクだった場合一緒に削除されてしまう
  • Cockpitやvirshによる誤削除を防止するには、qcow2形式のKickstartイメージファイル追加時に、明示的に読み取り専用オプションを指定する必要がある
    • Cockpit画面では、VMの詳細画面で追加済みのディスクをEditすることで読み取り専用に変更できる
    • virt-installVMを作成する際は、--disks path=xxx,readonly=onのように読み取り専用オプションを追加できる

ISO形式でKickstartイメージファイルを作成すれば、上記一連の面倒な仕様すべてから開放されます。

上述の理由から、KickstartイメージファイルはISOイメージファイルで作成すべきです。

参考URL

本記事に関連する参考URLをまとめて掲載します。

Kickstart用ディスクによるKickstartの自動開始については、Red Hat社のマニュアルが参考になります。
RHEL8 - Performing an advanced RHEL installation - 7.3. Starting a Kickstart installation automatically using a local volume

その他、Kickstart自体の概要やKickstartファイルの書き方については、前回記事で紹介した内容を前提としております。

まとめ

Kickstart用ディスクをセットしたマシンを起動するだけで、Kickstartを自動トリガーしてLinuxのインストールを自動化する方法を紹介しました。

前回記事と比較して、Kickstartのトリガーが自動化されたことで更に便利になりました。
しかし、mkisofsコマンドが使えるLinux環境にアクセスできない場合はKickstart用ディスクの作成・変更が少々面倒かもしれません。

KVMでローカル検証環境を組んでいる方は、この構成を便利に扱えると思います。
Linuxのインストールが面倒になったら、ぜひご活用ください。

関連記事