lxc / Ubuntu 22.04 / RTX 5060 Ti / CUDA の環境を構築

# 1. はじめに

この記事は、lxc を用いた CUDA 環境を構築する手順書です。

ホスト環境 Kubuntu 24.04 、ゲスト環境 Ubuntu 22.04 とし、そのゲスト内環境で CUDA を使えるようにしています。

2025年6月時点では、Ubuntu 24.04 公式では RTX 5060 Ti ドライバが配布されておらず、個別にドライバを導入する必要があります。
一方で、Ubuntu 22.04 では個別でドライバのインストールも利用できていません。

そこで、本記事ではドライバなどの足回りを Ubuntu 24.04 で有効にした上で、アプリケーション層を lxc による Ubuntu 22.04 仮想環境で構築し、Isaac-sim や ROS2 などを動作させられる環境を構築していきます。

構成は下記の通り。

| 項目 | 名称 |
|---|---|
| CPU | AMD Ryzen 9 PRO 8945HS |
| RAM | 64 GB |
| GPU | GeForce RTX 5060 Ti (Oculink 接続) |
| VRAM | 16 GB |
| Host OS | Kubuntu 24.04 |
| Guest OS | Ubuntu 22.04 |
| Guest OS 側ユーザー名 | ubuntu |

過去に下記を投稿していますが、当時は CUDA 環境がなかったことと、細々と手直しが必要だったため新規に書き起こしました。

https://qiita.com/Corgeek/items/71b9b1c2aa8fc06ab7e5

# 2. Host 側の CUDA 環境準備

## 2.1. NVIDIA のドライバをインストール

2025年6月時点では、まだ RTX 5060 Ti 用のドライバが Ubuntu 公式に取り込まれておらず、NVIDIA のドライバを個別で入れていく必要があります。
動作を確認できているバージョンは、NVIDIA-Linux-x86_64-575.57.08.run です。

https://www.nvidia.com/en-us/drivers/details/245537/

```bash:Host 側
sudo apt-get install -y build-essential
wget https://us.download.nvidia.com/XFree86/Linux-x86_64/575.57.08/NVIDIA-Linux-x86_64-575.57.08.run
chmod +x NVIDIA-Linux-x86_64-575.57.08.run
```

念のためランレベルを2に指定してCUIモードに切り替えておく。

```bash:Host 側
sudo init 2
```

CUI でログインし、ダウンロードしたドライバをインストール。

```bash:Host 側
sudo sh ./NVIDIA-Linux-x86_64-575.57.08.run --glvnd-egl-config-path=/etc/glvnd/egl_vendor.d --compat32-libdir=/usr/lib32
```

出てくる選択肢は、`MIT/GPL` を選び、`Continue installation` で進む。

:::note

正常に完了すれば、nvidia-smi でアクセスできていることを確認しておくこと。

```bash:Host 側
$ nvidia-smi 
Sun Jun 15 01:31:44 2025       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.57.08              Driver Version: 575.57.08      CUDA Version: 12.9     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 5060 Ti     On  |   00000000:01:00.0  On |                  N/A |
|  0%   57C    P0             28W /  180W |     816MiB /  16311MiB |      9%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

```
:::

# 3. lxd / lxc の準備

コンテナ名を適宜決めて、一時的なシェル変数に設定

```bash:Host 側
LXCNAME=jammy-base
```

## 3.1. lxd / lxc のインストール

今は lxd は snap 側で管理されているため、snap によるインストール＆初期設定。
lxd init での設定は、基本的にすべて default でも問題なし(好みで変更)

```bash: Host 側
sudo snap install lxd
sudo lxd init
```

コンテナの作成(初回はダウンロードで少し時間がかかります)

```bash: Host 側
sudo lxc launch ubuntu:22.04 $LXCNAME
```

## 3.2. lxc の設定

Host 側の UID/GID と共通化
(現在のアカウント以外と共通化する場合は適宜変更)

```bash: Host 側
sudo lxc config set $LXCNAME raw.idmap "both $(id -u) $(id -g)"
```

## 3.3. GUI / Audio の共有

GUI, Audio の作業ディレクトリを Host 側と bind して共有し、環境変数も設定

```bash: Host 側
sudo lxc config device add $LXCNAME audio disk source=/run/user/1000/pulse/native path=/tmp/.pulse-native
sudo lxc config device add $LXCNAME xorg disk source=/tmp/.X11-unix/X0 path=/tmp/.X11-unix/X0
sudo lxc config set $LXCNAME environment.DISPLAY :0
```

## 3.4. GPU へアクセスできるように設定

video グループの GID を gpu に割り当てて共有

```bash: Host 側
sudo lxc config device add $LXCNAME gpu gpu gid=`getent group video | cut -d: -f3`
sudo lxc config set $LXCNAME nvidia.runtime true
```

