Linux

【Zynq7】実践3. 組込みLinuxでコンテナ導入に苦労した話【Docker Engine編】 

1.記事一覧

記事は複数回に分けて投稿します。XilinxのARM SoC (Zynq7020SoC)で動作する、PetaLinuxを使わない素のLinuxをソースコードから構築する記事の続編です。

ZynqMP(arm64版)はこちら

エッジArm Linux構築編(Armv7)

エッジArm Linux実践編(Armv7)

2.【概要】組込みArmLinuxでDockerが動かない

IoTの組込み機器でコンテナ基盤を導入する場合になったと仮定して、いざインストールしてもあれ、動かない…?ような状況で役立つかもしれない内容を書きます。

クラウドネイティブと言われる今の時代、Docker、nerdctl、containerdと言ったコンテナ仮想化基盤を使用した開発は一般的になりました。組込み機器のLinux上でもコンテナを動かしたいという動きは少なからずあります。組込み機器でコンテナ基盤を採用すべきかどうかの議論はここではしませんが、今後もし試しにコンテナをエッジ側で動かしてみようという機会が来たときのために勉強としてコンテナ環境導入にチャレンジしてみました。

【警告】今回の試みはRootFs(Linuxディストリビューション)を破壊することがあります。修復可能にできるようバックアップを必ず取ってください。自己責任です。

2-1. クラウドやPCだと簡単に動くコンテナが組込みLinuxだとそうでもない

Dockerの本番運用という2017年の記事を読むと、Dockerやcontainerdのようなコンテナ基盤がトラブルなく動くのはAWSやGCPのようなクラウドプラットフォーマーが相当苦労してメンテナンスしているということのようです。つまり、クラウドが提供するLinuxディストリビューションやLinuxカーネルイメージを使わずに、自分たちの組込みLinuxを用いてコンテナを動かそうとすると全然動かなかったりするわけです。(それはそうですよね)

今回Zynq ArmSoCで動かしているLinuxはソースコードからほぼ最小限の機能をビルドして構築しています。つまり、コンテナ技術のコアとなっている、namespace(PID、UID、GID、ファイルシステムを独立させる名前空間機能)やネットワーク仮想化、union filesystemなどの多くの機能をほとんど有効にしていないので、逆にコンテナ動いたら奇跡と呼べます。

実際は奇跡だ、すごいね…とかのんきなこと言っている場合ではなくて、上記リンク記事では”バグが原因でファイルシステムに致命的な破壊を与えるクラッシュをすることがある”そうなので、不完全な状態で動かすと吹っ飛ぶまであと1秒みたいな可能性もなくはないです(笑)。システムが天国に離陸しても戻せるようにバックアップを取って挑みます。

今回はコンテナが動作しない原因の一つ、「Linuxカーネルの機能が足りない」場合についての内容になります。armv7Linux上でDockerコンテナを動かすまでに足りない機能を調べ、カーネルコンフィグを設定してはビルドし直してを繰り返したという感じです。

RaspberryPiやNvidia JetsonでDockerがうまく動かないようなときにも少し役に立つかもしれません。

2-2. まずは普通にインストールする場合の現象

まずは標準の状態で公式の手順でDockerをインストールしてみました。RootFsはUbuntu22.04(armv7l)です。

【警告】今回の試みはRootFs(Linuxディストリビューション)を破壊することがあります。修復可能にできるようバックアップを必ず取ってください。自己責任です。

手順の「2.Install Docker Engine, containerd, and Docker Compose.」でdocker-ceをインストールしようとしたときにエラーが出ます。原因はdokerd(dockerデーモン)が”code=exited, status=1/FAILURE”で起動失敗しているからです。

Bash
...
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xeu docker.service" for details.
invoke-rc.d: initscript docker, action "start" failed.
 docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Thu 2023-03-09 03:53:30 JST; 65ms ago
TriggeredBy:  docker.socket
Docs: https://docs.docker.com
Process: 841 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
Main PID: 841 (code=exited, status=1/FAILURE)
CPU: 903ms
dpkg: error processing package docker-ce (--configure):
installed docker-ce package post-installation script subprocess returned error exit status 1
Processing triggers for libc-bin (2.35-0ubuntu3) …
Errors were encountered while processing:
docker-ce
E: Sub-process /usr/bin/dpkg returned an error code (1)
...

3.環境

