🐋

runc と containerd と仲良くなったらコンテナともっと仲良くなれると思っていたのに

2024/05/28に公開

そう信じていたのに

背景

  • コンテナわからない
  • docker って runc とか containerd っていうやつが内部で動いていると聞いた
  • 中身を知ればもっとコンテナと仲良くなれる気がする

runc とか containerd とか、一体なんなんだ

https://medium.com/nttlabs/docker-to-containerd-4f3a56e6f2b6

containerd : コンテナの高レベルランタイムの一種。kubeletやユーザー等から支持を受け、コンテナやイメージ、ネットワーク等の管理を行う。Dockerはもちろん、kubernetes, Fargate1.4 でも使用されている。Docker社で開発が進められてDocker内部で使用されたのち、CNCFへ寄付され、CNCFのProjectとしてGraduatedステータスとなっている。

=> Docker でも内部的に使われている。

runc : コンテナの低レベルランタイムの一種。高レベルランタイムから支持を受け、ホストから隔離された実行環境をコンテナとして作り出し、その直接操作の手段を与える。仕様はOCI(Open Container Initiative)により「OCI Runtime Specification」として定められている。この仕様があることで、高レベルランタイムなどの上位コンポーネントから統一されたインタフェースを通じて利用できる。

=> さらに低レベルなランタイム。

多分こんな感じ
Alt text

普段は高レベルランタイムにしかお世話になっていないので、現場に行ってみましょう。

コンテナランタイムの仕様

OCI の標準仕様

コンテナの標準化を目標としている団体 : OCI(Open Container Initiative)により、「OCI Runtime Specification」として低レベルランタイムの仕様が定められています。この仕様があることで、高レベルランタイムなどの上位コンポーネントから統一されたインタフェースを通じて利用できます。

https://github.com/opencontainers/runtime-spec/blob/main/spec.md

コンテナは以下のようなライフサイクルになっています。[] はコンテナへの操作とお考えください。

[作成前] FileSystem Bundle の用意
↓
[create] config.json の中身に従って設定実行環境の作成
↓
[start] コンテナ実行
↓
[kill] プロセスをkillする
↓
[delete] コンテナ削除

その他、それぞれのステップ間にフック実行の処理が挟まります。
このうち、コンテナの素を確認してみましょう。

コンテナの素:Filesystem bundle

注意:コンテナイメージではない

containerd がイメージを pull → そのイメージを構成するファイル群をruncに渡しますが、この格納方法を定めた仕様のことを指すようです。

実態は、以下の2つのファイル群が格納されたディレクトリです。

  • コンテナのルートファイルシステム
  • コンテナ実行環境の設定ファイル

https://github.com/opencontainers/runtime-spec/blob/main/bundle.md

流れとしては以下のようなイメージ

  1. 高レベルランタイムがイメージをレジストリから取得する
  2. イメージに含まれるルートファイルシステム、実行時の情報などから Filesystem bundle を作成する
  3. この Filesystem bundle には、エントリポイント・コマンド、ユーザー、環境変数、namespace,cgroup などの設定項目を含んだJSONファイルが含まれており、これを使って低レベルランタイムでコンテナを作成する。

runc でコンテナを動かしてみる

環境

Docker がインストールされていれば基本的にruncもインストール入っている?(ECS optimized AMI であれば runc 使えました)

amzn2-ami-ecs-hvm-2.0.20230705-x86_64-ebs
ami-0e432635473484865

個別にインストールも可能です。

https://github.com/opencontainers/runc

やってみる

とりあえずコマンド叩いてみます

[root@ip-10-16-2-169 mycontainer]# runc --help

NAME:
   runc - Open Container Initiative runtime
...

USAGE:
   runc [global options] command [command options] [arguments...]
...

COMMANDS:
   checkpoint  checkpoint a running container
   create      create a container
   delete      delete any resources held by the container often used with detached container
   events      display container events such as OOM notifications, cpu, memory, and IO usage statistics
   exec        execute new process inside the container
   kill        kill sends the specified signal (default: SIGTERM) to the container's init process
   list        lists containers started by runc with the given root
   pause       pause suspends all processes inside the container
   ps          ps displays the processes running inside a container
   restore     restore a container from a previous checkpoint
   resume      resumes all processes that have been previously paused
   run         create and run a container
   spec        create a new specification file
   start       executes the user defined process in a created container
   state       output the state of a container
   update      update container resource constraints
   features    show the enabled features
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug             enable debug logging
....

