📑

Synology NAS DS218j に Docker を導入する

2023/12/17に公開

はじめに

この記事では、Synology NAS DS218j に Docker を導入した際の手順を紹介します。
この手順に従うことで、Docker の導入・起動に成功しますが、パッケージ更新が必要なイメージビルドやコンテナ内での操作があると失敗してしまいます。
これはコンテナ内部から外に向けてのネットワーク疎通がないためだと考えていますが、実際に原因を特定できておらず解決方法もわかっていないため、あくまでも参考程度に見ていただければと思います。

きっかけ

眠らせていたSynology NAS DS218j の存在を思い出し、何か面白い使い方できないかなと思って昨夜からごそごそ動き始めたのが事の始まりです。
その場の勢いで、(別にこれまでも構築したことは1度もないですが...)Ubuntuのミラーサーバを構築することに決めました。

https://louwrentius.com/how-to-setup-a-local-or-private-ubuntu-mirror.html

ミラーサーバーの構築方法について、上記の記事が良い感じにまとめられています。
いくつか構築方法があるようですが、容量の問題で Ubuntu の mirror script 実行は諦めました(NASの容量が2.4TBしかないのに、2.5TBぐらい必要となるらしい)。
そのため、今回は debmirror を利用したミラー作成を試してみることにしました。

しかし、ここで1つ問題になってくるのが DS218j に debmirror コマンドを導入できないことです。
Synolog NAS にはパッケージマネージャがなく、自由にパッケージを追加できません。
(厳密には、パッケージセンターで入手可能なパッケージを管理する synopkg コマンドが存在しています)

これを解決するために Docker を導入します。

パッケージマネージャの導入も可能

本記事の話題から逸れますが、パッケージを追加する方法として EntWare や Homebrew といったパッケージマネージャを導入・利用する方法もあります。

Docker の導入

実はパッケージセンターに「Container Manager」という名前で Docker が存在します。
しかし、そのパッケージが利用できるかは機種によります。

https://www.synology.com/ja-jp/dsm/packages/ContainerManager

さて、ここまで来るとお分かりになると思いますが、DS218j は「Container Manager」に対応していません。
この DS218j に Docker のバイナリをダウンロードして、手動でインストールしていくというのが今回の内容になります。

インストール手順はこちらを参考にしました。
https://inkblogdb.com/archive/synology/unsupport-docker

DS218j スペック

参考までに Docker 導入時のOS、ハードウェア情報を記載します。

  • DSMバージョン:DSM 7.1.1-42962 Update 1
  • 製品型番:DS218j
  • CPU: MARVELL Armada 385 88F6820
  • CPUコア: 2
  • メモリ: 512MB

手順

0. 前提

  • SSHサービスを有効化しておく
    • コントロールパネルの「端末とSNMP」を開き、「SSHサービスを有効化する」にチェックを入れる
  • 以降の作業は本的にSSHでNASに入り実行する
    • グループの作成、ユーザの追加だけは、コントロールパネルの「ユーザとグループ」を利用する

1. アーキテクチャの確認

バイナリをダウンロードするにあたり、まずはアーキテクチャを確認する必要があります。

joo@nas:~$ uname -m
armv7l

DS218j のアーキテクチャは「armv7l」でした。
初めて目にするアーキテクチャだったので調べてみたのですが、こちらはArmの32ビットアーキテクチャのようですね。

https://teratail.com/questions/190228

2. バイナリのダウンロード

以下のURLから最新のバイナリをダウンロードします。

https://download.docker.com/linux/static/stable/armhf/

「armv7l」というキーワードが見つからず最初混乱したのですが、どうやら「armhf」と利用できるバイナリは同じ(32bitだから...?)みたいです。

  • Docker のダウンロード
joo@nas:~$ curl https://download.docker.com/linux/static/stable/armhf/docker-24.0.7.tgz -o ./docker.gz
  • gzファイルを解凍
joo@nas:~$ tar xzvf docker.gz -C./
docker/
docker/docker-init
docker/containerd-shim-runc-v2
docker/ctr
docker/docker-proxy
docker/dockerd
docker/docker
docker/containerd
docker/runc

また、docker-compose のバイナリもダウンロードし実行権限を付与しておきます。

joo@nas:~$ curl -L https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-armv7 -o ./docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 54.1M  100 54.1M    0     0  4869k      0  0:00:11  0:00:11 --:--:-- 5217k
joo@nas:~$ chmod +x ./docker-compose

3. バイナリの配置

ダウンロードしたファイル群を配置します。

joo@nas:~$ sudo mv -f ./docker/* /usr/local/bin/
joo@nas:~$ sudo mv docker-compose /usr/local/bin/

4. デーモン構成ファイルの作成

/etc に docker ディレクトリを作成し、 daemon.json を作成します。

joo@nas:~$ sudo mkdir -p /etc/docker
joo@nas:~$ sudo vim /etc/docker/daemon.json

daemon.json には、以下の内容を記述します。

{
  "data-root": "/volume1/@docker/lib",
  "registry-mirrors" : [],
  "storage-driver" : "vfs",
  "bridge": "none"
}

ルートディレクトリを作成します。

joo@nas:~$ sudo mkdir -p /volume1/@docker/lib

5. Docker の起動と確認

以下のコマンドで Docker を立ち上げます。

joo@nas:~$ sudo dockerd &

Docker が起動したことを確認します。

joo@nas:~$ sudo docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

ちなみに、この時点では root 権限がないと docker コマンドの実行に失敗します。

joo@nas:~$ docker ps
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied

6. docker グループの追加

上記の通り、root 権限なしに docker コマンドを叩けません。
毎回 sudo をつけるのも煩わしいので、一般ユーザの常態でもコマンドを実行できるようにします。
まずは、docker グループを作成しユーザを追加します。

グループの追加

グループ作成&ユーザ追加は、Synology DiskStation Manager (DSM)から実施します。
DSMのコントロールパネルを開き、「ユーザとグループ」を選択します。その後、「グループ」のタブを選択し、「作成」ボタンを押します。
すると、画像のようにモーダルが表示されるので、「グループ名」に docker を記入します。

次にメンバーを追加していきます。
モーダルのタブから「メンバー」を選択すると、下記画像のように切り替わります。
ここには現存するユーザが一覧表示されます。追加したいユーザにチェックを付け保存します。

以上でグループ作成とユーザ追加が完了しました。
ここからはSSHでログインしているシェルに戻り進めます。

ちなみに、/etc/group を確認することで、docker グループが作成されそこにユーザ追加されていることがわかります。

joo@nas:~$ cat /etc/group
# 省略
docker:x:65536:joo
# 省略

動作確認

ここまで終えたら、一度ログアウトしてsshで入りなおします。
入りなおしたところで、5. で起動した docker のプロセスを終了させます。

joo@nas:~$ ps aux | grep docker
root     25333  0.2  6.4 805168 33176 ?        Sl   03:57   0:02 dockerd
root     25340  0.0  3.5 704832 18400 ?        Ssl  03:57   0:00 containerd --config /var/run/docker/containerd/containerd.toml
joo      26978  0.0  0.1   4860   992 pts/1    S+   04:17   0:00 grep --color=auto docke
joo@nas:~$ sudo kill -9 25333
joo@nas:~$ ps aux | grep docker
joo      26993  0.0  0.1   4860   992 pts/1    S+   04:17   0:00 grep --color=auto docke

その後、docker を立ち上げることで、root 権限なしにコマンドを実行できるようになります。

joo@nas:~$ sudo dockerd &
joo@nas:~$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

以上で Docker の導入ができました。

debmirror の実行はというと...

Docker を導入し終えて、本来やりたかったとである debmirror コマンドがたたけるイメージ作成に着手したのですが、Dockerfile のビルドに失敗してしまいます。
切り分けのため Ubuntu イメージにはいり手動で更新してみると、下記のように apt-get update で失敗しました。

joo@nas:~$ docker run -it -v /dev:/dev ubuntu /bin/bash
WARN[2023-12-16T05:19:40.021168601+09:00] seccomp is not enabled in your kernel, running container without default profile
time="2023-12-16T05:19:40.354955168+09:00" level=info msg="loading plugin \"io.containerd.internal.v1.shutdown\"..." runtime=io.containerd.runc.v2 type=io.containerd.internal.v1
time="2023-12-16T05:19:40.362689588+09:00" level=info msg="loading plugin \"io.containerd.ttrpc.v1.pause\"..." runtime=io.containerd.runc.v2 type=io.containerd.ttrpc.v1
time="2023-12-16T05:19:40.362918347+09:00" level=info msg="loading plugin \"io.containerd.event.v1.publisher\"..." runtime=io.containerd.runc.v2 type=io.containerd.event.v1
time="2023-12-16T05:19:40.363023026+09:00" level=info msg="loading plugin \"io.containerd.ttrpc.v1.task\"..." runtime=io.containerd.runc.v2 type=io.containerd.ttrpc.v1
root@eaeb73c0b621:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"
root@eaeb73c0b621:/# apt update -y
Ign:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
Ign:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease
Ign:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
Ign:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease
Ign:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
Ign:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease
Ign:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
Ign:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease
Ign:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
Ign:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease
Ign:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
Ign:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease
Err:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
  Temporary failure resolving 'ports.ubuntu.com'
Err:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease
  Temporary failure resolving 'ports.ubuntu.com'
Err:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
  Temporary failure resolving 'ports.ubuntu.com'
Err:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease
  Temporary failure resolving 'ports.ubuntu.com'
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://ports.ubuntu.com/ubuntu-ports/dists/jammy/InRelease  Temporary failure resolving 'ports.ubuntu.com'
W: Failed to fetch http://ports.ubuntu.com/ubuntu-ports/dists/jammy-updates/InRelease  Temporary failure resolving 'ports.ubuntu.com'
W: Failed to fetch http://ports.ubuntu.com/ubuntu-ports/dists/jammy-backports/InRelease  Temporary failure resolving 'ports.ubuntu.com'
W: Failed to fetch http://ports.ubuntu.com/ubuntu-ports/dists/jammy-security/InRelease  Temporary failure resolving 'ports.ubuntu.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.

だいぶ時間をかけてもわからなかったので、ここにきて原因の突き止めをあきらめました。
何か原因に心当たりある方がいたらぜひ教えてほしいです。

(...ping や dig が使えるイメージを探してきて、ネットワークの疎通性を確認できるともう少し切り分けできたのかも)

おわりに

最初からコンテナやVMが動くNAS(DS224+とか)がほしいですね。
次買い替えるときは、ちゃんと上位モデルを買います。

Discussion