開発PCUbuntu20.04, intel core i5 750 RAM 16G
ターゲットボードDigilent Zybo z7-20 Rev.B.2
SoC : Zynq7020 armv7hf (Xilinx社)
(XC7Z020-1CLG400C Arm Cortex-A9 ×2 666MHz)
DDR3 SDRAM 1GB
LinuxカーネルXilinxがGitHubで提供するソースコード tag=xilinx-v2022.2
Linux kernel v5.15
https://github.com/Xilinx/linux-xlnx/tree/xilinx-v2022.2
RootFsUbuntu22.04 armv7l
DockerDocker Engine version 23.0.1, build a5ee5b1

4.dockerd起動失敗の検証

systemdから詳細を見てみます。

Bash
zynq@zyboz7:~$ systemctl status docker.service
× docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2023-03-09 04:00:02 JST; 18s ago
TriggeredBy: × docker.socket
Docs: https://docs.docker.com
Process: 1109 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
Main PID: 1109 (code=exited, status=1/FAILURE)
CPU: 988ms
Mar 09 04:00:02 zyboz7 systemd[1]: docker.service: Scheduled restart job, restart counter is at 3.
Mar 09 04:00:02 zyboz7 systemd[1]: Stopped Docker Application Container Engine.
Mar 09 04:00:02 zyboz7 systemd[1]: docker.service: Start request repeated too quickly.
Mar 09 04:00:02 zyboz7 systemd[1]: docker.service: Failed with result 'exit-code'.
Mar 09 04:00:02 zyboz7 systemd[1]: Failed to start Docker Application Container Engine.
zynq@zyboz7:~$

プロセスが落ちた理由がよくわからないので、dockerdを手動起動

いくつか具体的なエラーが出ているようです。

  • storage-driver=overlay2が見つからない
  • storage-driver=fuse-overlayfsが見つからない
  • br_netfilterカーネルモジュールが見つからない

1つ目のoverlay2はOverlayfsと呼ばれ、ファイルシステムを階層化する技術をベースとするdocker製ストレージドライバです。
2つ目のfuse-overlayfsは”filesystem in userspace overlayfs”でrootlessコンテナに使います。あとで説明しますが、overlay2が無い場合の次の優先順位でロードしようとします。
3つ目はネットワークブリッジのパケットフィルタリングカーネルモジュールです。ファイアウォール周りの機能です。

3つともカーネルコンフィグをやり直して再ビルドする必要があります。しかし、結論から言うと足りないのはこの3つだけではありませんでした。もっと大量にあります。

5.KernelConfigチェックスクリプトによる調査

紆余曲折あって、便利なツールが公開されていることを知りました。

DockerのオープンソースプロジェクトMobyのGithubより、Kernelのconfigファイルから必要な項目をチェックするスクリプトが公開されています。
https://github.com/moby/moby/blob/master/contrib/check-config.sh

qiitaのLinux From Scratch に Docker Engine を導入の記事が参考になりました。先人に感謝です。(Linux From Scratchは初めて聞きましたが、すごいなこれ…)

5-1. 実機上でチェックする場合

Zyboz7ボード上でチェックしてみます。この方法はRaspberrypi、Jetsonでもできると思います。まずチェックスクリプトをダウンロードします。

Bash
$ wget https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh

現在実行されているカーネルのconfigを読み出します。

Bash
$ zcat /proc/config.gz > kernel.config

スクリプトを実行します。

Bash
$ sh check-config.sh kernel.config

5-2. ビルド環境上でチェックする場合

ビルド環境でmenuconfigすると、そのデータが.configに保存されます。一部のチェックはうまくできませんが(cgroup hierarchyなど)、menuconfigと見比べるときに使えます。

チェックスクリプトをダウンロードします。

Bash
$ wget https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh

スクリプトを実行します。

Bash
$ sh check-config.sh <linuxソースPATH>/linux-xlnx/.config

5-3. カーネル機能のチェック結果

今回チェック対象のconfigはxilinx_zynq_defconfig初期化からUSBとRTC関連の機能のみ有効にしています。そのためほとんどの機能は無効になっているはずです。

Generally Necessary:以下の項目で1つでもmissingがあるとdockerは起動できません。見ればわかりますが、9割以上missingでした。3つどころではないですね。

Optional Features:以下はオプションでなくても起動はしますが一部の機能は使えません。

6.Linux Menuconfigの設定

以前のLinuxカーネル構築記事を参考にmenuconfigでLinuxカーネルを再設定していきます。.configはテキストなのでCONFIG_XXXを直接設定すると楽なのですが、定数に依存関係があるので、あまり推奨はできません。しかし、menuconfig画面はCONFIG名と1:1ではないので、一つ一つ調べないとどこを有効にすればいいかわかりません。’/’をmenuconfig上で入力すると検索窓が出てくるので、例えば”NAMESPACES”と入力するとそれらしい項目が出てきます。

機能はできるだけカーネルに含めます”[*]”。カーネルモジュール”[M]”のみしか選択できない場合はカーネルモジュールとします。

6-1. Generally Necessary:コンテナ基盤向けカーネル必須機能

CONFIG定数とmenuconfigの設定場所を残しておきます。ただし、漏れやミスがあるかもしれません。

Namespace

CONFIG_NAMESPACES
-General setup>Namespaces support
CONFIG_PID_NS
-General setup>Namespaces support>PID Namespaces
CONFIG_IPC_NS
-General setup>Namespaces support>IPC namespace
CONFIG_UTS_NS
-General setup>Namespaces support>UTS namespace
CONFIG_USER_NS
-General setup>Namespaces support>User namespace

cgroups

CONFIG_CGROUP_CPUACCT
-General setup>Control Group support>CPU controller>Simple CPU accounting controller
CONFIG_CGROUP_DEVICE
-General setup>Control Group support>Device controller
CONFIG_CGROUP_FREEZER
-General setup>Control Group support>Freezer controller
CONFIG_CGROUP_SCHED
-General setup>Control Group support>Group scheduling for SCHED_OTHER
CONFIG_CPUSETS
-General setup>Control Group support>Cpuset controller
CONFIG_MEMCG
-General setup>Control Group support>Memory controller
CONFIG_CGROUP_BPF
-General setup>BPF subsystem>Enable bpf() system call
-General setup>Control Group support>Support for eBPF programs attached to cgroups

Security

CONFIG_KEYS
-Security options>Enable access key retention support

Network

CONFIG_VETH
-Device Drivers>Network device support>Network core driver support>Virtual ethernet pair device
CONFIG_BRIDGE_NETFILTER
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Advanced netfilter configuration>Bridged IP/ARP packets filtering
CONFIG_IP_NF_FILTER
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP: Netfilter Configuration>IP tables support (required for filtering/masq/NAT)>Packet filtering
CONFIG_IP_NF_TARGET_MASQUERADE
CONFIG_IP_NF_NAT
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Netfilter connection tracking support
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP: Netfilter Configuration>iptables NAT support>MASQUERADE target support
※NAT周りの依存を満たさないと出てきません。
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Core Netfilter Configuration>Netfilter Xtables support (required for ip_tables)>”addrtype” address type match support
CONFIG_NETFILTER_XT_MATCH_CONNTRACK
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Core Netfilter Configuration>Netfilter Xtables support (required for ip_tables)>”conntrack” connection tracking match support
CONFIG_NETFILTER_XT_MATCH_IPVS
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP virtual server support
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Core Netfilter Configuration>Netfilter Xtables support (required for ip_tables)>”ipvs” match support
※IP virtual server周りの依存を満たさないと出てきません。
CONFIG_NETFILTER_XT_MARK
-Networking support>Networking options>Network packet filtering framework (Netfilter)>Core Netfilter Configuration>”mark” match support

System Calls

CONFIG_POSIX_MQUEUE
-General setup>POSIX Message Queues

※menuconfig項目が出てこない場合の探し方

機能の依存関係があるので、項目が出現しない場合があります。
例:CONFIG_IP_NF_TARGET_MASQUERADEの場合
menuconfig画面上で’/’を入力し、検索画面に遷移します。
CONFIG_IP_NF_TARGET_MASQUERADE“と入力し、Enter
検索結果の”Depends on”(依存関係)にある、
NET [=y] && INET [=y] && NETFILTER [=y] && IP_NF_IPTABLES [=y] && IP_NF_NAT [=n]
がすべて有効[=y]にしているかを確認します。
‘/’で検索画面に移り、”IP_NF_NAT“を検索し場所を確認します。場所に移り、’*’or’M’を設定します。
今回の場合”IP_NF_NAT“の項目が表示されていませんでした。この場合、IP_NF_NATの”Depends on”のどれかが無効になっています。イタチごっこになりますが、地道に探してください。