コンテナの素:Filesystem bundle の作成

runc の github にある使い方に沿ってコマンドを叩いてみます。
https://github.com/opencontainers/runc

0からFilesystem bundle のファイル群を作成するのも大変なので、Docker でコンテナを動かしてルートファイルシステムを取得してきます。
低レベルランタイムを使って1から動かそうとか言っておいていきなり高レベルランタイムを頼ります

sh-5.2$ sudo su

// まずコンテナ用のフォルダを作ります
[root@ip-10-16-2-169 ~]# mkdir mycontainer

[root@ip-10-16-2-169 ~]# mkdir mycontainer/rootfs

[root@ip-10-16-2-169 ~]# cd mycontainer/

// ルートファイルシステムを作ります = busybox イメージから export しています
[root@ip-10-16-2-169 mycontainer]# docker export $(docker create busybox) | tar -C rootfs -xvf -

Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
809d8e20e203: Pulling fs layer
...
var/spool/mail/
var/www/

// ルートファイルはこんな感じ
[root@ip-10-16-2-169 mycontainer]# ls rootfs/
bin  dev  etc  home  lib  lib64  proc  root  sys  tmp  usr  var

// spec コマンドによりベースとなる実行環境の設定ファイルを作成できます。自身で編集なども可能です
[root@ip-10-16-2-169 mycontainer]# runc spec

[root@ip-10-16-2-169 mycontainer]# ls
config.json  rootfs

[root@ip-10-16-2-169 mycontainer]# cat config.json
(別ファイルに保存したためそちら参照)
config.json

{
"ociVersion": "1.0.2-dev",
"process": {
"terminal": true,
"user": {
"uid": 0,
"gid": 0
},
"args": [
"sh"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": "/",
"capabilities": {
"bounding": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"effective": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"permitted": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"ambient": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
]
},
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"noNewPrivileges": true
},
"root": {
"path": "rootfs",
"readonly": true
},
"hostname": "runc",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/sys/fs/cgroup",
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
}
],
"linux": {
"resources": {
"devices": [
{
"allow": false,
"access": "rwm"
}
]
},
"namespaces": [
{
"type": "pid"
},
{
"type": "network"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
},
{
"type": "cgroup"
}
],
"maskedPaths": [
"/proc/acpi",
"/proc/asound",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/sys/firmware",
"/proc/scsi"
],
"readonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
}
}

コンテナを動かしてみる

[root@ip-10-16-2-169 mycontainer]# runc run mycontainerid

/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var

/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    6 root      0:00 ps aux

/ # exit

コンテナが動きました🥳

ちょっと設定ファイルをいじる

では設定ファイルを少しいじってみます。
バックグラウンドで動かすために terminal をいじり、sleep させてみます。
terminal の仕様については理解しきれませんでした。詳細はこちら。
https://github.com/opencontainers/runc/blob/main/docs/terminals.md#terminals-and-standard-io

