ようへいの日々精進XP

よかろうもん

Docker コンテナランタイムについて少しだけ勉強した (5)

tl;dr

会社から借りっぱなしの Software Design 2020 年 2 月号で特集されている Docker コンテナランタイムについての記事を読んでみたメモです.

gihyo.jp

読みながら気になる単語や内容をマインドマップにまとめていきたいと思います.

今回は, runc のハンズオン第一弾.

マインドマップ

f:id:inokara:20200421231535p:plain

ハンズオンメモ

検証環境

ホスト側の OS は以下の通り.

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

runc バージョンは以下の通り.

$ runc --version
runc version spec: 1.0.1-dev

Filesystem bundle の作成

記事中は Ubuntu 18.04 のコンテナイメージからルートファイルシステムを作っていますが, ちょっとだけ変えて Alpine Linux のコンテナからルートファイルシステムを取得します.

$ mkdir bundle
$ docker run --rm -d --name rootfs alpine tail -f /dev/null
$ docker export rootfs > rootfs.tar
$ mkdir bundle/rootfs && tar xvf rootfs.tar -C bundle/rootfs
$ docker kill rootfs

この状態で, bundle/roofs を見ると以下のような状態になっています.

$ tree -L 1 bundle/rootfs
bundle/rootfs
├── bin
├── dev
├── etc
├── home
├── lib
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin
├── srv
├── sys
├── tmp
├── usr
└── var

17 directories, 0 files

続いて, コンテナ実行環境の定義ファイルを生成します.

$ runc spec -b bundle
$ cat bundle/config.json
{
        "ociVersion": "1.0.1-dev",
        "process": {
                "terminal": true,
                "user": {
                        "uid": 0,
                        "gid": 0
                },
                "args": [
                        "sh"
                ],
... 略 ...
                "readonlyPaths": [
                        "/proc/bus",
                        "/proc/fs",
                        "/proc/irq",
                        "/proc/sys",
                        "/proc/sysrq-trigger"
                ]
        }
}

コンテナの起動

記事の中では createstart をあわせた run というサブコマンドを利用してコンテナを起動しているので, それに倣って run サブコマンドでコンテナを起動しました.

$ runc --help
...
     create      create a container
...
     start       executes the user defined process in a created container
...
     run         create and run a container

以下, Alpine Linux コンテナを起動している様子です.

$ sudo runc run -b bundle myalpine
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.11.5
PRETTY_NAME="Alpine Linux v3.11"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    7 root      0:00 ps aux

ファイルシステムを確認出来ました. また, プロセスも確認出来ますが, ホストのプロセスは確認することが出来ません. 良い感じです.

ちなみに, createstart でも実行する場合は手順が多くて面倒と書かれていますが, 実際にどのくらい面倒なのか気になるところです.

コンテナの停止

コンテナを停止する為の kill サブコマンド, コンテナを削除する為の delete サブコマンドが用意されています.

$ runc --help
...
     delete      delete any resources held by the container often used with detached container
...
     kill        kill sends the specified signal (default: SIGTERM) to the container's init process

以下, 先程起動した Alpine Linux コンテナを停止している様子です.

$ sudo runc kill myalpine KILL

引き続き, delete を実行すると, 以下のようにエラーが.

$ sudo runc delete myalpine
ERRO[0000] container "myalpine" does not exist
container "myalpine" does not exist

ほう. kill と一緒に delete されるのかな...

以上

今回はここまで. docker コマンド叩かなくてもコンテナを起動したり停止することが出来ました. 面白いですな.