はじめに
現在Ubuntu24.04を普段使いしているが,ROS 2開発では依然Ubuntu22.04が主流である.しかし,デュアルブートで22.04と24.04の二つを用意するのは,切替時に再起動が必要となる面倒さや,リソースの圧迫といった弱点がある.また,仮想環境やDockerコンテナにより,ホストOS上で用意したいOSを起動する方法も存在するが,Docker単体では基本的に単一のサービスやアプリケーションの実行を前提とした設計であり,複数のプロセスやsystemdを含むフル機能の開発環境をそのまま扱うには工夫が必要となる.特にROS 2開発では,ノードの実行に加えてrvizやrqtといったGUIアプリケーション,さらには複数ノードの同時実行など,通常のLinux環境として扱いたい場面が多く,Dockerを用いた環境構築では構成が複雑になる.
そこで,本記事では,Ubuntuにおけるコンテナ管理ツールであるLXDを用い,UbuntuのホストOS上にもう一つのUbuntu環境を構築する方法を紹介する.LXDは,Dockerと同様にコンテナ技術を利用しながらも,より軽量な仮想マシンに近い形でOS環境を扱うことができ,systemdを含む通常のLinux環境をそのまま利用できる点に特徴がある.
LXDの特徴
Dockerと仮想マシンのいいとこどりで,軽量な仮想マシンのように扱える
LXDは仮想マシンと違いシステムコンテナであり,ホストOSのカーネルを共有して動作する.そのため,ゲストOSのように独立したカーネルを起動する必要がなく,起動時のオーバーヘッドが非常に小さいという特徴がある.起動時のメモリ使用量について筆者が試したところ,何もしていない場合では約80MBのメモリ使用量であった.
また前述のように,Dockerは単一のアプリケーションの実行に使われるのが基本であるため,ROS 2開発でよく行われる仮想マシン的な使い方はあまり向いていない.
LXDではDockerと同様に手軽にOSを用意でき,コンテナなので仮想マシンよりも軽量であるため,Dockerと仮想マシンのいいとこどりのような感じである.
なお,LXDは仮想マシンも管理することができる.