[root@ip-10-16-2-169 mycontainer]# vim config.json
{
        "ociVersion": "1.0.2-dev",
        "process": {
                "terminal": false,   <-edit here
                "user": {
                        "uid": 0,
                        "gid": 0
                },
                "args": [
                        "sleep", "30"   <-edit here
...

[root@ip-10-16-2-169 mycontainer]# runc create mycontainerid

// コンテナが作られただけ。まだ動いてません。
[root@ip-10-16-2-169 mycontainer]# runc list
ID              PID         STATUS      BUNDLE              CREATED                          OWNER
mycontainerid   4013        created     /root/mycontainer   2023-07-08T04:16:15.660625376Z   root

// コンテナを動かします
[root@ip-10-16-2-169 mycontainer]# runc start mycontainerid

[root@ip-10-16-2-169 mycontainer]# runc list
ID              PID         STATUS      BUNDLE              CREATED                          OWNER
mycontainerid   4013        running     /root/mycontainer   2023-07-08T04:16:15.660625376Z   root

// exec コマンドも使えます
[root@ip-10-16-2-169 mycontainer]# runc exec mycontainerid ps
PID   USER     TIME  COMMAND
    1 root      0:00 sleep 30
    5 root      0:00 ps

// sleep が終わった後、stopped に変化しています
[root@ip-10-16-2-169 mycontainer]# runc list
ID              PID         STATUS      BUNDLE              CREATED                          OWNER
mycontainerid   0           stopped     /root/mycontainer   2023-07-08T04:16:15.660625376Z   root

runc を動かしてみたまとめ

ここまで runc でコンテナを動かしてみました。コンテナを動かすだけであれば、runc のみで十分可能であることがわかります。

余談 1

runc の README にはこんなことが書かれています。

Using runc
Please note that runc is a low level tool not designed with an end user in mind. It is mostly employed by other higher level container software.

Therefore, unless there is some specific use case that prevents the use of tools like Docker or Podman, it is not recommended to use runc directly.

If you still want to use runc, here's how.

意訳:直接使うの想定してへん

containerd でもコンテナを動かしてみる

さて、runcでもコンテナが動かせることがわかりました。
しかし、runcはあくまでもコンテナの中身を動かすだけの役割。コンテナそのものを色々と管理することはできません。
というわけで、高レベルランタイムがやっていることをのぞいてみます。

ctr コマンド

containerdはデーモンとして起動するため、それを操作するプログラムが別に必要となります。
そこで、containerd を操作する ctrコマンドというものが用意されています。

[root@ip-10-16-2-169 ]# ctr --help

NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI
...
COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   ...

containerd でのコンテナ操作

containerd では、runc でできなかったイメージの pull ができます!

// nginx, busybox イメージを pull してみます
root@ip-10-16-2-169 ~]# ctr image pull docker.io/library/nginx:latest
docker.io/library/nginx:latest:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe29c8892c7ef:    done           |++++++++++++++++++++++++++++++++++++++|
...
total:  67.3 M (14.9 MiB/s)
unpacking linux/amd64 sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe29c8892c7ef...
done: 3.442834427s

[root@ip-10-16-2-169 ~]# ctr image pull quay.io/quay/busybox:latest
quay.io/quay/busybox:latest:                                                      resolved       |++++++++++++++++++++++++++++++++++++++|
....
total:  746.9  (298.3 KiB/s)
unpacking linux/amd64 sha256:92f3298bf80a1ba949140d77987f5de081f010337880cd771f7e7fc928f8c74d...
done: 101.85732ms

// イメージも確認できます
[root@ip-10-16-2-169 ~]# ctr image ls
REF                            TYPE                                                      DIGEST                                                                  SIZE      PLATFORMS                                                                                               LABELS
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe29c8892c7ef 67.3 MiB  linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -
quay.io/quay/busybox:latest    application/vnd.docker.distribution.manifest.v2+json      sha256:92f3298bf80a1ba949140d77987f5de081f010337880cd771f7e7fc928f8c74d 748.4 KiB linux/amd64                                                                                             -

// pull するイメージの指定方法は docker と異なるようです
[root@ip-10-16-2-169 ~]# ctr image pull nginx
ctr: failed to resolve reference "nginx": object required

ただここで1つ問題がありました。

build ができない・・・・

それでも build がしたい

というわけで独自にイメージを作成して build する時は、docker で build -> save でイメージを tar ファイルとして出力してから ctr でインポートします。

[root@ip-10-16-2-169 ~]# docker build -t example.com/yk68/test:latest - <<EOF
> FROM busybox:latest
> CMD echo HelloContainerd!
> EOF

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM busybox:latest
...
Successfully built 2bcab6762ccb
Successfully tagged example.com/yk68/test:latest

[root@ip-10-16-2-169 ~]# docker save -o yk68-test.tar example.com/yk68/test:latest

[root@ip-10-16-2-169 ~]# ls
yk68-test.tar  mycontainer

[root@ip-10-16-2-169 ~]# ctr image import yk68-test.tar
unpacking example.com/yk68/test:latest (sha256:f6ffbe473b7492eee8368bf32f2c1f51480a2db2d29d7eecc2997ecbe9785125)...done

[root@ip-10-16-2-169 ~]# ctr images ls
REF                            TYPE                                                      DIGEST                                                                  SIZE      PLATFORMS                                                                                               LABELS
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe29c8892c7ef 67.3 MiB  linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -
example.com/yk68/test:latest  application/vnd.docker.distribution.manifest.v2+json      sha256:f6ffbe473b7492eee8368bf32f2c1f51480a2db2d29d7eecc2997ecbe9785125 4.3 MiB   linux/amd64                                                                                             -
quay.io/quay/busybox:latest    application/vnd.docker.distribution.manifest.v2+json      sha256:92f3298bf80a1ba949140d77987f5de081f010337880cd771f7e7fc928f8c74d 748.4 KiB linux/amd64                                                                                             -

コンテナイメージを覗いてみる

コンテナイメージの仕様は、OCI Image Layout Specification により定められています。

https://github.com/opencontainers/image-spec/blob/main/image-layout.md

// 先ほど pull した nginx イメージを export してみます
[root@ip-10-16-2-169 ~]# ctr image export /tmp/nginx.tar docker.io/library/nginx:latest

[root@ip-10-16-2-169 ~]# ls /tmp/
nginx.tar 

[root@ip-10-16-2-169 ~]# mkdir /tmp/nginx_image

// nginx.tar を展開します
[root@ip-10-16-2-169 ~]# tar -xf /tmp/nginx.tar -C /tmp/nginx_image/

// これらがまさにコンテナイメージを構成するコンポートネントです。
[root@ip-10-16-2-169 ~]# ls -lah /tmp/nginx_image/
total 12K
drwxr-xr-x.  3 root root 120 Jul  8 05:00 .
drwxrwxrwt. 12 root root 260 Jul  8 05:00 ..
drwxr-xr-x.  3 root root  60 Jan  1  1970 blobs
-rw-r--r--.  1 root root 323 Jan  1  1970 index.json
-rw-r--r--.  1 root root 691 Jan  1  1970 manifest.json
-r--r--r--.  1 root root  30 Jan  1  1970 oci-layout

コンテナを動かしてみる

root@ip-10-16-2-169 ~]# ctr image pull docker.io/library/hello-world:latest
docker.io/library/hello-world:latest:                                             resolved       |++++++++++++++++++++++++++++++++++++++|
....
total:  4.4 Ki (1.4 KiB/s)
unpacking linux/amd64 sha256:a13ec89cdf897b3e551bd9f89d499db6ff3a7f44c5b9eb8bca40da20eb4ea1fa...
done: 43.072766ms

[root@ip-10-16-2-169 ~]# ctr images ls
REF                                  TYPE                                                      DIGEST                                                                  SIZEPLATFORMS                                                                                                                           LABELS
docker.io/library/hello-world:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:a13ec89cdf897b3e551bd9f89d499db6ff3a7f44c5b9eb8bca40da20eb4ea1fa 6.8 KiBlinux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/riscv64,linux/s390x,windows/amd64 -
...

// run コマンドでイメージからコンテナを起動できます
// この時、コンテナIDは独自に命名しなければなりません
[root@ip-10-16-2-169 ~]# ctr run docker.io/library/hello-world:latest hello-container

Hello from Docker!
This message shows that your installation appears to be working correctly.
....
For more examples and ideas, visit:
 https://docs.docker.com/get-started/

[root@ip-10-16-2-169 ~]# ctr container ls
CONTAINER          IMAGE                                   RUNTIME
hello-container    docker.io/library/hello-world:latest    io.containerd.runc.v2

// コンテナの中身を確認してみると、runc で扱った環境設定ファイル「config.json」の内容らしきものが "Spec" 以下に確認できます
[root@ip-10-16-2-169 ~]# ctr container info hello-container
{
    "ID": "hello-container",
    "Labels": {
        "io.containerd.image.config.stop-signal": "SIGTERM"
    },
    "Image": "docker.io/library/hello-world:latest",
    "Runtime": {
        "Name": "io.containerd.runc.v2",
        "Options": {
            "type_url": "containerd.runc.v1.Options"
        }
    },
    "SnapshotKey": "hello-container",
    "Snapshotter": "overlayfs",
    "CreatedAt": "2023-07-09T04:00:17.191581244Z",
    "UpdatedAt": "2023-07-09T04:00:17.191581244Z",
    "Extensions": {},
    "Spec": {
        "ociVersion": "1.0.2-dev",
        "process": {
            "user": {
                "uid": 0,
                "gid": 0,
                "additionalGids": [
                    0
                ]
            },
            "args": [
                "/hello"
            ],
            ...
            "capabilities": {
                ....
            },
            ...
        },
        "root": {
            "path": "rootfs"
        },
        "mounts": [
            ....
        ],
        "linux": {
   ....
            },
            "cgroupsPath": "/default/hello-container",
            "namespaces": [
                {
                    "type": "pid"
                },
                {
                    "type": "ipc"
                },
                {
                    "type": "uts"
                },
                {
                    "type": "mount"
                },
                {
                    "type": "network"
                }
            ],
            "maskedPaths": [
                "/proc/acpi",
                ...
                "/proc/scsi"
            ],
            "readonlyPaths": [
                "/proc/bus",
                ...
                "/proc/sysrq-trigger"
            ]
        }
    }
}