## 3.5. ディレクトリの共有(任意)

その他、Host 側とディレクトリを共有したい場合は適宜下記コマンドで追加
(e.g. Host 側 /home/user/Downloads, Guest 側 /home/ubuntu/Downloads を共有する場合)

```bash: Host 側
sudo lxc config device add $LXCNAME share disk source=${HOME}/Downloads path=/home/ubuntu/Downloads
```

## 3.6. lxc 内で docker を動かす設定(任意)

lxc 内で docker を動かしたい場合は下記のコマンドでネストを有効化

```
sudo lxc config set $LXCNAME security.nesting true
```

## 3.7. インスタンスの自動起動を off にする(任意)

host 起動時に、毎回インスタンスを起動させたくない場合は以下のコマンドで抑制
(起動させたい場合は `sudo lxc start $LXCNAME` による手動)

```
sudo lxc config set $LXCNAME boot.autostart=false
```

## 3.8. 設定の確認

以下で設定を確認できます。
both 1000 1000, audio, xorg, gpu など追加されていることが確認できます。

```bash: Host 側
sudo lxc config show $LXCNAME
```

# 4. コンテナ内環境構築

コンテナ内で作業するため、bash を実行
(ログアウトするまでroot権限なので注意)

```bash: Host 側
sudo lxc exec $LXCNAME /bin/bash
```

## 4.1. 基本パッケージ(日本語含む)のインストール

まずは最新の環境にまで upgrade

```bash: Guest 側
apt update && apt full-upgrade -y
```

基本的なパッケージのインストール

```bash: Guest 側
apt install -y x11-apps pulseaudio dbus-x11 language-pack-ja fonts-noto-cjk-extra task-japanese-gnome-desktop language-pack-gnome-ja-base language-pack-gnome-ja gnome-user-docs-ja gnome-control-center fonts-noto-color-emoji manpages-ja fcitx5-mozc ibus-mozc
```

サウンドの設定

```bash: Guest 側
sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf
```

日本語設定/ロケール設定

```bash: Guest 側
update-locale LANG=ja_JP.UTF-8
timedatectl set-timezone Asia/Tokyo
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
localectl set-x11-keymap jp jp106
source /etc/default/locale
dbus-uuidgen > /var/lib/dbus/machine-id
```

ubuntu ユーザーに切り替えて、ユーザー個別の設定

```bash: Guest 側
su - ubuntu
im-config -n fcitx5
source /etc/default/locale
```

下記コマンドで ~/.profile に追記

```bash: Guest 側
cat << 'EOF' >> ~/.profile

export PULSE_SERVER=unix:/tmp/.pulse-native

export LANG=ja_JP.UTF8
export GTK_IM_MODULE=fcitx5
export QT_IM_MODULE=fcitx5
export XMODIFIERS=@im=fcitx5
export DefaultIMModule=fcitx5
if [ \$SHLVL = 1 ] ; then
  (fcitx5 > /dev/null 2>&1 &)
  xset -r 49  > /dev/null 2>&1
fi
EOF
```

:::note

せっかくなので、ゲスト側で作業中というのがわかりやすいように、ゲストの `.bashrc` の下記行の `\[\033[01;32m\]\u@\h\` の`32`の数字を変えて、プロンプトを好みの色に変更しておく(例えば`32`から`33`にすると緑から黄色になります)。

```bash
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
```

:::

ここまでの作業を確実に反映させるためコンテナの再起動
(Host 側に戻ります)

```bash: Guest 側
sudo reboot
```

## 4.2. ssh の有効化

ホストからゲストに ssh でログインするための鍵を作成
(すべて未指定の改行のみでもOKですが、気になる方は適宜指定を)

```bash:Host 側
ssh-keygen -f ~/.ssh/${LXCNAME}
```

`3.5. ディレクトリの共有(任意)` を有効にしているなら、Downloads が Host と Guest 両方からアクセスできるようになっているため、ここに作成した公開鍵を一旦保存

```bash:Host 側
cp ~/.ssh/${LXCNAME} ~/Downloads
```

Guest 側に移行

```bash:Host 側
sudo lxc exec $LXCNAME /bin/bash
```

Guest 側に ssh をインストール

```bash:Guest 側
apt install ssh
```

鍵による認証を有効にするため `/etc/ssh/sshd_config` ファイル内の `PubkeyAuthentication` のコメントアウトを解除

```bash: Guest 側
nano /etc/ssh/sshd_config
```
`#PubkeyAuthentication yes`
　　　　　　↓
`PubkeyAuthentication yes`

Downloads に複製した公開鍵を、Guest 側の `authorized_keys` にコピー

```bash:Guest 側
cp /home/ubuntu/Downloads/*.pub /home/ubuntu/.ssh/authorized_keys
```

## 4.3. IP アドレスの固定