また設定場所がそもそもない場合もあります。arch、arm関係などはSoC選択などで自動で決定されることもありました。今回の場合ソースコードの各フォルダ階層にある、KconigファイルでCONFIG定義を直接読んで雰囲気で調べてました。

6-2. Optional Features:コンテナ基盤向けカーネルオプション機能

cgroups

CONFIG_CGROUP_PIDS
-General setup>Control Group support>PIDs controller
CONFIG_BLK_CGROUP
-General setup>Control Group support>IO controller
※なぜIO controllerの名称なのか…せめてblockという単語を入れてほしい
CONFIG_CGROUP_PERF
-General setup>Control Group support>Perf controller
CONFIG_CGROUP_HUGETLB(無視)
ArmではHugeTLB(Huge Translation Lookaside Buffer)をv5.15でサポートしていない模様
CGROUP_HUGETLBはHUGETLB_PAGEに依存
(Linuxカーネルソースルートフォルダ)/fs/KconfigにHUGETLB_PAGE定義がある。
HUGETLB_PAGEはHUGETLB_PAGE_FREE_VMEMMAPで有効にされるが、
これはx86_64のみに依存しているため有効にならないはず。Armは使えないと思われる。
CONFIG_NET_CLS_CGROUP
-Networking support>Networking options>QoS and/or fair queueing>Control Group Classifier
CONFIG_CGROUP_NET_PRIO
-Networking support>Networking options>Network priority cgroup
CONFIG_CFS_BANDWIDTH
-General setup>Control Group support>CPU controller>CPU bandwidth provisioning for FAIR_GROUP_SCHED
CONFIG_RT_GROUP_SCHED
-General setup>Control Group support>CPU controller>Group scheduling for SCHED_RR/FIFO

Network

CONFIG_IP_NF_TARGET_REDIRECT
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP: Netfilter Configuration>IP tables support>iptables NAT support>REDIRECT target support
CONFIG_IP_VS_NFCT
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP virtual server support>Netfilter connection tracking
CONFIG_IP_VS_PROTO_TCP
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP virtual server support>TCP load balancing support
CONFIG_IP_VS_PROTO_UDP
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP virtual server support>UDP load balancing support
CONFIG_IP_VS_RR
-Networking support>Networking options>Network packet filtering framework (Netfilter)>IP virtual server support>round-robin scheduling

Security

CONFIG_SECURITY_SELINUX
CONFIG_SECURITY_APPARMOR
-Security options>NSA SELinux Support
CONFIG_SECURITY(依存)
-Security options>Enable different security models
CONFIG_SECURITY_NETWORK(依存)
-Security options>Simplified Mandatory Access Control Kernel Support
-Security options>TOMOYO Linux Support
-Security options>AppArmor support

File systems

CONFIG_EXT4_FS_POSIX_ACL
-File systems>Ext4 POSIX Access Control Lists
CONFIG_EXT4_FS_SECURITY
-File systems>Ext4 Security Labels

Block Devices

CONFIG_BLK_DEV_THROTTLING
-Enable the block layer>Block layer bio throttling support

Network Drivers

CONFIG_VXLAN
-Device Drivers>Network device support>Network core driver support>Virtual eXtensible Local Area Network (VXLAN)
CONFIG_BRIDGE_VLAN_FILTERING
-Networking support>Networking options>802.1d Ethernet Bridging>VLAN filtering
CONFIG_XFRM
CONFIG_XFRM_USER
CONFIG_XFRM_ALGO
-Networking support>Networking options>Transformation user configuration interface
CONFIG_INET_ESP
-Networking support>Networking options>IP: ESP transformation
CONFIG_IPVLAN
-Device Drivers>Network device support>Network core driver support>IP-VLAN support
CONFIG_MACVLAN
-Device Drivers>Network device support>Network core driver support>MAC-VLAN support
CONFIG_DUMMY
-Device Drivers>Network device support>Network core driver support>Dummy net driver support
CONFIG_NF_NAT_FTP
CONFIG_NF_CONNTRACK_FTP
-Networking support>Networking options>Network packet filtering framework (Netfilter)>FTP protocol support
CONFIG_NF_NAT_TFTP
CONFIG_NF_CONNTRACK_TFTP
-Networking support>Networking options>Network packet filtering framework (Netfilter)>TFTP protocol support