// コンテナ削除
[root@ip-10-16-2-169 ~]# ctr container remove hello-container

今度は nginx コンテナを起動してみます

// イメージを pull
[root@ip-10-16-2-169 ~]# ctr image pull docker.io/library/nginx:alpine
docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:2d194184b067db3598771b4cf326cfe6ad5051937ba1132b8b7d4b0184e0d0a6:    done           |++++++++++++++++++++++++++++++++++++++|
....
layer-sha256:8de2a93581dcb1cc62dd7b6e1620bc8095befe0acb9161d5f053a9719e145678:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 3.5 s                                                                    total:  16.2 M (4.6 MiB/s)
unpacking linux/amd64 sha256:2d194184b067db3598771b4cf326cfe6ad5051937ba1132b8b7d4b0184e0d0a6...
done: 1.081538154s

// コンテナを立ち上げます(まだ起動はしてません)
[root@ip-10-16-2-169 ~]# ctr container create docker.io/library/nginx:alpine nginx1

[root@ip-10-16-2-169 ~]# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx1       docker.io/library/nginx:alpine    io.containerd.runc.v2

// プロセスを確認してみますが、特に出力されません
[root@ip-10-16-2-169 ~]# pgrep nginx

// コンテナを動かすには、task start で動かす必要があるそうです
[root@ip-10-16-2-169 ~]# ctr task start --detach nginx1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf

[root@ip-10-16-2-169 ~]# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx1       docker.io/library/nginx:alpine    io.containerd.runc.v2

// プロセスを確認してみると、今度はプロセスが確認できます
[root@ip-10-16-2-169 ~]# pgrep nginx
3009
3059

// task をみてみると動いてますね
[root@ip-10-16-2-169 ~]# ctr task ls
TASK      PID     STATUS
nginx1    3009    RUNNING

// 先ほどはバックグラウンドで起動しましたが、フォアグラウンドで起動してみます
[root@ip-10-16-2-169 ~]# ctr task attach nginx1
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/07/09 04:04:46 [notice] 1#1: using the "epoll" event method
2023/07/09 04:04:46 [notice] 1#1: nginx/1.25.1
2023/07/09 04:04:46 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r4)
2023/07/09 04:04:46 [notice] 1#1: OS: Linux 6.1.34-58.102.amzn2023.x86_64
2023/07/09 04:04:46 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:1024
2023/07/09 04:04:46 [notice] 1#1: start worker processes
2023/07/09 04:04:46 [notice] 1#1: start worker process 30

// [Ctrl + C] で抜けます

コンテナに入ってみる

exec コマンドもできます

[root@ip-10-16-2-169 ~]# ctr task exec -t --exec-id shell1 nginx1 sh
/ # ls
bin                   docker-entrypoint.sh  lib                   opt                   run                   sys                   var
dev            

最後にタスクを kill してあげます

[root@ip-10-16-2-169 ~]# ctr task kill -s 9 nginx1

[root@ip-10-16-2-169 ~]# ctr task ls
TASK      PID     STATUS
nginx1    3307    STOPPED

[root@ip-10-16-2-169 ~]# ctr task rm nginx1
WARN[0000] task nginx1 exit with non-zero exit code 137

[root@ip-10-16-2-169 ~]# ctr task ls
TASK    PID    STATUS

Next Step

runc よりもコンテナイメージを pull したり、コンテナ操作が色々できることがわかりました。
しかし、イメージの build ができなかったり、コンテナIDを自分で命名する必要があったり、複数のコンテナを管理・運用するには痒いところが痒い状態です。

これらを色々とやってくれるのが、まさに docker コマンドであったり nerdctl コマンドであるということがよくわかりました。

https://github.com/containerd/nerdctl

余談 2

本当は nerdctl コマンドも首を突っ込んでみようと思いましたが、いつも目にする操作とほとんど変わらないのでスルーしました。

余談 3

なんかのゲームシリーズで ver.4 くらいから入門してハマっていき、過去作に戻っていく感覚を思い出しました。
普段使っている docker などはたくさんの機能がある最新バージョン。そこから過去バージョンに戻ると機能が減っていき、「あ、最初ってこんなシンプルだったのか」って思うやつ。
結果的に「最新作しか勝たん」ってなるやつ。

おしまい
誰かの役に立つかわかりませんが、参考になれば幸いです。

Discussion