Docker 仕組みメモ

今更感あるけどDockerの基礎技術について調べたことを自分用にメモdocs.docker.com

Dockerとは

Linux Containerによる仮想実行環境(コンテナ)を操作するツール。コンテナはホストOSから独立した環境で動作しているように見えるが、実際はホストOS上のプロセスに過ぎない。Linux Containerは割と古く2008年頃から開発している。でもVersion 1.0が提供されたのは最近で2014年。Linux ContainerはカーネルのNamespaceとcgroupsに依存している。

Namespaceは以下のようなリソースの参照を、プロセスをグループ化して隔離する機能。

Namespace   Constant        Isolates
IPC         CLONE_NEWIPC    System V IPC, POSIX message queues
Network     CLONE_NEWNET    Network devices, stacks, ports, etc.
Mount       CLONE_NEWNS     Mount points
PID         CLONE_NEWPID    Process IDs
User        CLONE_NEWUSER   User and group IDs
UTS         CLONE_NEWUTS    Hostname and NIS domain name

cgroupsは以下のようなリソースの利用を、プロセスをグループ化して制限できる機能。

CPU(使用率、割り当てコア、niceなど)、メモリ、Swap、物理IO帯域、ネットワークIO帯域、etc

コンテナの作成や実行だけならDockerがなくてもLXCでできる。しかしイメージ(コンテナのディスクイメージ)の作成やそのバージョン管理、またコンテナをexportとして他の環境へデプロイなどはDockerが得意とするところ。さらにDocker Hubを通じてイメージをインターネットで共有できる。

Dockerコンテナ

DockerコンテナはDockerイメージから作成された実行単位。start、stop、pauseもできるし、stopしたからと言ってコンテナ内で作成されたファイルが消えるわけではない。

Dockerイメージ

Dockerコンテナを作成するためのテンプレート。要はベースとなるディスクイメージ。実体はunion filesystemによる差分管理。初期のDockerはAUFSが利用されていた。今はdevice-mapperやbtrfs、overlayfsなんかが主に利用されている。なお、device-mapper(のdm-thin)はファイルシステムではなく、ブロックレベルでのoverlayを実現している。
https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt

差分のbaseは空っぽのディスクイメージ。なのでDockerイメージはすべてsnapshot。

CentOS7のデフォルトはdevice-mapper。ローカルのファイル(/var/lib/docker/devicemapper/devicemapper)をループバックデバイスとしてマウントし、さらにthin provisioningでプールを構築して、イメージの差分保存に利用している。

補足:
device-mapperとは論理ブロックデバイスの中の各ブロックが、どの物理ブロックデバイス内の、どのブロックを指すかマッピングする機能。まさにメモリのページング(仮想メモリアドレスと実メモリアドレスのマッピング)のブロックデバイス版。これにより、例えばHDDとSSDを1つの大きなディスクに見せることもできる。
※実際は論理ブロックデバイス上のブロックが、さらに別の論理ブロックデバイス上のブロックを指すこともできる