dockerが不調なのでLXDに触れてみる

# 前置き
あるとき、友人A君が言いました。
「夏休みに身内でArkしたいんだけどさぁ、サーバー建てられねぇ？」
もちろん私は誇り高きインフラ園児にあ(6歳)なので、快く快諾しました。

その後、私はサーバーの稼働環境にDockerを選定し、そして友人A君にもLinuxについて~~布教~~知見を深めてもらうべく、SSHできる環境を整え、ある程度は自分で作業してもらうことにしました。

その試作として、以下のようなDockerfileを書きました。

::: note warn
以下のDockerfile及びdocker-composeは動きません！
:::

```dockerfile
FROM ubuntu:latest
RUN apt update && apt install lib32gcc-s1 libc6-i386 wget screen htop vim  -y
RUN mkdir /usr/steamcmdsrc
WORKDIR /root
RUN cd /root
RUN apt install openssh-server  software-properties-common -y 
RUN add-apt-repository multiverse
RUN dpkg --add-architecture i386
RUN apt update -y
RUN mkdir  /run/sshd
RUN apt install sudo -y
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
RUN echo "ark ALL=(ALL) ALL" | EDITOR='tee -a' visudo >/dev/null
ARG USERNAME=ark
ARG GROUPNAME=ark
ARG UID=1190
ARG GID=1190
RUN groupadd -g $GID $GROUPNAME
RUN useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
RUN echo "ark:password" | chpasswd
WORKDIR /home/$USERNAME/
RUN mkdir /home/$USERNAME/.ssh/ 
RUN touch /home/$USERNAME/.ssh/authorized_keys
RUN echo  "@ShutdownOnFailedCommand 1\n@NoPromptForPassword 1\nforce_install_dir /home/ark/arkdata\nlogin anonymous\n\napp_update 376030 validate\nquiti" > /home/ark/arkprofile.txt


#internalスクリプト
RUN echo '#!/bin/sh\n\
su - ark -c "screen -dmS arkserver bash -c '"'"'/home/ark/bootark.sh; exec bash'"'"'"\n\
/usr/sbin/sshd -D\n\
' > /root/boot.sh && chmod +x /root/boot.sh

#bootarkスクリプト
RUN echo "steamcmd +runscript /home/ark/arkprofile.txt\n\
cd /home/ark/arkdata/ShooterGame/Binaries/Linux/n\
./ShooterGameServer Gen2?Listen?SessionName=hogehogeServerPassword=piyppiyo?ServerAdminPassword=hugahuga -server -log -culture=ja\n\
exit\n" > /home/ark/bootark.sh

RUN chmod 755 /home/ark/bootark.sh
RUN chmod 755 /home/ark/arkprofile.txt

# suke公開鍵
RUN echo "ssh-rsa hogehoge"  >> /home/$USERNAME/.ssh/authorized_keys

RUN chmod 600 /home/$USERNAME/.ssh/authorized_keys
RUN chmod 700 /home/$USERNAME/.ssh
RUN chown -R ark:ark /home/$USERNAME/
ENTRYPOINT [ "/usr/sbin/sshd" ]
CMD [ "-D" ]
```

```docker
services:
  app:
    deploy:
    container_name: testarkserver
    tty: true
    build:
      dockerfile: ./docker/Dockerfile
    ports:
      - '18820:22' #ssh
      - '27015:27015/udp' 
      - '7778:7778/udp'
      - '7777:7777/udp'
      - '27020:27020'
    restart: always
    volumes:
      - ./arkdata/:/home/ark/arkdata

```

しばらくはこれで動く...と**皆が思っていました...**

# 実行環境
- OS Win11 23H2(ライセンスの範囲内での運用です)
- Dockerengine v24.0.7 + Dockerdesktop
- WSL2
```
PS C:\Users\user> wsl --version
WSL バージョン: 2.0.14.0
カーネル バージョン: 5.15.133.1-1
WSLg バージョン: 1.0.59
MSRDC バージョン: 1.2.4677
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22631.3880
```
- CPU 5950X
- RAM 64GB

