2019-11-22に投稿

minq開発日記 (1) Dockerの基本語彙

MinQ(ミンク)

個人用的に勉強したことを一問一答という感じで返してくれるAPIを作ろうと思います. VPS上にDockerコンテナを・・・と思ったのですが現状ではコンテナの軽量化やセキュリティなど難しそうなのでとりあえず地道に勉強していこうと思います. 当面はローカル上にデプロイするのと同じ環境を構築しようと思います.

Dockerの語彙

具体的な話の前に, Dockerの基本用語を確認しておこうと思います.

Dockerイメージ

レイヤーで構成された何か. コンテナのテンプレートという表現もドキュメントには見られる.

An image is a read-only template with instructions for creating a Docker container.

どう表現するべきかいまいち難しいがソースコードがDockerfileとすると実行可能ファイルがイメージという感じだろうか. イメージを実行(run)することでコンテナを起動することができる. 突き詰めるとファイルと言うことになるのだが, それは大抵のプログラムがそうなのでなんとも表現しがたい.

Dockerコンテナ

イメージをDockerエンジン上でインスタンス化したものがコンテナとなる. もう少し詳しく言うとイメージの上に書き込み可能のレイヤー(コンテナ・レイヤー)を加えたものをコンテナと呼ぶ. 仮に複数のコンテナが同じイメージから生成されても, コンテナ・レイヤーにアプリの固有の状態を記録することで違うアプリケーションとして運用できる. 逆にコンテナ・レイヤー以下のイメージ・レイヤは読み込み専用なので変更はできない. なおこの層のファイルなどの変更もコンテナ・レイヤーに記録されるらしい.

イメージ・レイヤー

A Docker image is built up from a series of layers. Each layer represents an instruction in the image’s Dockerfile. Each layer except the very last one is read-only.

Dockerイメージを構成する要素で, Dockerfileの各インストラクションに対応するらしい. つまりインストラクションごとに生成されたレイヤーが積層されてDockerイメージはできている. これらは全て読み込み専用で, 実態はファイルらしいです. historyサブコマンドを使うとイメージのレイヤーが構築された歴史を見ることができる.

コンテナ・レイヤー

All changes made to the running container, such as writing new files, modifying existing files, and deleting files, are written to this thin writable container layer.

ファイルの新規作成, 修正, そして削除はコンテナ・レイヤーに書き込まれる.

Docker allocates a read-write filesystem to the container, as its final layer.

また読み書き可能なファイルシステムとも表現されている.

イメージ・レイヤーはread-onlyなレイヤーでコンテナを実行中は不変に保たれる(変更は再ビルドが必要). 実行中に行われるファイルへの変更はイメージ・レイヤーの上に構築されるコンテナ・レイヤーに書き込まれる.

ベース・イメージ

Scratchという名前のイメージのことをDockerではベース・イメージと呼ぶそうです. 一方あるイメージの元になったイメージは親イメージ(parent image)と呼び分けているようです.

Dockerデーモン

Dockerエンジンとか単にDockerといった場合これを指すことが多い. イメージやコンテナ(と言ったDockerオブジェクト)の管理をしてくれる.

The docker daemon process running on the host which manages images and containers (also called Docker Engine)

The daemon creates and manages Docker objects, such as images, containers, networks, and volumes.

Dockerコマンドと言ったコマンドライン・インターフェースが提供されておりユーザーはこれを使ってDockerデーモンと対話する. このクライアント・サーバー・アプリケーション自体をDockerエンジンと呼ぶこともあるらしい.

Docker Engine is a client-server application with these major components:

何れにしてもDockerと呼ばれるシステムの中核にこのDockerデーモンがあることは間違いないようです.

Docker Container Format

デフォルトではlibcontainerというらしいですが, 以下の三つの機能から実現されているようです.

  • Namespaces
  • Control Group (cgroup)
  • Union File System (UnionFS)

ドキュメントにも説明があるのですが正直よく分かりません.

Namespace

貨物輸送のコンテナのように,隔離された空間にプロセスが入っているので,この空間を『コンテナ』と呼ぶわけです。