Cryptography

暗号化関連(依存関係が多いので有効にできそうなものからやるといいです)
CONFIG_CRYPTO_AEAD
CONFIG_CRYPTO_NULL2
-Cryptographic API>Null algorithms
CONFIG_CRYPTO_GCM
CONFIG_CRYPTO_GHASH
-Cryptographic API>GCM/GMAC support
CONFIG_CRYPTO_SEQIV
-Cryptographic API>Sequence Number IV Generator

Storage Drivers

ストレージドライバは基本的にどれかを選択して使用することになるので、すべて入れる必要はないです。DockerDocsにストレージドライバの選び方が載っていますのでまずは読みます。設定で固定しない場合は内部の優先順位で選択されるようです。優先順位のソースコードを見ると、btrfs>zfs>overlay2…となっていて、overlay2が無難な選択かなと思います。
overlay2自体はdocker製で内部ではLinuxKernelのOverlayFSとext4が使用されるようです。そのため、ここではOverlayFSを有効にします。
CONFIG_OVERLAY_FS
-File systems>Overlay filesystem support

7.再ビルドして実機カーネルコンフィグ確認

7-1. Linuxカーネルイメージのビルド

Linuxカーネルをビルドしていきます。

Bash
$ make clean
$ make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage

7-2. カーネルモジュールのビルド

前のカーネルモジュールの構築記事を参考にカーネルモジュールをビルドします。linuxソースフォルダ直下にmodrootフォルダを作りそこに格納します。

Bash
$ make -j5 ARCH=arm INSTALL_MOD_PATH=./modroot modules
$ make ARCH=arm INSTALL_MOD_PATH=./modroot modules_install

7-3. RootFsのバックアップと復帰

Docker導入前の正常なSDカードのrootパーティションをバックアップします。
まずSDカードを開発PCにマウントしておきます(/media/user/ROOT_FSなど)。

SDカードからバックアップを取る場合

Bash
$ mkdir rootfs_bk
$ sudo rsync -av /media/user/ROOT_FS/ ./rootfs_bk

バックアップから復帰する場合

