Linux From Scratch に Docker Engine を導入

### はじめに
[Linux From Scratch](http://www.linuxfromscratch.org/index.html) に基づいて構築した手作りの Linux OS 内に Docker Engine を導入します。Linux From Scratch というものが、そもそもソースコードを使って一から作り上げていくシステムであるため、Docker も一から作り上げていくしかありません。この目的は何よりも Docker を理解することです。Docker の実用を目指すものではありません。

なお本文は Linux From Scratch に基づいた Linux OS を用いるため、カーネルソースの再ビルドという大きな作業が含まれます。Linux From Scratch を使うつもりのない方には、無縁の話に見えるかもしれません。ただしカーネルソースのビルド以降では、Docker バイナリを導入して環境設定を行う手順を示しています。主要 Linux ディストリビューションでは Docker がパッケージ提供されていると思いますが、そうでないディストリビューションをお使いの方は、Docker バイナリを用いることになるため、本文に示す手順が参考になるのではないかと思っています。

### 前提
Docker Engine をソースコードからビルドするためには、Docker そのものが必要になります。したがってまずは、公式に提供されている Docker Engine のバイナリをインストールすることから始めます。

ソースコードからのビルドにこだわる Linux From Scratch の流儀に従うのであれば、次に Docker ソースコードを使ってビルドすることになります。ただし Docker Engine バイナリの動作環境を作り出すだけでも、ひと苦労があります。さらにその環境が出来てしまえば Docker が動作するわけですから、そこで目的は一応達成していると見ることもできます。本文では、Docker バイナリを使った環境を構築するところまでの説明とします。

また本質的ではありませんが個人環境の都合により、すべての手順を VMware Workstation 上に構築した Linux From Scratch システム上で行うものとします。この理由は、ただ単に自由になる Linux マシンがなかったからです。VMware 仮想イメージに関する固有な情報は含まれませんので、純粋な Linux OS 上での処理操作と思って頂いて構いません。

PCおよび各ソフトウェアは、以下を利用します：

|項目          |内容          |
|:-------------|:-------------|
|ノートPC|Windows 7、64bit、amd、メモリ4GB （わりと貧弱）|
|VMware Workstation|VMware Workstaion 10.0.7 build-2844087 （結構古い）|
|[Linux From Scratch](http://www.linuxfromscratch.org/lfs/view/systemd/)|最新 SVN systemd 版 SVN-20200528 （linux-5.6.15、gcc-10.1.0、systemd-245）、VMware 上の仮想イメージとして構築。64bit、メモリ1.5GB|
|[Beyond Linux From Scratch](http://www.linuxfromscratch.org/blfs/view/systemd/index.html)|上記 SVN-20200528 に、種々ツール類をインストール （主要ツールについて、以降の手順にて説明）|
|[Docker](https://www.docker.com)|最新 Docker Engine バイナリ: docker-19.03.10|

### 手順
#### 1. Linux カーネルの再ビルド
##### 1.1. カーネル再ビルドの概略
Linux From Scratch を特に何も考えずに構築した場合、Docker 環境向けの Linux カーネル設定が十分になっていないはずです。カーネルソースのデフォルト設定では、ビルトインまたはモジュールビルド設定になっていないものがあり、しかも Docker 環境向けに必要となるものが多々あるからです。

Linux カーネルを再ビルドするには、Linux From Scratch を構築した際の「ホストシステム」を再度用いることになります。つまりもう一度「ホストシステム」からログインして、`chroot` コマンドによって Linux From Scratch 環境内の Linux カーネルを再ビルドするものです。

Linux カーネルを再ビルドする方法は、確かに当初の「ホストシステム」を使うというものなのですが、はたして実際にその「ホストシステム」を、簡単に用意できるかどうか、再び必要になるとは思いもよらず、もう捨ててしまっているかもしれません。

このテーマはわりと現実的ではありながら、結構面倒なものです。ひょっとすると初めから Linux From Scratch を作り直すことの方が、一番の近道になるかもしれません。ここでは Docker 環境を構築することに比重を置くため、カーネル再ビルドの細かな情報は示しません。以下では再ビルド最中の、カーネルオプション設定メニューに焦点を当てて説明します。

##### 1.2. 必要なカーネルオプションの確認
Docker 公式の github に、必要となるカーネル設定を確認するスクリプトがあります。[check-config.sh](https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh) というものです。これをダウンロードして実行します。

```shell
# wget https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh
# sh ./check-config.sh
```

この出力はおよそ以下のようになります。

```
warning: /proc/config.gz does not exist, searching other paths for kernel config ...
info: reading kernel config from /boot/config-5.6.15 ...

Generally Necessary:
- cgroup hierarchy: nonexistent??
    (see https://github.com/tianon/cgroupfs-mount)
- CONFIG_NAMESPACES: enabled
- CONFIG_NET_NS: enabled
- CONFIG_PID_NS: enabled
- CONFIG_IPC_NS: enabled
- CONFIG_UTS_NS: enabled
- CONFIG_CGROUPS: enabled
- CONFIG_CGROUP_CPUACCT: enabled
- CONFIG_CGROUP_DEVICE: missing
- CONFIG_CGROUP_FREEZER: enabled
- CONFIG_CGROUP_SCHED: enabled
- CONFIG_CPUSETS: enabled
- CONFIG_MEMCG: missing
- CONFIG_KEYS: enabled
- CONFIG_VETH: missing
- CONFIG_BRIDGE: missing
- CONFIG_BRIDGE_NETFILTER: missing
- CONFIG_NF_NAT_IPV4: missing
- CONFIG_IP_NF_FILTER: enabled
- CONFIG_IP_NF_TARGET_MASQUERADE: missing
- CONFIG_NETFILTER_XT_MATCH_ADDRTYPE: missing
- CONFIG_NETFILTER_XT_MATCH_CONNTRACK: enabled
- CONFIG_NETFILTER_XT_MATCH_IPVS: missing
- CONFIG_IP_NF_NAT: missing
- CONFIG_NF_NAT: enabled
- CONFIG_NF_NAT_NEEDED: missing
- CONFIG_POSIX_MQUEUE: enabled

Optional Features:
- CONFIG_USER_NS: missing
- CONFIG_SECCOMP: enabled

(以下略)
```

ここに示される `Generally Necessary`（全般的に必須）の配下に示されるカーネルオプションが、Docker 環境において必要になります。`enabled` であれば現状有効であり、`missing` であれば、該当するカーネルモジュールが存在しないことを意味します。ちなみに Linux From Scratch 構築での Linux カーネルを、デフォルト設定にまかせてビルドしていた場合、この `missing` がいくつも並ぶことになるはずです。`missing` が存在するということは、一部の例外を除き、Docker を動作させることができません。

`Optional Features` の配下に示されるカーネルオプションは、文字通りオプション的なものであり、必要に応じてビルド設定するものです。今後、必要に応じてビルドすることにしましょう。

なお `Generally Necessary` の次行に、上では `- cgroup hierarchy: nonexistent??` と示されています。これは cgroup マウントが存在しないか、あるいは適切なマウントになっていないことを意味します。この後に cgroup マウント設定をおこなうと、この表示は以下のように変わります。このような出力結果となるように、これより順に作業を進めていきます。

```terminal
Generally Necessary:
- cgroup hierarchy: properly mounted [/sys/fs/cgroup]
```

##### 1.3. カーネルオプションの再設定
Linux カーネルを再ビルドする処理を行います。Linux From Scratch ブックの [Linux カーネルのビルド](http://www.linuxfromscratch.org/lfs/view/systemd/chapter08/kernel.html) をもう一度実施するということです。そしてその手順の最中、`make menuconfig` を実行した際のオプション設定メニューから、以降に示す必要オプションを有効にして Linux カーネルインストールまで行います。

以下は筆者が行ったカーネル設定です。最低でもこれらを設定しないと Docker 環境は動作しません。試行錯誤しながら進めてきた経緯があるため、誤りや不足があるかもしれません。気づき次第、加筆修正していこうと思います。

```terminal
 <カーネル設定項目>                                                       <オプション名>
     General setup  --->
       [*] Control Group support  --->                                  CONFIG_CGROUPS
       [*]   Memory controller (NEW)                                    CONFIG_MEMCG
       [*]     Swap controller (NEW)                                    CONFIG_MEMCG_SWAP
       [*]       Swap controller enabled by default (NEW)               CONFIG_MEMCG_SWAP_ENABLED
       [*]   CPU controller  --->                                       
       [*]     Group scheduling for SCHED_OTHER                         CONFIG_CGROUP_SCHED
       [*]       CPU bandwidth provisioning for FAIR_GROUP_SCHED        CONFIG_CFS_BANDWIDTH
       [*]   IO controller (NEW)                                        CONFIG_BLK_CGROUP
       [*]   PIDs controller (NEW)                                      CONFIG_CGROUP_PIDS
       [*]   Device controller (NEW)                                    CONFIG_CGROUP_DEVICE
 [*] Networking support  --->                                           CONFIG_NET
       Networking options  --->
       [*] Network packet filtering framework (Netfilter)  --->         CONFIG_NETFILTER
       [*]   Advanced netfilter configuration                           CONFIG_NETFILTER_ADVANCED
       <M>     Bridged IP/ARP packets filtering (NEW)                   CONFIG_BRIDGE_NETFILTER
             Core Netfilter Configuration  --->
                 <M> LOG target support                                 CONFIG_NETFILTER_XT_TARGET_LOG
                 *** Xtables matches ***
                 <M>   "addrtype" address type match support            CONFIG_NETFILTER_XT_MATCH_ADDRTYPE
             IP: Netfilter Configuration  --->
                 <*>   Packet filtering                                 CONFIG_IP_NF_FILTER
                 <M>   iptables NAT support                             CONFIG_IP_NF_NAT
                 <M>     MASQUERADE target support (NEW)                CONFIG_IP_NF_TARGET_MASQUERADE
       <M> 802.1d Ethernet Bridging                                     CONFIG_BRIDGE
   Device Drivers  --->
     [*] Network device support  --->                                   
     [*]   Network core driver support                                  CONFIG_NET_CORE
         <*>     Virtual ethernet pair device                           CONFIG_VETH
   File systems  --->
     <*> Overlay filesystem support                                     CONFIG_OVERLAY_FS
```
(Linux-5.6.15 カーネル設定メニュー)

なおビルトインする設定「`*`」と、モジュールビルドする設定「`M`」は、あまり気にしていません。ビルドインできるものはできるだけ「`*`」を選び、それができないものは「`M`」にしています。

##### 1.4. カーネルオプションの再確認
Linux カーネルビルドを終えたら、この新しい Linux カーネルに基づくシステムを起動し直します。そしてもう一度、前述の `check-config.sh` を実行してみます。出力結果の多くが `missing` でなく `enabled` になっているはずです。

#### 2. ツール類導入
そもそも Docker バイナリを導入するためのシステム要件は、公式ドキュメント [Install Docker Engine from binaries](https://docs.docker.com/engine/install/binaries/) の Prerequisites の項に説明されています。以下、それを簡易に訳して示します。

* 64ビット
* Linux カーネル 3.10 以降
* iptables 1.4 以降
* git 1.7 以降
* procps パッケージの ps
* xzutils 4.9 以降
* 適正にマウントされた cgroup 階層

Linux From Scratch により構築したばかりのシステムでも、すでに procps、xz は導入されています。64ビットやカーネル 3.10以降といったものは、それを選ぶしかありません。ここで必要となるのは git と iptables です。cgroup階層は大きなテーマですので後述します。

##### 2.1. make-ca など
`git` と `iptables` のインストールに取り掛かる前に、おそらく必須であろう `make-ca` を導入します。上に示したシステム要件では、あまりにも当たり前すぎて明記されていないのかもしれません。すべてを一から作り出す Linux From Scratch にとって、自分でビルドしてインストールしない限り、勝手に入ってくれるソフトウェアは一つもないということです。

`make-ca` を入れるためには `p11-kit` が必須、また `make-ca` インストール作業時に `wget` が必要となります。`wget` は何かにつけ利用していくものですから、ここで導入します。`make-ca`、`p11-kit`、`wget` はいずれも [Beyond Linux From Scratch](http://www.linuxfromscratch.org/blfs/view/systemd/index.html) の各項に示されているインストール手順に従って導入します。

##### 2.2. git
[Beyond Linux From Scratch](http://www.linuxfromscratch.org/blfs/view/systemd/index.html) の [git](http://www.linuxfromscratch.org/blfs/view/systemd/general/git.html)  のページに従ってインストールします。依存パッケージは [cURL](http://www.linuxfromscratch.org/blfs/view/systemd/basicnet/curl.html) くらいで十分でしょう。バージョンは本文執筆時点最新の `git-2.27.0` です。

##### 2.3. iptables
[Beyond Linux From Scratch](http://www.linuxfromscratch.org/blfs/view/systemd/index.html) の [iptables](http://www.linuxfromscratch.org/blfs/view/systemd/postlfs/iptables.html)  のページに従ってインストールします。依存パッケージは（面倒なので）特に入れません。バージョンは本文執筆時点最新の `iptables-1.8.4` です。

iptables の設定ファイル `/etc/systemd/scripts/iptables` は、上記ページ内の Personal Firewall の項に示される設定をそのまま使います。必要なときに設定を加えていきます。

#### 3. Docker バイナリ類の入手、インストール
##### 3.1. Docker バイナリの入手、インストール
Docker ドキュメントの [Install static binaries](https://docs.docker.com/engine/install/binaries/) ページに、バイナリのダウンロード URL https://download.docker.com/linux/static/stable/ が示されています。アーキテクチャー別のサブディレクトリが用意されているので、ここでは x86_64 配下の [docker-19.03.10.tgz](https://download.docker.com/linux/static/stable/x86_64/docker-19.03.10.tgz) をダウンロードします。以降の操作はすべて `root` ユーザーになって行います。（参考： 公式ドキュメント [Install static binaries](https://docs.docker.com/engine/install/binaries/#install-static-binaries)）


```shell
# wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.10.tgz
```

なお、この tarball は `docker` というディレクトリ内にバイナリモジュールを含めてアーカイブされています。

```shell
# tar tf docker-19.03.10.tgz
docker/
docker/ctr
docker/docker
docker/containerd
docker/docker-proxy
docker/runc
docker/docker-init
docker/containerd-shim
docker/dockerd
```

そこで tarball を伸張（解凍）した上で、以下のように `/usr/bin` にインストールすることにします。（参考： 公式ドキュメント [Install static binaries](https://docs.docker.com/engine/install/binaries/#install-static-binaries)）

```shell
# tar xf docker-19.03.10.tgz
# cp -p docker/* /usr/bin
```

##### 3.2. systemd 用 Docker サービスの入手とインストール
上記のバイナリ tarball には、systemd 用のサービス設定ファイル `docker.service`、`docker.socket` が含まれていません。そこで公式 github からそれらを入手し、systemd サービスを収容するディレクトリ `/lib/systemd/system` に移動させます。（参考： 公式ドキュメント [Control Docker with systemd ＞ Manually create the systemd unit files](https://docs.docker.com/config/daemon/systemd/#manually-create-the-systemd-unit-files)）

```shell
# wget https://raw.githubusercontent.com/moby/moby/master/contrib/init/systemd/docker.service
# wget https://raw.githubusercontent.com/moby/moby/master/contrib/init/systemd/docker.socket
# cp docker.{service,socket} /lib/systemd/system
```

#### 4. もろもろの設定
#### 4.1. グループ `docker` の生成
グループ `docker` を生成します。（参考：公式ドキュメント [Post-installation steps for Linux](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)）

```shell
# groupadd docker
```

#### 4.2. systemd に関する設定
systemd 243 以降？に、cgroup は v2 なるものがデフォルト採用されることになったそうで、v2 のままにしていると Docker のさまざまな機能が動作しないようです。（入手情報元を失念につき、後日加筆予定）

そこでこれを解消するために、`/boot/grub/grub.cfg` のブートオプションとして `systemd.unified_cgroup_hierarchy=0` を加えます。

```text
systemd.unified_cgroup_hierarchy=0
```
他サイトでは随所に `GRUB_CMDLINE_LINUX_DEFAULT` にこの記述を加えて `updated-grub` を実行する解消法が示されていますが、同じことです。Linux From Scratch では `GRUB_CMDLINE_LINUX_DEFAULT` を利用していないので、`grub.cfg` への直接指定とします。

なお具体例として筆者の `/boot/grub/grub.cfg` は以下となっています。

```shell
# cat /boot/grub/grub.cfg
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5

insmod ext2
set root=(hd0,1)

menuentry "GNU/Linux, Linux 5.6.15-lfs-20200528-systemd" {
        linux   /vmlinuz-5.6.15-lfs-20200528-systemd root=/dev/sda3 ro net.ifnames=0 biosdevname=0 systemd.unified_cgroup_hierarchy=0
}
```

`linux` 行の最後に `systemd.unified_cgroup_hierarchy=0` を加えています。ちなみに筆者は `/boot` を専用パーティションにマウントして利用しているため、上の `linux` 行は `linux /boot/vmlinux...` ではなく `linux /vmlinux...` という記述にしています。

修正後はシステムを再起動します。

#### 4.3. `cgroup` マウント
`cgroup`（control group）のマウント設定を行います。`/etc/fstab` ファイルに以下の記述を加えてマウントします。（参考： [Docker の Github issue #2683](https://github.com/moby/moby/issues/2683)）

```shell
# echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
# mount -a
```
確認として以下を実行してみます。これはまず、カーネルモジュールが生成できているかどうかの確認です。

```shell
# less /proc/cgroups
#subsys_name    hierarchy       num_cgroups     enabled
cpuset  4       1       1
cpu     3       1       1
cpuacct 3       1       1
blkio   5       1       1
memory  2       42      1
devices 6       29      1
freezer 7       1       1
```

だいたい上のような出力となるはずです。ここで重要なのは `memory` や `devices` の行が存在していることです。もしこれが出力されていないなら、前述の Linux カーネルオプションが適切にビルドされていないことを意味します。

次に以下を実行します。これは cgroup が適切にマウントされているかどうかの確認です。

```shell
# mount | grep ^cgroup
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
```

`/sys/fs/cgroup` 配下に各グループ（`cpu` や `devices` など）が存在しマウントされていることが確認できます。

#### 5. 動作確認
#### 5.1. docker デーモンの起動確認
まずは Docker デーモンの起動確認を行います。

systemd サービスである `docker.service` を動作させるのでも良いですが、それよりも `dockerd` を直接実行する方が、エラーメッセージを直接示してくれるので便利です。以下のようにして `dockerd` コマンドを実行します。（参考： 公式ドキュメント [Install static binaries](https://docs.docker.com/engine/install/binaries/#install-static-binaries)）

```shell
# dockerd &
```

エラーが発生した場合は、出力の最終行に以下のようなメッセージが表示されます。

```shell
failed to start daemon: Error XXXXXXXXXX
```

こういったエラーメッセージがなければ、とりあえず正常起動したものと思われます。

#### 5.2. `docker info` による確認
`docker info` を実行してみます。

```shell
# docker info
```

以下の出力が得られました。

```shell
Client:
 Debug Mode: false

Server:
 Containers: 5
  Running: 0
  Paused: 0
  Stopped: 5
 Images: 0
 Server Version: 19.03.10
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
 init version: fec3683
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 5.6.15
 Operating System: Linux From Scratch 20200528-systemd
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 1.432GiB
 Name: DockerOnLFS
 ID: PMIG:ONBA:YGH6:XMWF:GFGH:EW66:2GBR:A2E4:4D5X:TBWT:M2BL:KRVE
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine

WARNING: No cpu cfs quota support
WARNING: No cpu cfs period support
```

#### 5.3. `docker run hello-world` による確認
`docker run hello-world` を実行してみます。（参考： 公式ドキュメント [Install static binaries](https://docs.docker.com/engine/install/binaries/#install-static-binaries)）

```shell
# docker run hello-world
```

以下の出力が得られました。

```shell
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest
INFO[2020-06-08T10:56:23.077433898+09:00] shim containerd-shim started
                  address="/containerd-shim/moby/fa9173d0b26b33c1075296abd578df5c0c088a61f5683214d60bbf5d1f12fa47/shim.sock" debug=false pid=504

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

INFO[2020-06-08T10:56:24.864625786+09:00] shim reaped
                                   id=fa9173d0b26b33c1075296abd578df5c0c088a61f5683214d60bbf5d1f12fa47
INFO[2020-06-08T10:56:24.874963601+09:00] ignoring event
                                module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
```

この後も、公式ドキュメントの [チュートリアル part2](https://docs.docker.com/get-started/part2/) を実行してみました。問題なく動作しています。

#### 6. systemd の設定
##### 6.1. `dockerd` プロセスの kill
上記手順で実行した `dockerd` プロセスを kill します。

```shell
# kill -SIGKILL $(pidof dockerd)
```

##### 6.2. `docker.service` の起動
`docker.service` を起動します。（参考： 公式ドキュメント [Control Docker with systemd ＞ Start the Docker daemon](https://docs.docker.com/config/daemon/systemd/#start-the-docker-daemon)）

```shell
# systemctl start docker.service
```

誤りがなければエラーなく、出力もないはずです。

必要に応じて `systemctl enable docker.service` を実行しておき、システム起動時にこのサービスが自動起動するようにします。（参考： 公式ドキュメント [Post-installation steps for Linux ＞ Configure Docker to start on boot](https://docs.docker.com/engine/install/linux-postinstall/#configure-docker-to-start-on-boot)）

```shell
# systemctl enable docker.service
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
```

念のためサービスのステータスを確認します。

```shell
# systemctl status docker.service
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset:
 enabled)
     Active: active (running) since Mon 2020-06-08 11:27:52 JST; 9min ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 269 (dockerd)
      Tasks: 27 (limit: 1755)
     Memory: 98.5M
     CGroup: /system.slice/docker.service
             tq269 /usr/bin/dockerd -H fd://
             mq284 containerd --config /var/run/docker/containerd/containerd.toml --log-level info

 6月 08 11:27:50 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:50.415279942+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.write_bps_device"
 6月 08 11:27:50 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:50.415333378+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.read_iops_device"
 6月 08 11:27:50 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:50.415385780+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.write_iops_device"
 6月 08 11:27:50 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:50.438407022+09:00" level=info msg="Loading containers: start."
 6月 08 11:27:51 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:51.864165833+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
 6月 08 11:27:51 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:51.957543814+09:00" level=info msg="Loading containers: done."
 6月 08 11:27:52 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:52.591932252+09:00" level=info msg="Docker daemon" commit=9424aea graphdriver(s)=overlay2 version=19.03.10
 6月 08 11:27:52 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:52.663437436+09:00" level=info msg="Daemon has completed initialization"
 6月 08 11:27:52 DockerOnLFS systemd[1]: Started Docker Application Container Engine.
 6月 08 11:27:52 DockerOnLFS dockerd[269]: time="2020-06-08T11:27:52.950638271+09:00" level=info msg="API listen on /run/docker.sock"
```

ちなみに `DockerOnLFS` はホスト名です。

また warning メッセージとして `Your kernel does not support cgroup blkio throttle.write_bps_device` などが出ていますが、これは対応するカーネルモジュールがビルドされていないためです。今のところ Docker は動作していることと、それらのモジュールがどういったものか理解できていないため、今後理解していくことにして、今はそのまま無視しておくことにします。

本文は以上です。