事前に lxdbr0 のホストアドレスを取得し、その範囲内でゲスト側のIPアドレスを設定していきます。

```bash: Host 側
LXCHOSTADDR=`ip a |grep lxdbr0 | grep inet | awk '{print $2}'`
LXCADDR=`echo $LXCHOSTADDR | sed 's|1/24|100|'`
echo $LXCHOSTADDR
echo $LXCADDR
```

ホストアドレスは `10.240.191.1/24` だったので、上記コマンドの場合、LXCADDR は `10.240.191.100` になります。

下記コマンドで IP アドレスを固定化し、再起動。

```bash: Host 側
sudo lxc network attach lxdbr0 ${LXCNAME} eth0 eth0
sudo lxc config device set ${LXCNAME} eth0 ipv4.address ${LXCADDR}
sudo lxc restart ${LXCNAME}
```

コンテナにアクセスしやすいように、固定化したIPアドレスを登録させておく

```bash: Host 側
echo "${LXCADDR} ${LXCNAME}" | sudo tee -a /etc/hosts > /dev/null
```

Host 側のユーザーで、ssh で Guest 側にアクセスする際の設定を行う。
~/.ssh/config をエディタで開き、下記を追記

```: Host 側 ~/.ssh/config の設定
Host jammy-base
    HostName jammy-base
    ForwardX11 yes
    User ubuntu
    IdentityFile ~/.ssh/jammy-base
```

ssh 接続テスト

```bash: Host 側
ssh $LXCNAME
```

# 5. ゲスト内に CUDA をインストール

## 5.1. ゲストからホストのGPUへアクセスできるか確認

:::note info

```
ubuntu@jammy-base:~$ nvidia-smi 
Sun Jun 15 01:57:56 2025       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.57.08              Driver Version: 575.57.08      CUDA Version: 12.9     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 5060 Ti     Off |   00000000:01:00.0  On |                  N/A |
|  0%   54C    P3             18W /  180W |     868MiB /  16311MiB |      9%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
                                                                                         
+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

```
:::

## 5.2. CUDA 12-9 をインストール

下記からの引用

https://developer.nvidia.com/cuda-downloads

```bash:Guest 側
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda-toolkit-12-9
```

インストール完了後パスを通す。

```bash:Guest 側
cat << 'EOF' >> ~/.profile
PATH=/usr/local/cuda/bin:$PATH
LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
EOF
```

:::note info

ログインしなおすなどして、上記環境変数を反映させる。
設定が適切であれば以下のようにバージョンの確認ができる。

```bash:Guest 側
ubuntu@jammy-base:~$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2025 NVIDIA Corporation
Built on Tue_May_27_02:21:03_PDT_2025
Cuda compilation tools, release 12.9, V12.9.86
Build cuda_12.9.r12.9/compiler.36037853_0
```
:::

# 6. サンプル実行

構築したゲスト環境で cuda-samples をビルドして実行してみる。

```bash:Guest 側
git clone https://github.com/NVIDIA/cuda-samples.git
cd cuda-samples
mkdir build && cd build
cmake ..
make -j 10
```

ビルドしたサンプルを実行してみる。

```bash:Guest 側
cd Samples/6_Performance/UnifiedMemoryPerf
./UnifiedMemoryPerf
```

:::note info

実際に実行したときの結果がこちら。Oculink なので、若干パフォーマンスが下がっていそうですが、PCIe 直結環境がないため比較できず。Oculink 採用の参考にしていただければ。

```
GPU Device 0: "Blackwell" with compute capability 12.0

Running ........................................................

Overall Time For matrixMultiplyPerf 

Printing Average of 20 measurements in (ms)
Size_KB  UMhint UMhntAs  UMeasy   0Copy MemCopy CpAsync CpHpglk CpPglAs
4         0.168   0.164   0.358   0.014   0.029   0.018   0.032   0.018
16        0.190   0.200   0.538   0.043   0.047   0.089   0.041   0.034
64        0.263   0.301   1.009   0.178   0.093   0.085   0.086   0.073
256       0.723   0.752   1.620   0.951   0.332   0.268   0.260   0.258
1024      2.249   2.025   2.998   9.376   1.687   1.663   1.120   1.137
4096      8.022   7.383  11.160  95.890   6.886   7.047   5.011   4.926
16384    34.911  32.620  47.920 952.183  30.725  31.063  26.371  26.344

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
```
:::

# 7. あとがき

環境が構築できたら、snapshot やコンテナの複製などで保持しておきましょう。

最近は目先の業務に追われ気味で、エンジニアとしての勉強がまったくできておらず(ﾉ∀`)
業界の問題点・課題なども見えてきましたが、一個人ではどうしようもないというのもわかっており、もどかしい今日この頃ですが、地道に積み重ねて貢献していけたらと思っております。