ACRi ルームのつくりかた (2)

ACRi ルームのしくみについて解説するコースの後半の記事です。この記事では、ACRi ルームと似た環境を研究室などのローカル環境で構築したい人のために、ACRi ルームの Atry サーバ群の物理サーバや VM をどのようにセットアップしているかについて解説します。

解説の前提

サーバの構成

今回の解説は、EdgeTech+ 2023 において アヴネット株式会社の協力により展示した、ミニ版の ACRi ルームともいえる環境を構築したときの作業メモをもとにしています。この環境は、FPGA を遠隔環境で開発・検証できるという ACRi ルームのコンセプトを、必要最小限の構成で実現したものになっています。以下に、ミニ版の ACRi ルームのサーバ構成の概略図を示します。

ミニ版 ACRi ルームのサーバ構成の概要

通常の ACRi ルームとは異なり、この環境では各サーバや VM はそれぞれ互いに独立したユーザアカウントを持ち、ユーザ情報やユーザのホームの共有は行いません。これらの管理・共有の方法は、各自すでにお使いのものや、使いやすい方法を適用いただければと思います。また、共有されたユーザ情報がないことから、必然的に予約システムも使用しません。予約システムについては、次に説明するインタフェースの仕様に従うものを、自前で用意することも可能です。

また、ACRi ルームではすべての物理サーバと VM とが同じネットワークに接続されています。言い換えれば、VM はブリッジ接続を行うように設定されています。対して、この環境では、IP アドレス 192.168.aa.bbb の物理サーバ上に 192.168.cc.0/24 の仮想ネットワークを構築し、すべての VM はその仮想ネットワークに接続されるものとします。つまり、VM は Host-only Adapter を使用するように設定されます。ただし、これについては、ルータが不要で展示ができるようにする、という要求に応えるために必要な想定でした。物理サーバがルータに接続されていれば、ブリッジ接続を使っても問題はありません。また、スケルトンのセットアップ中は、インターネット接続のためにブリッジ接続を使うことになります。

予約システムのインタフェース

このコースの前半の記事でも紹介した通り、予約システムは最終的にローカル Web サーバが提供する CGI スクリプトをインタフェースにして、予約情報を送信しています。スクリプトのパスは /olb-view.cgi で、GET リクエストを受け付けます。クエリには以下のキーが含まれます。

キー説明
year取得対象の日付の年部分 (西暦)
month取得対象の日付の月部分 (1-12)
date取得対象の日付の日部分 (1-31)
host取得対象のサーバ名
partialyes であればサーバ名を前方一致で検索する (それ以外なら完全一致)

スクリプトは、リクエストに対して、サーバ名が一致するすべてのサーバの当日の予約情報を、JSON 形式で出力します。出力は、1段目をサーバ名、2段目を時間枠のそれぞれをキーとする、2重の連想配列です。host に vs0 を指定し、partial を yes にしたときの、出力の例を以下に示します。

{
    "vs001": {
        "12:00:00": "closed",
        "15:00:00": "u_*******",
        "18:00:00": "u_*******"
    },
    "vs002": {
        "12:00:00": "closed",
        "15:00:00": "u_********",
        "21:00:00": "u_******"
    },
    "vs003": {
        "12:00:00": "closed"
    }
}

ACRi ルームの物理サーバから予約情報をリクエストする際は、year、month、date は現在の5分後の日付をもとに決定し、partial は yes に固定しています。また、JSON 出力に自身の管理していない VM の予約情報が含まれていても、問題はありません。そのため、仕様には反しますが、単にクエリにかかわらず当日 (23:55 以降は翌日) のすべての予約情報を出力するといった、より簡易な実装も考えられます。

物理サーバのセットアップ

ここからが本題です。まずは、使用したいバージョンの Ubuntu Desktop をインストールしておきます。あるいは、Ubuntu Server をインストールしてから、apt install ubuntu-desktop で、デスクトップ関連のパッケージを後からインストールしても構いません。そこから、必要なパッケージのインストールと設定を行っていきます。以下に、ACRi ルームの環境のために必要最低限の設定を示していきます。

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install language-pack-ja-base language-pack-ja ibus-mozc
$ sudo timedatectl set-timezone Asia/Tokyo

# 自動スリープなどを無効化
$ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
# アップデート確認やエラー送信を無効化
$ sudo apt remove update-manager apport
# Wi-Fi を無効化 (有線 LAN のみ使用)
$ sudo nmcli radio wifi off
# 検索インデックス作成を無効化
$ sudo chmod -x /usr/libexec/tracker-*
# 自動アップグレードを無効化: 下記設定ファイルで、両方の値を 0 に設定
$ sudo nano /etc/apt/apt.conf.d/20auto-upgrades

# SSH の切断対策: 下記設定ファイルで、以下の項目をアンコメント・設定
#   ClientAliveInterval 60
#   ClientAliveCountMax 3
$ sudo nano /etc/ssh/sshd_config

# DNS のローカルリゾルバを無効化
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
$ sudo systemctl restart systemd-resolved