# 発生した問題
- Ark Server(Shooter Game)が起動しない
    - どうやらロガーの起動で止まってるっぽい
    - 永続化せずに起動したところ正常に動いたのでマウントの問題だと思う
    - ログすら出力されず 権限とオーナーも書き換えても治らず
- UDPの挙動が不安定
    - Minecraft Bedrockのサーバーも微妙な動きだったのでおそらくUDPに問題がある？
    - Steamのサーバー一覧からは見えないもののArk本体からは入れた

他のユーザーが運用しているコンテナが止まるのは避けなくてはならず、また環境保持のためにも簡単にDockerはアップデートできず...

そのため、こうなればインフラごと変えちまえ！ということで今回使うコンテナインフラ自体を
Docker→LXD
に変更しようと思います。
LXDに切り替えるメリットは、

- 現状のアプローチでは１コンテナ１プロセスのベストプラクティスを満たせない
- systemtemdが使用できる
- "Dockerコンテナ内"の挙動ではなく実マシンに近い環境を再現できる
- Dockerに起因する不具合を回避できる
etc...

本記事では、その時に学んだLXDの操作や概念などを**個人的備忘録として**残しておこうと思います。

# 本編
### 環境解説
本番環境(WSL2)で作業する前に、練習として実マシンのAlpine linuxで作業しようと思います。
マシンが余っているためメインサーバーへの影響を考慮し空いている実マシンを使用しましたが、仮想マシンでも仕組み上は大丈夫です。

