NanoPi M4V2にdockerを仕込む(microSD運用で乗り切る)

Posted by 雅楽斎 on Tuesday, March 31, 2020

TOC

せっかくRAMを4GBも積んでいるので、NanoPi M4V2でDockerを使えるようにします。

NanoPi M4V2はRockChip RK3399を採用していて、CPUのアーキテクチャとしては64bitのARMなので、適したアーキテクチャ(arm64またはaarch64)のDockerをインストールします。OSはUbuntu 18.04ベースのArmbian Bionic serverです。

Dockerのインストール

Docker自体のインストールは以前纏めたこともありますが3種類あります。

GalliumOSでSnapが使えない件(使えるようになりました)とDocker

Ubuntuのパッケージとして提供されるdocker

$ apt-cache policy docker.io
docker.io:
  Installed: (none)
  Candidate: 19.03.6-0ubuntu1~18.04.1
  Version table:
     19.03.6-0ubuntu1~18.04.1 500
        500 http://ports.ubuntu.com bionic-updates/universe arm64 Packages
     18.09.7-0ubuntu1~18.04.4 500
        500 http://ports.ubuntu.com bionic-security/universe arm64 Packages
     17.12.1-0ubuntu1 500
        500 http://ports.ubuntu.com bionic/universe arm64 Packages

snapのdocker

Install docker on Linux | Snap Store

現在のバージョンは18.09.9です。

Docker Inc.が提供するパッケージ

$ apt-cache policy docker-ce
docker-ce:
  Installed: 5:19.03.8~3-0~ubuntu-bionic
  Candidate: 5:19.03.8~3-0~ubuntu-bionic
  Version table:
 *** 5:19.03.8~3-0~ubuntu-bionic 500
        500 http://download.docker.com/linux/ubuntu bionic/stable arm64 Packages
        100 /var/lib/dpkg/status

アーキテクチャがarm64でもちゃんと3種類選べるのは時代が変わったなぁと実感するところですが、今回は最後のDocker Inc.が提供するパッケージをインストールします。1

インストール

Ubuntu

Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.
# apt-get install \
>     apt-transport-https \
>     ca-certificates \
>     curl \
>     gnupg-agent \
>     software-properties-common

↑1行で入力できれば改行する必要はありません。

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg  | apt-key add -
OK
# add-apt-repository \
>    "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
>    $(lsb_release -cs) \
>    stable"

↑1行で入力できれば改行する必要はありません。

# apt-get update
# apt-get install docker-ce docker-ce-cli containerd.io

最後にこんなエラーが表示されます。

invoke-rc.d: initscript docker, action "start" failed.
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabl
ed)
   Active: activating (auto-restart) (Result: exit-code) since Thu 2020-03-11 18:24:
16 JST; 13ms ago
     Docs: https://docs.docker.com
  Process: 2661 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/con
tainerd.sock (code=exited, status=1/FAILURE)
 Main PID: 2661 (code=exited, status=1/FAILURE)
dpkg: error processing package docker-ce (--configure):
 installed docker-ce package post-installation script subprocess returned error exit
 status 1
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for systemd (237-3ubuntu10.39) ...
Errors were encountered while processing:
 docker-ce
E: Sub-process /usr/bin/dpkg returned an error code (1)

systemdのdaemon起動でエラーが出てますが、なぜかよくわかりませんが使ってるうちにエラーが出なくなりました。パッケージのインストール自体も正常に終わっています。

以下のバージョン確認でサーバー側の情報が表示されれば正しく動作しています。

# docker version
Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:26:27 2020
 OS/Arch:           linux/arm64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:24:59 2020
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
# docker info
Client:
 Debug Mode: false

Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 1
 Server Version: 19.03.8
 Storage Driver: overlay2
  Backing Filesystem: <unknown>
  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.4.28-rockchip64
 Operating System: Ubuntu 18.04.4 LTS
 OSType: linux
 Architecture: aarch64
 CPUs: 6
 Total Memory: 3.777GiB
 Name: nanopim4v2
 ID: EIAD:TIJG:465R:52SD:FPDU:M6XF:5LS5:B4KQ:I3Y5:OSLS:UY3T:IXKP
 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