次に必要なのは、VM との共有フォルダです。/tools 以下に、各種の管理スクリプトと Vivado を、それぞれインストールします。Vivado のインストールを除く手順を以下に示します。ここでは、全サーバ共通の管理ユーザの名前を acriuser としています。

$ sudo apt install nfs-kernel-server
$ sudo mkdir /tools
$ cd /tools
$ sudo git clone https://github.com/acri-room/acri-olb.git
$ sudo chown -R acriuser:acriuser acri-olb
# 共有設定: 下記設定ファイルに1行追記 (IP は環境に合わせて変更する)
#   /tools 172.16.0.0/16(rw,no_subtree_check)
$ sudo nano /etc/exports
$ sudo systemctl restart nfs-server.service

Vivado の必要なバージョンのインストール先は、/tools/Xilinx 以下とします。Vivado をインストールしたら、必要に応じてボードファイルをコピーしたり、古いバージョンの Vitis HLS に存在するバグの修正パッチを適用します。2021.2 以前のバージョンに存在する Export IP の日付に起因するバグに対するパッチは、AMD が公開しています。2022.1 以前のバージョンに存在する mpfr.h の参照先の不備に対するパッチは、藤枝が作成したものをダウンロードできるようにしておきます。

そのあと、リモートデスクトップ接続のために xrdp をインストールします。インストール後、先ほど git でダウンロードした管理スクリプトの中に、xrdp に必要な設定を記したシェルスクリプトがあるので、これを適用します。また、管理スクリプトの多くは Ruby で書かれているので、Ruby もインストールしておきます。

$ sudo apt install xrdp
$ sudo systemctl start xrdp
$ sudo systemctl enable xrdp
$ sudo /tools/acri-olb/client/xrdp_setup.sh
$ sudo systemctl restart xrdp
$ sudo apt install build-essential ruby ruby-dev

VM を動かす準備をします。VirtualBox のダウンロードページの Debian-based Linux distributions の節を参考に、VirtualBox を apt でインストールする準備をしてから、インストールします。その後、以下の手順で、管理ユーザへの権限付加と、VM 関係のファイルの置き場所の用意 (ここでは /usr/local/vm) をしておきます。

# apt の設定: 下記設定ファイルに1行追記 (<mydist> は適宜 jammy などに置き換える)
#   deb [arch=amd64 signed-by=/usr/share/keyrings/oracle-virtualbox-2016.gpg] https://download.virtualbox.org/virtualbox/debian <mydist> contrib
$ sudo nano /etc/apt/sources.list
$ wget -O- https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmor --yes --output /usr/share/keyrings/oracle-virtualbox-2016.gpg
$ sudo apt update
$ sudo apt install virtualbox-7.0
$ sudo usermod -aG vboxusers acriuser
$ sudo mkdir /usr/local/vm
$ sudo chown acriuser:acriuser /usr/local/vm

その後、設定を反映させるためにログインし直します。

VM 共通のセットアップ

ここからは VM のひな型 (スケルトン) のセットアップです。VirtualBox を起動し、名前の後ろに skel とつけた新しい VM を作成します。こちらにも Ubuntu をインストールしたら、物理サーバの設定の「DNS のローカルリゾルバを無効化」のところまでは、同様に進めます。

VM 側では、物理サーバで設定した共有フォルダ (/tools) を NFS でマウントします。以下の手順を適用することで、Vivado (/tools/Xilinx) や管理スクリプト (/tools/acri-olb) が VM からもアクセスできるようになります。

$ sudo apt install rpcbind nfs-common
$ sudo mkdir /tools
# 共有設定: 下記設定ファイルに1行追記 (<VM_HOST_IP> は物理サーバの IP)
#   <VM_HOST_IP>:/tools /tools nfs rw,auto,x-systemd.automount,x-systemd.mount-timeout=5,x-systemd.device-timeout=5 0 0
$ sudo nano /etc/fstab
$ sudo mount -a

そうしたら、Vivado の起動や管理スクリプトの実行に必要な、各種のツールやライブラリ、FPGA ボード用のドライバをインストールします。それ以外にも、必要なツールやライブラリがあれば、ここで併せてインストールしておきます。お好みで調整してください。

# Vivado の起動に必要なものたち
$ sudo apt install python3-pip libtinfo5 libncurses5 libgoogle-perftools4
$ sudo apt install libusb-0.1-4 libusb-1.0-0 libusb-1.0-0-dev libusb-dev
$ sudo apt install libftdi1 libftdi1-2 libftdi1-dev libftdi-dev
# ケーブルドライバ
$ (cd /tools/Xilinx/Vivado/2020.2/data/xicom/cable_drivers/lin64/install_script/install_drivers/; sudo ./install_drivers)
# USB 設定: 下記設定ファイルに1行追記
#   KERNEL=="ttyUSB*", MODE="0666"
$ sudo nano /etc/udev/rules.d/90-local.rules
# その他のツール
$ sudo apt install emacs-nox iverilog gtkwave vim gnuplot graphviz libgraphviz-dev tmux zsh verilator ruby ruby-dev gtkterm lv
$ sudo pip3 install pipenv pyserial matplotlib numpy scipy jupyter pillow
$ sudo sed -i -e 's/!java_platform? && !solaris/win/g' /usr/lib/ruby/vendor_ruby/rubygems.rb
$ sudo gem install serialport