- OS Alpine linux
```
localhost:~$ uname -a
Linux localhost 6.6.36-0-lts #1-Alpine SMP PREEMPT_DYNAMIC Thu, 27 Jun 2024 19:18:37 +0000 x86_64 GNU/Linux

localhost:~$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Celeron(R) CPU G1610 @ 2.60GHz
以下略

localhost:~$ cat /proc/meminfo
MemTotal:        3892096 kB
MemFree:          373428 kB
MemAvailable:    2922588 kB
以下略
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654625/0e809ca2-396a-f280-e3aa-67cb350789a9.png)
稼働時はこのような感じでした。
本当に僅かですがswapを使用しているようです。
***
### コマンドのシンタックス（書き方について）
以下の記事を参考にさせていただき、これを基に本記事では流れを通して実際に使用したものを乗せていきます。

https://qiita.com/d-ebi/items/eb8f84f230029ef0e2c5


### 環境構築

以下のページを参考にしました。

https://lunar.computer/news/lxd-alpine/

インストール
```
sudo apk add lxd
```

サービスの有効化
```
sudo rc-update add lxd && sudo rc-service lxd start
```

LXDの初期化
```
sudo lxd init
```

これでAlpine linux上でLXDを利用する準備が整いました。
執筆時は以下の環境になりました。
```
localhost:~$ sudo lxc version
Client version: 5.0.3
Server version: 5.0.3
```
***
### テスト起動
とりあえずテストとして、慣れ親しんだAlpine...ではなく
ubuntuを起動してみようと思います。

まず最初に、イメージを落としてくる先である、リモートサーバーの一覧を調べます。

```
localhost:~$ sudo 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     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-minimal       | https://cloud-images.ubuntu.com/minimal/releases/ | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-minimal-daily | https://cloud-images.ubuntu.com/minimal/daily/    | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
```

今回はubuntu-dailyからイメージを落とそうと思います。
次に、リモートにあるイメージのリストを確認します。


```
localhost:~$ sudo lxc image list ubuntu-daily:
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|       ALIAS        | FINGERPRINT  | PUBLIC |                 DESCRIPTION                 | ARCHITECTURE |      TYPE       |    SIZE    |          UPLOAD DATE          |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
| b (5 more)         | 8d21d7ed8198 | yes    | ubuntu 18.04 LTS amd64 (daily) (20230607)   | x86_64       | VIRTUAL-MACHINE | 386.88MiB  | Jun 7, 2023 at 12:00am (UTC)  |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
| b (5 more)         | c533845b5db1 | yes    | ubuntu 18.04 LTS amd64 (daily) (20230607)   | x86_64       | CONTAINER       | 215.55MiB  | Jun 7, 2023 at 12:00am (UTC)  |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
中略
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | f9850847f203 | yes    | ubuntu 24.10 s390x (daily) (20240627)       | s390x        | VIRTUAL-MACHINE | 425.00MiB  | Jun 27, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fa4d65dd1de8 | yes    | ubuntu 20.04 LTS s390x (daily) (20240731)   | s390x        | CONTAINER       | 320.34MiB  | Jul 31, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fac65c4cf482 | yes    | ubuntu 24.10 ppc64el (daily) (20240622)     | ppc64le      | VIRTUAL-MACHINE | 461.38MiB  | Jun 22, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fc2c933dd7b0 | yes    | ubuntu 24.10 s390x (daily) (20240622)       | s390x        | CONTAINER       | 195.61MiB  | Jun 22, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fcee5129b17e | yes    | ubuntu 20.04 LTS amd64 (daily) (20240730)   | x86_64       | VIRTUAL-MACHINE | 597.75MiB  | Jul 30, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fd8f43d82fca | yes    | ubuntu 24.10 s390x (daily) (20240622)       | s390x        | CONTAINER       | 235.88MiB  | Jun 22, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | fe251f1b4c0e | yes    | ubuntu 22.04 LTS amd64 (daily) (20240726)   | x86_64       | VIRTUAL-MACHINE | 592.13MiB  | Jul 26, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | feed2703a239 | yes    | ubuntu 24.10 armhf (daily) (20240719)       | armv7l       | CONTAINER       | 191.19MiB  | Jul 19, 2024 at 12:00am (UTC) |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | ff5aeb6037a4 | yes    | ubuntu 16.04 LTS armhf (daily) (20210804)   | armv7l       | CONTAINER       | 151.50MiB  | Aug 4, 2021 at 12:00am (UTC)  |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
```
もしほかのホストを調べたい場合は、`ubuntu-daily`を調べたいホスト名にしてください

めちゃくちゃな量がありますね。
今回は以下のイメージを使用しようと思います。
```
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
|                    | f9b790da0c0b | yes    | ubuntu 22.04 LTS amd64 (daily) (20240802)   | x86_64       | CONTAINER       | 413.61MiB  | Aug 2, 2024 at 12:00am (UTC)  |
+--------------------+--------------+--------+---------------------------------------------+--------------+-----------------+------------+-------------------------------+
```
<br>
次に、このイメージをつかい実際にコンテナを立てていきます。
初回構築ではイメージのダウンロードから始まるため、比較的時間がかかります（当環境では1時間くらい）

```
localhost:~$ sudo lxc launch ubuntu-daily:f9b790da0c0b ubuntucontainer
Creating ubuntucontainer
Retrieving image: rootfs: 10% (318.57kB/s)
Starting ubuntucontainer
localhost:~$ sudo lxc list
+-----------------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
|      NAME       |  STATE  |         IPV4          |                     IPV6                      |   TYPE    | SNAPSHOTS |
+-----------------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| ubuntucontainer | RUNNING | 10.187.117.218 (eth0) | fd42:4466:ffff:ffff:ffff:ffff:fe3c:62b4 (eth0) | CONTAINER | 0         |
+-----------------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
```

``ubuntucontainer``という名前でコンテナを作成できました。
実際にコンテナ内に入ってみましょう。
```
localhost:~$ sudo lxc exec ubuntucontainer bash
root@ubuntucontainer:~# apt update
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
中略
Get:40 http://archive.ubuntu.com/ubuntu jammy-backports/multiverse amd64 c-n-f Metadata [116 B]
Fetched 33.1 MB in 7s (4431 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
10 packages can be upgraded. Run 'apt list --upgradable' to see them.
root@ubuntucontainer:~# apt install openssh-server screen vim
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
screen is already the newest version (4.9.0-1).
screen set to manually installed.
openssh-server is already the newest version (1:8.9p1-3ubuntu0.10).
vim is already the newest version (2:8.2.3995-1ubuntu2.17).
vim set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 10 not upgraded.
root@ubuntucontainer:~#

```
vimもopenssh-serverも入っているのは想定していませんでしたが、いつも通りのubuntuですね。
今回の機能の目玉である、Systemtemdの呼び出しを試してみます。
```
root@ubuntucontainer:~# ls
snap
root@ubuntucontainer:~# systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2024-08-09 16:41:27 UTC; 16min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 324 (sshd)
      Tasks: 1 (limit: 4536)
     Memory: 1.7M
        CPU: 28ms
     CGroup: /system.slice/ssh.service
             └─324 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Aug 09 16:41:27 ubuntucontainer systemd[1]: Starting OpenBSD Secure Shell server...
Aug 09 16:41:27 ubuntucontainer sshd[324]: Server listening on 0.0.0.0 port 22.
Aug 09 16:41:27 ubuntucontainer sshd[324]: Server listening on :: port 22.
Aug 09 16:41:27 ubuntucontainer systemd[1]: Started OpenBSD Secure Shell server.
root@ubuntucontainer:~# systemctl restart sshd
root@ubuntucontainer:~# systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2024-08-09 16:58:02 UTC; 1s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 1495 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 1496 (sshd)
      Tasks: 1 (limit: 4536)
     Memory: 1.7M
        CPU: 26ms
     CGroup: /system.slice/ssh.service
             └─1496 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Aug 09 16:58:02 ubuntucontainer systemd[1]: Starting OpenBSD Secure Shell server...
Aug 09 16:58:02 ubuntucontainer sshd[1496]: Server listening on 0.0.0.0 port 22.
Aug 09 16:58:02 ubuntucontainer sshd[1496]: Server listening on :: port 22.
Aug 09 16:58:02 ubuntucontainer systemd[1]: Started OpenBSD Secure Shell server.
root@ubuntucontainer:~# systemctl enable sshd
Failed to enable unit: Refusing to operate on alias name or linked unit file: sshd.service
root@ubuntucontainer:~# systemctl enable ssh
Synchronizing state of ssh.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable ssh
root@ubuntucontainer:~#
```
いい感じに動いていますね。
### コンテナ管理
とりあえずubuntuは起動できたので、インスタンスの管理について学んでみます

#### インスタンス一覧確認
```
localhost:~$ sudo lxc list
```
インスタンス削除
``` 
localhost:~$ sudo lxc rm <コンテナ名>
```

インスタンス停止
```
sudo lxc stop <コンテナ名>
```

インスタンス起動
```
sudo lxc start <コンテナ名>
```

他にも``restart``や``pause``,``rename``
などがありますが、
```
sudo lxc help
```
でほぼ確認できるので、残りのコマンドは割愛します。

***
### まとめ
これでとりあえず環境構築してリモートからイメージをダウンロードし、コンテナを起動するところまではたどり着きました。
見る限り普通のubuntuとして使えそうなので、あとはこのままtailscaleを入れてグローバルにポートを公開せずにサーバにするもよし、ポートマッピングを学びホストのポートにつなげるもよし、macvlanやipvlanでLANに値を下ろすもよし、煮ても焼いても美味しい状態となりました。

最後に、LXDにはまだまだSnapshotなどの面白い機能がたくさんあります。
あくまで個人の備忘録程度なので深くは触れませんが、非常に面白いのでもし興味が湧くようであればぜひ学習してみてください。

参考にさせていだだいた記事

https://qiita.com/gounx2/items/39181e69e7f72316d5f2