Bash
$ sudo rm -rf /media/user/ROOT_FS/*
$ sudo rsync -av ./rootfs/ /media/user/ROOT_FS/
$ sync

7-4. カーネルモジュールの格納

RootFsのカーネルモジュール格納フォルダ(/lib/modules)を作成します。

Bash
$ sudo mkdir /media/user/ROOT_FS/lib/modules

格納します。

Bash
$ sudo cp -r <LinuxソースPATH>/linux-xlnx/modroot/lib/5.15.0-zyboz7-custom/media/user/ROOT_FS/lib/modules/


ROOTFS以下はこうなります。

Bash
$ ls /media/kerngt/ROOT_FS/lib/modules/5.15.0-zyboz7-custom/
build kernel modules.builtin modules.builtin.modinfo modules.order source

7-5. 起動と確認

bootパーティションにLinuxカーネルイメージuImageを上書きし、実機にSDカードを指し直します。起動できたらカーネルコンフィグチェックスクリプトを実行します。

おそらくこれでコンテナが起動できると思います。

7-6. Docker Engineのインストール再び→失敗

公式手順に従い、進めます。

docker-ceのインストール結果ですが、dockerdの起動に失敗しました。

8.dockerd起動失敗の検証(第2試合)

8-1. 原因調査1(カーネルモジュールがmodprobeできない)

手動起動でメッセージを見てみます。

Bash
$ sudo /usr/bin/dockerd &
... 一部抜粋
level=warning msg="Running modprobe bridge br_netfilter failed with message: modprobe: WARNING: Module bridge not found in directory /lib/modules/5.15.0-zyboz7_custom\nmodprobe: WARNING: Module br_netfilter not found in directory /lib/modules/5.15.0-zyboz7_custom\n, error: exit status 1"

カーネルモジュールbr_netfilterのmodprobeに失敗していました。
/lib/modules/5.15.0-zyboz7_custom/kernel/net/bridge/br_netfilter.ko
が存在しているので、おかしいなと思っていたら、depmodを忘れていました。

インデックス情報を更新して取り込んでみます。行けました。

Bash
$ sudo depmod -a
$ sudo modprobe br_netfilter

もう一度dockerdを起動します。また失敗しました。

8-2. 原因調査2(iptablesとnftablesの競合)

次のエラーはiptablesです。

Bash
$ sudo /usr/bin/dockerd &
... 一部抜粋
unable to detect if iptables supports xlock: 'iptables --wait -L -n': iptables/1.8.7 Failed to initialize nft: Protocol not supported error="exit status 1"

docker-ceをインストールしたときにiptablesがインストールされていました。iptableはファイアウォール操作コマンドです。

試しにiptablesでルールを表示してみます。

Bash
zynq@zyboz7:~$ sudo iptables -L
iptables/1.8.7 Failed to initialize nft: Protocol not supported

使えないようです。原因を調べました。

現在RootFsにUbuntu22.04を使用していますが、iptablesよりも新しいnftablesも導入されているようです。今移行期なのかもしれません。Dockerではnftablesが使えないため、従来のiptablesに切り替える必要があるようです。

切り替えは簡単にできそうです。UFW (Uncomplicated FireWall)というiptables/nftablesのフロントエンドパッケージがあるため、これの設定を変えます。

次のコマンドで切り替えます。

Bash
$ sudo update-alternatives --config iptables

現在*が0に選択されているので1を入力してiptables-legacyに切り替えます。

Bash
zynq@zyboz7:~$ sudo update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

Selection Path Priority Status

*0   /usr/sbin/iptables-nft 20 auto mode
 1   /usr/sbin/iptables-legacy 10 manual mode
 2   /usr/sbin/iptables-nft 20 manual mode
Press to keep the current choice[*], or type selection number: 1

dockerdを起動します。今度は立ち上がりました。一度killしてsystemdから立ち上げてみます。無事起動しました。

Bash
zynq@zyboz7:~$ sudo systemctl start docker.service
zynq@zyboz7:~$ sudo 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 Fri 2023-03-10 01:12:00 JST; 7s ago
TriggeredBy:  docker.socket
Docs: https://docs.docker.com
Main PID: 435 (dockerd)
Tasks: 8
Memory: 15.1M
CPU: 2.012s
CGroup: /system.slice/docker.service
└─435 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Mar 10 01:11:59 zyboz7 dockerd[435]: time="2023-03-10T01:11:59.684008098+09:00" level=info msg="[graphdriver] using prior storage driver: overlay2"
Mar 10 01:11:59 zyboz7 dockerd[435]: time="2023-03-10T01:11:59.704680682+09:00" level=info msg="Loading containers: start."
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.002534421+09:00" level=warning msg="Could not load necessary modules for Conntrack: Running modprobe nf_conntrack_netlink failed with message: `>
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.377674813+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>
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.639239029+09:00" level=info msg="Loading containers: done."
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.809169832+09:00" level=info msg="Docker daemon" commit=bc3805a graphdriver=overlay2 version=23.0.1
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.809859599+09:00" level=info msg="Daemon has completed initialization"
Mar 10 01:12:00 zyboz7 dockerd[435]: time="2023-03-10T01:12:00.934697674+09:00" level=info msg="[core] [Server #7] Server created" module=grpc
Mar 10 01:12:00 zyboz7 systemd[1]: Started Docker Application Container Engine.
Mar 10 01:12:01 zyboz7 dockerd[435]: time="2023-03-10T01:12:01.023542231+09:00" level=info msg="API listen on /run/docker.sock"

残りのパッケージをインストールします。

Bash
$ sudo apt install docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

9.hello-worldコンテナ実行

Hello worldコンテナを実行してみます。無事うまくいきました。ここまで長かった…

Bash
zynq@zyboz7:~$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
04341b189be6: Pull complete
Digest: sha256:6e8b6f026e0b9c419ea0fd02d3905dd0952ad1feea67543f525c73a0a790fefb
Status: Downloaded newer image for hello-world:latest

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.
(arm32v7)
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/
zynq@zyboz7:~$

10.最後に

今回使用したZyboz7ボードには DDR3 SDRAMが1GB搭載されています。コンテナはかなりメモリ消費があるので、そもそも32bitアドレス空間のarmv7では現実的ではないです。いよいよarm64に手を出すときが来そうかな…最近はZynqMPとOrangePi5に注目しています。この2つは詳細なLinuxのビルド方法が公開されているので遊びがいがありそうです。

ABOUT ME
sh-goto
組込エンジニア. 最近の遊びはLinuxの低レイヤいじりとXilinxのZynqとFPGAを使った電子工作
関連記事