そして、VM の起動時に実行するスクリプトをサービスとして登録します。

$ sudo cp /tools/acri-olb/client/acri-startup.service /lib/systemd/system/
$ sudo systemctl enable acri-startup.service

ここまでの手順で、この VM はスケルトンとして完成し、クローンされる準備が整いました。VM をシャットダウンして、物理サーバから続きの手順を進めます。

スクリプトの定数の書き換え

管理スクリプトのいくつかは、環境に応じた定数の書き換えが必要です。書き換える必要のあるスクリプトは、VM 起動時処理 (client/acri-startup.rb および client/acri-startup-post.sh)、VM 固有のセットアップ処理 (client/vm-host-setup.py) と物理サーバの VM 再起動処理 (vm-host/restart-vm.rb) です。順番に説明します。

VM 起動時処理では、デフォルトのビットストリームを書き込むための Vivado のパス (VIVADO_DIR、後処理では不要)、管理ユーザのユーザ名 (USER_NAME)、管理ユーザから書き込める非共有フォルダのパス (USER_DIR) が必要です。ビットストリームを書き込む際、デフォルトでは Vivado 2020.2 を使用します。これ以外のバージョンの Vivado をインストールした場合は、バージョンの部分を書き換えてください。また、非共有フォルダは、メインの処理と後処理との間で、設定ファイルなどをやりとりするために使用します。ACRi ルームの Arty サーバ群の VM では、管理ユーザのホームは /usr/local/home/acriuser に設定されているため、デフォルトではそこを非共有フォルダに指定しています。環境に合わせて、適切なパスを設定してください。

VM 固有のセットアップ処理では、ネットワークの設定ファイルを書き換えるため、ゲートウェイの IP アドレス (gateway)、検索ドメイン名 (domain)、DNS サーバの IP アドレス (nameserver) が必要です。それぞれ、ネットワーク構成に合わせて書き換えてください。

VM 再起動処理では、予約情報の問い合わせ先のローカル Web サーバ (SERVER) の情報が必要です。予約システムを動作させていない場合には、ここには空文字列 (”) を入れておきます。また、/tools/acri-olb/vm-host/data/no-restriction.txt というテキストファイルを作成し、その中にサーバ名を1行につき1つ記載しておくと、記載されたサーバはどのユーザからもログインできるようになります。この記載がない場合、そのサーバは、予約しているユーザと管理ユーザだけがログインできます。

VM 固有のセットアップ

それでは作成したスケルトンから、VM をクローンで作成し、VM 固有のセットアップを行います。必要な数だけの FPGA ボードを物理サーバに接続したあと、物理サーバから以下の2つのスクリプトを実行します。

$ cd /tools/acri-olb/vm-host
$ ./create-vms.rb vsX 172.16.1X vsX-skel 10
$ ./setup-created-vms.rb

ただし、create-vms.rb の引数は、サーバ名のプレフィクス、IP アドレスのプレフィクス、スケルトンのサーバ名、クローンの台数の順に指定します。ただし、クローンの台数には、FPGA ボードが接続されない、サーバ名の末尾が 00 の VM を含みません。例えば、サーバ名のプレフィクスを vsd、台数を 3 に設定した場合は、vsd00、vsd01、vsd02、vsd03 の4台の VM がクローンにより作成され、vsd00 以外の3台にそれぞれ FPGA ボードが1枚ずつ割り当てられます。

このあと、サーバを自動的に再起動したい場合には、crontab -e で cron に以下のタスクを登録します。ただし、<LIST_OF_VMS> には自動再起動の対象とする VM をスペース区切りで指定します。

*/2 * * * * /tools/acri-olb/vm-host/restart-vm.rb <LIST_OF_VMS>

これで準備は完了です。必要に応じて、物理サーバの /etc/hosts に VM のサーバ名と IP アドレスの組とを登録するなどの微調整を行います。それから、リモートデスクトップ経由で VM にログインできるか、Vivado が起動できるか、FPGA ボードが認識されるか、任意のビットストリームを書き込んで動作するか、などのテストを進めてください。

まとめ

このコースでは、ACRi ルームでの FPGA ボードの時間貸しをシステムとして見たときに、それがどのように実現されているか、その簡易版をどうすれば実現するかをご紹介しました。可能な限りの自動化を進め、人的な運用コストの低減を図っています。一方で、FPGA ボードを想定外に近い方法 (1台の物理サーバに10枚接続、それを10台の VM に1対1で割当て、複数ユーザで共用……) で使用しているがゆえのトラブルというのも、これまでにそれなりに経験してきました。

ということで、ACRi ルームは今日も稼働中です。FPGA 入門は Arty をはじめとした FPGA ボードで、より挑戦的な課題は Alveo などの拡張ボードでと、FPGA を使った教育研究に幅広く使える環境になっています。ぜひご活用ください。

愛知工業大学 藤枝直輝

タイトルとURLをコピーしました