Raspberry Pi 2 に snap版 LXD をインストールする

# はじめに

Linuxの検証環境をつくりたいと思い、手元に余っていた RaspberryPi2 に LXD をインストールしてみた。


# 環境

+ Raspberry Pi 2 Model B V1.1 
+ Raspberry Pi OS Lite(2021-05-07-raspios-buster-armhf-lite.img)

```shell
root@localhost:~#
root@localhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster
root@localhost:~#
```

# インストール

## 1. Raspberry Pi OS をインストールする。

## 2. `raspi-config` で必要な設定をする。

## 3. ブリッジインターフェース `br0` を作る。 

## 4. パッケージインストール  

パッケージの依存関係があるようで、`core` → `lxd` の順でインストールする。
インストール完了後はいったん再起動する。

```shell
root@localhost:~#
root@localhost:~# apt install snapd
root@localhost:~#
root@localhost:~# snap install core
root@localhost:~#
root@localhost:~# snap install lxd
root@localhost:~#
root@localhost:~# snap list
Name    Version   Rev    Tracking       Publisher   Notes
core    16-2.52   11802  latest/stable  canonical?  core
core20  20210928  1170   latest/stable  canonical?  base
lxd     4.19      21622  latest/stable  canonical?  -
root@localhost:~#
root@localhost:~# reboot
　　：
＜再起動＞
　　：
root@localhost:~#
root@localhost:~# lxd version
4.19
root@localhost:~#
root@localhost:~# lxc version
Client version: 4.19
Server version: 4.19
root@localhost:~#
```

## 5. 初期設定をする  

(1) ストレージは `dir` にする。
(2) ローカルブリッジは作成せずに `br0` を割り当てる

```shell
root@localhost:~#
root@localhost:~# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (dir, lvm, ceph, btrfs) [default=btrfs]: dir <---(1)
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]: no <---(2)
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes <---(2)
Name of the existing bridge or host interface: br0 <---(2)
Would you like the LXD server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
config: {}
networks: []
storage_pools:
- config: {}
  description: ""
  name: default
  driver: dir
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      nictype: bridged
      parent: br0
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: default
projects: []
cluster: null

root@localhost:~#
```

## 6. 設定確認

###  6-1. ネットワーク関係

本記事の構成では、OS側でブリッジインターフェース `br0` を作成し LXD では管理しないことになっています。

```shell
root@localhost:~#
root@localhost:~# lxc network list
+------+----------+---------+------+------+-------------+---------+
| NAME |   TYPE   | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY |
+------+----------+---------+------+------+-------------+---------+
| br0  | bridge   | NO      |      |      |             | 1       |
+------+----------+---------+------+------+-------------+---------+
| eth0 | physical | NO      |      |      |             | 0       |
+------+----------+---------+------+------+-------------+---------+
root@localhost:~#
root@localhost:~# lxc network show br0
config: {}
description: ""
name: br0
type: bridge
used_by:
- /1.0/profiles/default
managed: false
status: ""
locations: []
root@localhost:~#
```

###  6-2. ストレージ関係

```shell
root@localhost:~#
root@localhost:~# lxc storage list
+---------+--------+------------------------------------------------+-------------+---------+
|  NAME   | DRIVER |                     SOURCE                     | DESCRIPTION | USED BY |
+---------+--------+------------------------------------------------+-------------+---------+
| default | dir    | /var/snap/lxd/common/lxd/storage-pools/default |             | 1       |
+---------+--------+------------------------------------------------+-------------+---------+
root@localhost:~#
```

###  6-3. プロファイル関係

```shell
root@localhost:~#
root@localhost:~# lxc profile list
+---------+---------------------+---------+
|  NAME   |     DESCRIPTION     | USED BY |
+---------+---------------------+---------+
| default | Default LXD profile | 0       |
+---------+---------------------+---------+
root@localhost:~#
root@localhost:~# lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: br0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: default
used_by: []
root@localhost:~#
```


###  6-4. リモート関係

```shell
root@localhost:~#
root@localhost:~# lxc remote list
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
|      NAME       |                   URL                    |   PROTOCOL    |  AUTH TYPE  | PUBLIC | STATIC | GLOBAL |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| images          | https://images.linuxcontainers.org       | simplestreams | none        | YES    | NO     | NO     |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| local (current) | unix://                                  | lxd           | file access | NO     | YES    | NO     |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases | simplestreams | none        | YES    | YES    | NO     |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily    | simplestreams | none        | YES    | YES    | NO     |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
root@localhost:~#
```

## 7. コンテナを操作する

### 7-1. コンテナ作って起動する

コンテナのイメージとして使えるのは `lxc image list images:` コマンドか [Image server for LXC and LXD](https://uk.images.linuxcontainers.org/) で確認できる。

RaspberryPiで使えるのは、Architecture が `armhf(armv7l)` のイメージのみ。 
`lxc image list images: armhf`コマンドで確認できる。

コンテナが起動したら `lxc exec [コンテナ名] -- /bin/bash` でコンテナにログインできる。

```shell
root@localhost:~#
root@localhost:~# lxc launch c1 images:ubuntu/20.04
root@localhost:~#
root@localhost:~#
root@localhost:~# lxc exec c1  -- /bin/bash
root@c1 :~#
root@c1 :~#
root@c1 :~# exit
root@localhost:~#
```

### 7-2. コンテナ一覧

ブリッジインターフェース `br0` が適切に設定され、Raspberry Pi 2 が接続されている物理ネットワークで DHCPサーバー が動いていれば、自動でIPアドレスが割り当てられるはずです。

```shell
root@localhost:~#
root@localhost:~# lxc list
+------+---------+----------------------+------------------------------------------+-----------+-----------+
| NAME |  STATE  |         IPV4         |                   IPV6                   |   TYPE    | SNAPSHOTS |
+------+---------+----------------------+------------------------------------------+-----------+-----------+
| c1   | RUNNING | 192.168.3.170 (eth0) | 240f:30:d120:1:216:3eff:febf:ce7c (eth0) | CONTAINER | 0         |
+------+---------+----------------------+------------------------------------------+-----------+-----------+
root@localhost:~#
```

### 7-1. コンテナを停止して削除する

```shell
root@localhost:~#
root@localhost:~# lxc stop c1
root@localhost:~#
root@localhost:~# lxc list
+------+---------+------+------+-----------+-----------+
| NAME |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+------+------+-----------+-----------+
| c1   | STOPPED |      |      | CONTAINER | 0         |
+------+---------+------+------+-----------+-----------+
root@localhost:~#
root@localhost:~# lxc delete c1
root@localhost:~#
root@localhost:~# lxc list
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
root@localhost:~#
```



# 補足

## 補足1) `ERROR: ld.so: object ～` への対処

`lxc`コマンドを実行するたびに `ERROR: ld.so: object ～` が出る。

```shell
root@localhost:~# 
root@localhost:~# lxc version
ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: obj
  :
```


この場合は、`/etc/ld.so.preload` に記述されている1行をコメントアウトするとエラーが出なくなる。
※この方法が適切なのかどうかはわからない※


```shell
root@localhost:~# 
root@localhost:~# vi /etc/ld.so.preload
/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so
　↓
#/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so
root@localhost:~# 
```