Docker Composeのインストール

Docker Composeのインストールはpipで行いました。途中で地味にコンパイルが走りましたがしょうがないです。

pipのインストール

# apt-get install python3-pip 

必須パッケージのインストール

Docker Composeのインストール時に必要なパッケージを先にインストールします。

# apt-get install python3-setuptools python3-dev libffi-dev

ちなみにこれを怠るとこんなエラーが表示されます。大量のTracebackに埋もれますが。

python3-setuptools

ModuleNotFoundError: No module named 'setuptools'

python3-dev

c/_cffi_backend.c:2:10: fatal error: Python.h: No such file or directory
#include <Python.h>

libffi-dev

c/_cffi_backend.c:15:10: fatal error: ffi.h: No such file or directory
#include <ffi.h>

Docker Composeのインストール

docker-compose

Multi-container orchestration for Docker
# pip3 install docker-compose

バージョン確認します。

# docker-compose --version
docker-compose version 1.25.4, build unknown

イメージ格納場所の変更

Dockerはイメージのダウンロードをガシガシするので、ストレージに余裕があるところでやりたいところ、うちのNanoPi M4V2はmicroSDで動かしてるので何もしないとあっという間にdisk fullになる未来が見えています。 ということで、Dockerイメージの格納場所を変更します。

まず、(存在しない場合は)格納場所にするディレクトリを作成します。

# mkdir /autofs/usbhdd1/var/docker-image

Dockerのservice systemdの定義ファイルを見てみると、

# systemctl cat docker
# /lib/systemd/system/docker.service
(snip)
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
(snip)

この中のExecStartの最後に引数-gと格納場所の指定を追加します。上のコマンド実行結果の1行目に表示されている/lib/systemd/system/docker.serviceを変更します。/lib/systemd/system/docker.servicedocker-ceパッケージが管理するファイルで、一時的に変更ができてもパッケージの更新で変更内容が上書きされてしまうため、ファイルを新たに作り、その内容を変更します。

# cp /lib/systemd/system/docker.service /etc/systemd/system/

/etc/systemd/system/docker.serviceを以下の内容に更新します。(ExecStartの行の末尾を追加)

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -g /autofs/usbhdd1/var/docker-image
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

変更したら、systemdに反映します。

# systemctl daemon-reload
# systemctl restart docker

格納場所が変更されていることを確認します。

# docker info | grep Root
 Docker Root Dir: /autofs/usbhdd1/var/docker-image

Dockerの動作確認

改めてdockerの動作確認をします。arm64に対応しているCentOSのイメージを引っ張って、中で動作するlsコマンドの依存ライブラリを確認します。

# docker run -it centos:7
Unable to find image 'centos:7' locally
7: Pulling from library/centos
3f2696f8166f: Pull complete 
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Downloaded newer image for centos:7
[root@8877644aa6f0 /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr
[root@8877644aa6f0 bin]# ldd /bin/ls
	linux-vdso.so.1 =>  (0x0000ffff95ea7000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x0000ffff95e36000)
	libcap.so.2 => /lib64/libcap.so.2 (0x0000ffff95e15000)
	libacl.so.1 => /lib64/libacl.so.1 (0x0000ffff95df4000)
	libc.so.6 => /lib64/libc.so.6 (0x0000ffff95c6e000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffff95e79000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x0000ffff95c1d000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000ffff95bfc000)
	libattr.so.1 => /lib64/libattr.so.1 (0x0000ffff95bdb000)

64bit ARMのdockerが動いていることが確認できました。

スポンサーリンク


  1. 既にインストールしてしまっていますが。 [return]

comments powered by Disqus