---
source_url: https://codeandcake.dev/posts/2026-10-22-docker-is-weird
source_title: "Code and Cake - Docker is weird"
tags: docker,containers,linux,go,runc
generated_at: 2026-10-23T04:00:55.998Z
model: claude-haiku-5-5
---
# Dockerの仕組み：コンテナは5つのLinuxカーネル機能の組み合わせ

筆者は趣味で自作コンテナランタイムを開発しており、Dockerの内部動作について学んだ内容をまとめている。コンテナは特別な制限を課されたプロセスであり、複数のLinuxカーネル機能によって構成されるという。

Code and Cakeに掲載された記事で、筆者は独自のコンテナランタイムを作る過程で得たDockerに関する知見を紹介している。

## コンテナの正体

コンテナは仮想マシンと異なり、特別な制限が課されたプロセスである。カーネルは引き続きそのプロセスを実行しており、/proc でプロセスを確認することもできる。

Linuxには「コンテナ」という単一の機能は存在せず、コンテナは5つのLinuxカーネル機能の組み合わせである。Namespacesはホストとコンテナが互いに見えるものを隠し、cgroupsはコンテナのリソース使用量を制限する。

## イメージとルートディレクトリ

イメージは、Dockerが配置するフォルダである。Dockerはそのフォルダをchroot（またはpivot_root）によってプロセスの新しいルートディレクトリにする。

`docker run -it --rm ubuntu /bin/bash` を実行すると、Dockerは Dockerhub からubuntuイメージをダウンロードして配置し、/some/weird/docker/path/bin/bash を実行する。

## runcとGoランタイム

Dockerのコンテナランタイムであるruncは、Goで書かれている。Goのランタイムはネイティブにマルチスレッドであるが、コンテナランタイムに必要な多くのLinuxシステムコールは単一スレッドの環境で実行しなければならない。そのためrsuncには、Goのランタイムが初期化される前に動作し、これらのシステムコールを実行するCモジュールがある。

Goにはforkが存在せず、forkはメインスレッドしか複製しない。runcは、子プロセスであることを示す特別なコマンドライン引数を付けて /proc/self/exe を実行することで、forkを近似している。

## rootで動作するDockerデーモン

コンテナランタイムが利用するLinuxカーネルのAPIの多くは、root権限での実行を必要とする、または以前は必要としていた。そのため、Dockerデーモンは通常root権限で動作する。筆者はMacOS上でDockerを実行している。

## 筆者の見立て

- 筆者はDockerを「奇妙」だと論じている。
- 筆者は、Goはコンテナランタイムにとって「かなりひどい言語」だと論じている。
- 筆者は、Goにforkがないことは、Goのようなランタイムでは「やっかいな落とし穴」になりうると論じている。
- 筆者は、Goのネイティブなマルチスレッドランタイムを「非常に優れた機能」だと論じている。
- 筆者は、コンテナランタイムのroot権限要件は近年改善しているように見えると解釈している。
- 筆者は、rootlessコンテナランタイムが同等の機能を得るには、ネットワークスタック全体をユーザー空間で再実装する必要があるようだと解釈している。
- 筆者は、コンテナのセキュリティは非常に難しい仕事だと論じている。
- 筆者は、使っているツールを自作することはそのツールを学ぶ優れた方法だと論じている。
- 筆者は、学ぶことは楽しいと論じている。

*この記事は元記事の事実のみに基づいて自動生成されました。*

## 出典

- 媒体名：Code and Cake
- 原題：Code and Cake - Docker is weird
- URL：https://codeandcake.dev/posts/2026-10-22-docker-is-weird
