ナンモワカランアザラシ

技術的なアレコレを自分の言葉で書いて保管・公開しておくための静かなインターネット

Dockerを動かすためのコンポーネントって何があるの

runcのアレがあったのでバージョンを上げようとしていたら、この辺が全く分からないことに気づいた。

~ $ docker version
Client: Docker Engine - Community
 Version:           25.0.2
 API version:       1.44
 Go version:        go1.21.6
 Git commit:        29cf629
 Built:             Thu Feb  1 00:22:57 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          25.0.2
  API version:      1.44 (minimum version 1.24)
  Go version:       go1.21.6
  Git commit:       fce6e0c
  Built:            Thu Feb  1 00:22:57 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

ClientとServerがあるらしい。それはなんとなくわかる。クライアント-サーバーアプリケーションとして動いているのだろう。 Clientの方は、それぞれ書かれていることが概ね推測できる。 Serverの方、それぞれどれが何を担当しているのかを知りたい。

Engine

https://docs.docker.com/engine/ Docker Engineは、サーバーとしてふるまうdockerd, API, CLIコマンドで構成されている。 docker versionコマンドで出たServer.Engineはおそらくdockerdを表すのだろう。

https://docs.docker.com/engine/reference/commandline/dockerd/ dockerdはコンテナを管理する永続的なプロセスである。 クライアントからのAPIリクエストをリッスンする。APIリクエストはunix, tcp, fdという3系統のソケットから来る。fdってなんだ?ファイルディスクリプタか。 デフォルトはunix、リモートで操作するときはtcp、systemdであれこれしたいときはfd、という理解でよいだろうか。

containerd

https://docs.docker.com/engine/reference/commandline/dockerd/#runtime-options dockerdがコンテナのあれこれを操作する際にnamespace, cgroups, SELinuxをいじるのにcontainerdをインターフェースとして使う。 namespaceはそのまま名前空間、cgroupsはメモリとかの管理、SELinuxってなんだ?

https://www.redhat.com/ja/topics/linux/what-is-selinux#:~:text=SELinux%20(Security%2DEnhanced%20Linux),%E7%94%A8%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%BB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%A7%E3%81%99%E3%80%82 SELinuxはSecurity-Enhanced Linux、ユーザー権限の制御をするためのアーキテクチャ

runc

https://docs.docker.com/engine/reference/commandline/dockerd/#configure-container-runtimes dockerdがコンテナランタイムとしてruncを使う。

コンテナランタイムってなんだ?

https://github.com/opencontainers/runc runcはコンテナの発生と実行をするためのツールらしい。それぞれ「発生」「実行」ってなんだ?になると沼りそうなのでこの辺で引き返しておく。

docker-init

https://docs.docker.com/engine/reference/commandline/init/ プロジェクト上で必要なファイルを生成するコマンド?多分違うなこれ。

https://docs.docker.com/engine/reference/commandline/container_run/#init これか。AIに聞いてもdocker initコマンドのことしか話さないからドキュメントを探すのに手こずった。

Docker daemonプロセスのシステムpathで最初に見つかった実行可能なファイルが、コンテナ内のPID 1のプロセスとして動くらしい。docker versionコマンドで出たdocker-initは、おそらくデフォルトのdocker-initバイナリを指す。

tiniってやつにbackedされているらしい。backedってなんだ?英語がわからない。雑に機械翻訳したら「サポートされている」とか「バックアップされている」とかになった。なるほど?

https://github.com/krallin/tini tiniはコンテナの中でゾンビプロセスを刈り取る1プロセスとして動くらしい。ほむ。

雑理解のまとめ

  • dockerdがデーモンプロセスとしてAPIとしてふるまう。あといろいろやる。
  • containerdはnamespace, cgroups, SELinuxを操作するためのインターフェースとして使われる
  • runcはコンテナランタイムとして使われる(コンテナランタイムって結局具体的になんだろう)
  • docker-initはそれぞれのコンテナのPID 1のプロセスとして動くバイナリファイル