引用: https://ubuntu.com/blog/lxd-5-easy-pieces
構成
今回構築する構成は以下の通りである.なお,ホストOSはUbuntu推奨である.
| OS | ROS 2 | |
|---|---|---|
| ホストOS | Ubuntu 24.04 LTS | Jazzy |
| LXDコンテナ | Ubuntu 22.04 LTS | Humble |
用意されているコンテナイメージは以下のリンクから確認できる.
Ubuntu 22.04 LXDコンテナの構築
LXDをインストールする
sudo snap install lxd
LXDのインスタンスを生成する前に,LXDにおけるネットワークやストレージのセットアップが必要である.基本的にはデフォルトのままでよく,最小構成の場合には—minimalオプションをつける.
sudo lxd init --minimal
sudoを使わずにLXDを操作するためには,ユーザーをlxdグループに入れる必要がある.
以下のコマンドを実行して,設定を反映するために再起動もしくは再ログインする
sudo usermod -a -G lxd $USER
Ubuntu22.04のイメージをサーバーからダウンロードし,Ubuntu-22-04-containerという名前でインスタンス生成を行う.lxc launchはlxc initとlxc startをまとめて実行するので,自動でコンテナが起動される.
lxc launch ubuntu:22.04 ubuntu-22-04-container
コンテナの基本操作
作成されたコンテナの確認
lxc list
コンテナの情報やリソース使用状況を確認
lxc info <コンテナ名>
コンテナの起動・停止
# 起動
lxc start <コンテナ名>
# 停止
lxc stop <コンテナ名>
コンテナへログイン
デフォルトではrootでログインする
lxc exec <コンテナ名> -- /bin/bash
ユーザー権限でログインする場合は,以下のコマンドでログイン
lxc exec <コンテナ名> -- su - <ユーザ名>
コンテナの削除
# まずコンテナの停止
lxc stop <コンテナ名>
# コンテナの削除
lxc delete <コンテナ名>
コンテナのコピー
lxc copy <コンテナ名1> <コンテナ名2>
コンテナのリネーム
# まずコンテナの停止
lxc stop <コンテナ名>
# コンテナのリネーム
lxc move <旧コンテナ名> <新コンテナ名>
Ubuntu 22.04 LXDコンテナの起動
一旦root権限でコンテナに入る
lxc exec ubuntu-22-04-container -- /bin/bash
ROS開発では非rootユーザー推奨であるため,新たにユーザーを作成する.ここではユーザ名をrosとした.パスワードなども設定する.
adduser ros
usermod -aG sudo ros
exitコマンドでコンテナを抜け,ユーザーとして入れるかを確認する.
# コンテナを抜ける
exit
# ユーザーrosとしてコンテナに入る
lxc exec ubuntu-22-04-container -- su --login ros
ログインには1秒もかからない.
X11によるGUIの有効化
LXDコンテナ上でrvizなどのGUIアプリケーションを実行するためには,ホスト側のXサーバとコンテナを接続する必要がある.ここでは,X11を用いてGUIを表示する方法を説明する.
X11ソケットの共有
まず,ホスト側のX11ソケットをコンテナにマウントする.
lxc config device add ubuntu-22-04-container X0 disk \
source=/tmp/.X11-unix \
path=/tmp/.X11-unix
Xサーバへのアクセス許可
ホスト側で以下を実行する
xhost +local:
これにより,ローカル環境からのXサーバ接続が許可される.なお,同一マシン上のすべてのユーザーがXサーバにアクセス可能となるため,特定ユーザーのみに限定したい場合は以下のコマンドを実行する.
xhost +SI:localuser:<ユーザ名>
DISPLAY環境変数の設定
コンテナ内で以下を設定する.
export DISPLAY=:0
GPUの有効化
rvizなどのGUIアプリケーションはGPUを使用するため,コンテナにGPUデバイスを渡しておくと動作が大幅に改善される.
ホスト側で以下を実行する
lxc config device add ubuntu-22-04-container gpu gpu
その後,コンテナを再起動する
lxc restart ubuntu-22-04-container
動作確認
sudo apt update
sudo apt install -y x11-apps
xeyes
永続化のためのTip
なお,ここまでをまとめると,これからUbuntu環境へログインしGUIアプリケーションが表示できるようにするには,以下のコマンドを実行することになる
# **** ホスト側 ****
# X11サーバへのアクセス許可
xhost +local:
# ユーザーrosでコンテナにログイン
lxc exec ubuntu-container -- su - ros
# **** コンテナ内 ****
# DISPLAY環境変数の設定
export DISPLAY=:0
しかし,これらをいちいちログインするたびに打つのは面倒である.よって,筆者は以下のように設定している.
ホスト側
ホスト側で実行する2つのコマンドを~/.bashrcにエイリアスとして定義.ここではubuntu22 というコマンド名にしている.
~/.bashrc
# 末尾に追加
ubuntu22() {
# xhostの出力を抑制
xhost +local: >/dev/null 2>&1
lxc exec ubuntu-container -- su - ros
}
コンテナ内
起動時に自動でDISPLAY環境変数の設定を行う
~/.bashrc
# 末尾に追加
export DISPLAY=:0
これで,好きなコマンドでコンテナにログインし,GUIソフトウェアも扱える.
ROS 2環境の構築
ROS 2環境の構築は普通のUbuntu環境で構築する場合と同じである.ROS 2の公式ドキュメントなどを参考に構築するとよい.
最小限のインストール例
# ロケールの設定
locale
sudo apt update && sudo apt install locales
sudo locale-gen ja_JP ja_JP.UTF-8
sudo update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8
echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc
# リポジトリ追加
sudo apt install software-properties-common
sudo add-apt-repository universe
# ROS 2リポジトリ登録
sudo apt update
sudo apt install curl
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
-o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
http://packages.ros.org/ros2/ubuntu \
$(. /etc/os-release && echo $UBUNTU_CODENAME) main" | \
sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# インストール
sudo apt update
sudo apt install ros-humble-desktop
ROS 2開発やデバイス利用のために,ユーザー適切なグループへ追加しておくとよい
sudo usermod -aG dialout ros
sudo usermod -aG video ros
sudo usermod -aG plugdev ros
sudo usermod -aG render ros
動作確認
コンテナ内でターミナルを2つ用意し,それぞれ以下を実行する
# ターミナル1
ros2 run demo_nodes_cpp talker
# ターミナル2
ros2 run demo_nodes_cpp listener
listenerがtalkerからのデータを取得できていることを確認
rvizも起動してみる
rviz2
ちゃんと表示されることを確認した.UIを操作してみてもまったく遅延はなく,LXDの恩恵を受けられていると感じる.