image

OSを通して使用できるコンピュータのリソースを各コンテナごとに隔離して,ホストOS上で直接動作するプロセスや他のコンテナから独立した空間を作り出し,リソースを分割,分配,制限するわけです。

この説明はDockerでも通用しそうです.

Docker uses a technology called namespaces to provide the isolated workspace called the container.

隔離された作業空間をコンテナと呼んでいます. この隔離された空間を作る機能を提供しているのが名前空間でかなり核心的な機能だと言えそうです. 大雑把に名前空間 = コンテナと考えていいでしょうか.

では名前空間は具体的にどのような要求に答えているのでしょうか. これはプログラミングでも同じで名前空間を使って名前の衝突を回避したりします. 同じように名前空間が別の空間では同じ名前が使えます. PIDは通常OSで一意となるはずですが, 名前空間を使って隔離されていると共通のIDが使えるようになるようです. またこの空間は隔離されているので外界は見えません. 例えばIPCは同一空間内に限定されます.

LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術 第2回 コンテナの仕組みとLinuxカーネルのコンテナ機能[1]名前空間とは?

cgroup

cgroupは"Control Group"の略です。プロセスをグループ化して,そのグループ内に存在するプロセスに対して共通の管理を行うために使います。たとえば,ホストOSが持つCPUやメモリなどのリソースに対して,グループごとに制限をかけることができます。

コンテナごとにグループ化してリソース管理できるという機能のようです. コンテナ内のプロセスもホストOS(Linux限定?)が管理しますので, cgroupのような機能でコンテナごとに別グループとしておくことことは重要でしょう. ドキュメントでも同じような解説がされています.

Control groups allow Docker Engine to share available hardware resources to containers and optionally enforce limits and constraints. For example, you can limit the memory available to a specific container.

なんとなく他の二つに比べると具体的な感じがつかめません. リソース管理はOSがしてくれると基本的な書籍に良く書いてあるのですが, ホストOSと切り離されたコンテナと言う単位でリソースを管理する場合はこう言う仕組みが必要になるのかもしれません.

Union FileSystem(UnionFS)

Docker コンテナが軽量だと言われる理由のひとつが、ユニオンファイルシステムにあります。ユニオンファイルシステムは、複数のファイルシステム上のディレクトリやファイルをレイヤとして重ね合わせ、それらを仮想的に一つのファイルシステムとして扱う技術です。

イメージやコンテナのレイヤーをを管理するための機構のようです. レイヤーの実態はファイル群なのですが, このUnion FileSystemを使って仮想的なファ入りシステムとして扱えるようになるようです.

知らないと損する Docker イメージのレイヤ構造とは

実際UnifonFSがどのような機能を提供するかは以下が参考になります. Ubuntuのunionfs-fuseというパッケージを例に説明されています.

まとめて束ねるUnionFSの不思議な世界

なおDockerはいくつかのUnionFSを採用しており, 以下のコマンドを使って調べると私のMacの場合はoverlay2でした.

docker info | grep Storage

まとめ

  • コンテナはOS上で動くプロセスである(Linuxカーネルの場合).
  • ビルドされたDockerイメージからDockerコンテナを実行する.
  • 名前空間を用いて隔離された作業空間をコンテナと呼ぶ.
  • リソースはcgroupでOSによる自動的な割り振りを離れてよりきめ細やかに管理できる.
  • Dockerの内部構造であるレイヤーはUnion FileSystemの機能を使って構築されている.

間違いや勘違いがあれば適宜訂正したいと思います.

Referece

公式

Docker overview
About images, containers, and storage drivers
Glossary

Use multi-stage builds
Create the smallest and secured golang docker image based on scratch
Digging into Docker layers
FROM scratchから始める軽量Docker image for Go
DockerのscratchイメージでHello Worldする


ブレイン

Androidアプリ開発者を目指しています. 興味あることリスト: https://t.co/ew3bb6grdJ Github: https://t.co/9btqysHqWr Qiita: https://t.co/ZVRhjouauX

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント