CentOS 7でLXDを動かしてみる

## はじめに
LXDはLinuxのシステムコンテナの１つです。LXDはCanonicalが主導しているコンテナ技術であるため、Ubuntuでは、標準で利用することができます。（Ubuntu 16.04 LTSおよびそれ以降のサーバ向けディストリビューションでは、標準でインストールされています）

LXDは非常に便利ではあるのですが、これまでCentOSでLXDを動かすには色々と手間がかかりました。しかし最近では簡単にインストールできるようになり、CentOSでもLXDを気軽に動かせるようになりました。

※以下の作業は全てrootで行います。

## 1.Snapのインストール
CentOSでLXDを利用するには、Snapを使うのが簡単です。
Snapは、ディストリビューションに依存しないLinux向けのパッケージマネージャーです。

```
# yum update
# yum install yum-plugin-copr epel-release
# yum copr enable ngompa/snapcore-el7
# yum install snapd bridge-utils
# systemctl enable --now snapd.socket
```
## 2.カーネル周りの設定
### grubへの設定追加
grubbyコマンドで、grubへの設定追加を行います。

```
# grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
# grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
```

上記コマンドを実行すると、次の通りgrub2.cfgファイルが更新されます。

```
# cat /etc/grub2.cfg  |grep "namespace"
	linux16 /boot/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=UUID=180160de-303c-443b-9378-371aa37eb551 ro crashkernel=auto rhgb quiet LANG=ja_JP.UTF-8 user_namespace.enable=1 namespace.unpriv_enable=1
```


### /etc/sysctl.confへの設定追加
sysctl.confを開き、次の通りカーネルパラメータを追加して保存します。

```
user.max_user_namespaces = 3883
fs.inotify.max_queued_events = 1048576
fs.inotify.max_user_instances = 1048576
fs.inotify.max_user_watches = 1048576
vm.max_map_count = 262144
net.ipv4.ip_forward = 1
```

### /etc/security/limits.conf への設定追加
limits.confを開き、次の通り設定を追加して保存します。

```
*               soft    nofile          1048576
*               hard    nofile          1048576
root            soft    nofile          1048576
root            hard    nofile          1048576
*               soft    memlock         unlimited
*               hard    memlock         unlimited
```

### OS再起動
ここまでの状態で、一旦CentOSを再起動します。

``` 
# reboot
```

## LXDのインストール
snapコマンドでLXDをインストールします

```
snap install lxd
```

## LXDの初期設定
LXDを初期設定します。LXDを標準で利用可能なディストリビューション（Ubuntu等）と手順は同様です。
なお、環境や運用方法等にあわせ、設定は適宜調整します。

```
# lxd init
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 (btrfs, ceph, dir, lvm) [default=btrfs]: dir
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]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
Would you like LXD 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]: 
```
## コンテナの作成と起動
ｌｘｃコマンドでコンテナを作成してみます。以下はUbuntu 18.04コンテナをubuntu-testという名前で作成する場合の例です。
この手順も、LXDを標準で利用可能なディストリビューション（Ubuntu等）と同様です。

```
# lxc launch ubuntu:18.04 ubuntu-test
```

なお、コンテナ作成中に次のようなエラーが発生した場合はgrubやsysctl.confへの設定追加を忘れていないか確認してください。

```
# lxc launch ubuntu:18.04 ubuntu-test
Creating ubuntu-test
Starting ubuntu-test
Error: Failed to run: /snap/lxd/current/bin/lxd forkstart ubuntu-test /var/snap/lxd/common/lxd/containers /var/snap/lxd/common/lxd/logs/ubuntu-test/lxc.conf:
Try `lxc info --show-log local:ubuntu-test` for more info

# lxc info --show-log local:ubuntu-test
Name: ubuntu-test
Location: none
Remote: unix://
Architecture: x86_64
Created: 2018/11/23 07:24 UTC
Status: Stopped
Type: persistent
Profiles: default

Log:

lxc ubuntu-test 20181123072432.460 ERROR    start - start.c:lxc_spawn:1650 - Invalid argument - Failed to clone a new set of namespaces
lxc ubuntu-test 20181123072432.520 WARN     network - network.c:lxc_delete_network_priv:2597 - Invalid argument - Failed to remove interface "vethJMVHJB" from "lxdbr0"
lxc ubuntu-test 20181123072432.520 ERROR    start - start.c:__lxc_start:1910 - Failed to spawn container "ubuntu-test"
lxc ubuntu-test 20181123072432.520 ERROR    conf - conf.c:userns_exec_1:4333 - Failed to clone process in new user namespace
lxc ubuntu-test 20181123072432.520 WARN     cgfsng - cgroups/cgfsng.c:cgfsng_destroy:1119 - Failed to destroy cgroups
lxc ubuntu-test 20181123072432.521 ERROR    lxccontainer - lxccontainer.c:wait_on_daemonized_start:840 - Received container state "ABORTING" instead of "RUNNING"
lxc 20181123072432.521 WARN     commands - commands.c:lxc_cmd_rsp_recv:130 - Connection reset by peer - Failed to receive response for command "get_state"
```

## コンテナの確認
lxc listを実行すると、作成済みのコンテナを一覧で確認することができます。

```
# lxc list
+-------------+---------+----------------------+------+------------+-----------+
|    NAME     |  STATE  |         IPV4         | IPV6 |    TYPE    | SNAPSHOTS |
+-------------+---------+----------------------+------+------------+-----------+
| ubuntu-test | RUNNING | 10.153.159.19 (eth0) |      | PERSISTENT |           |
+-------------+---------+----------------------+------+------------+-----------+

```

## コンテナへ入る（コンテナ上のシェルを利用する）
lxc exec <コンテナ名> /bin/bashを実行すると、指定されたコンテナへ入る（コンテナ上のシェルを利用する）ことができます。
uname -aを実行すると、Ubuntu 18.04 LTSにしてはカーネルのバージョンがやけに古いなというところで、CentOS 7上でUbuntu 18.04 LTSコンテナが動いていると実感するでしょう（笑）

```
# lxc exec ubuntu-test /bin/bash

# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS"

# uname -a
Linux ubuntu-test 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
```
　　　
## 参考
- LXD on Centos 7
 - https://discuss.linuxcontainers.org/t/lxd-on-centos-7/1250
- lxc/lxd Production setup
    -  https://github.com/lxc/lxd/blob/master/doc/production-setup.md
- LXDを本番導入するときに気をつけるべき事
    - https://kurochan-note.hatenablog.jp/entry/2017/01/31/190200