110
-1- はじめに DockerEngineユーザガイド〜活⽤編 このガイドについて Docker Engine ドキュメント(https://docs.docker.com/)の⽇本語翻訳版(http://docs.docker.jp/)をもとに電 ⼦データ化しました。 現時点ではベータ版であり、内容に関しては無保証です。PDF の評価⽤として公開しました。Docker は活発な 開発と改善が続いています。同様に、ドキュメントもオリジナルですら⽇々書き換えが進んでいますので、あらか じめご了承願います。 このドキュメントに関する問題や翻訳に対するご意⾒がありましたら、GitHub リポジトリ上の Issue までご連 絡いただくか、pull request をお願いいたします。 https://github.com/zembutsu/docs.docker.jp 履歴 2016 年 6 ⽉ 4 ⽇ Docker Engine 活⽤編 beta1 を公開 docs.docker.jp 16/06/04 Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

Embed Size (px)

Citation preview

Page 1: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 1 -

はじめに

DockerEngineユーザガイド〜活⽤編

このガイドについてDocker Engineドキュメント(https://docs.docker.com/)の⽇本語翻訳版(http://docs.docker.jp/)をもとに電

⼦データ化しました。

現時点ではベータ版であり、内容に関しては無保証です。PDF の評価⽤として公開しました。Docker は活発な開発と改善が続いています。同様に、ドキュメントもオリジナルですら⽇々書き換えが進んでいますので、あらかじめご了承願います。このドキュメントに関する問題や翻訳に対するご意⾒がありましたら、GitHub リポジトリ上の Issue までご連

絡いただくか、pull request をお願いいたします。

https://github.com/zembutsu/docs.docker.jp

履歴

2016年6⽉4⽇ Docker Engine 活⽤編beta1を公開

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 2: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 2 -

⽬次

このガイドについて 1

免責事項 1

履歴 1

6.1 MongoDB の Docker 化 9

6 .1 .1 MongoDB ⽤の Dockerfi le を 作成 9

6.1 .2 MongoDB Docker イ メージの構築 11

6 .1 .3 MongoDB イメージを Docker Hub に送信 11

6 .1 .4 MongoDB イメージを使う 11

6.2 Pos tg reSQL の Docker 化 13

6 .1 .2 Docker に Pos tgreSQL をインストール 13

コンテナのリンク機能を使う 14

ホストシステムから接続 14

コンテナ・ボリュームを使う 15

6 .3 CouchDB サービスの Docker 化 16

1つめのデータベースを作成 16

1つめのデータベースにデータを追加 16

2つめのデータベースを作成 16

2つめのデータベースのデータを表⽰ 16

6 .4 Couchbase サービスの Docker 化 17

6 .4 .1 Couchbase サーバの起動 17

6 .4 .2 Couchbase Docker コ ンテナの設定 17

Data と Index サービスのメモリ設定 17

Data・ Query・ index サービスの設定 18

Couchbase サーバの認証情報をセットアップ 19

サンプル・データのインストール 19

CBQ を使って Couchbase に問い合わせ 20

6 .4 .3 Couchbase ウェブ・コンソール 21

6 .5 Node . j s ウ ェブ・アプリの Docker 化 22

6 .5 .1 Node . j s ア プリの作成 22

6.5 .2 Dockerfi le の 作成 22

6 .5 .3 イ メージを構築 24

6 .5 .4 イ メージの実⾏ 24

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 3: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 3 -

6 .5 .5 テ スト 25

6 .6 Red i s サ ービスの Docker 化 26

6 .6 .1 Red i s ⽤ の Docker コ ンテナを作成 26

6 .6 .2 サ ービスの実⾏ 26

6 .6 .3 ウ ェブ・アプリケーションのコンテナを作成 26

6.7 Riak の Docker 化 28

6 .7 .1 Dockerfi le の 作成 28

6 .7 .2 superv i so rd 設定ファイルの作成 29

6 .7 .3 R iak ⽤の Docker イ メージを構築 29

次のステップ 29

6 .8 SSH デーモン⽤サービスの Docker 化 30

6 .8 .1 eg_s shd イメージの構築 30

6 .8 .2 tes t _s shd コンテナの実⾏ 30

6 .8 .3 環 境変数 31

6 .8 .4 ク リーンアップ 31

6 .9 apt -cacher -ng サービスの Docker 化 32

7 .1 コンテナの⾃動起動 35

7 .1 .1 プ ロセス・マネージャを使う場合 35

7 .1 .2 例 35

7 .2 sys temd で Docker の 管理・設定 37

7 .2 .1 Docker デ ーモンの起動 37

7 .2 .2 Docker デ ーモンのオプション変更 37

実⾏時のディレクトリとストレージ・ドライバ 38

HTTP プロキシ 39

7 .2 .3 sys t emd ユニットファイルの⼿動作成 39

7.3 PowerShe l l DSC で使う 40

7 .3 .1 動 作条件 40

7 .3 .2 イ ンストール 40

7 .3 .3 使 い⽅ 40

Docker イ ンストール 40

7 .3 .4 イ メージ 41

7 .3 .5 コ ンテナ 41

7 .4 CFEng ine でプロセス管理 43

7 .4 .1 ど のように動作するのか 43

7 .4 .2 使 い⽅ 43

イメージの構築 43

コンテナのテスト 44

7 .4 .3 ⾃ 分のアプリケーションに適⽤ 45

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 4: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 4 -

7 .5 Chef を 使う 46

7 .5 .1 動 作条件 46

7 .5 .2 イ ンストール 46

7 .5 .3 使 い⽅ 46

7 .5 .4 は じめましょう 46

7 .6 Puppet を 使う 48

7 .6 .1 動 作条件 48

7 .6 .2 イ ンストール 48

7 .6 .3 使 い⽅ 48

インストール 48

イメージ 48

コンテナ 49

7.7 Superv i so r を Docker で 使う 50

7 .7 .1 Dockerfi le の 作成 50

7 .7 .2 Superv i so r の インストール 50

7 .7 .3 Superv i so r の 設定ファイルを追加 50

7 .7 .4 ポ ートの公開と Superv i so r の 実⾏ 51

7 .7 .5 イ メージの構築 51

7 .7 .6 Superv i so r コ ンテナを実⾏ 51

7 .8 各システムの Docker 設 定と実⾏ 52

7 .8 .1 docker デ ーモンを直接実⾏ 52

7 .8 .2 docker デ ーモンを直接設定 52

デーモンのデバッグ 52

7.8 .3 Ubuntu 53

コンテナの実⾏ 53

Docker の 設定 53

ログ 54

7 .8 .4 CentOS / Red Hat Enterpr i se L inux / Fedora 54

Docker の 実⾏ 55

Docker の 設定 55

ログ 56

7 .9 ランタイム・メトリクス(監視) 57

7 .9 .1 コ ントロール・グループ 57

7 .9 .2 コ ントロール・グループの列挙 57

7 .9 .3 特 定のコンテナに割り当てられた cgroup の確認 57

7 .9 .4 cgroups からのメトリクス:メモリ、 CPU、ブロック I/O 58

メモリ・メトリクス:memory . s t a t 58

CPU メトリクス: cpuacct . s t a t 60

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 5: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 5 -

B lock I/O メトリクス 60

7 .9 .5 ネ ットワーク・メトリクス 60

IPtab le s 61

インターフェース・レベルのカウンタ 61

7 .9 .6 ⾼ 性能なメトリクス収集⽤の Tip 62

7 .9 .7 終 了したコンテナのメトリクスを収集 62

7 .10 アンバサダを経由したリンク 64

7 .10 .1 はじめに 64

7 .10 .2 2つのホスト例 64

7 .10 .3 動作内容 65

7 .10 .4 svendowide i t /ambassador Docker fi l e 66

7 .11 ログ保存 67

7 .11 .1 ロギング・ドライバの設定 67

JSON ファイルのオプション 67

sys log のオプション 68

journa ld オプション 69

ge l f オ プション 69

fl uentd オプション 69

Amazon CloudWatch Logs オプションの指定 70

ETW ロギング・ドライバのオプション 70

Goog le C loud ロギング 70

7 .11 .2 ログ⽤のタグ 70

7 .11 .3 Amazon Cloud Watch ロギング・ドライバ 71

使い⽅ 72

Amazon CloudWatch ログのオプション 72

認証情報 72

7 .11 .4 ETW ロギング・ドライバ 73

使い⽅ 73

7 .11 .5 F luentd ロギング・ドライバ 74

使い⽅ 74

オプション 75

Docker と Fluentd デーモンの管理 75

7 .11 .6 Goog le C loud ロギング・ドライバ 76

使い⽅ 76

gpc logs オ プション 76

7 .11 .7 Sp lunk ロギング・ドライバ 77

使い⽅ 77

Sp lunk オプション 77

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 6: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 6 -

7 .11 .8 Journa ld ロギング・ドライバ 78

使い⽅ 78

オプション 79

コンテナ名に関する考慮点 79

journa l c t l で ログメッセージを表⽰ 79

journa l API でログメッセージを表⽰ 79

8 .1 安全な Engine 80

8 .2 Docker の セキュリティ 81

8 .2 .1 カ ーネルの名前空間 81

8 .2 .2 コ ントロール・グループ 81

8 .2 .3 Docker デ ーモンが直⾯する攻撃 82

8 .2 .4 L inux カーネルのケーパビリティ 82

8 .2 .5 そ の他のカーネル・セキュリティ機能 84

8 .2 .6 ま とめ 84

8 .3 Docker デ ーモンのソケットを守る 86

8 .3 .1 OpenSSL で CA(サーバとクライアントの鍵)を作成 86

8 .3 .2 デ フォルトで安全に 88

8 .3 .3 他 のモード 88

デーモン・モード 88

クライアント・モード 89

cur l を 使って Docker ポ ートに安全に接続 89

8 .4 リポジトリのクライアント認証で証明書 90

8 .4 .1 設 定の理解 90

8 .4 .2 ク ライアント証明書の作成 90

8 .4 .3 上 ⼿くいかない場合の確認点 91

9 .1 Docker プ ラグインの理解 92

9 .1 .1 プ ラグインの種類 92

9 .1 .2 プ ラグインのインストール 92

9 .1 .3 プ ラグインを探す 92

9 .1 .4 プ ラグインのトラブルシューティング 94

9 .1 .5 プ ラグインを書くには 94

9 .2 Docker ネ ットワーク・プラグイン 95

9 .2 .1 ネ ットワーク・ドライバ・プラグインを使う 95

9 .2 .2 ネ ットワーク・プラグインを書くには 95

9 .2 .3 ネ ットワーク・プラグイン・プロトコル 95

9 .3 Docker ボ リューム・プラグインを書く 96

9 .3 .1 コ マンドラインの変更 96

9 .3 .2 ボ リューム・ドライバの作成 96

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 7: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 7 -

9 .3 .3 ボ リューム・プラグイン・プロトコル 96

/Vo lumeDr iver .Crea te 96

/Vo lumeDr iver .Remove 97

/Vo lumeDr iver .Mount 97

/Vo lumeDr iver .Pa th 98

10 .1 よくある質問と回答 (FAQ) 99

Docker を 使うには、どれだけの費⽤がかかりますか? 99

オープンソースのライセンスは何を使っていますか? 99

Mac OS X や Windows で Docker は 動きますか? 99

コンテナと仮想マシンの違いは何ですか? 99

なぜ Docker は LXC に技術を追加しようとしたのですか? 99

Docker コ ンテナと仮想マシンの違いは何ですか? 101

コンテナを終了するとデータが失われますか? 101

Docker コ ンテナは、どれだけスケールできますか? 101

Docker コ ンテナにどうやって接続しますか? 101

Docker コ ンテナで複数のプロセスを実⾏するには? 101

どのプラットフォーム上で Docker は 動きますか? 101

Docker の セキュリティ問題はどこに報告したらよいですか? 102

なぜ Docker の DCO で署名してからコミットする必要があるのですか? 102

イメージの構築時、望ましいシステムライブラリや同梱物はありますか? 102

なぜ Dockerfi le で DEBIAN_FRONTEND=nonin terac t i ve な のですか? 103

実⾏中のコンテナ上のサービスにリクエストを送ると Connec t ion rese t by peer が 出る

のはなぜ? 103

docker-mach ine 利⽤時に Cannot connect to . . . .と いうエラーが出ます 103

他にも答えを探せますか? 104

10 .2 廃⽌機能 105

docker log in の -e および --emai l フ ラグ 105

イベント API における不明確なフィールド 105

docker tag の -f フ ラグ 105

API による HostConfi g を使ったコンテナ開始 105

docker ps の 「 before」「 since」オプション 105

コマンドラインの短縮オプション 105

ログ⽤のドライバを指定するタグ 106

内部 LXC 実⾏ドライバ 106

古いコマンドライン・オプション 106

V1 レジストリとの通信 107

Docker Content Trus t ENV パスフレーズの変数名を変更 107

10 .3 破壊的変更と⾮互換性 108

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 8: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 8 -

10 .3 .1 Eng ine 1 .10 108

Reg i s t ry 108

Docker Content Trus t 108

10 .4 Engine 1 .10 への移⾏ 109

10 .4 .1 ア ップグレードの準備 109

10 .4 .2 移 ⾏時間の最⼩化 109

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 このガイドについて

Page 9: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //www.mongodb .org/

*2 ht tps ://hub .docker . com/_/mongo/

- 9 -

6 章 アプリケーションのDocker 化

6.1 MongoDBの Docker 化この例では、MongoDB*1 がインストール済みのDocker イメージを、どのようにして構築するかを学びます。ま

モンゴデービー

た、イメージをDocker Hubレジストリに送信して、他⼈と共有する⽅法も理解します。

このガイドではMongoDBコンテナを構築する仕組みを紹介しますが、Docker Hubの公式イメージ*2を使っても構いません。

Docker を使いMongoDBインスタンスをデプロイしたら、次のメリットがあります。

簡単なメンテナンス、MongoDBインスタンスの⾼い設定性 ミリ秒以内で実⾏と開始 どこからでも接続可能で共有できるイメージに基づく

構築⽤の Dockerfileを作成しましょう。

$ nano Dockerfile

オプションですが、Dockerfileの冒頭に⾃⾝の役割などをコメントしておくと便利です。

# MongoDB の Docker化:MongoDB イメージを構築する Dockerfile# ubuntu:latest をベースとし、MongoDB は以下の手順でインストール:# http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/

Dockerfile は柔軟性がありますが、特定の書式に従う必要があります。最初に必要になるのは、これから作成するMongoDBをDocker 化したイメージの親にあたるイメージ名の定義です。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.1 MongoDBのDocker化

Page 10: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps ://hub .docker . com/_/ubuntu/

- 10 -

Docker Hub Ubuntu リポジトリ*1 にあるUbuntuの バージョンを使い、イメージを構築します。レイテスト

# 書式:FROM リポジトリ[:バージョン]FROM ubuntu:latest

続けて、Dockerfileの を宣⾔します。メ ン テ ナ

# 書式:MAINTAINER 名前 <[email protected]>MAINTAINER M.Y. Name <[email protected]>

Ubuntu システムにもMongoDBパッケージがありますが、作成⽇が古いものです。そのため、この例では公式のMongoDBパッケージを使います。

MongoDB 公開GPG鍵を取り込みます。また、パッケージ・マネージャ⽤にMongoDB リポジトリ・ファイルも作成します。

# インストール:# MongoDB 公開 GPG 鍵を取り込み、MongoDB リストファイルを作成RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10RUN echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" \

| tee /etc/apt/sources.list.d/mongodb-org-3.0.list

この初期準備が終われば、パッケージを更新し、MongoDBをインストールできます。

# apt-get ソースを更新し、MongoDB をインストールRUN apt-get update && apt-get install -y mongodb-org

MongoDB のバージョンを指定したインストールできます。そのためには、次の例のようにパッケージのバージョン番号のリストが必要です。

RUN apt-get update && apt-get install -y mongodb-org=3.0.1 mongodb-org-server=3.0.1 \mongodb-org-shell=3.0.1 mongodb-org-mongos=3.0.1 mongodb-org-tools=3.0.1

MongoDBはデータ・ディレクトリが必要です。インストール命令ステップで作成を命令しましょう。

# MongoDB データ・ディレクトリの作成RUN mkdir -p /data/db

最後に ENTRYPOINT を設定します。これは Docker に対して MongoDB イメージでコンテナを起動する時、コンテナ内で mongodを実⾏するよう命令します。そして、ポートを公開するために EXPOSE命令を使います。

# コンテナのポート 27017 をホスト側に露出(EXPOSE)

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.1 MongoDBのDocker化

Page 11: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/docker/docker/b lob/mas te r/docs/examples/mongodb/Docker fi l e

- 11 -

EXPOSE 27017

# usr/bin/mongod を Docker 化アプリケーションのエントリ・ポイントに設定ENTRYPOINT ["/usr/bin/mongod"]

ファイルを保存したら、イメージを構築しましょう。

この Dockerfileの完成版はこちら*1 をご覧ください。

6.1.2 MongoDB Docker イメージの構築

作成した Dockerfile を使い、新しい MongoDB イメージを Docker で構築できます。テスト⽤でない限り、docker buildコマンドに --tagオプションを通してDocker イメージをタグ付けするのが良い⼿法です。

# 書式:docker build --tag/-t <ユーザ名>/<リポジトリ># 例$ docker build --tag my/repo .

コマンドを実⾏したら、Docker は Dockerfile を処理してイメージを構築します。イメージは最終的に my/repo

とタグ付けされます。

全てのDocker イメージ・リポジトリをDocker Hubで保管・共有できるようにするには、docker pushコマンドを使います。送信するためには、ログインの必要があります。

# ログイン$ docker loginUsername:..

# イメージを送信# 書式:docker push <ユーザ名>/<リポジトリ>$ docker push my/repoThe push refers to a repository [my/repo] (len: 1)Sending image listPushing repository my/repo (1 tags)..

6.1.4 MongoDB イメージを使う

作成したMongoDBイメージを使い、他のMongoDBインスタンスをデーモン・プロセスとして実⾏できます。

# 基本的な方法# 使い方:docker run --name <コンテナ名> -d <ユーザ名>/<リポジトリ>$ docker run -p 27017:27017 --name mongo_instance_001 -d my/repo

# Docker 化した Mongo DB 、学び理解しました!# 使い方:docker run --name <コンテナ名> -d <ユーザ名>/<リポジトリ> --noprealloc --smallfiles

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.1 MongoDBのDocker化

Page 12: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 12 -

$ docker run -p 27017:27017 --name mongo_instance_001 -d my/repo --smallfiles

# MongoDB コンテナのログを確認# 使い方:docker logs <コンテナ名>$ docker logs mongo_instance_001

# MongoDB を使う# 使い方:mongo --port <`docker ps` で得られるポート>$ mongo --port 27017

# If using docker-machine# docker-machine を使う場合# 使い方:mongo --port <`docker ps` で得られるポート> --host <`docker-machine ip VM名`の IP アドレス>$ mongo --port 27017 --host 192.168.59.103

ちなみに、もし同じエンジン上で2つのコンテナを実⾏したい場合、ホスト側は2つの異なったポートを各コンテナに割り当てる必要があります。

# 2つのコンテナを起動し、ポートを割り当て$ docker run -p 28001:27017 --name mongo_instance_001 -d my/repo$ docker run -p 28002:27017 --name mongo_instance_002 -d my/repo

# 各 MongoDB インスタンスのポートに接続できる$ mongo --port 28001$ mongo --port 28002

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.1 MongoDBのDocker化

Page 13: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 13 -

6.2 PostgreSQL の Docker 化

6.1.2 Docker に PostgreSQL をインストール

ここではDocker Hubで配布されているDocker イメージを使っていますが、⾃分⾃⾝で作成しても構いません。まず、新しい Dockerfileを作成します。

この PostgreSQL のセットアップは、開発⽤途専⽤です。より安全にするためには、PostgreSQLのドキュメントを参照し、適切に調整ください。

## https://docs.docker.com/examples/postgresql_service/ にあるサンプルの Dockerfile です#

FROM ubuntuMAINTAINER [email protected]

# Add the PostgreSQL PGP key to verify their Debian packages.# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.ascRUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keysB97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

# Add PostgreSQL's repository. It contains the most recent stable release# of PostgreSQL, ``9.3``.RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" >/etc/apt/sources.list.d/pgdg.list

# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3# There are some warnings (in red) that show up during the build. You can hide# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get install -y python-software-properties software-properties-commonpostgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3

# Note: The official Debian and Ubuntu images automatically ``apt-get clean``# after each ``apt-get``

# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was``apt-get installed``USER postgres

# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and# then create a database `docker` owned by the ``docker`` role.# Note: here we use ``&&\`` to run commands one after the other - the ``\``# allows the RUN command to span multiple lines.RUN /etc/init.d/postgresql start &&\

psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\createdb -O docker docker

# Adjust PostgreSQL configuration so that remote connections to the# database are possible.RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf

# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.2 PostgreSQLのDocker化

Page 14: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 14 -

RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf

# Expose the PostgreSQL portEXPOSE 5432

# Add VOLUMEs to allow backup of config, logs and databasesVOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

# Set the default command to run when starting the containerCMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c","config_file=/etc/postgresql/9.3/main/postgresql.conf"]

Dockerfile で構築するイメージに名前を割り当てます。

$ docker build -t eg_postgresql .

それからPostgreSQLサーバコンテナを(フォアグラウンドで)実⾏します。

$ docker run --rm -P --name pg_test eg_postgresql

PostgreSQL サーバに接続するには2つの⽅法があります。 コンテナをリンクするか、ホスト側(あるいはネットワーク側)から接続できます。

--rm

クライアントの docker run時に -link リモート名:ローカル・エイリアス を指定時、コンテナが他のコンテナのポートに直接接続できるようになります。これは接続のために使える複数の環境変数を作成します。

$ docker run --rm -t -i --link pg_test:pg eg_postgresql bash

postgres@7ef98b1b7243:/$ psql -h $PG_PORT_5432_TCP_ADDR -p $PG_PORT_5432_TCP_PORT -d docker -U docker--password

ホストシステムから接続

postgresql クライアントがインストールされていれば、ホスト側に割り当てられたポートに対しても、同様にテストできます。docker psでコンテナがどこのポートに割り当てられているか確認します。

$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS

PORTS NAMES5e24362f27f6 eg_postgresql:latest /usr/lib/postgresql/ About an hour ago Up About an hour0.0.0.0:49153->5432/tcp pg_test

$ psql -h localhost -p 49153 -d docker -U docker --password

データベースのテスト

認証すると docker =#プロンプトが表⽰され、テーブル作成を処理できます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.2 PostgreSQLのDocker化

Page 15: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 15 -

psql (9.3.1)Type "help" for help.

$ docker=# CREATE TABLE cities (docker(# name varchar(80),docker(# location pointdocker(# );CREATE TABLE$ docker=# INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');INSERT 0 1$ docker=# select * from cities;

name | location---------------+-----------San Francisco | (-194,53)(1 row)

コンテナ・ボリュームを使う

PostgreSQLのログファイル調査や、設定やデータのバックアップのために、ボリュームを定義できます。

$ docker run --rm --volumes-from pg_test -t -i busybox sh

/ # lsbin etc lib linuxrc mnt proc run sys usrdev home lib64 media opt root sbin tmp var/ # ls /etc/postgresql/9.3/main/environment pg_hba.conf postgresql.confpg_ctl.conf pg_ident.conf start.conf/tmp # ls /var/logldconfig postgresql

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.2 PostgreSQLのDocker化

Page 16: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 16 -

6.3 CouchDBサービスのDocker 化2つの CouchDB コンテナ間で同じデータを共有するため、ここでは例としてデータ・ボリュームを使います。

これはホット・アップグレード、同じデータを使った異なったCouchDBバージョンのテストなどに便利です。

/var/lib/couchdbをデータ・ボリュームとして作成するのに注意してください。

$ COUCH1=$(docker run -d -p 5984 -v /var/lib/couchdb shykes/couchdb:2013-05-03)

Docker ホストは到達可能な localhostを想定しています。もしそうでなければ、localhostをDocker ホストのパブリックIPアドレスに置き換えてください。

$ HOST=localhost$ URL="http://$HOST:$(docker port $COUCH1 5984 | grep -o '[1-9][0-9]*$')/_utils/"$ echo "Navigate to $URL in your browser, and use the couch interface to add data"

今回は$COUCH1のボリュームに対する共有アクセスをリクエストします。

$ COUCH2=$(docker run -d -p 5984 --volumes-from $COUCH1 shykes/couchdb:2013-05-03)

$ HOST=localhost$ URL="http://$HOST:$(docker port $COUCH2 5984 | grep -o '[1-9][0-9]*$')/_utils/"$ echo "Navigate to $URL in your browser. You should see the same data as in the first database"'!'

おめでとうございます。2つのCouchdbコンテナを実⾏し、お互いのデータを完全に隔離しました。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.3 CouchDBサービスのDocker化

Page 17: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //couchbase . com/

*2 ht tp : //deve loper . couchbase . com/documenta t ion/server/4 .0/res t -ap i/ re s t -endpo int s -a l l .h tm l

*3 ht tps ://hub .docker . com/_/couchbase/

*4 ht tp : //deve loper . couchbase . com/documenta t ion/server/4 .1/ ins ta l l / ins ta l l -por t s .h tml

- 17 -

6.4 Couchbase サービスのDocker 化この例ではDocker Composeを使いCouchbase*1 サーバを起動し、 REST API*2 を使えるように設定し、結果を

カ ウ チ ベ ー ス レストエーピーアイ

確認します。Couchbase はオープンソースです。そして、最近のウェブ、モバイル、IoT アプリケーション向けのドキュメン

ト指向 N o S Q L データベースです。簡単な開発とインターネットで性能をスケールできるように設計されていまノーエスキユーエル

す。

Couchbase Docker イメージはDocker Hub上*3 で公開されています。Couchbase サーバは次のように起動します:

docker run -d --name db -p 8091-8093:8091-8093 -p 11210:11210 couchbase

各ポートを公開する理由は、Couchbase Developer Portal - Network Configuration *4 をご覧ください。

ログには次のように表⽰されます:

docker logs dbStarting Couchbase Server -- Web UI available at http://<ip>:8091

このページの例では、接続先のDocker ホストの IP アドレスは 192.168.99.100 を前提にしています。192.168.88.100 は実際の Docker ホストの IP アドレスに置き換えてください。DockerMachineでDockerを実⾏している場合は、次のコマンドで IPアドレスを確認できます。docker-machine ip <マシン名>

Couchbase コンソールには http://192.168.99.100:8091 でアクセスできます。デフォルトのユーザ名はAdministrator、パスワードは passwordです。

通常はCouchbase サーバを使う前にコンソール上での設定が必要です。これをREST API を使えば簡単に設定できます。

Couchbase インスタンス上では、Data・Query・Index は別々のサービスです。各サービスは別々の設定が必要です。例えば、QueryはCPUの処理が集中するため、より速いCPUが必要です。 Indexはディスクが重いため、速いSSDが必要です。Dataは読み書きを速くするため、より多くのメモリが必要です。メモリが必要になる設定はDataと Index サービスのみです。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.4 CouchbaseサービスのDocker化

Page 18: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 18 -

curl -v -X POST http://192.168.99.100:8091/pools/default -d memoryQuota=300 -d indexMemoryQuota=300* Hostname was NOT found in DNS cache* Trying 192.168.99.100...* Connected to 192.168.99.100 (192.168.99.100) port 8091 (#0)> POST /pools/default HTTP/1.1> User-Agent: curl/7.37.1> Host: 192.168.99.100:8091> Accept: */*> Content-Length: 36> Content-Type: application/x-www-form-urlencoded>* upload completely sent off: 36 out of 36 bytes< HTTP/1.1 401 Unauthorized< WWW-Authenticate: Basic realm="Couchbase Server Admin / REST"* Server Couchbase Server is not blacklisted< Server: Couchbase Server< Pragma: no-cache< Date: Wed, 25 Nov 2015 22:48:16 GMT< Content-Length: 0< Cache-Control: no-cache<* Connection #0 to host 192.168.99.100 left intact

これはRESTエンドポイント /pools/default にHTTP POSTリクエストを送信した結果です。ホストとはDocker Machine の IPアドレスです。ポートはCouchbase サーバによって公開されているものです。サーバに対して、メモリとインデックスに対する制限(quota)をリクエストしています。

3つの全サービス、または、1つに対しての設定が可能です。これにより、それぞれのアフィニティ(ハードウェア要件等)、サービスを適切にセットアップします。例えば、Data サービスが開始できるのは、Docker ホストがSSDマシン上で動作している場所といった指定です。

curl -v http://192.168.99.100:8091/node/controller/setupServices -d 'services=kv%2Cn1ql%2Cindex'* Hostname was NOT found in DNS cache* Trying 192.168.99.100...* Connected to 192.168.99.100 (192.168.99.100) port 8091 (#0)> POST /node/controller/setupServices HTTP/1.1> User-Agent: curl/7.37.1> Host: 192.168.99.100:8091> Accept: */*> Content-Length: 26> Content-Type: application/x-www-form-urlencoded>* upload completely sent off: 26 out of 26 bytes< HTTP/1.1 200 OK* Server Couchbase Server is not blacklisted< Server: Couchbase Server< Pragma: no-cache< Date: Wed, 25 Nov 2015 22:49:51 GMT< Content-Length: 0< Cache-Control: no-cache<* Connection #0 to host 192.168.99.100 left intact

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.4 CouchbaseサービスのDocker化

Page 19: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 19 -

これはRESTエンドポイント /node/controller/setupServices にHTTP POSTリクエストを送信した結果です。コマンドの結果は、Couchbase サーバ⽤に3つのサービスが設定されています。Data サービスは kv、Queryサービスは n1ql、Indexサービスは indexなのが分かります。

あとでCouchbase サーバを管理するため、ユーザ名とパスワードの認証情報を設定します。

curl -v -X POST http://192.168.99.100:8091/settings/web -d port=8091 -d username=Administrator -dpassword=password* Hostname was NOT found in DNS cache* Trying 192.168.99.100...* Connected to 192.168.99.100 (192.168.99.100) port 8091 (#0)> POST /settings/web HTTP/1.1> User-Agent: curl/7.37.1> Host: 192.168.99.100:8091> Accept: */*> Content-Length: 50> Content-Type: application/x-www-form-urlencoded>* upload completely sent off: 50 out of 50 bytes< HTTP/1.1 200 OK* Server Couchbase Server is not blacklisted< Server: Couchbase Server< Pragma: no-cache< Date: Wed, 25 Nov 2015 22:50:43 GMT< Content-Type: application/json< Content-Length: 44< Cache-Control: no-cache<* Connection #0 to host 192.168.99.100 left intact{"newBaseUri":"http://192.168.99.100:8091/"}

これはRESTエンドポイント /settings/web にHTTP POSTリクエストを送信した結果です。ユーザ名とパスワードの認証情報がリクエスト中に含まれています。

サンプル・データのインストール

Couchbase サーバはcouchbase インスタンス内で簡単にサンプル・データを読み込めます。

curl -v -u Administrator:password -X POST http://192.168.99.100:8091/sampleBuckets/install -d'["travel-sample"]'* Hostname was NOT found in DNS cache* Trying 192.168.99.100...* Connected to 192.168.99.100 (192.168.99.100) port 8091 (#0)* Server auth using Basic with user 'Administrator'> POST /sampleBuckets/install HTTP/1.1> Authorization: Basic QWRtaW5pc3RyYXRvcjpwYXNzd29yZA==> User-Agent: curl/7.37.1> Host: 192.168.99.100:8091> Accept: */*> Content-Length: 17> Content-Type: application/x-www-form-urlencoded>* upload completely sent off: 17 out of 17 bytes

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.4 CouchbaseサービスのDocker化

Page 20: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //deve loper . couchbase . com/documenta t ion/server/4 .1/c l i /cbq- too l .h tml

* 2

h t tp : //deve loper . couchbase .com/documenta t i on/se rve r/4 .1/n1q l/n1q l - l anguage- re fe rence/ index .h tm

l

- 20 -

< HTTP/1.1 202 Accepted* Server Couchbase Server is not blacklisted< Server: Couchbase Server< Pragma: no-cache< Date: Wed, 25 Nov 2015 22:51:51 GMT< Content-Type: application/json< Content-Length: 2< Cache-Control: no-cache<* Connection #0 to host 192.168.99.100 left intact[]

これはRESTエンドポイント /sampleBuckets/install にHTTP POSTリクエストを送信した結果です。サンプル・バケット名をリクエスト中に指定します。おつかれさまでした。Couchbase コンテナの設定を、全てREST APIを使って⾏いました。

CBQ を使って Couchbase に問い合わせ

CBQ*1 は Couchbase への問い合わせを省略するコマンドライン・ツールです。これは Couchbase サーバに対してJSONドキュメントの作成・読み込み・更新・削除が可能です。ツールはCouchbase Docker イメージに同梱されています。CBQ ツールの実⾏:

docker run -it --link db:db couchbase cbq --engine http://db:8093Couchbase query shell connected to http://db:8093/ . Type Ctrl-D to exit.cbq>

--engineパラメータは、CBQ にDocker ホスト上で動いている Couchbase サーバのホストとポートを指定します。ホストとは、通常、Couchbaseサーバを実⾏しているホストの名前もしくはIPアドレスです。今回の例では、コンテナを起動時に指定したコンテナ名 dbとポート 8093が全てのクエリを受け付けます。Couchbase にはN1QL*2 を使う JSONドキュメントで問い合わせます。N1QLは包括的な宣⾔型クエリ⾔語であ

り、JSONドキュメントにSQLのような機能を持たせます。N1QLクエリを使ってデータベースに問い合わせます:

cbq> select * from `travel-sample` limit 1;{

"requestID": "97816771-3c25-4a1d-9ea8-eb6ad8a51919","signature": {

"*": "*"},"results": [

{"travel-sample": {

"callsign": "MILE-AIR","country": "United States",

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.4 CouchbaseサービスのDocker化

Page 21: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //deve loper . couchbase . com/documenta t ion/server/4 .1/admin/u i- in t ro .h tml

- 21 -

"iata": "Q5","icao": "MLA","id": 10,"name": "40-Mile Air","type": "airline"

}}

],"status": "success","metrics": {

"elapsedTime": "60.872423ms","executionTime": "60.792258ms","resultCount": 1,"resultSize": 300

}}

6.4.3 Couchbase ウェブ・コンソール

Couchbase ウェブ・コンソール*1 は Couchbase インスタンスを管理できるコンソールです。次の URL で表⽰します。

http://192.168.99.100:8091/

この IPアドレスの部分はDocker Machineの IPアドレスか、ローカルで動かしている場合は localhostです。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.4 CouchbaseサービスのDocker化

Page 22: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //expre ss j s . com/

- 22 -

6.5 Node.js ウェブ・アプリのDocker 化この例のゴールは、Dockerfile を使い、親イメージから⾃分の Docker イメージを構築できるようにする⽅法を

理解します。ここではCentOS 上で簡単なNode.js の hello world ウェブ・アプリケーションを実⾏します。ソースコード全体は https://github.com/enokd/docker-node-hello/ から⼊⼿できます。

6.5.1 Node.js アプリの作成

まず、全てのファイルを置く src ディレクトリを作成します。それから package.json ファイルを作成し、アプリケーションと依存関係について記述します。

{"name": "docker-centos-hello","private": true,"version": "0.0.1","description": "Node.js Hello world app on CentOS using docker","author": "Daniel Gasienica <[email protected]>","dependencies": {"express": "3.2.4"

}}

次に index.jsファイルを作成し、ウェブアプリがExpress.js*1 フレームワークを使うように定義します。

var express = require('express');

// Constantsvar PORT = 8080;

// Appvar app = express();app.get('/', function (req, res) {res.send('Hello world\n');

});

app.listen(PORT);console.log('Running on http://localhost:' + PORT);

次のステップでは、Docker が CentOS コンテナの中で、どのようにこのアプリを実⾏するかを理解していきます。まず、⾃分のアプリを動かす Docker イメージを作成します。

Dockerfileという名称の空ファイルを作成します。

touch Dockerfile

好みのエディタで Dockerfileを開きます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.5 Node.jsウェブ・アプリのDocker化

Page 23: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps :// reg i s t ry .hub .docker . com/_/centos/

* 2

h t tps : //g i thub . com/ joyen t/node/wik i/ Ins t a l l ing-Node . j s - v i a -package -manager#rhe lcentos sc ien t i f i c - l

inux-6

- 23 -

⾃分のイメージの構築に使いたい親イメージを定義します。ここではDocker Hub上で利⽤可能なCentOS*1(タグ:centos6)を使います。

FROM centos:centos6

Node.js アプリを作るために、CentOS イメージ上にNode.js と npm をインストールします。アプリケーションの実⾏にはNode.js が必要です。また、package.jsonで定義したアプリケーションをインストールするためにnpmも必要です。CentOS⽤の適切なパッケージをインストールするため、Node.js wiki*2 の指⽰に従って作業します。

# Enable Extra Packages for Enterprise Linux (EPEL) for CentOSRUN yum install -y epel-release# Install Node.js and npmRUN yum install -y nodejs npm

npmバイナリでアプリケーションの依存関係をインストールします。

# Install app dependenciesCOPY package.json /src/package.jsonRUN cd /src; npm install --production

アプリケーションのソースコードをDocker イメージに取り込むため、COPY命令を使います。

# Bundle app sourceCOPY . /src

アプリケーションはポート 8080を利⽤のため、EXPOSE命令を使い dockerデーモンがポートを割り当てるようにします。

EXPOSE 8080

最後にあと少し、実⾏時にアプリケーションを実⾏できるよう CMD 命令でコマンドを定義します。例えば node

と、アプリケーション、例えば src/index.js を指定します(ソースファイルは前の⼿順でコンテナに加えていました)。

CMD ["node", "/src/index.js"]

これで Dockerfileは次のようになります。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.5 Node.jsウェブ・アプリのDocker化

Page 24: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 24 -

FROM centos:centos6

# Enable Extra Packages for Enterprise Linux (EPEL) for CentOSRUN yum install -y epel-release# Install Node.js and npmRUN yum install -y nodejs npm

# Install app dependenciesCOPY package.json /src/package.jsonRUN cd /src; npm install --production

# Bundle app sourceCOPY . /src

EXPOSE 8080CMD ["node", "/src/index.js"]

6.5.3 イメージを構築

Dockerfile のあるディレクトリに移動し、Docker イメージを構築するため次のコマンドを実⾏します。-t フラグを使いイメージにタグを付ければ、あとから docker imagesコマンドで簡単に探せます。

$ docker build -t <自分のユーザ名>/centos-node-hello .

作成したイメージは、Docker のイメージ⼀覧に表⽰されます。

$ docker images

# ExampleREPOSITORY TAG ID CREATEDcentos centos6 539c0211cd76 8 weeks ago<your username>/centos-node-hello latest d64d3505b0d2 2 hours ago

イメージに -d を付けて実⾏したら、コンテナはデタッチド・モードで動作します。これは、コンテナをバックグラウンドで動作するものです。 -pフラグで、コンテナ内のプライベートなポートを公開ポートに渡します。

$ docker run -p 49160:8080 -d <自分のユーザ名>/centos-node-hello

アプリケーションの出⼒を表⽰します。

# Get container ID$ docker ps

# Print app output$ docker logs <container id>

# ExampleRunning on http://localhost:8080

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.5 Node.jsウェブ・アプリのDocker化

Page 25: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 25 -

6.5.5 テスト

アプリケーションをテストするには、Docker でアプリケーションにポートを割り当てます。

$ docker ps

# ExampleID IMAGE COMMAND ... PORTSecce33b30ebf <your username>/centos-node-hello:latest node /src/index.js 49160->8080

この例は、Docker はコンテナのポート 8080をポート 49160に割り当てます。これで curlを使ってアプリケーションを呼び出せます(インストールの必要があれば sudo apt-get install curl

を実⾏します。 )。

$ curl -i localhost:49160

HTTP/1.1 200 OKX-Powered-By: ExpressContent-Type: text/html; charset=utf-8Content-Length: 12Date: Sun, 02 Jun 2013 03:53:22 GMTConnection: keep-alive

Hello world

OS X上でDocker Machineを使っている場合は、ポートが実際に割り当てられているのはDocker ホストの VM側であり、次のコマンドを使う必要があります。

$ curl $(docker-machine ip VM_NAME):49160

私たちはこのチュートリアルが、Docker 上で Node.js と CentOS を動かす⼿助けになるのを望みます。全てのソースコードは https://github.com/enokd/docker-node-hello/ にあります。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.5 Node.jsウェブ・アプリのDocker化

Page 26: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 26 -

6.6 Redis サービスのDocker 化⾮常にシンプルで飾り気の無い Redis サービスを、リンク機能を使ってウェブ・アプリケーションにアタッチし

ます。

6.6.1 Redis ⽤の Docker コンテナを作成

まず、新しいRedis イメージ⽤の Dockerfileを作成します。

FROM ubuntu:14.04RUN apt-get update && apt-get install -y redis-serverEXPOSE 6379ENTRYPOINT ["/usr/bin/redis-server"]

次に、Dockerfileからイメージを構築します。 <自分の名前> の場所は、⾃分⾃⾝のリポジトリ名に置き換えてください。

$ docker build -t <自分のユーザ名>/redis .

先ほど作成したイメージを使い、コンテナ名を redisとします。コンテナに -d を付けて実⾏したら、デタッチド・モードとして実⾏され、コンテナはバックグラウンドで動作

します。重要なのは、コンテナ内のポートを全く公開していない点です。そのかわり、Redis データベースに接続するに

は、コンテナに対するリンク機能を使います。

$ docker run --name redis -d <自分の名前>/redis

6.6.3 ウェブ・アプリケーションのコンテナを作成

次にアプリケーションのコンテナを作成します。 --link フラグを使い、redisコンテナに対するリンクを作成します。ここでは dbというエイリアス(別名)で作成します。これにより、redisコンテナと安全なトンネルが作成されます。Redis インスタンスが公開しているコンテナ内のポートには、ここで指定したコンテナだけ接続できるようになります。

$ docker run --link redis:db -i -t ubuntu:14.04 /bin/bash

新しく作成したコンテナの中では、接続をテストするために redis-cli バイナリの取得・インストールが必要です。

$ sudo apt-get update$ sudo apt-get install redis-server$ sudo service redis-server stop

それから --link redis:db オプションを使い、Docker がウェブ・アプリケーションのコンテナ内で利⽤可能な環境変数を作成します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.6 RedisサービスのDocker化

Page 27: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 27 -

$ env | grep DB_

# Should return something similar to this with your valuesDB_NAME=/violet_wolf/dbDB_PORT_6379_TCP_PORT=6379DB_PORT=tcp://172.17.0.33:6379DB_PORT_6379_TCP=tcp://172.17.0.33:6379DB_PORT_6379_TCP_ADDR=172.17.0.33DB_PORT_6379_TCP_PROTO=tcp

ここでは DB が接頭語となっている複数の環境変数が⾒えます。DB とはコンテナ起動時に指定した、リンクのエイリアスです。DB_PORT_6379_TCP_ADDRを使ってRedis コンテナに接続してみましょう。

$ redis-cli -h $DB_PORT_6379_TCP_ADDR$ redis 172.17.0.33:6379>$ redis 172.17.0.33:6379> set docker awesomeOK$ redis 172.17.0.33:6379> get docker"awesome"$ redis 172.17.0.33:6379> exit

ウェブ・アプリケーションが redis コンテナに接続するために、この環境変数や他の環境変数を利⽤できます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.6 RedisサービスのDocker化

Page 28: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps ://hub .docker . com/_/ubuntu/

- 28 -

6.7 Riak の Docker 化この例は、Riak がインストール済みの Docker イメージをどのように構築するかを紹介するのが⽬的です。

Dockerfileという名称の空ファイルを作成します。

$ touch Dockerfile

次に、⾃分のイメージを構築するにあたり、元になる親イメージを定義します。ここではDocker Hubで利⽤可能なUbuntu*1(タグ:trusty)を使います。

# Riak## VERSION 0.1.1

# Use the Ubuntu base image provided by dotCloudFROM ubuntu:trustyMAINTAINER Hector Castro [email protected]

次は、curl をインストールします。curl はリポジトリのセットアップ・スクリプトをダウンロードし、実⾏するためです。

# Install Riak repository before we do apt-get update, so that update happens# in a single stepRUN apt-get install -q -y curl && \

curl -fsSL https://packagecloud.io/install/repositories/basho/riak/script.deb | sudo bash

それから、いくつかの依存関係のインストールとセットアップをします。

supervisorはRiakプロセスの管理に使⽤ riak-2.0.5-1はRiackバージョン2.0.5 のパッケージ

# プロジェクトの依存関係をインストール・セットアップRUN apt-get update && \

apt-get install -y supervisor riak=2.0.5-1

RUN mkdir -p /var/log/supervisor

RUN locale-gen en_US en_US.UTF-8

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

それから、Riakの設定を変更します。

# Riak が、あらゆるホストから接続できるよう設定

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.7 RiakのDocker化

Page 29: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //basho .com/why-your- r iak-c lus te r - shou ld-have-a t - l eas t - fi ve -nodes/

*2 ht tps : //g i thub . com/hec tcas t ro/docke r- r iak

- 29 -

RUN sed -i "s|listener.http.internal = 127.0.0.1:8098|listener.http.internal = 0.0.0.0:8098|" /etc/riak/riak.conf

RUN sed -i "s|listener.protobuf.internal = 127.0.0.1:8087|listener.protobuf.internal = 0.0.0.0:8087|" /etc/riak/riak.conf

それから、Riakプロトコル・バッファ⽤ポートとHTTPインターフェースを公開します。

# Riack プロトコル・バッファと HTTP インターフェースの露出EXPOSE 8087 8098

最後に supervisordを実⾏し、Riack を開始します。

CMD ["/usr/bin/supervisord"]

supervisord.conf という空のファイルを作成します。Dockerfile がある同じディレクトリかどうか確認してください。

touch supervisord.conf

以下のプログラム定義を投⼊します。

[supervisord]nodaemon=true

[program:riak]command=bash -c "/usr/sbin/riak console"numprocs=1autostart=trueautorestart=trueuser=riakenvironment=HOME="/var/lib/riak"stdout_logfile=/var/log/supervisor/%(program_name)s.logstderr_logfile=/var/log/supervisor/%(program_name)s.log

6.7.3 Riak ⽤の Docker イメージを構築

これでRiak⽤のDocker イメージを構築できます。

$ docker build -t "<自分のユーザ名>/riak" .

次のステップ

Riak は分散データベースです。多くのプロダクションへのデプロイには、 少なくとも5ノードが必要*1 と考えられています。docker-riak プロジェクト*2 に、Docker と Pipework を使った Riak クラスタのデプロイ⽅法の詳細があります。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.7 RiakのDocker化

Page 30: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 30 -

6.8 SSHデーモン⽤サービスのDocker 化

6.8.1 eg_sshd イメージの構築

以下の Dockerfileはコンテナ内に SSHd サービスをセットアップします。これは他のコンテナ⽤ボリュームの調査や、テスト⽤コンテナに対する迅速なアクセスを提供します。

# sshd## VERSION 0.0.2

FROM ubuntu:14.04MAINTAINER Sven Dowideit <[email protected]>

RUN apt-get update && apt-get install -y openssh-serverRUN mkdir /var/run/sshdRUN echo 'root:screencast' | chpasswdRUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after loginRUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22CMD ["/usr/sbin/sshd", "-D"]

イメージを構築するには:

$ docker build -t eg_sshd .

次は実⾏します。docker portを使い、コンテナのポート22がホスト側のどのポートに割り当て(マップ)されているか確認できます。

$ docker run -d -P --name test_sshd eg_sshd$ docker port test_sshd 220.0.0.0:49154

それから、コンテナに 対して rootとしてSSHできます。接続先は、IPアドレス(これは docker inspectで確認できます)か、Docker デーモンのIPアドレス(ip addressや ifconfigで確認できます )上のポート 49154か、Docker デーモンのホスト localhostです。

$ ssh [email protected] -p 49154# パスワードは ``screencast`` です。$$

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.8 SSHデーモン⽤サービスのDocker化

Page 31: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 31 -

6.8.3 環境変数

sshdデーモンでシェルを呼び出すのは複雑です。シェルを起動する前に sshd環境を調整し、 環境変数をユーザのシェルから通常のDocker のメカニズムに対して渡す必要があるためです。値を設定するためには、Dockerfile で ENV を使います。先ほどの Dockerfile の例では、シェルの初期化のため

に /etc/profileを送る必要があるでしょう。docker run -e ENV=valueで値を渡す必要がある場合は、同様の処理を⾏うスクリプトを準備する必要があります。

そのためには sshd -Dを CMD命令に置き換え、その準備したスクリプトを実⾏します。

6.8.4 クリーンアップ

最後に、テストの後でコンテナの停⽌と削除をし、そのイメージを削除します。

$ docker stop test_sshd$ docker rm test_sshd$ docker rmi eg_sshd

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.8 SSHデーモン⽤サービスのDocker化

Page 32: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 32 -

6.9 apt-cacher-ng サービスのDocker 化複数のDocker サーバを持っている場合や、Docker 構築キャッシュを使わないDocker コンテナを構築する場合

は、パッケージ⽤のキャッシュ・プロキシを使うと便利です。このコンテナは、パッケージを既にダウンロード済みの環境から⼆次ダウンロードできるようにします。以下のDockerfile を使います。

## Build: docker build -t apt-cacher .# Run: docker run -d -p 3142:3142 --name apt-cacher-run apt-cacher## and then you can run containers with:# docker run -t -i --rm -e http_proxy http://dockerhost:3142/ debian bash## Here, `dockerhost` is the IP address or FQDN of a host running the Docker daemon# which acts as an APT proxy server.FROM ubuntuMAINTAINER [email protected]

VOLUME ["/var/cache/apt-cacher-ng"]RUN apt-get update && apt-get install -y apt-cacher-ng

EXPOSE 3142CMD chmod 777 /var/cache/apt-cacher-ng && /etc/init.d/apt-cacher-ng start && \tail -f /var/log/apt-cacher-ng/*

イメージを構築するには、次のようにします。

$ docker build -t eg_apt_cacher_ng .

それから実⾏します。公開されたポートをホスト側に割り当てます。

$ docker run -d -p 3142:3142 --name test_apt_cacher_ng eg_apt_cacher_ng

ログファイルを参照します。デフォルトのコマンドに -f(末尾を表⽰)オプションを付けます。

$ docker logs -f test_apt_cacher_ng

Debianをベースとしたコンテナでproxy を使うには、以下の⼿順とオプションを進めます。

1. apt プロキシ設定を追加します。

echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/conf.d/01proxy

2. 環境変数を設定します: http_proxy=http://dockerhost:3142/

3. sources.listエントリを変更し、 http://dockerhost:3142/から始めるようにします。4. --linkを使ってAPT proxyコンテナをDebianベースのコンテナにリンクします。5. Debianベースのコンテナで、APT proxyコンテナに接続するカスタム・ネットワークを作成します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.9 apt-cacher-ngサービスのDocker化

Page 33: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 33 -

オプション1:apt設定を安全に⾏うには、共通の基盤となるバージョンでapt設定を⾏う⽅法があります。

FROM ubuntuRUN echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/apt.conf.d/01proxyRUN apt-get update && apt-get install -y vim git

# docker build -t my_ubuntu .

オプション2:http_proxy 設定はテストに便利ですが、curl と wget のような HTTP クライアントでは動作しない場合があります。

$ docker run --rm -t -i -e http_proxy=http://dockerhost:3142/ debian bash

オプション3:これは最新版を取り⼊れるためですが、 Dockerfile では何度が記述が必要になるかもしれません。

オプション4:Debianコンテナをproxy サーバに次のコマンドでリンクします。

$ docker run -i -t --link test_apt_cacher_ng:apt_proxy -e http_proxy=http://apt_proxy:3142/ debian bash

オプション5:APT proxy サーバと Debian ベースのコンテナが接続するカスタム・ネットワークを作成します。

$ docker network create mynetwork$ docker run -d -p 3142:3142 --net=mynetwork --name test_apt_cacher_ng eg_apt_cacher_ng$ docker run --rm -it --net=mynetwork -e http_proxy=http://test_apt_cacher_ng:3142/ debian bash

apt-cacher-ng はリポジトリを管理するのと同じツールを持っています。VOLUME 命令を使い、サービスを実⾏するイメージを構築します。

$ docker run --rm -t -i --volumes-from test_apt_cacher_ng eg_apt_cacher_ng bash

$$ /usr/lib/apt-cacher-ng/distkill.plScanning /var/cache/apt-cacher-ng, please wait...Found distributions:bla, taggedcount: 0

1. precise-security (36 index files)2. wheezy (25 index files)3. precise-updates (36 index files)4. precise (36 index files)5. wheezy-updates (18 index files)

Found architectures:6. amd64 (36 index files)7. i386 (24 index files)

WARNING: The removal action may wipe out whole directories containingindex files. Select d to see detailed list.

(Number nn: tag distribution or architecture nn; 0: exit; d: show details; r: remove tagged; q: quit): q

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.9 apt-cacher-ngサービスのDocker化

Page 34: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 34 -

最後に、コンテナのテストが終わったら、クリーンアップのためにコンテナを停⽌・削除し、イメージを削除します。

$ docker stop test_apt_cacher_ng$ docker rm test_apt_cacher_ng$ docker rmi eg_apt_cacher_ng

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 6.9 apt-cacher-ngサービスのDocker化

Page 35: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 35 -

7 章

7章 Docker Engine 管理

Docker 1.2から がDocker の機能に組み込まれました。これはコンテナ終了時に再起動するための仕組みです。再起動ポリシーを設定しておけば、Docker デーモンの起動時、典型的なのはシステムの起動時に⾃動的にコンテナを開始します。リンクされたコンテナであっても、再起動ポリシーは適切な順番で起動します。必要に応じて再起動ポリシーを使わないでください(例:Docker ではないプロセスがDocker コンテナに依存す

る場合)。そのような場合は、再起動ポリシーの代わりに upstart、systemd、supervisor といったプロセス・マネージャをお使いください。

7.1.1 プロセス・マネージャを使う場合

デフォルトの Docker は再起動ポリシーを設定しません。しかし、多くのプロセス・マネージャと衝突を引き起こす可能性については知っておいてください。もしプロセス・マネージャを使うのであれば、再起動ポリシーを使わない⽅が良いでしょう。イメージのセットアップが完了したら、コンテナを実⾏できるようになり満⾜でしょう。この実⾏をプロセス・

マネージャに委ねられます。 docker start -aを実⾏したら、Docker は⾃動的に実⾏中のコンテナにアタッチします。そして、実⾏後は必要に応じて全てのシグナルを転送しますので、コンテナの停⽌をプロセス・マネージャが検出したら、適切に再起動するでしょう。以下はsystemdとupstart をDocker と連携する例を紹介します。

7.1.2 例

この例では2つの有名なプロセス・マネージャ、upstart と systemd 向けの設定ファイルを扱います。これらの例では、既に作成しているコンテナ --name=redis_serverを使ってRedis を起動するのを想定しています。これらのファイルは新しいサービスを定義し、docker サービスが起動した後で⾃動的に起動するものです。upstart

description "Redis container"author "Me"start on filesystem and started dockerstop on runlevel [!2345]respawnscript/usr/bin/docker start -a redis_server

end script

docs.docker.jp 16/06/04

Page 36: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 36 -

systemd

[Unit]Description=Redis containerRequires=docker.serviceAfter=docker.service

[Service]Restart=alwaysExecStart=/usr/bin/docker start -a redis_serverExecStop=/usr/bin/docker stop -t 2 redis_server

[Install]WantedBy=local.target

redis コンテナに( --env のような)オプションを渡したい場合は、 docker runに代わって docker startを使う必要があります。次の例は、起動したコンテナのサービスが停⽌、または、サービス停⽌によってコンテナが削除されたとしても、新しいコンテナを毎回作成します。

[Service]...ExecStart=/usr/bin/docker run --env foo=bar --name redis_server redisExecStop=/usr/bin/docker stop -t 2 redis_server ; /usr/bin/docker rm -f redis_server...

docs.docker.jp 16/06/04

Page 37: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 37 -

多くのLinuxディストリビューションはsystemdを使ってDocker デーモンを起動します。このドキュメントは、様々な Docker の設定例を紹介します。

Docker をインストールしたら、Docker デーモンを起動する必要があります。

$ sudo systemctl start docker# 他のディストリビューションでは、次のように実行します$ sudo service docker start

また、Docker をブート時に⾃動起動するには、次のように実⾏すべきです。

$ sudo systemctl enable docker# 他のディストリビューションでは、次のように実行します$ sudo chkconfig docker on

7.2.2 Docker デーモンのオプション変更

Docker デーモンの設定を変更するには、多くのフラグを使う⽅法と、環境変数を使う⽅法があります。推奨する⽅法は、 systemd ⽤ のファイルを使うことです。ローカルの設定ファイルは

/etc/systemd/system/docker.service.dディレクトリにあります。あるいは/etc/systemd/system/docker.service

かもしれません。これは /lib/systemd/system/docker.serviceにあるデフォルト設定を上書きします。⼀⽅で、既にパッケージを使ってインストールしていた場合は、環境設定ファイル(通常は

/etc/sysconfig/docker ) があるかもしれません。これは後⽅互換性のためです。このファイルの内容は、/etc/systemd/system/docker.service.dディレクトリにあるファイルに落とし込めます。

[Service]EnvironmentFile=-/etc/sysconfig/dockerEnvironmentFile=-/etc/sysconfig/docker-storageEnvironmentFile=-/etc/sysconfig/docker-networkExecStart=ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS \

$DOCKER_STORAGE_OPTIONS \$DOCKER_NETWORK_OPTIONS \$BLOCK_REGISTRY \$INSECURE_REGISTRY

docker.serviceが環境設定ファイルを使っているか確認します。

$ systemctl show docker | grep EnvironmentFileEnvironmentFile=-/etc/sysconfig/docker (ignore_errors=yes)

あるいは、サービス⽤のファイルがどこにあるか探します。

$ systemctl status docker | grep LoadedFragmentPath=/usr/lib/systemd/system/docker.service

docs.docker.jp 16/06/04

Page 38: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 38 -

$ grep EnvironmentFile /usr/lib/systemd/system/docker.serviceEnvironmentFile=-/etc/sysconfig/docker

Docker デーモンのオプションは、以下のHTTP Proxy 例で説明するようなファイルを使って上書き可能です。このファイルは /usr/lib/systemd/system か /lib/systemd/system にありますが、デフォルトのオプション設定は変更すべきではありません。

Docker イメージ、コンテナ、ボリュームを別々のパーティションのディスク・スペースで管理したくなるでしょう。この例では、次のような docker.serviceファイルがあるものとします。

[Unit]Description=Docker Application Container EngineDocumentation=https://docs.docker.comAfter=network.target docker.socketRequires=docker.socket

[Service]Type=notifyExecStart=/usr/bin/docker daemon -H fd://LimitNOFILE=1048576LimitNPROC=1048576TasksMax=1048576

[Install]Also=docker.socket

これはドロップイン・ファイル(先ほど扱いました)を経由して外部フラグを追加できます。以下の内容を含むファイルを /etc/systemd/system/docker.service.dに作成します。

[Service]ExecStart=ExecStart=/usr/bin/docker daemon -H fd:// --graph="/mnt/docker-data" --storage-driver=overlay

このファイルに他の環境変数も設定できます。例えば、HTTP_PROXY 環境変数を下に追加することもできるでしょう。ExecSart 設定を変更するには、空の設定の次の⾏に、新しい設定を追加します。

[Service]ExecStart=ExecStart=/usr/bin/docker daemon -H fd:// --bip=172.17.42.1/16

空の設定があると失敗しますので、次のように表⽰されるでしょう。

docker.service has more than one ExecStart= setting, which is only allowed for Type=oneshot services.Refusing.

docs.docker.jp 16/06/04

Page 39: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/docker/docker/ t ree/maste r/cont r ib/ in i t /sys temd

- 39 -

HTTP プロキシ

この例はデフォルトの docker.serviceファイルを上書きします。HTTP プロキシサーバの背後にいる場合、ここではオフィスで設定する例として、Docker の systemd サービス

・ファイルに設定を追加する必要があるものとします。まず、docker サービス向けのsystemdドロップイン・ディレクトリを作成します。

mkdir /etc/systemd/system/docker.service.d

次は /etc/systemd/system/docker.service.d/http-proxy.conf ファイルを作成し、 HTTP_PROXY環境変数を追加します。

[Service]Environment="HTTP_PROXY=http://proxy.example.com:80/"

内部の Docker レジストリがあれば、プロキシを通さずに通信できるようにするため、 NO_PROXY 環境変数を指定します。

Environment="HTTP_PROXY=http://proxy.example.com:80/""NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"

設定を反映します。

$ sudo systemctl daemon-reload

設定ファイルが読み込まれたのを確認します。

$ systemctl show --property=Environment dockerEnvironment=HTTP_PROXY=http://proxy.example.com:80/

Docker を再起動します。

$ sudo systemctl restart docker

7.2.3 systemd ユニットファイルの⼿動作成

パッケージを使わずにバイナリをインストールした場合でも、Docker と systemd を連動したくなるでしょう。簡単に実現するには、単純に GitHub リポジトリ にある2つのユニットファイル*1(サービスとソケット⽤)を/etc/systemd/systemに置くだけです。

docs.docker.jp 16/06/04

Page 40: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : // technet .mic roso f t . com/ja - jp/ l ib ra ry/dn249912. a spx? f=255&mspper ror=-2147217396

- 40 -

7.3 PowerShell DSC で使うWindows PowerShell DSC (Desired State Configuration) は設定管理ツールです。これはWindows PowerShell

パ ワ ー シ ェ ル デ ザ イ ヤ ド ステート コンフィギユレーシヨン

の機能を拡張します。DSCは宣⾔型の構⽂を使いターゲットがどのような状態になるかを設定します。PowerShellDSCに関する詳しい情報は、Microsoft 社のサイト*1 をご覧ください。

7.3.1 動作条件

このガイドの利⽤にあたり、Windows ホストはPowerShell v4.0 以上の必要があります。DSC 設定に含まれるスクリプトは、公式では Ubuntu ターゲットのみサポートされています。 Ubuntu ターゲ

ットは OMI サーバと PowerShell DSC for Linux providers のインストールが必要です。詳しい情報はhttps://github.com/MSFTOSSMgmt/WPSDSCLinux をご覧ください。ソース・リポジトリの⼀覧に、PowerShellDSC for Linuxのインストール⽅法や、初期化スクリプトに関するより詳しい情報があります。

7.3.2 インストール

DSC 設定例のソースは次のリポジトリ https://github.com/anweiss/DockerClientDSC から利⽤可能です。クローンも可能です。

$ git clone https://github.com/anweiss/DockerClientDSC.git

7.3.3 使い⽅

DSC 設定はシェルスクリプトのセットを使い、どこにDocker の構成物を置くかや、ターゲット・ノードの設定を⾏います。ソース・リポジトリはスクリプト(RunDockerClientConfig.ps1 があり)、CIM セッションに必要な接続と、 Set-DscConfiguration cmdletの実⾏に使います。より詳細な情報は次の URL をご覧ください。https://github.com/anweiss/DockerClientDSC

Docker インストール

apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys\36A1D7869245C8950F966E92D8576A8BA88D21E9sh -c "echo deb https://apt.dockerproject.org/repo ubuntu-trusty main\> /etc/apt/sources.list.d/docker.list"apt-get updateapt-get install docker-engine

現在の作業ディレクトリが DockerClientDSC ソースに設定されていることを確認し、Docker クライアント設定を現在のPowerShell セッションに反映します。

. .\DockerClient.ps1

ターゲット・ノード⽤のDSC設定に必要な .mof ファイルを⽣成します。

DockerClient -Hostname "myhost"

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.3 PowerShell DSCで使う

Page 41: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 41 -

サンプルのDSC設定データ・ファイルは、 Hostnameパラメータの情報を元に連結されます。

DockerClient -ConfigurationData .\DockerConfigData.psd1

ターゲット・ノードでアプリケーション設定プロセスを開始します。

.\RunDockerClientConfig.ps1 -Hostname "myhost"

RunDockerClientConfig.ps1 スクリプトは DSC 設定データファイルもパースして、次のように複数のノードに対して設定を反映します。

.\RunDockerClientConfig.ps1 -ConfigurationData .\DockerConfigData.psd1

7.3.4 イメージ

イメージ設定とは docker pull [image]あるいは docker rmi -f [IMAGE]処理と同等です。先ほどのステップで定義したファイルを使い、DockerClientの Imageパラメータで設定を追加します。

DockerClient -Hostname "myhost" -Image "node".\RunDockerClientConfig.ps1 -Hostname "myhost"

ホストに対して複数のイメージを取得する設定も可能です。

DockerClient -Hostname "myhost" -Image "node","mongo".\RunDockerClientConfig.ps1 -Hostname "myhost"

イメージを削除するには、次のようにハッシュ・テーブルを使います。

DockerClient -Hostname "myhost" -Image @{Name="node"; Remove=$true}.\RunDockerClientConfig.ps1 -Hostname $hostname

7.3.5 コンテナ

コンテナの設定は次のように⾏います。

docker run -d --name="[containername]" -p '[port]' -e '[env]' --link '[link]'\'[image]' '[command]'

あるいは

docker rm -f [containername]

コンテナを作成・削除するには、1つまたは複数コンテナをハッシュ・テーブルで指定します。ハッシュ・テーブルは次のプロパティのパラメータを指定します。

Name(必須)

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.3 PowerShell DSCで使う

Page 42: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 42 -

Image(Remove プロパティが $trueの以外は必要) Port Env Link Command Remove

例えば、ハッシュテーブルの設定でコンテナを作成するには、次のようにします。

$webContainer = @{Name="web"; Image="anweiss/docker-platynem"; Port="80:80"}

それから、先補との定義と同じ⼿順で DockerClientに -Imageと -Containerパラメータを使います。

DockerClient -Hostname "myhost" -Image node -Container $webContainer.\RunDockerClientConfig.ps1 -Hostname "myhost"

既存のコンテナは次のように削除できます。

$containerToRemove = @{Name="web"; Remove=$true}DockerClient -Hostname "myhost" -Container $containerToRemove.\RunDockerClientConfig.ps1 -Hostname "myhost"

このハッシュテーブルは全てのパラメータを使い、コンテナを作成しています。

$containerProps = @{Name="web"; Image="node:latest"; Port="80:80"; `Env="PORT=80"; Link="db:db"; Command="grunt"}

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.3 PowerShell DSCで使う

Page 43: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 43 -

7.4 CFEngine でプロセス管理プロセスを管理するDocker コンテナを作成します。Docker は各実⾏中のコンテナで1つのプロセスを監視します。そして、コンテナの⽣死とは、そのプロセスの

⽣死を指します。Docker コンテナ内でのCFEngine の動かし⽅を紹介します。これは、次の問題を軽減するものでシーエフエンジン

す。

1つのコンテナの中で、複数のコンテナを簡単に起動できるかもしれません。通常の docker runコマンドを実⾏するだけで、全てを⾃動的に管理します。

停⽌またはクラッシュしたプロセスを管理し、1分以内にCFEngineが対象プロセスを再起動します。 CFEngine スケジューリング・デーモン(cf-execd)が動いている限り、コンテナ⾃⾝も動かし続けます。

CFEngine によって、コンテナの⽣存をサービスの状況と切り離せるようになります。

7.4.1 どのように動作するのか

CFEngineは、cfe-docker 統合ポリシー(integration policies)と⼀緒に Dockerfileの中でインストールします。Docker イメージの中でCFEngineが構築されています。Dockerfile の ENTRYPOINT には任意のコマンド(と任意の引数)をパラメータとして指定できます。Docker コン

テナが CFEngine ポリシーの書かれたパラメータを受け取り実⾏する時、CFEngine はコンテナ内で任意のプロセスが間違いなく実⾏されるようにします。CFEngine は ENTRYPOINTで指定したコマンドのベースネーム(最終的に実⾏するコマンドの名前)にあたるプロ

セス・テーブルをスキャンし、 ベースネームのプロセスが⾒つからなければ、それを開始しようとします。例えば、コンテナを docker run "/path/to/my/application パラメータ" で開始したら、CFEngineは applicationという名前のプロセスを探し、コマンドを実⾏します。もし application にあたるエントリがプロセス・テーブルに無ければ、CFEngine は /path/to/my/application パラメータ でアプリケーションを再度起動しようとします。このプロセス・テーブルの確認は、毎分実⾏されます。従って重要になるのは、アプリケーションを開始するにあたり、そのプロセスにベースネームが含まれている必

要があるため、ご注意ください。

7.4.2 使い⽅

この例は、Docker をインストール済みであり、動くものと想定しています。これから1つのコンテナの中にapache2と sshdをインストール・管理します。3つの⼿順を踏みます:

1. コンテナの中にCFEngineをインストールします。2. CFEngineのDocker プロセス管理ポリシーを、CFEngineをインストールしたコンテナにコピーします。3. docker runコマンドの⼀部として、アプリケーション・プロセスを開始します。

イメージの構築

以下のように、Dockerfile の1〜2ステップで設定できます。

FROM ubuntuMAINTAINER Eystein M å løy Stenberg <[email protected]>

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.4 CFEngineでプロセス管理

Page 44: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 44 -

RUN apt-get update && apt-get install -y wget lsb-release unzip ca-certificates

# install latest CFEngineRUN wget -qO- http://cfengine.com/pub/gpg.key | apt-key add -RUN echo "deb http://cfengine.com/pub/apt $(lsb_release -cs) main" >/etc/apt/sources.list.d/cfengine-community.listRUN apt-get update && apt-get install -y cfengine-community

# install cfe-docker process management policyRUN wget https://github.com/estenberg/cfe-docker/archive/master.zip -P /tmp/ && unzip /tmp/master.zip-d /tmp/RUN cp /tmp/cfe-docker-master/cfengine/bin/* /var/cfengine/bin/RUN cp /tmp/cfe-docker-master/cfengine/inputs/* /var/cfengine/inputs/RUN rm -rf /tmp/cfe-docker-master /tmp/master.zip

# apache2 and openssh are just for testing purposes, install your own apps hereRUN apt-get update && apt-get install -y openssh-server apache2RUN mkdir -p /var/run/sshdRUN echo "root:password" | chpasswd # need a password for ssh

ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"]

作業ディレクトリでこのファイルをDockerfile として保存します。イメージを構築するにはdocker build コマンドを使います。例: docker build -t managed_image。

コンテナのテスト

apache2と sshdを実⾏するコンテナを開始し、SSHインスタンスのポート転送を管理します。

$ docker run -p 127.0.0.1:222:22 -d managed_image "/usr/sbin/sshd" "/etc/init.d/apache2 start"

これが、まさに cfe-docker 統合における明確な利点です。通常の docker runコマンドの⼀部として、複数のプロセスを開始します。新しいコンテナ内にログインしたら、apache2 と sshd の両⽅が動作しています。先ほどの Dockerfile で root パ

スワードを “ password ” と指定しましたので、これを使ってSSHでログインします。

ssh -p222 [email protected]

ps -efUID PID PPID C STIME TTY TIME CMDroot 1 0 0 07:48 ? 00:00:00 /bin/bash /var/cfengine/bin/docker_processes_run.sh/usr/sbin/sshd /etc/init.d/apache2 startroot 18 1 0 07:48 ? 00:00:00 /var/cfengine/bin/cf-execd -Froot 20 1 0 07:48 ? 00:00:00 /usr/sbin/sshdroot 32 1 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k startwww-data 34 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k startwww-data 35 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k startwww-data 36 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k startroot 93 20 0 07:48 ? 00:00:00 sshd: root@pts/0root 105 93 0 07:48 pts/0 00:00:00 -bashroot 112 105 0 07:49 pts/0 00:00:00 ps -ef

もし apache2 を停⽌しても、CFEngine が1分以内に再起動します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.4 CFEngineでプロセス管理

Page 45: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 45 -

service apache2 statusApache2 is running (pid 32).service apache2 stop

* Stopping web server apache2 ... waiting [ OK ]service apache2 statusApache2 is NOT running.# ... wait up to 1 minute...service apache2 statusApache2 is running (pid 173).

⾃分のアプリケーションを同じように設定できます。上記の例で調整が必要なのは、2ヵ所だけです。

上記の Dockerfile を使い、apache2と sshdの代わりに⾃分のアプリケーションをインストールします。 docker run でコンテナ起動時に、apache2と sshdではなく、⾃分のアプリケーション⽤のコマンドライン

引数を指定します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.4 CFEngineでプロセス管理

Page 46: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://www.che f . io/

*2 ht tps ://supermarke t . che f . io/cookbooks/docker

- 46 -

7.5 Chef を使う

このインストール⽅法に関するドキュメントは、コミュニティからの貢献です。

7.5.1 動作条件

このガイドを使う前に、Chef*1 のインストール作業が必要です。cookbookは様々なオペレーティング・システムシ ェ フ ク ツ ク ブ ツ ク

に対応しています。

7.5.2 インストール

Chef Supermarket*2 上の cookbookが利⽤可能です。そして、好みのcookbook依存関係マネージャ(dependencyスーパーマーケツト

manager)を使ってインストールできます。ソースはGitHub上(https://github.com/someara/chef-docker)にあります。

7.5.3 使い⽅

⾃分のcookbookのmetadata.rb に depends 'docker', '~> 2.0'を追加します。 cookbook のレシピに送信するリソースを指定します。同様にコア Chef リソースも使えます(file、template、

directory、package 等)。

docker_service 'default' doaction [:create, :start]

end

docker_image 'busybox' doaction :pull

end

docker_container 'an echo server' dorepo 'busybox'port '1234:1234'command "nc -ll -p 1234 -e /bin/cat"

end

7.5.4 はじめましょう

こちらの例は、最新のイメージを取得し、コンテナ実⾏時にポートを公開します。

# Pull latest imagedocker_image 'nginx' dotag 'latest'action :pull

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.5 Chef を使う

Page 47: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 47 -

end

# Run container exposing portsdocker_container 'my_nginx' dorepo 'nginx'tag 'latest'port '80:80'binds [ '/some/local/files/:/etc/nginx/conf.d' ]host_name 'www'domain_name 'computers.biz'env 'FOO=bar'subscribes :redeploy, 'docker_image[nginx]'

end

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.5 Chef を使う

Page 48: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //puppet l abs . com/

*2 ht tps :// forge .puppet labs . com/gare thr/docker/

- 48 -

7.6 Puppet を使う

このインストール⽅法は、コミュニティにからの貢献です。 公式のインストール⽅法は Ubuntuを使います。このバージョンは情報が古いかもしれません。

7.6.1 動作条件

このガイドを利⽤するには、Puppet Labsが提供するPuppet*1 をインストールする必要があります。パ ケ ツ ト ラ ブ ズ パ ペ ツ ト

また、現時点の公式パッケージが利⽤できるモジュールは、Ubuntu向けのみです。

7.6.2 インストール

モジュールは Puppet Forge*2 のものが使えます。内部モジュールのツールを使ってインストールします。フォージ

$ puppet module install garethr/docker

また、ソースをダウンロードするには、GitHub (https://github.com/garethr/garethr-docker)も使えます。

7.6.3 使い⽅

モジュールは Docker をインストールする puppet クラスを提供し、イメージとコンテナを管理するために2つのタイプを定義します。

インストール

include 'docker'

イメージ

次の⼿順でほとんどの Docker イメージをインストールします。この例では、次のように使⽤するタイプを定義しています。

docker::image { 'ubuntu': }

これは、次のコマンドと同等です。

$ docker pull ubuntu

docker::image { 'ubuntu':ensure => 'absent',

}

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.6 Puppet を使う

Page 49: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 49 -

コンテナ

これで、Docker によって管理されるコンテナ内で、コマンドを実⾏するイメージができます。

docker::run { 'helloworld':image => 'ubuntu',command => '/bin/sh -c "while true; do echo hello world; sleep 1; done"',

}

これは upstart 下での次のコマンドと同等です。

$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

ports 、 env 、 dns 、 volumesの属性は⽂字で指定するか、先ほどの の値で指定します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.6 Puppet を使う

Page 50: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //superv i sord .org/

- 50 -

7.7 Supervisor を Docker で使う伝統的に Docker コンテナは起動時に1つのプロセスを実⾏します。例えば、Apache デーモンや SSH サーバの

デーモンです。しかし、コンテナ内で複数のプロセスを起動したいこともあるでしょう。これを実現するにはいくつもの⽅法があります。プロセス管理ツールをインストールすることで、コンテナの CMD 命令で単純な Bash スクリプトを使えるようにします。ここでは例としてプロセス管理ツールSupervisor*1 を使い、コンテナ内で複数のプロセスを管理します。Supervisor

スーパーバイザー

を使うことにより、制御・管理しやすくし、実⾏したいプロセスを再起動できます。デモンストレーションとして、SSHデーモンとApacheデーモンの両⽅をインストール・管理します。

基本的な Dockerfileから新しいイメージを作りましょう。

FROM ubuntu:13.04MAINTAINER [email protected]

7.7.2 Supervisor のインストール

SSHとApacheデーモンと同じように、Supervisor をコンテナにインストールできます。

RUN apt-get update && apt-get install -y openssh-server apache2 supervisorRUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/run/sshd /var/log/supervisor

ここでインストールしたパッケージは openssh-server、apache2、supervisor(Supervisor デーモンを提供)です。それから、SSHデーモンとSupervisor を実⾏するための新しいディレクトリの作成も必要です。

次は Supervisor の設定ファイルを追加しましょう。デフォルトのファイルは supervisord.conf であり、/etc/supervisor/conf.d/に置きます。

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

superviserd.confの内容を⾒ましょう。

[supervisord]nodaemon=true

[program:sshd]command=/usr/sbin/sshd -D

[program:apache2]command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"

supervisord.conf 設定ファイルにはディレクティブ(命令)を記述します。これは Supervisor とプロセスを管

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.7 SupervisorをDockerで使う

Page 51: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 51 -

理するためです。始めのブロック [supervisord] は Supervisord ⾃⾝の設定を指定します。ここで使ったディレクティブ nodaemonは、Supervisor をデーモン化するのではなく、インタラクティブに実⾏します。次の2つのブロックは制御したいサービスを管理します。各ブロックは、別々のプロセスです。ブロックには

commandというディレクティブが1つあり、各プロセスで何のコマンドを起動するか指定します。

Dockerfile を仕上げるには、コンテナの実⾏時に必要な公開ポートや、 Supervisor 起動のための CMD 命令を追加します。

EXPOSE 22 80CMD ["/usr/bin/supervisord"]

ここでは、コンテナのポート22と80を公開し、コンテナの起動時に /usr/bin/supervisord バイナリを実⾏します。

7.7.5 イメージの構築

これで新しいイメージを構築できます。

$ docker build -t <yourname>/supervisord .

イメージを構築したら、これを使ってコンテナを起動します。

$ docker run -p 22 -p 80 -t -i <yourname>/supervisord2013-11-25 18:53:22,312 CRIT Supervisor running as root (no user in config file)2013-11-25 18:53:22,312 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" duringparsing2013-11-25 18:53:22,342 INFO supervisord started with pid 12013-11-25 18:53:23,346 INFO spawned: 'sshd' with pid 62013-11-25 18:53:23,349 INFO spawned: 'apache2' with pid 7. . .

docker runコマンドを実⾏することで、新しいコンテナをインタラクティブに起動しました。このコンテナはSupervisor を実⾏し、⼀緒にSSHとApacheデーモンを起動します。 -p フラグを指定し、ポート22と80を公開します。ここで、SSH と Apache デーモンの両⽅に接続できるようにするため、公開ポートを個々に指定しています。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.7 SupervisorをDockerで使う

Page 52: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 52 -

Docker のインストールに成功したら、dockerデーモンはデフォルトの設定で動いています。プロダクション環境では、システム管理者は組織における必要性に従い、dockerデーモンの設定を変更し、起動

・停⽌するでしょう。ほとんどの場合、システム管理者は docker デーモンの起動・停⽌のために SysVinit、Upstart、systemdといったプロセス・マネージャを設定するでしょう。

docker デーモンは docker daemon コマンドで直接操作できます。デフォルトでは Unix ソケットunix:///var/run/docker.sockをリッスンします。

$ docker daemon

INFO[0000] +job init_networkdriver()INFO[0000] +job serveapi(unix:///var/run/docker.sock)INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)......

プロセス・マネージャの代わりに、docker daemon コマンドを使って docker デーモンを直接実⾏できます。docker をコマンドで直接実⾏時に、オプション設定を追加可能です。docker デーモンを設定するための他のオプションも追加できます。デーモンで利⽤可能なオプション:

フラグ 説明-D , --debug=false デバッグ・モードの有効化と無効化。デフォルトは false-H , --host=[] デーモンが接続するソケット--tls=false TLS の有効化と無効化。デフォルトは false

以下は docker デーモンに設定オプションを付けて実⾏する例です。

$ docker daemon -D --tls=true --tlscert=/var/docker/server.pem --tlskey=/var/docker/serverkey.pem \-H tcp://192.168.59.3:2376

3つのオプションがあります:

-D(デバッグ)モードの有効化 tlsを有効にするため、サーバ証明書と鍵を --tlscertと --tlskeyで個々に指定 tcp://192.168.59.3:2376への接続をリッスン

コマンドライン・リファレンスのデーモンのフラグ⼀覧に説明があります。

デーモンのデバッグ

更に捕捉しますと、管理者やオペレータがデーモンの実⾏時の挙動に関して、更に詳細な情報を得るには、デー

docs.docker.jp 16/06/04

Page 53: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 53 -

モンのログレベルを「debug」に設定するか、 -D オプションを付けてデバッグ・モードにします。デーモンからの応答が無くても、Docker デーモンに対して SIGUSR1 シグナルを送信することで、デーモンのログに追加された全てのスレッドを強制的に追跡します。Linux システム上でシグナルを送る⼀般的な⽅法は kill シグナルを使います。例えば kill -USR1 <デーモンのpid> を実⾏したら、デーモンのプロセスに SIGUSR1シグナルを送信し、スタック・ダンプをデーモンのログに追加します。

スタック・トレースをログに保存するには、 デーモンのログレベルの設定は少なくとも「info」レベル以上にする必要があります。デフォルトのデーモンのログレベルは「info」に設定されています。

デーモンは SIGUSR1 シグナルを受け取った後、スタック・トレースをダンプしてログに出⼒します。スタック・トレースはデーモン内部の全ての goroutine の状態とスレッドの把握に使えます。

7.8.3 Ubuntu

Ubunt 14.04 からはプロセス・マネージャに Upstart を使います。デフォルトでは、Upstart のジョブはアツプスタート

/etc/initに保管され、 docker Upstart ジョブは /etc/init/docker.confにあります。UbuntuでDocker のインストールに成功した後、Upstart で稼働状態を確認するには、次のようにします。

$ sudo status dockerdocker start/running, process 989

dockerデーモンは次のように開始・停⽌・再起動できます。

$ sudo start docker

$ sudo stop docker

$ sudo restart docker

以下の例は、プロセス・マネージャに upstartを使いDocker システムを設定する⽅法です。Ubuntu 15.04以降はプロセス・マネージャに systemdを使います。Ubuntu 15.04 以降は、「systemdでDocker の管理・設定」のセク

システムディー

ションをご覧ください。システム上にある dockerデーモンの設定は、/etc/default/dockerファイルを編集します。ここに DOCKER_OPTS

環境変数を指定可能です。Docker オプションの設定を変更するには:

1. ホストに sudoや root特権を持つユーザでログインします。

2. ホスト上に /etc/default/docker ファイルが無ければ作成します。Docker のインストール⽅法によっては、既にファイルが作成されている場合があります。

3. 任意のエディタでファイルを開きます。

docs.docker.jp 16/06/04

Page 54: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 54 -

$ sudo vi /etc/default/docker

4. DOCKER_OPTS変数に、次のオプションを指定します。これらのオプションは dockerデーモンを実⾏する時に追加されます。

DOCKER_OPTS="-D --tls=true --tlscert=/var/docker/server.pem --tlskey=/var/docker/serverkey.pem \-H tcp://192.168.59.3:2376"

これらのオプションの意味は:

-D(デバッグ)モードの有効化 tlsを有効にするため、サーバ証明書と鍵を --tlscertと --tlskeyで個々に指定 tcp://192.168.59.3:2376への接続をリッスン

コマンドライン・リファレンスのデーモンのフラグ⼀覧に説明があります。

5. ファイルを保存して閉じます。

6. dockerデーモンを再起動します。

$ sudo restart docker

7. dockerデーモンが指定したオプションで実⾏しているか、 psコマンドで確認します。

$ ps aux | grep docker | grep -v grep

ログ

Upstart ジョブのログは、デフォルトでは /var/log/upstart に保管されており、docker デーモンのログは/var/log/upstart/docker.logにあります。

$ tail -f /var/log/upstart/docker.logINFO[0000] Loading containers: done.INFO[0000] Docker daemon commit=1b09a95-unsupported graphdriver=aufs version=1.11.0-devINFO[0000] +job acceptconnections()INFO[0000] -job acceptconnections() = OK (0)INFO[0000] Daemon has completed initialization

7.8.4 CentOS / Red Hat Enterprise Linux / Fedora

CentOSとRHELの 7.x以降では、プロセス・マネージャに systemdを使います。Fedora 21以降は、プロセス・マネージャに systemdを使います。CentOS、Red Hat Enterprise Linux、FedoraにDocker をインストール後は、次のように稼働状態を確認できま

す。

$ sudo systemctl status docker

docs.docker.jp 16/06/04

Page 55: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 55 -

dockerデーモンは次のように開始・停⽌・再起動できます。

$ sudo systemctl start docker

$ sudo systemctl stop docker

$ sudo systemctl restart docker

Docker をブート時に起動するようにするには、次のように実⾏すべきです。

$ sudo systemctl enable docker

CentOS 7.x とRHEL 7.x では systemdでDocker を管理・設定できます 。以前のCentOS 6.x やRHEL 6.x の場合は、システム上にある dockerデーモンの設定は /etc/default/docker

ファイルを編集し、ここで様々な変数を設定します。CentOS 7.x とRHEL 7.x では、この変数名が OPTIONSになります。CentOS 6.x とRHEL 6.x では、この変数名は other_argsです。このセクションでは CentOS 7の docker

デーモンを例に説明します。Docker オプションの設定を変更するには:

1. ホストに sudoや root特権を持つユーザでログインします。

2. /etc/systemd/system/docker.service.dディレクトリを作成します。

$ sudo mkdir /etc/systemd/system/docker.service.d

3. /etc/systemd/system/docker.service.d/docker.confファイルを作成します。

4. 任意のエディタでファイルを開きます。

$ sudo vi /etc/systemd/system/docker.service.d/docker.conf

5. docker デーモンの設定を変更するため、docker.service ファイルの ExecStart 設定を上書きします。ExecStart設定を変更するためには、新しい設定⾏を追加する前に、次のように空の設定⾏を追加します。

[Service]ExecStart=ExecStart=/usr/bin/docker daemon -H fd:// -D --tls=true --tlscert=/var/docker/server.pem--tlskey=/var/docker/serverkey.pem -H tcp://192.168.59.3:2376

これらのオプションの意味は:

-D(デバッグ)モードの有効化

docs.docker.jp 16/06/04

Page 56: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 56 -

tlsを有効にするため、サーバ証明書と鍵を --tlscertと --tlskeyで個々に指定 tcp://192.168.59.3:2376への接続をリッスン

コマンドライン・リファレンスのデーモンのフラグ⼀覧に説明があります。

6. ファイルを保存して閉じます。

7. 変更を反映(フラッシュ)します。

$ sudo systemctl daemon-reload

8. dockerデーモンを再起動します。

$ sudo systemctl restart docker

9. dockerデーモンが指定したオプションで実⾏しているか、psコマンドで確認します。

$ ps aux | grep docker | grep -v grep

ログ

systemd は⾃⾝で journal と呼ばれるロギング・システムを持っています。docker デーモンのログ表⽰はjournalctl -u dockerを使います。

$ sudo journalctl -u dockerMay 06 00:22:05 localhost.localdomain systemd[1]: Starting Docker Application Container Engine...May 06 00:22:05 localhost.localdomain docker[2495]: time="2015-05-06T00:22:05Z" level="info" msg="+jobserveapi(unix:///var/run/docker.sock)"May 06 00:22:05 localhost.localdomain docker[2495]: time="2015-05-06T00:22:05Z" level="info"msg="Listening for HTTP on unix (/var/run/docker.sock)"May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info" msg="+jobinit_networkdriver()"May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info" msg="-jobinit_networkdriver() = OK (0)"May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info"msg="Loading containers: start."May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info"msg="Loading containers: done."May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info"msg="Docker daemon commit=1b09a95-unsupported graphdriver=aufs version=1.11.0-dev""May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info" msg="+jobacceptconnections()"May 06 00:22:06 localhost.localdomain docker[2495]: time="2015-05-06T00:22:06Z" level="info" msg="-jobacceptconnections() = OK (0)"

journal の使い⽅や設定⽅法は⾼度なトピックのため、このドキュメントの範囲では扱いません。

docs.docker.jp 16/06/04

Page 57: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //www.kerne l .org/doc/Documenta t ion/cgroup-v1/cgroups . t x t

- 57 -

コンテナのラインタイム・メトリクス(訳注;コンテナ実⾏時の、様々なリソース指標や数値データ)をライブ(⽣)で表⽰するには、docker statsコマンドを使います。コマンドがサポートしているのは、CPU、メモリ使⽤

スタツツ

率、メモリ上限、ネットワークI/Oのメトリクスです。以下は docker statsコマンドを実⾏した例です。

$ docker stats redis1 redis2CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/OBLOCK I/Oredis1 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B3.568 MB / 512 KBredis2 0.07% 2.746 MB / 64 MB 4.29% 1.266 KB / 648 B12.4 MB / 0 B

docker statsコマンドのより詳細な情報は、docker statsリファレンス・ページ をご覧ください。

7.9.1 コントロール・グループ

Linux はプロセス・グループの追跡だけでなく、CPU・メモリ・ブロック I/O のメトリクス表⽰は、コントロール・グループ*1 に依存しています。これらのメトリクスやネットワーク使⽤量のメトリクスも同様に取得できます。これらは「純粋な」 LXCコンテナ⽤であり、Docker コンテナ⽤でもあります。コントロール・グループは を通して公開されています。最近のデ

ィストリビューションでは、 /sys/fs/cgroup以下で⾒つかるでしょう。このディレクトリの下に、device・freezer・blkio 等の複数のサブディレクトリがあります。各サブディレクトリは、それぞれ異なったcgroup階層に相当します。古いシステムでは、コントロール・グループが /cgroupにマウントされており、その下に明確な階層が無いかも

しれません。そのような場合、サブディレクトリが⾒える代わりに、たくさんのファイルがあるでしょう。あるいは、存在しているコンテナに相当するディレクトリがあるかもしれません。どこにコントロール・グループがマウントされているかを調べるには、次のように実⾏します。

$ grep cgroup /proc/mounts

7.9.2 コントロール・グループの列挙

/proc/cgroups を調べれば、システム上の様々に異なるコントロール・グループのサブシステムが⾒えます。それぞれに階層がサブシステムに相当しており、多くのグループが⾒えるでしょう。コントロール・グループのプロセスに属する情報は、 /proc/<pic>/cgroup からも確認できます。コントロール

・グループは階層のマウントポイントからの相対パス上に表⽰されます。例えば、 /が意味するのは「対象のプロセスは特定のグループに割り当てられていない」であり、 /lxc/pumpkin が意味するのはプロセスが pumpkin と呼ばれるコンテナのメンバであると考えられます。

コンテナごとに、それぞれの階層にcgroupが作成されます。古いシステム上のバージョンが古いLXC userland

docs.docker.jp 16/06/04

Page 58: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 58 -

tools の場合、cgroups の名前はコンテナ名になっています。より最近のバージョンのLXCツールであれば、cgroupは lxc/<コンテナ名>になります。Docker コンテナはcgroupsを使うため、コンテナ名はフルIDか、コンテナのロングIDになります。 docker ps

コマンドで表⽰されたコンテナ ID が ae836c95b4c3 のように⾒えるのであれば、このコンテナのロング ID はae836c95b4c3c9e9179e0e91015512da89fdec91612f63cebae57df9a5444c79のようなものです。この情報を調べるには、docker inspectか docker ps --no-truncを使います。Docker コンテナが利⽤するメモリのメトリクスは、 /sys/fs/cgroup/memory/docker/<ロング ID>/ から全て参

照できます。

各サブシステム(メモリ、CPU、ブロック I/O)ごとに、1つまたは複数の に統計情報が含まれます。

メモリ・メトリクスは「memory」cgroups にあります。メモリのコントロール・グループは少々のオーバーヘッドが増えるのを覚えておいてください。これはホスト上における詳細なメモリ使⽤情報を計算するためです。そのため、多くのディストリビューションではデフォルトでは無効です。⼀般的に、有効にするためには、カーネルのコマンドライン・パラメータに cgroup_enable=memory swapaccount=1を追加します。メトリクスは疑似ファイル memory.statにあります。次のように表⽰されます。

cache 11492564992rss 1930993664mapped_file 306728960pgpgin 406632648pgpgout 403355412swap 0pgfault 728281223pgmajfault 1724inactive_anon 46608384active_anon 1884520448inactive_file 7003344896active_file 4489052160unevictable 32768hierarchical_memory_limit 9223372036854775807hierarchical_memsw_limit 9223372036854775807total_cache 11492564992total_rss 1930993664total_mapped_file 306728960total_pgpgin 406632648total_pgpgout 403355412total_swap 0total_pgfault 728281223total_pgmajfault 1724total_inactive_anon 46608384total_active_anon 1884520448total_inactive_file 7003344896total_active_file 4489052160total_unevictable 32768

前半(total_が先頭に無い )は、cgroup 中にあるプロセス関連の統計情報を表⽰します。サブグループは除外しています。後半(先頭に total_がある )は、サブグループも含めたものです。

docs.docker.jp 16/06/04

Page 59: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 59 -

いくつかのメトリクスは「gauges」(ゲージ;計測した値そのものの意味)であり、例えば、値が増減するものです(例:swapは cgroupのメンバによって使われているswap領域の容量です)。あるいは「counter」(カウンタ)は、特定のイベント発⽣後に増えた値のみ表⽰します(例:pgfault はページ・フォルトの回数を表しますが、cgroupが作成された後の値です。この値は決して減少しません。)。

cache:コントロール・グループのプロセスによって使⽤されるメモリ容量であり、ブロック・デバイス上のブロックと密接に関わりがあります。ディスクからファイルを読み書きしたら、この値が増えます。値が増えるのは「通常」のI/O(open、read、writeシステムコール)だけでなく、ファイルのマップ(mmapを使⽤)でも同様です。あるいは tmpfs マウントでメモリを使う場合も、理由が明確でなくともカウントされます。

rss:ディスクに関連 しない メモリ使⽤量です。例えば、stacks、heaps、アノニマスなメモリマップです。 mapped_file:コントロール・グループ上のプロセスに割り当てられるファイル容量です。 メモリをどのように使⽤しているかの情報は得られません。どれだけ使っているかを表⽰します。

pgfault とpgmajfault:cgroupのプロセスが「page fault」と「major fault」の回数を個々に表⽰します。pagefault とは、存在しないかプロテクトされた仮想メモリスペースにプロセスがアクセスした時に発⽣します。かつては、プロセスにバグがあり、無効なアドレスにアクセスしようとした時に発⽣しました(SIGSEGVシグナルが送信されます。典型的なのは Segmentation faultメッセージを表⽰してkill される場合です )。最近であれば、プロセスがスワップ・アウトされたメモリ領域を読み込みに⾏くか、あるいはマップされたファイルに相当する時に発⽣します。そのような場合、カーネルはページをディスクから読み込み、CPUがメモリへのアクセスを処理します。これはまた、プロセスがコピー・オン・ライト(copy-on-write)のメモリ領域に書き込んだ時にも発⽣します。これはカーネルがプロセスの実⾏を阻⽌するのと同じであり、メモリページを複製し、プロセスが⾃⾝のページをコピーして書き込み作業を再開しようとします。「メジャー」な失敗が起こるのは、カーネルが実際にディスクからデータを読み込む時点です。読み込みによって、既存のページと重複するか、空のページが割り当てられると⼀般的な(あるいは「マイナー」な)エラーが発⽣します。

swap:対象のcgroupにあるプロセスが、現在どれだけswapを使っているかの量です。 active_anonと inactive_anon:カーネルによってactive と inactive に区分されるanonymousメモリ容量

です。anonymous メモリとは、ディスク・ページにリンクされないメモリです。⾔い換えれば、先ほど説明したrss カウンタと同等なものです。実際、rssカウンタの厳密な定義は、active_anon + inactive_anon -tmpfsです(tmpfs のメモリ容量とは、このコントロール・グループの tmpfsファイルシステムがマウントして使っている容量です)。では次に、「active」と「inactive」の違いは何でしょうか? ページは「active」として始まりますが、⼀定の時間が経てば、カーネルがメモリを整理(sweep)して、いくつかのページを「inactive」にタグ付けします。再度アクセスがあれば、直ちに「active」に再度タグ付けされます。カーネルがメモリ不⾜に近づくか、ディスクへのスワップアウト回数により、カーネルは「inactive」なページをスワップします。

:キャッシュメモリの active と inactive は、先ほどの anonymou メモリの説明にあるものと似ています。正確な計算式は、キャッシュ = active_file + inactive_file + tmpfsです。この正確なルールが使われるのは、カーネルがメモリページを active から inactive にセットする時です。これはanonymousメモリとして使うのとは違って、⼀般的な基本原理によるものと同じです。注意点としては、カーネルがメモリを再要求(reclaim)するするとき、直ちに再要求(anonymous ページや汚れた/変更されたページをディスクに書き込む)よりも、プール上のクリーンな(=変更されていない)ページを再要求するほうが簡単だからです。

unevictable:再要求されないメモリの容量です。⼀般的に mlockで「ロックされた」メモリ容量です。暗号化フレームワークによる秘密鍵の作成や、ディスクにスワップさせたくないような繊細な素材に使われます。

memory と memsw の limits:これらは実際のメトリクスではありませんが、対象の cgroup に適⽤される上限の確認に使います。「memory」はこのコントロール・グループのプロセスによって使われる最⼤の物理メモリを⽰します。「memsw」はRAM+swapの最⼤容量を⽰します。

ページキャッシュ中のメモリ計算は⾮常に複雑です。もし2つのプロセスが異なったコントロール・グループ上にあるなら、それぞれの同じファイル(結局はディスク上の同じブロックに依存しますが)を読み込む必要があり

docs.docker.jp 16/06/04

Page 60: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : // lwn .ne t/Ar t i c l e s/549580/

*2 ht tps : //www.kerne l .org/doc/Documenta t ion/cgroups/b lk io-contro l l e r . t x t

- 60 -

ます。割り当てられたメモリは、コントロール・グループごとの容量に依存します。これは良さそうですが、cgroupを削除したら、メモリページとして消費していた領域は使わなくなり、他の cgroup のメモリ容量を増加させることをも意味します。

これまではメモリのメトリクスを⾒てきました。メモリに⽐べると他のものは⾮常に簡単に⾒えるでしょう。CPUメトリクスはcpuacct コントローラにあります。コンテナごとに疑似ファイル cpuacct.stat があり、ここにコンテナにあるプロセスの CPU 使⽤率を、user 時

間と system時間に分割して記録されます。いずれも慣れていなければ、userとはプロセスが CPU を直接制御する時間のこと(例:プロセス・コードの実⾏)であり、systemとはプロセスに代わり CPU のシステムコールを実⾏する時間です。これらの時間は100分の1秒の周期(tick)で表⽰されます。実際にはこれらは「user jiffies」として表⽰されま

す。USER_HZ「jillies」が毎秒かつ x86 システムであれば、USER_HZは100です。これは1秒の「周期」で、スケジューラが実際に割り当てる時に使いますが、tickless kernels*1 にあるように、多くのカーネルでticks は適切ではありません。まだ残っているのは、主に遺産(レガシー)と互換性のためです。

Block I/O メトリクス

Block I/Oは blkioコントローラを算出します。異なったメトリックスが別々のファイルに散在しています。より詳細な情報を知りたい場合は、カーネル・ドキュメントの blkio-controller*2 をご覧ください。ここでは最も関係が深いものをいくつか扱います。

blkio.sectors:cgroups のプロセスのメンバが、512バイトのセクタをデバイスごとに読み書きするものです。読み書きは単⼀のカウンタに合算されます。

blkio.io_service_bytes:cgroup で読み書きしたバイト数を表⽰します。デバイスごとに4つのカウンタがあります。これは、デバイスごとに同期・⾮同期I/Oと、読み込み・書き込みがあるからです。

blkio.io_serviced:サイズに関わらず I/O 操作の実⾏回数です。こちらもデバイスごとに4つのカウンタがあります。

blkio.io_queued:このグループ上で I/O 動作がキュー(保留)されている数を表⽰します。⾔い換えれば、cgroup が何らI/Oを処理しなければ、この値は0になります。ただし、その逆の場合は違うので気を付けてください。つまり、I/O キューが発⽣していなくても、cgroup がアイドルだとは⾔えません。これは、キューが無くても、純粋に停⽌しているデバイスからの同期読み込みを⾏い、直ちに処理することができるためです。また、cgroupは I/O サブシステムに対するプレッシャーを、相対的な量に保とうとする⼿助けになります。プロセスのグループが更に I/O が必要になれば、キューサイズが増えることにより、他のデバイスとの負荷が増えるでしょう。

7.9.5 ネットワーク・メトリクス

ネットワークのメトリクスは、コントロール・グループから直接表⽰されません。ここに良いたとえがあります。ネットワーク・インターフェースとはネットワーク名前空間 (network namespaces) 内のコンテクスト(内容)として存在します。カーネルは、プロセスのグループが送受信したパケットとバイト数を⼤まかに計算できます。しかし、これらのメトリックスは使いづらいものです。インターフェースごとのメトリクスが欲しいでしょう(なぜなら、ローカルの lo インターフェスに発⽣するトラフィックが実際に計測できないためです )。ですが、単⼀のcgroup内のプロセスは、複数のネットワーク名前空間に所属するようになりました。これらのメトリクスの解釈は

docs.docker.jp 16/06/04

Page 61: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //co l l ec td .o rg/wik i/ index .php/Tab le_o f_P lug ins

- 61 -

⼤変です。複数のネットワーク名前空間が意味するのは、複数の lo インターフェース、複数の eth0インターフェース等を持ちます。つまり、コントロール・グループからネットワーク・メトリクスを簡単に取得する⽅法はありません。そのかわり、他のソースからネットワークのメトリクスを集められます。

IPtables

IPtables を使えば(というよりも、インターフェースに対する iptables の netfilter フレームワークを使うことにより)、ある程度正しく計測できます。例えば、ウェブサーバの外側に対する(outbound) HTTPトラフィックの計算のために、次のようなルールを作

成できます。

$ iptables -I OUTPUT -p tcp --sport 80

ここには何ら -j や -g フラグはありませんが、ルールがあることにより、⼀致するパケットは次のルールに渡されます。それから、次のようにしてカウンタの値を確認できます。

$ iptables -nxvL OUTPUT

技術的には -nは不要なのですが、今回の例では、不要なDNS逆引きの名前解決をしないために付けています。カウンタにはパケットとバイト数が含まれます。これを使ってコンテナのトラフィック⽤のメトリクスをセット

アップしたければ、 コンテナの IP アドレスごとに(内外の⽅向に対する)2つの iptablesルールの forループを FORWARD チェーンに追加します。これにより、NAT レイヤを追加するトラフィックのみ計測します。つまり、ユーザランド・プロキシを通過しているトラフィックも加えなくてはいけません。後は通常の⽅法で計測します。 collectd を使ったことがあるのなら、⾃動的に iptables のカウンタを収集する

コレクトディー

便利なプラグイン*1 があります。

インターフェース・レベルのカウンタ

各コンテナは仮想イーサネット・インターフェースを持つため、そのインターフェースから直接TX・RXカウンタを取得したくなるでしょう。各コンテナが vethKk8Zq のような仮想イーサネット・インターフェースに割り当てられているのに気を付けてください。コンテナに対応している適切なインターフェースを⾒つけることは、残念ながら⼤変です。しかし今は、 コンテナを通さなくても 数値を確認できる良い⽅法があります、ホスト環境上で⼒を使い、ネットワーク名前空間内のコンテナの情報を確認します。ip netns execコマンドは、あらゆるネットワーク名前空間内で、あらゆるプログラムを実⾏し(対象のホスト

上の)、現在のプロセス状況を表⽰します。つまり、ホストがコンテナのネットワーク名前空間に⼊れますが、コンテナはホスト側にアクセスできないだけでなく、他のコンテナにもアクセスできません。次のサブコマンドを通すことで、コンテナが「⾒える」⽤になります。正確なコマンドの形式は、次の通りです。

$ ip netns exec <nsname> <command...>

docs.docker.jp 16/06/04

Page 62: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 62 -

例:

$ ip netns exec mycontainer netstat -i

ip netnsは「mycontainer」コンテナを名前空間の疑似ファイルから探します。各プロセスは1つのネットワーク名前空間、PIDの名前空間、mnt名前空間等に属しています。これらの名前空間は /proc/<pid>/ns/ 以下にあります。例えば、PID 42のネットワーク名前空間に関する情報は、疑似ファイル /proc/42/ns/netです。ip netns exec mycontainer ... を実⾏したら、 /var/run/netns/mycontainer が疑似ファイルの1つとなるでし

ょう(シンボリック・リンクが使えます)。⾔い換えれば、私たちが必要であれば、ネットワーク名前空間の中でコマンドを実⾏できるのです。

調査したいコンテナに⼊っている、あらゆる PID を探し出します /var/run/netns/<何らかの名前> から /proc/<thepid>/ns/net へのシンボリック・リンクを作成します。 ip netns exec <何らかの名前> ....を実⾏します。

ネットワーク使⽤状況を調査したいコンテナがあり、そこで実⾏しているプロセスを⾒つける⽅法を学ぶには、「コントロール・グループの列挙」のセクションを読み直してください。ここからは tasks と呼ばれる疑似ファイルを例に、コントロール・グループ(つまり、コンテナ)の中にどのようなPIDがあるかを調べましょう。これらを⼀度に実⾏したら、取得したコンテナの「ショートID」は変数$CIDに⼊れて処理されます。

$ TASKS=/sys/fs/cgroup/devices/docker/$CID*/tasks$ PID=$(head -n 1 $TASKS)$ mkdir -p /var/run/netns$ ln -sf /proc/$PID/ns/net /var/run/netns/$CID$ ip netns exec $CID netstat -i

新しいプロセスごとに毎回メトリクスを更新するのは、(⽐較的)コストがかかるので注意してください。メトリクスを⾼い解像度で収集したい場合、そして/または、⼤量のコンテナを扱う場合(1ホスト上に 1,000 コンテナと考えます)、毎回新しいプロセスをフォークしようとは思わないでしょう。ここでは1つのプロセスでメトリクスを収集する⽅法を紹介します。メトリクス・コレクションをC⾔語で書く

必要があります(あるいは、ローレベルなシステムコールが可能な⾔語を使います)。setns()という特別なシステムコールを使えば、任意の名前空間上にある現在のプロセスを返します。必要があれば、他にも名前空間疑似ファイルのファイル・ディスクリプタ(file descriptor)を開けます(思い出してください:疑似ファイルは/proc/<pid>/ns/netです)。しかしながら、これはキャッチするだけです。ファイルをオープンのままにできません。つまり、そのままにし

ておけば、コントロール・グループが終了しても名前空間を破棄できず、ネットワーク・リソース(コンテナの仮想インターフェース等)が残り続けるでしょう(あるいはファイル・ディスクリプタを閉じるまで)。適切なアプローチで、コンテナごとの最初の PID と、都度、名前空間の疑似ファイルが開かれるたびに、追跡

し続ける必要があります。

時々、リアルタイムなメトリクス収集に気を配っていなくても、コンテナ終了時に、どれだけ CPU やメモリ等を使⽤したか知りたい時があるでしょう。Docker は lxc-start に依存しており、終了時は丁寧に⾃分⾃⾝をクリーンアップするため困難です。しかし、

docs.docker.jp 16/06/04

Page 63: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 63 -

他にも⽅法があります。定期的にメトリクスを集める⽅法(例:毎分 collectd LXC プラグインを実⾏)が簡単です。しかし、停⽌したコンテナに関する情報を集めたい時もあるでしょう。次のようにします。各コンテナで収集プロセスを開始し、コントロール・グループに移動します。これは対象の cgroup のタスクフ

ァイルに PID が書かれている場所を監視します。収集プロセスは定期的にタスクファイルを監視し、コントロール・グループの最新プロセスを確認します(先ほどのセクションで暑かったネットワーク統計情報も取得したい場合は、プロセスを適切なネットワーク名前空間にも移動します)。コンテナが終了すると、lxc-start はコントロール・グループを削除しようとします。コントロール・グループ

が使⽤中のため、処理は失敗しますが問題ありません。⾃分で作ったプロセスは、対象のグループ内に⾃分しかいないことが分かります。それが必要なメトリックスを取得する適切なタイミングです。最後に、⾃分のプロセスをルート・コントロール・グループに移動し、コンテナのコントロール・グループを削

除します。コントロール・グループの削除は、ディレクトリを rmdir するだけです。感覚的にディレクトリに対する rmdir は、まだ中にファイルのではと思うかもしれませんが、これは疑似ファイルシステムのため、通常のルールは適⽤されません。クリーンアップが完了したら、これで収集プロセスを安全に終了できます。

docs.docker.jp 16/06/04

Page 64: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 64 -

7.10 アンバサダを経由したリンク

7.10.1 はじめに

サービスの利⽤者とプロバイダ間をネットワーク・リンクで固定するよりも、サービスのポータビリティをDocker は推奨します。

(利用者) --> (redis)

利⽤者が別の redis サービスに接続するには再起動が必⽤です。そこで、アンバサダ(ambassador;⼤使、使節の意味)を追加できます。

(利用者) --> (redis-ambassador) --> (redis)

(利用者) --> (redis-ambassador) ---network---> (redis-ambassador) --> (redis)

利⽤者が別の Redis サーバに通信するよう書き換える必要がある時、コンテナを接続する redis-ambassador しか再起動が不要です。このパターンは利⽤者を別のdocker ホスト上に対し、透過的に移動させるのにも使えます。svendowideit/ambassadorコンテナを使い、docker runパラメータで全体を制御するリンクを追加してみましょ

う。

Docker ホスト上で実際のRedis サーバを開始します。

big-server $ docker run -d --name redis crosbymichael/redis

それからRedis サーバにリンクしてポートを公開するアンバサダを追加します。

big-server $ docker run -d --link redis:redis --name redis_ambassador -p 6379:6379 \svendowideit/ambassador

別のホスト上で、更にアンバサダをセットアップできます。ここではプロキシしたい big-server のリモート・ポートを環境変数に設定します。

client-server $ docker run -d --name redis_ambassador --expose 6379 \-e REDIS_PORT_6379_TCP=tcp://192.168.1.52:6379 svendowideit/ambassador

それから client-serverホスト上で Redis クライアント・コンテナがリモートの Redis サーバに通信できるようにするため、ローカルのRedis アンバサダにリンクします。

client-server $ docker run -i -t --rm --link redis_ambassador:redis relateiq/redis-cliredis 172.17.0.160:6379> pingPONG

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.10アンバサダを経由したリンク

Page 65: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 65 -

7.10.3 動作内容

以下の例で、svendowideit/ambassador コンテナが⾃動的に(多少の sed の⼒を使い)何を⾏っているか⾒ていきましょう。Docker ホスト(192.168.1.52)上では Redis が実⾏されています。

# 実際の redis サーバを起動$ docker run -d --name redis crosbymichael/redis

# 接続テスト用の redis-cli コンテナを取得$ docker pull relateiq/redis-cli

# redis サーバと直接通信してテスト$ docker run -t -i --rm --link redis:redis relateiq/redis-cliredis 172.17.0.136:6379> pingPONG^D

# redis アンバサダを追加$ docker run -t -i --link redis:redis --name redis_ambassador -p 6379:6379 alpine:3.2 sh

redis_ambassadorコンテナ内では、リンクされた Redisコンテナの状態を envで確認できます。

/ # envREDIS_PORT=tcp://172.17.0.136:6379REDIS_PORT_6379_TCP_ADDR=172.17.0.136REDIS_NAME=/redis_ambassador/redisHOSTNAME=19d7adf4705eSHLVL=1HOME=/rootREDIS_PORT_6379_TCP_PORT=6379REDIS_PORT_6379_TCP_PROTO=tcpREDIS_PORT_6379_TCP=tcp://172.17.0.136:6379TERM=xtermPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binPWD=// # exit

この環境変数は、アンバサダの socatスクリプトがRedis を公開するために使います( -p 6379:6369でポートを割り当てます)。

$ docker rm redis_ambassador$ CMD="apk update && apk add socat && sh"$ docker run -t -i --link redis:redis --name redis_ambassador -p 6379:6379 alpine:3.2 sh -c "$CMD"[...]/ # socat -t 100000000 TCP4-LISTEN:6379,fork,reuseaddr TCP4:172.17.0.136:6379

次はRedis サーバにアンバサダ経由でpingします。次は別のサーバに移動します。

$ CMD="apk update && apk add socat && sh"$ docker run -t -i --expose 6379 --name redis_ambassador alpine:3.2 sh -c "$CMD"

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.10アンバサダを経由したリンク

Page 66: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 66 -

[...]/ # socat -t 100000000 TCP4-LISTEN:6379,fork,reuseaddr TCP4:192.168.1.52:6379

redis-cliイメージを取得し、アンバサダ・ブリッジを経由して通信します。

$ docker pull relateiq/redis-cli$ docker run -i -t --rm --link redis_ambassador:redis relateiq/redis-cliredis 172.17.0.160:6379> pingPONG

7.10.4 svendowideit/ambassador Dockerfile

svendowideit/ambassadorイメージは socatがインストールされた alpine:3.2イメージをベースとしています。コンテナを実⾏すると、⼩さなsedスクリプトが(利⽤可能な複数の)リンク環境変数をポート転送⽤に使います。リモートホストであれば、コマンドラインのオプション実⾏に -eで環境変数を指定する必要があります。

--expose 1234 -e REDIS_PORT_1234_TCP=tcp://192.168.1.52:6379

ローカルの 1234ポートをリモートのIPとポートに転送します。この例では 192.168.1.52:6379です。

## do# docker build -t svendowideit/ambassador .# then to run it (on the host that has the real backend on it)# docker run -t -i -link redis:redis -name redis_ambassador -p 6379:6379 svendowideit/ambassador# on the remote host, you can set up another ambassador# docker run -t -i -name redis_ambassador -expose 6379 -e REDIS_PORT_6379_TCP=tcp://192.168.1.52:6379# svendowideit/ambassador sh# you can read more about this process at https://docs.docker.com/articles/ambassador_pattern_linking/

# use alpine because its a minimal image with a package manager.# prettymuch all that is needed is a container that has a functioning env and socat (or equivalent)FROM alpine:3.2MAINTAINER [email protected]

RUN apk update && \apk add socat && \rm -r /var/cache/

CMD env | grep _TCP= | sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.10アンバサダを経由したリンク

Page 67: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 67 -

7.11 ログ保存

コンテナには、Docker デーモンよりも多い様々なロギング(ログ保存)ドライバがあります。ロギング・ドライバを指定するには、docker runコマンドで --log-driver=VALUE を使います。以下のオプションをサポートしています。

none コンテナ⽤のロギング・ドライバを無効化します。このドライバを指定したら docker logsは無効化されます。

json-file Docker ⽤のデフォルト・ロギング・ドライバです。JSONメッセージをファイルに記録します。syslog Docker ⽤の syslogロギング・ドライバです。ログ・メッセージをsyslogに記録します。journald Docker ⽤の journald ロギング・ドライバです。ログ・メッセージを journaldに記録します。gelf Docker ⽤のGraylog Extendef ログ・フォーマット(GELF)ロギング・ドライバです。ログ・

メッセージをGraylogのエンドポイントやLogstashに記録します。fluentd Docker ⽤の fluentd ロギング・ドライバです。ログ・メッセージを fluentd に記録します

(forward input)。awslogs Docker ⽤のAmazon CloudWatch Logsロギング・ドライバです。ログ・メッセージを Amazon

CloudWatch Logsに記録します。splunk Docker ⽤の Splunk ロギング・ドライバです。HTTPイベント・コレクタを使いログを splunk

に書き込みます。etwlogs Docker ⽤の ETW ロギング・ドライバです。ログメッセージを ETW イベントとして書き込み

ます。gcplogs Docker ⽤のGoogle Cloudロギング・ドライバです。ログメッセージをGoogle Cloud Logging

に書き込みます。

docker logsコマンドが使えるのは json-fileか journaldロギング・ドライバ使⽤時のみです。label と env オプションは、ロギング・ドライバで利⽤可能な追加属性を加えます。各オプションはキーのリス

トをカンマで区切ります。labelと envキーの間に衝突があれば、envを優先します。各種オプションは、Docker デーモン起動時に指定します。

docker daemon --log-driver=json-file --log-opt labels=foo --log-opt env=foo,fizz

それから、labelや envの値を指定してコンテナを起動します。例えば、次のように指定するでしょう。

docker run --label foo=bar -e fizz=buzz -d -P training/webapp python app.py

これはドライバ上のログに依存する追加フィールドを加えるものです。次の例は json-fileの場合です。

"attrs":{"fizz":"buzz","foo":"bar"}

JSON ファイルのオプション

json-fileロギング・ドライバがサポートしているロギング・オプションは以下の通りです。

--log-opt max-size=[0-9+][k|m|g]--log-opt max-file=[0-9+]--log-opt labels=label1,label2--log-opt env=env1,env2

ログが max-sizeに到達したら、ロールオーバされます(別のファイルに繰り出されます)。設定できるサイズは、

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 68: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 68 -

キロバイト(k)、メガバイト(m)、ギガバイト(g) です。例えば、 --log-opt max-size=50mのように指定します。もしも max-sizeを設定しなければ、ログはロールオーバされません。max-fileで指定するのは、ログが何回ロールオーバされたら破棄するかです。例えば --log-opt max-file=100

のように指定します。もし max-sizeを設定しなければ、max-fileは無効です。max-sizeと max-fileをセットしたら、docker logsは直近のログファイルのログ⾏だけ表⽰します。

syslog のオプション

syslogロギング・ドライバがサポートしているロギング・オプションは以下の通りです。

--log-opt syslog-address=[tcp|udp|tcp+tls]://host:port--log-opt syslog-address=unix://path--log-opt syslog-facility=daemon--log-opt syslog-tls-ca-cert=/etc/ca-certificates/custom/ca.pem--log-opt syslog-tls-cert=/etc/ca-certificates/custom/cert.pem--log-opt syslog-tls-key=/etc/ca-certificates/custom/key.pem--log-opt syslog-tls-skip-verify=true--log-opt tag="mailer"--log-opt syslog-format=[rfc5424|rfc3164]

syslog-address は、ドライバが接続するリモートの syslog サーバのアドレスを指定します。指定しなければ、デフォルトでは実⾏中システム上にあるローカルの unix ソケットを使います。tcp や udp で portを指定しなければ、デフォルトは 514になります。以下の例は syslogドライバを使い、リモートの 192.168.0.42サーバ上のポート 123に接続する⽅法です。

$ docker run --log-driver=syslog --log-opt syslog-address=tcp://192.168.0.42:123

syslog-facility オプションは syslog のファシリティを設定します。デフォルトでは、システムは daemon 値を使います。これを上書きするには、0から 23までの整数か、以下のファシリティ名を指定します。

kern

user

mail

daemon

auth

syslog

lpr

news

uucp

cron

authpriv

ftp

local0

local1

local2

local3

local4

local5docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 69: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 69 -

local6

local7

認証局(CA)によって署名済みの、信頼できる証明書への絶対パスを syslog-tls-ca-cert で指定します。このオプションは tcp+tls以外のプロトコルを使う場合は無視されます。syslog-tls-certはTLS証明書⽤ファイルに対する絶対パスです。このオプションは tcp+tls以外のプロトコル

を使う場合は無視されます。syslog-tls-key は TLS 鍵ファイルに対する絶対パスを指定します。このオプションは tcp+tls 以外のプロトコ

ルを使う場合は無視されます。syslog-tls-skip-verify は TLS 認証を設定します。デフォルトでは認証が有効ですが、オプションの値を true

に指定したら、この設定を上書きします。このオプションは tcp+tls以外のプロトコルを使う場合は無視されます。デフォルトでは、Docker はコンテナ ID の冒頭 12 ⽂字のみログ・メッセージにタグ付けします。タグ・フォー

マットの記録⽅式をカスタマイズするには、「log tagオプション」のセクションをご覧ください。syslog-format は syslog メッセージを書き込み時の書式を指定します。何も指定しなければ、デフォルトではホ

スト名を指定しないローカルのunix syslog 形式です。rfc3164を指定したら、RFC-3164互換形式でログを記録します。rfc5424を指定したら、RFC-5424互換形式で記録します。

journald オプション

journaldロギング・ドライバは journal の CONTAINER_IDフィールドにコンテナ IDを記録します。ロギング・ドライバの詳細な動作については、「journald ロギング・ドライバ」リファレンスをご覧ください。

gelf オプション

GELFロギングドライバは以下のオプションをサポートしています。

--log-opt gelf-address=udp://host:port--log-opt tag="database"--log-opt labels=label1,label2--log-opt env=env1,env2

gelf-address オプションは、接続先のリモート GELF サーバのアドレスを指定します。現時点では udp が転送⽤にサポートされており、利⽤時に portを指定する必要があります。次の例は gelfドライバでGELFリモートサーバ 192.168.0.42のポート 12201に接続します。

$ docker run --log-driver=gelf --log-opt gelf-address=udp://192.168.0.42:12201

デフォルトでは、Docker はコンテナ ID の冒頭 12 ⽂字のみログ・メッセージにタグ付けします。タグ・フォーマットの記録⽅式をカスタマイズするには、「log tagオプション」のドキュメントをご覧ください。labelと envオプションが gelf ロギング・ドライバでサポートされています。これは extraフィールドに、冒頭

がアンダースコア ( _ ) で始まるキーを追加するものです。

// […]"_foo": "bar","_fizz": "buzz",// […]

--log-opt NAME=VALUEフラグを使い、以下のFluentdロギング・ドライバのオプションを追加できます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 70: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 70 -

fluentd-address: 接続先を host:portの形式で指定。[localhost:24224] tag: fluentd メッセージのタグを指定。 fluentd-buffer-limit: fluentd ログバッファの最⼤サイズを指定します。 [8MB] fluentd-retry-wait: 接続リトライ前の初回遅延時間です(以降は指数関数的に増えます) [1000ms] fluentd-max-retries : docker で不意の障害が発⽣時、最⼤のリトライ数を指定します。 [1073741824] fluentd-async-connect: 初期接続をブロックするかどうかを指定します。 [false]

例えば、両⽅のオプションを指定したら、次のようになります。

docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 \--log-opt tag=docker.{{.Name}}

コンテナは指定した場所にある Fluentd デーモンに接続できなければ、コンテナは直ちに停⽌します。このロギング・ドライバの動作に関する詳細情報は「fluentdロギング・ドライバ」をご覧ください。

Amazon CloudWatch Logs オプションの指定

Amazon CloudWatch ロギングドライバは、以下のオプションをサポートしています。

--log-opt awslogs-region=<aws_region>--log-opt awslogs-group=<log_group_name>--log-opt awslogs-stream=<log_stream_name>

このロギング・ドライバの動作に関する詳細情報は「awslogsロギング・ドライバ」をご覧ください。

ETW ロギング・ドライバのオプション

etwlogs ロギング・ドライバには必須のオプションはありません。このロギング・ドライバは各ログメッセージをETWイベントとして転送します。ETW受信側(リスナー)は受信したイベントを作成できます。このロギング・ドライバの動作に関する詳細情報は「ETWロギング・ドライバ」をご覧ください。

Google Cloud ロギング

Google Cloudロギング・ドライバはいかのオプションをサポートしています。

--log-opt gcp-project=<gcp_projext>--log-opt labels=<label1>,<label2>--log-opt env=<envvar1>,<envvar2>--log-opt log-cmd=true

このロギング・ドライバの動作に関する詳細情報はGoogle Cloudロギング・ドライバ をご覧ください。

7.11.2 ログ⽤のタグ

tag ログ・オプションは、コンテナのログ・メッセージを識別するため、どのような形式のタグを使うか指定します。デフォルトでは、システムはコンテナ ID の冒頭 12 ⽂字を使います。この動作を上書きするには、tag オプションを使います。

docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224 --log-opt tag="mailer"

Docker はタグの値を指定するために、特別なテンプレート・マークアップをサポートしています。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 71: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //go lang .org/pkg/tex t/ templa te/

*2 ht tps : //g i thub . com/docker/docker/b lob/maste r/daemon/ logger/contex t .go

*3 ht tps ://aws .amazon .com/c loudwatch/de ta i l s /# log-moni tor ing

*4 ht tps : //conso le . aws . amazon .com/c loudwatch/home# logs :

*5 ht tp : //docs .aws .amazon .com/c l i / l a tes t/ re fe rence/ logs/ index .h tml

- 71 -

マークアップ 説明{{.ID}} コンテナIDの冒頭12⽂字{{.FullID}} コンテナの完全ID{{.Name}} コンテナ名{{.ImageID}} イメージIDの冒頭12⽂字{{.ImageFullId}} コンテナの完全ID{{.ImageName}} コンテナが使っているイメージ名

例えば、 --log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}" を値に指定したら、syslogのログ⾏は次のようになります。

Aug 7 18:33:19 HOSTNAME docker/hello-world/foobar/5790672ab6a0[9103]: Hello from Docker.

起動時に、システムは container_nameフィールドと{{.Name}}をタグに設定します。docker renameでコンテナ名を変更しても、ログメッセージに新しいコンテナ名は反映されません。そのかわり、これらのメッセージは元々のコンテナ名を使って保存され続けます。⾼度な使い⽅は、goテンプレート*1 のタグ⽣成や、コンテナのログ内容*2 をご覧ください。以下は syslog ロガーを使う例です:

$ docker run -it --rm \--log-driver syslog \--log-opt tag="{{ (.ExtraAttributes nil).SOME_ENV_VAR }}" \--log-opt env=SOME_ENV_VAR \-e SOME_ENV_VAR=logtester.1234 \flyinprogrammer/logtester

ログの結果は次のようになります。

Apr 1 15:22:17 ip-10-27-39-73 docker/logtester.1234[45499]: + exec appApr 1 15:22:17 ip-10-27-39-73 docker/logtester.1234[45499]: 2016-04-01 15:22:17.075416751 +0000 UTCstderr msg: 1

ドライバがログのオプション syslog-tag、fluentd-tag、gelf-tagを指定しても後⽅互換性があります。ですが、これらの代わりに、標準化のため⼀般的な tagログ・オプションを使うべきです。

7.11.3 Amazon Cloud Watch ロギング・ドライバ

awslogs ロギングドライバは、コンテナのログをAmazon CloudWatchログ*3 に送信します。ログのエントリは、AWS マネジメント・コンソール*4 やAWS SDKやコマンドライン・ツール*5 を通して確認できます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 72: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://docs . aws .amazon.com/AmazonCloudWatch/ la tes t/Deve loperGuide/What IsCloudWatchLogs .h tml

*2 ht tp ://docs . aws .amazon.com/AmazonCloudWatch/ la tes t/Deve loperGuide/What IsCloudWatchLogs .h tml

- 72 -

使い⽅

デフォルトのロギング・ドライバを指定するには、Docker デーモンで --log-driverオプションを使います。

docker daemon --log-driver=awslogs

特定のコンテナに対するロギング・ドライバの指定は、docker runで --log-driverオプションを使います。

docker run --log-driver=awslogs ...

Amazon CloudWatch ログのオプション

Amazon CloudWatch Logsロギング・ドライバのオプションを指定するには、 --log-opt NAME=VALUEフラグを使います。awslogs-region

awslogs ロギング・ドライバを使うには、リージョンの指定が必須です。リージョンを指定するにはログのオプションで awslogs-regionを指定するか、環境変数 AWS_REGIONを使います。

docker run --log-driver=awslogs --log-opt awslogs-region=us-east-1 ...

awslogs-group

log group*1 を使う場合は、awslogs-groupログ・オプションを指定します。awslogs-groupログ・オプションでlog groupを指定します。

docker run --log-driver=awslogs --log-opt awslogs-region=us-east-1 \--log-opt awslogs-group=myLogGroup ...

awslogs-stream

log stream*2 を使う場合は、awslogs-streamログ・オプションを指定します。指定しなければ、コンテナ ID がログ・ストリームのために使われます。

ログ・ストリームに使うログ・グループはコンテナごとに指定すべきです。複数のコンテナが同じログ・ストリームを並⾏して使⽤すると、ログ記録性能が低下します。

Docker デーモンが awslogsロギング・ドライバを使う時は、AWSの認証情報(credentials)の指定が必要です。認証情報とは環境変数 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN 境変数です。デフォルトはAWS共有認証ファイル(root ユーザであれば ~/.aws/credentials)か、(Amazon EC2インスタンス上でDockerデーモンを実⾏するのであれば)Amazon EC2インスタンス・プロファイルです。認証情報には、次の例のように logs:CreateLogStream と logs:PutLogEvents の各アクションに対するポリシー

追加が必要です。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 73: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 73 -

{"Version": "2012-10-17","Statement": [{"Action": ["logs:CreateLogStream","logs:PutLogEvents"

],"Effect": "Allow","Resource": "*"

}]

}

7.11.4 ETW ロギング・ドライバ

ETW ロギング・ドライバはコンテナのログを ETW イベントとして転送します。ETW はWindows におけるイベント・トレース(追跡)であり、Windows上のアプリケーションをトレースする共通フレームワークです。各ETWイベントにはログとコンテクスト情報の両⽅があります。クライアントは ETW リスナーを通して、これらのイベントを確認できます。ETW はロギング・ドライバを {a3693192-9ed6-46d2-a981-f8226c8363bd} のような GUID 識別⼦でWindows

に登録します。クライアントは新しい ETW リスナーを作成し、ロギング・ドライバが送信するイベントを受信・登録できます。

使い⽅

ここでは⼤部分の Windows にインストール済みの logman ユーティリティ・プログラムを使い、これらのイベントのリッスン例を扱います。

1. logman start -ets DockerContainerLogs -p {a3693192-9ed6-46d2-a981-f8226c8363bd} 0 0 -o trace.etl

2. コンテナをetwlogドライバと⼀緒に起動します。docker runコマンドに--log-driver=etwlogsを追加します。

3. logman stop -ets DockerContainerLogs

4. 実⾏するとイベントを含むetl ファイルを作成します。⼈間が読める形式に変換する⽅法の1つが tracerpt -y

trace.etlの実⾏です。

各ETWイベントには、次の形式のように構造化されたメッセージを含みます。

container_name: %s, image_name: %s, container_id: %s, image_id: %s, source: [stdout | stderr], log: %s

各メッセージの詳細は以下の通りです。

フィールド 説明container_name 開始のコンテナ名image_name コンテナのイメージ名container_id 64⽂字のコンテナIDimage_id コンテナ・イメージのフルIDsource stdout(標準出⼒)または stderr(標準エラー出⼒)log コンテナのログ・メッセージ

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 74: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://www. fl uentd .org/

*2 ht tp ://www. fl uentd .o rg/p lug ins

- 74 -

以下はイベント・メッセージの例です。

container_name: backstabbing_spence,image_name: windowsservercore,container_id: f14bb55aa862d7596b03a33251c1be7dbbec8056bbdead1da8ec5ecebbe29731,image_id: sha256:2f9e19bd998d3565b4f345ac9aaf6e3fc555406239a4fb1b1ba879673713824b,source: stdout,log: Hello world!

クライアントはこのメッセージ⽂字列をログメッセージごとにパース可能です。また、コンテクスト情報も同様です。ETWイベント無いのタイムスタンプも利⽤可能です。

ETW プロバイダはメッセージ文字列のみ転送するだけであり、特別なETW イベント構造ではありません。そのため、システムが ETW イベントの読み込み・受信のため、マニフェスト・ファイルを登録する必要がありません。

7.11.5 Fluentd ロギング・ドライバ

fluentdロギング・ドライバは、コンテナのログをFluentd*1 コレクタに構造化したログ・データとして送信します。それから、ユーザはFluentdの様々な出⼒プラグイン*2 を使い、ログを様々な送信先に送れます。ログ・メッセージ⾃⾝に加え、fluentログ・ドライバは以下のメタデータを構造化ログ・メッセージの中に⼊れ

て送信できます。

フィールド 説明container_id 64⽂字の完全コンテナIDcontainer_name 開始時のコンテナ名。docker renameでコンテナの名称を変え

ても、新しい名前は journal エントリに反映されない。source stdoutか stderr

このロギング・ドライバの使⽤時は、docker logsコマンドを利⽤できません。

使い⽅

必要であれば、同じ --log-optオプションを何度も指定可能です。

fluentd-address: localhost:24224に接続する host:portを指定します。 tag : fluentdメッセージに送るタグを指定します。 {{.ID}}、{{.FullID}}、{{.Name}}、docker.{{.ID}}

のようなマークアップ形式です。

デフォルトのロギング・ドライバを設定するには、Docker デーモンに --log-driverオプションを使います。

docker daemon --log-driver=fluentd

特定のコンテナに対してロギング・ドライバを指定する場合は、docker runに --log-driverオプションを指定します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 75: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://www. fl uentd .org/

*2 ht tp : //docs . fl uentd .org/

*3 ht tps : // reg i s t ry .hub .docker . com/u/fl uent/ fl uentd/

- 75 -

docker run --log-driver=fluentd ...

このロギング・ドライバを使う前に、Fluentd デーモンを起動します。ロギング・ドライバは、デフォルトでlocalhost:24224 のデーモンに接続を試みます。fluentd-address オプションを使えば、異なったアドレスに接続できます。

docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224

コンテナがFluentd デーモンに接続できなければ、コンテナは直ちに停⽌します。

オプション

--log-opt NAME=VALUEフラグでFluentdロギング・ドライバのオプションを追加できます。fluentd-address

デフォルトでは、ロギング・ドライバは localhost:24224 に接続します。fluentd-address オプションを指定すると、異なったアドレスに接続します。

docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224

tag

デフォルトでは、Docker はコンテナIDの冒頭12⽂字を tag logメッセージで使います。このログフォーマットをカスタマイズするには、「log tag オプションのドキュメント」をご覧ください。label と env

labelと envオプションは、どちらもカンマ区切りでキーを指定できます。labelと envキーが重複する場合は、env の値が優先されます。どちらのオプションもロギング・メッセージの特別属性(extra attributes)に追加フィールドを加えます。fluentd-acync-connect

Docker は Fluentd にバックグラウンドで接続します。接続が確⽴できるまでメッセージはバッファされます。

Docker と Fluentd デーモンの管理

Fluentd そのものについては、プロジェクトのウェブページ*1 とドキュメント*2 をご覧ください。このロギング・ドライバを使うには、ホスト上に fluentdデーモンを起動します。私たちはFluentd docker イメ

ージ*3 の利⽤を推奨します。このイメージが特に役⽴つのは、各ホスト上にある複数のコンテナのログを統合する場合です。そして、ログはデータを統合する⽤途として作成した、別のFluentdノードに転送できます。

1. 設定ファイル (test.conf) に⼊⼒ログをダンプするよう記述します。

<source>@type forward

</source>

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 76: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps ://c loud .goog le . com/ logg ing/docs/

*2 ht tps ://c loud .goog le . com/compute/docs/metada ta

*3 ht tps : //deve lopers .goog le . com/ident i t y/pro toco l s/app l i ca t ion-de fau l t -c redent i a l s

- 76 -

<match docker.**>@type stdout

</match>

2. Fluentdコンテナを、この設定を使って起動します。

$ docker run -it -p 24224:24224 -v /path/to/conf/test.conf:/fluentd/etc \-e FLUENTD_CONF=test.conf fluent/fluentd:latest

3. fluentdロギング・ドライバを使うコンテナを更に起動します。

$ docker run --log-driver=fluentd your/application

7.11.6 Google Cloud ロギング・ドライバ

Google Cloudロギング・ドライバはコンテナのログをGoogle Cloud Logging*1 に送ります。

使い⽅

デフォルトのロギング・ドライバを設定するには、Docker デーモンに --log-driverオプションを使います。

docker daemon --log-driver=gcplogs

ロギング・ドライバをコンテナに指定するには docker runのオプションで --log-driverを指定します。

docker run --log-driver=gcplogs ...

このログ・ドライバを実装すると、docker logsコマンドでログを参照できません。Docker がGoogle Cloudプロジェクトを検出すると、インスタンス・メタデータ・サービス*2 上で設定を⾒つけ

られるようになります。あるいは、ユーザがプロジェクトのログを記録するには --gcp-projectログ・オプションを指定し、Docker がGoogle Application Default Credential*3 から証明書を得る必要があります。 --gcp-project

はメタデータ・サーバによって発⾒される情報よりも優先します。そのため、Google Cloud Project で動いているDocker デーモンのログは、 --gcp-projectを使って異なったプロジェクトに出⼒できます。

gpclogs オプション

Google Cloudロギング・ドライバのオプションは、--log-opt 名前=値 の形式で指定できます。

フィールド 必須 説明gcp-project オプション どの GCP プロジェクトにログを記録するか指定。デフォルトは GCE

メタデータ・サービスを経由して確認された値gcp-log-cmd オプション コンテナ起動時、どこにログ記録コマンドがあるか指定。デフォルトは

falselables オプション ラベルをコンテナに指定する場合、メッセージを含むラベルのキー⼀覧

をカンマ区切りでenv オプション 環境変数をコンテナに指定する場合、メッセージに含める環境変数があ

れば、キーの⼀覧をカンマ区切りで指定

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 77: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : //dev . sp lunk . com/v iew/event -co l l ec tor/SP-CAAAE6M

- 77 -

label と env キーの間で衝突があれば、env が優先されます。いずれのオプションもロギング・メッセージの追加フィールドの属性に追加します。以下は、GCE メタデータ・サーバで発⾒されたデフォルトのログ送信先を使うために必要なオプション指定の

例です。

docker run --log-driver=gcplogs \--log-opt labels=location--log-opt env=TEST--log-opt gcp-log-cmd=true--env "TEST=false"--label location=westyour/application

また、この設定ではラベル location、環境変数 ENV、コンテナ起動時に使うコマンドの引数も指定しています。

7.11.7 Splunk ロギング・ドライバ

splunkロギング・ドライバは、コンテナのログをSplunk Enterprise もしくはSplunk CloudのHTTP EventCollector*1 に送ります。

使い⽅

デフォルトのロギング・ドライバを変更するには、Docker デーモンに --log-driverオプションを付けます。

docker daemon --log-driver=splunk

特定のコンテナに対してロギング・ドライバを指定するには、docker runの実⾏時に --log-driverオプションを付けます。

docker run --log-driver=splunk ...

Splunk オプション

Splunnkロギング・ドライバでは、--log-opt 名前=値 フラグを指定できます。

オプション 必須 説明splunk-token 必須 Splunk HTTP Event Collector トークンを指定splunk-url 必須 Splunk Enterprise またはSplunk Cloudインスタンスに対するパ

ス(HTTP Event Collector の使うポートとスキームを含む)https://your_splunk_instance:8088

splunk-source オプション イベント・ソースsplunk-sourcetype オプション イベント・ソースのタイプsplunk-index オプション Event インデックスsplunk-capath オプション root 証明書のパスsplunk-caname オプション サーバ証明書に使う有効な名前。デフォルトでは splunk-url で

指定したホスト名が使われるsplunk-insecureskipverify オプション サーバ証明書の認証を無効化splunk-tag オプション メッセージに対するタグを指定。いくつかのマークアップを利⽤

可能。デフォルトの値は {{.ID}}(コンテナ ID の 12 ⽂字)。ログのタグ書式のカスタマイズ⽅法は、「ログ⽤のタグ」を参照

splunk-labels オプション メッセージに含めるラベルを、カンマ区切りのキーで指定できる。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 78: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://www. f reedesk top .org/so f tware/sys temd/man/sys temd- journa ld . se rv i ce .h tml

- 78 -

ラベルはコンテナで指定できるsplunk-env オプション メッセージに含める環境変数を、カンマ区切りのキーで指定でき

る。これらの変数はコンテナで指定できる

label と env のキーが重複する場合は、env が優先されます。どちらのオプションも、ロギング・メッセージの追加フィールドに追加できるものです。以下はロギング・ドライバにSplunk Enterprise インスタンスを指定する例です。インスタンスはDocker デーモ

ンを実⾏している同じマシン上のローカルにインストールされています。root 証明書とコモンネームの指定にはHTTPスキームを使います。これが証明書の使い⽅です。SplunkServerDefaultCertは⾃動的に⽣成されたSplunk証明書です。

docker run --log-driver=splunk \--log-opt splunk-token=176FCEBF-4CF5-4EDF-91BC-703796522D20 \--log-opt splunk-url=https://splunkhost:8088 \--log-opt splunk-capath=/path/to/cert/cacert.pem \--log-opt splunk-caname=SplunkServerDefaultCert--log-opt tag="{{.Name}}/{{.FullID}}"--log-opt labels=location--log-opt env=TEST--env "TEST=false"--label location=westyour/application

7.11.8 Journald ロギング・ドライバ

journaldロギング・ドライバは、コンテナログをsystemd journal*1 に送信します。ログエントリは、journalctl

コマンドを使ってログエントリを確認できます。使うには journal APIか docker logsコマンドを通します。ログメッセージ⾃⾝の⽂字列に加え、journald ログドライバは各メッセージの journal に以下のメタデータを保

管できます。

フィールド 説明CONTAINER_ID コンテナIDの先頭から12⽂字CONTAINER_ID_FULL 64⽂字の完全コンテナIDCONTAINER_NAME 開始時のコンテナ名。docker renameでコンテナの名称を変え

ても、新しい名前は journal エントリに反映されない。CONTAINER_TAG コンテナのタグ

使い⽅

デフォルトのロギング・ドライバを設定するには、Docker デーモンに --log-driverオプションを使います。

docker daemon --log-driver=journald

特定のコンテナに対してロギング・ドライバを指定する場合は、docker runに --log-driverオプションを指定します。

docker run --log-driver=journald ...

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 79: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 79 -

オプション

--log-opt NAME=VALUEフラグで journald ロギング・ドライバのオプションを追加できます。タグ

journald のログに CONTAINER_TAG 値でテンプレートを指定します。ログのタグ形式をカスタマイズするには「ログ⽤タグのオプション」についてのドキュメントをご覧ください。label と env

labelと envオプションは、どちらもカンマ区切りでキーを指定できます。labelと envキーが重複する場合は、env の値が優先されます。どちらのオプションもロギング・メッセージの特別属性(extra attributes)に追加フィールドを加えます。

CONTAINER_NAMEフィールドに記録される値は、起動時のコンテナ名が使われます。docker renameでコンテナの名前を変更しても、journal エントリの名前には反映されません。journal のエントリはオリジナルの名前を表⽰し続けます。

journalctlコマンドを使って、ログメッセージを表⽰できます。フィルタ表現を追加することで、特定のコンテナに関するメッセージしか表⽰しないようにできます。例えば、特定のコンテナ名に関する全てのメッセージを表⽰するには、次のようにします。

# journalctl CONTAINER_NAME=webserver

メッセージの制限だけでなく、他のフィルタも利⽤できます。例えば、システムが直近でリブートした以降のメッセージを⽣成するには、次のように実⾏します。

# journalctl -b CONTAINER_NAME=webserver

あるいは、全てのメタデータを含むJSON形式でメッセージを表⽰するには、次のようにします。

# journalctl -o json CONTAINER_NAME=webserver

この例は systemd Python モジュールを使い、コンテナのログを取得しています。

import systemd.journal

reader = systemd.journal.Reader()reader.add_match('CONTAINER_NAME=web')

for msg in reader:print '{CONTAINER_ID_FULL}: {MESSAGE}'.format(**msg)

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 7.11ログ保存

Page 80: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 80 -

8 章

8章 セキュリティ

8.1 安全な Engineこのセクションは Docker Engineのセキュリティ機能や、インストール時の設定について扱います。

トラステッド・イメージ(trusted image)を送受信できる機能を設定することで、Docker の信頼性を⾼めます。設定の詳細は「トラステッド・イメージを使う」をご覧ください。

Docker デーモン・ソケットを守り、確かなものとするには信頼された Docker クライアント接続を使います。詳細は「Docker デーモンのソケットを守る」をご覧ください。

証明書をベースとするクライアント・サーバ認証を使えます。これはDocker デーモンがレジストリ上のイメージに対する適切なアクセス権があるかどうかを確認します。詳細は「証明書をリポジトリのクライアント認証に使⽤」をご覧ください。

セキュア・コンピューティング・モード(Seccomp)ポリシーを設定することで、コンテナ内のシステムコールを安全にします。詳細な情報は「Docker ⽤の seccomp セキュリティ・プロフィール」をご覧ください。

公式の .deb パッケージは、Docker ⽤の AppArmor プロファイルがインストールされます。プロファイルや更新⽅法は「Docker ⽤のapparmorセキュリティ・プロフィール」をご覧ください。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.1 安全なEngine

Page 81: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp : // l xc . source forge .ne t/ index .php/about/kerne l -namespaces/

*2 ht tp : // ja .w ik iped ia .o rg/wik i/OpenVZ

- 81 -

8.2 Docker のセキュリティDocker のセキュリティには、主に3つの検討項⽬があります。

カーネルに起因するセキュリティと、カーネルがサポートする名前空間とcgroupsについて Docker デーモン⾃⾝が直⾯する攻撃について コンテナ設定プロファイル(デフォルトでもユーザによってカスタマイズされた場合も含む)における抜

け道について カーネルのセキュリティ「硬化」(hardening)機能と、コンテナへの対応。

ハ ー デ ニ ン グ

Docker コンテナは LXC コンテナに⾮常に似ており、類似のセキュリティ機能を持っています。コンテナをdocker runで起動する時、その背後でDocker がコンテナ向けの名前空間とコントロール・グループを作成します。名前空間は、一流かつ最も簡単な方法で分離(isolation)を提供します。これによりコンテナの中で実⾏してい

るプロセスは、他のコンテナやホスト上のプロセスから⾒えなくなり、影響すら受けません。各コンテナは自分自身のネットワーク・スタックを持ちます。つまり、コンテナはソケットや他のコンテナのイ

ンターフェースに対する特権(privileged)アクセスが得られません。もちろん、ホストシステムが適切に設定されている必要があります。そうしておけば、コンテナが相互に適切なネットワーク・インターフェースを通して通信できるようになります。ホストの外と通信できるのも同様です。コンテナに対して公開⽤のポートを指定するか、リンク機能を使うことで、コンテナ間での IP 通信が許可されます。お互いに ping できるようになり、UDP パケットの送受信や、TCP 接続が確⽴されます。しかし、必要があれば制限を設けられます。ネットワーク・アーキテクチャの視点から考えますと、全てのコンテナは特定のホスト上のブリッジ・インターフェースを備えています。つまりこれは、物理マシン上で共通のイーサネット・スイッチを使っているのと同じような状態を意味します。それ以上でも、それ以下でもありません。カーネルの名前空間を提供するコードやプライベート・ネットワーキングの成熟度とは、どの程度でしょうか。

カーネルの名前空間は カーネル 2.6.15 から 2.6.26 の間*1 に導⼊されました。これが意味するのは、2008 年 6 ⽉にリリースされた(2.6.26 がリリースされたのは、今から 7 年前です)名前空間のコードは、多数のプロダクション・システム上で動作・精査されています。更にもう1つ。名前区間コードの設計と発想はやや古いものです。名前空間が効果的に実装された例としては OpenVZ*2 があり、カーネルのメインストリームとしてマージされたこともありました。OpenVZ の初期リリースは 2005 年であり、設計と実装は、多少成熟していると⾔えるでしょう。

8.2.2 コントロール・グループ

コントロール・グループは Linux コンテナにおけるもう1つの重要なコンポーネントです。これはリソースの計測と制限を実装しています。これらは多くの便利なメトリクス(監視上の指標)を提供するだけでなく、各コンテナが必要な共有リソース(メモリ、CPU、ディスク I/O)の割り当て保証にも役⽴ちます。更に重要なのは、単⼀のコンテナが膨⼤なリソースを消費しても、システムダウンを引き起こさない点です。そのため、あるコンテナが他のコンテナからアクセスできませんし、データに対する何らかのアクセスや影響を

及ぼすこともありません。これはあらゆるサービス拒否(denial-of-service)攻撃の本質です。特に重要なのはマルチテナントなプラットフォーム、例えばパブリックやプライベートな PaaS において、特定のアプリケーションが

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.2 Dockerのセキュリティ

Page 82: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 82 -

誤った動作をしても、⼀定の稼働(とパフォーマンス)を保証します。コントロール・グループも同様に、以前から存在していました。コードは 2006 年から書き始めら、カーネルに

2.6.24で初めてマージされました。

Docker を使ったコンテナ(とアプリケーション)を実⾏するとは、Docker デーモンの稼働を意味します。このデーモンは現時点でroot 特権が必要であり、それゆえ、いくつか重要な点に配慮が必要です。まずはじめに、信頼する利用者だけ、Docker デーモンに対するアクセスを許可するべきです。これはDocker が

もたらす強⼒な機能を直接扱うためです。特に、Docker はDocker ホストとゲストコンテナ間でディレクトリを共有できます。そして、それにより、コンテナ内に対する適切なアクセス権限が無くても、ディレクトリを使えるようになる可能性があります。つまりコンテナの /host ディレクトリは、ホスト上の / ディレクトリとしても実⾏可能です。それだけではありません。コンテナは何ら制限を受けずに、ホスト上のファイルシステム上に対する修正が可能になります。これは仮想化システムによるファイルシステム・リソースの共有に似ています。仮想マシン上における⾃分のルート・ファイルシステム(ルート・ブロック・デバイスも同様)の共有を阻⽌する⽅法はありません。これはセキュリティに重⼤な影響を及ぼします。例えば、Docker の API を通してウェブ・サーバ⽤コンテナを

プロビジョンしたいとします。通常通りパラメータの確認に注意を払うべきです。ここでは、悪意のあるユーザが⼿の込んだパラメータを使い、Docker が余分なコンテナを作成不可能にしてください。この理由により、REST APIエンドポイント(Docker CLIがDocker デーモンとの通信に使います)がDocker

0.5.2 で変更されました。現在は 127.0.0.1 上の TCP ソケットに代わり、UNIX ソケットを使います(最近はローカルのマシン上の Docker に対して、仮想マシンの外から直接クロスサイト・リクエスト・フォージェリ、CSRFを⾏う傾向があります)。伝統的な Unix パーミッションを確認し、ソケットに対するアクセスを制限するような管理が必要です。明⽰的にHTTP上でREST APIを晒すことも可能です。しかし、そのように設定すべきではありません。上記

で⾔及したセキュリティ実装のため、信頼できるネットワークや VPN、stunnel やクライアント SSL 証明が利⽤できる所でのみ使うべきです。より安全にするためにはHTTPSと証明書を利⽤できます。また、デーモンは⼊⼒に関する脆弱性を潜在的に持っています。これはディスク上で docker load、あるいはネ

ットワーク上で docker pullを使いイメージを読み込む時です。これはコミュニティにおける改良に焦点がおかれており、特に安全に pullするためです。これまでの部分と重複しますが、docker loadはバックアップや修復のための仕組みです。しかし、イメージの読み込みにあたっては、現時点で安全な仕組みではないと考えられていることに注意してください。Docker 1.3.2からは、イメージはLinux/Unix プラットフォームのchroot サブ・プロセスとして展開されるようになりました。これは広範囲にわたる特権分離問題に対する第⼀歩です。最終的には、Docker デーモンは制限された権限下で動作するようになるでしょう。それぞれが⾃⾝の(あるい

は限定された)Linuxケーパビリティ(capability;「能力」や「機能」の意味)、仮想ネットワークのセットアップ、ファイルシステム管理といった、サブプロセスごとに委任したオペレーションを監査できるようになることを期待しています。なお、Docker をサーバで動かす場合は、サーバ上でDocker 以外を動かさないことを推奨します。そして、他の

サービスは Docker によって管理されるコンテナに移動しましょう。もちろん、好きな管理ツール(おそらく SSHサーバでしょう)や既存の監視・管理プロセス(例:NRPE、collectd、等)はそのままで構いません。

8.2.4 Linux カーネルのケーパビリティ

デフォルトでは Docker はケーパビリティ(capability;「能⼒」や「機能」の意味)を抑えた状態でコンテナを起動します。つまり、これはどのような意味でしょうか。ケーパビリティとは、「root」か「root 以外か」といったバイナリの⼆分法によって分類する、きめ細かなアクセ

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.2 Dockerのセキュリティ

Page 83: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps ://g i thub.com/docker/docker/b lob/master/daemon/execdr iver/nat ive/ templa te/defau l t_templa te .go

*2 ht tp ://man7.org/ l inux/man-pages/man7/capabi l i t i e s .7 .html

- 83 -

ス制御システムです。(ウェブサーバのような)プロセスがポート1024以下でポートをバインドする必要がある時、root 権限でなければ実⾏できません。そこで net_bind_service ケーパビリティを使い、権限を与えます。他にも多くのケーパビリティがあります。⼤部分は特定の条件下でroot 特権を利⽤できるようにするものです。つまり、コンテナのセキュリティを⾼めます。理由を⾒ていきましょう!あなたの平均的なサーバ(ベアメタルでも、仮想マシンでも)が必要とするのは、root として実⾏される⼀連の

プロセスです。典型的なものにSSH、cron、syslogdが含まれるでしょう。あるいは、ハードウェア管理ツール(例:load モジュール)、ネットワーク設定ツール(例:DHCP、WPA、VPNを取り扱うもの)、等々があります。ですが、コンテナは⾮常に異なります。なぜなら、これらのタスクのほぼ全てが、コンテナの中という基盤上で処理されるからです。

SSH接続は、 Docker ホストのサーバ上を管理する典型的な⼿法です。

cron は、必要があればユーザ・プロセスとして実⾏可能です。プラットフォーム上のファシリティを広範囲に使うのではなく、専⽤、もしくはアプリケーションが個別に必要なサービスをスケジュールします。

ログ管理もまた Docker の典型的な処理であり、あるいはサードパーティー製の Loggly や Splunk を使うでしょう。

ハードウェア管理には適していません。これはコンテナ内で udevd や同等のデーモンを実⾏できないためです。

ネットワーク管理はコンテナの外で⾏われので、懸念されうる事項を分離します。つまり、コンテナではifconfig、route、ipコマンドを実⾏する必要がありません(ただし、コンテナでルータやファイアウォール等の振る舞いを処理させる場合は、もちろん除きます)。

これらが意味するのは、⼤部分のケースにおいて、コンテナを「本当の」root 特権で動かす必要は全く無いということです。それゆえ、コンテナはケーパビリティの組み合わせを減らして実⾏できるのです。つまり、コンテナ内の「root」は、実際の「root」よりも権限が少ないことを意味します。例えば、次のような使い⽅があります。

全ての「mount」操作を拒否 rawソケットへのアクセスを拒否(パケット・スプーフィングを阻⽌) ファイルシステムに関するいくつかの操作を拒否(新しいデバイス・ノードの作成、ファイル所有者の変

更、immutable フラグを含む属性の変更) モジュールの読み込みを禁⽌ などなど

これが意味するのは、侵⼊者がコンテナ内でroot に昇格しようとしても、深刻なダメージを与えるのが困難であり、ホストにも影響を与えられません。通常のウェブ・アプリケーションには影響を与えません。しかし、悪意のあるユーザであれば、⾃分たちが⾃由

に使える武器が減ったと分かるでしょう! Docker は必要に応じて*1 全てのケーパビリティを除外し、ブラックリストからホワイトリストに除外する⽅法も使えます。利⽤可能なケーパビリティについては、Linuxのmanページ*2

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.2 Dockerのセキュリティ

Page 84: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : // in tegra tedcode .u s/2015/10/13/use r-namespaces -have -ar r i ved- in-docker/

- 84 -

をご覧ください。Docker コンテナ実⾏にあたり、最も重要なリスクというのは、デフォルトのケーパビリティのセットとコンテ

ナに対するマウントにより、不完全な分離(独⽴性、あるいは、カーネルの脆弱性と組み合わせ)をもたらすかもしれない点ですDocker はケーパビリティの追加と削除をサポートしますので、デフォルトで何も無いプロファイルも扱えます。

これにより、ケーパビリティが削除されても Docker は安全ですが、ケーパビリティを追加する時はセキュリティが低下します。利⽤にあたってのベストプラクティスは、各プロセスが明らかに必要なケーパビリティを除き、全て削除することです。

ケーパビリティは、最近の Linux カーネルで提供されている、様々なセキュリティ機能の1つです。他にも既存のよく知られているTOMOYO、AppArmor、SELinux、GRSECのようなシステムがDocker で使えます。

現時点のDocker はケーパビリティの有効化しかできず、他のシステムには⼲渉できません。つまり、Docker ホストを堅牢にするには様々な異なった⽅法があります。以下は複数の例です。

カーネルで GRSEC と PAX を実⾏できます。これにより、コンパイル時と実⾏時の安全チェック機能をもたらします。アドレスランダム化のような技術に頼る、多くの exploit を無効化します。Docker 固有の設定は不要です。コンテナとは独⽴して、システムの広範囲にわたるセキュリティ機能を提供します。

ディストリビューションにDocker コンテナに対応したセキュリティ・モデル・テンプレートがあれば、それを利⽤可能です。例えば、私たちはAppArmor で動作するテンプレートを提供しています。また、Red hatは Docker 対応の SELinux ポリシーを提供しています。これらのテンプレートは外部のセーフティーネットを提供します(ケーパビリティと⼤いに重複する部分もありますが)。

好みのアクセス管理メカニズムを使って、⾃分⾃⾝でポリシーを制限できます。

Docker コンテナと連携する多くのサードパーティー製ツールが提供されています。例えば、特別なネットワーク・トポロジーや共有ファイルシステムです。これらは Docker のコアの影響を受けずに、既存の Docker コンテナを堅牢にするものです。Docker 1.10以降はDocker デーモンがユーザ名前空間(User Namespaces)を直接サポートしました。この機

能により、コンテナ内のroot ユーザをコンテナ外のuid 0以外のユーザに割り当て(マッピング)できるようになります。コンテナからブレイクアウト(脱獄)する危険性を軽減する⼿助けとなるでしょう。この実装は利⽤可能ですが、デフォルトでは有効ではありません。こちらの機能に関するより詳しい情報は daemon コマンド のリファレンスをご覧ください。Docker におけるユ

ーザ名前空間の実装に関する詳細情報は、ブログ投稿記事*1 をご覧ください。

8.2.6 まとめ

Docker コンテナはデフォルトでも安全ですが、とりわけコンテナ内でプロセスを権限の無いユーザ(例:root以外のユーザ)で実⾏する時に、注意が必要です。AppArmor、SELinux、GRSEC など任意の堅牢化ソリューションを有効化することで、更に安全なレイヤを追加

できます。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.2 Dockerのセキュリティ

Page 85: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 85 -

最後ですが疎かにできないのは、他のコンテナ化システムのセキュリティ機能に興味があれば、それらはDockerと同じようにシンプルにカーネルの機能を実装しているのが分かるでしょう。私たちは皆さんからの問題報告、プルリクエスト、メーリングリストにおける議論を歓迎します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.2 Dockerのセキュリティ

Page 86: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 86 -

8.3 Docker デーモンのソケットを守るデフォルトでは、ネットワークを通さないUnix ソケットでDocker を操作します。オプションでHTTP ソケッ

トを使った通信も可能です。Docker をネットワーク上で安全な⽅法で使う必要があるなら、TLS を有効にすることもできます。そのために

は、tlsverifyフラグの指定と、tlscacertフラグで信頼できるCA証明書をDocker に⽰す必要があります。デーモン・モードでは、その CA で署名された証明書を使うクライアントのみ接続可能にします。クライアント

・モードでは、そのCAで署名されたサーバのみ接続可能にします。

【警告】TLSとCAの管理は⾼度なトピックです。プロダクションで使う前に、⾃分⾃⾝でOpenSSL、x509、TLSに慣れてください。

【警告】各TLSコマンドはLinux上で作成された証明書のセットのみ利⽤可能です。Mac OS XはDocker デーモンが必要なOpenSSLのバージョンと互換性がありません。

以下の例にある $HOST は、⾃分のDocker デーモンが動いているDNSホスト名に置き換えてください。

まず、CA秘密鍵と公開鍵を作成します。

$ openssl genrsa -aes256 -out ca-key.pem 4096Generating RSA private key, 4096 bit long modulus............................................................................................................................................................................................++........++e is 65537 (0x10001)Enter pass phrase for ca-key.pem:Verifying - Enter pass phrase for ca-key.pem:$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pemEnter pass phrase for ca-key.pem:You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [AU]:State or Province Name (full name) [Some-State]:QueenslandLocality Name (eg, city) []:BrisbaneOrganization Name (eg, company) [Internet Widgits Pty Ltd]:Docker IncOrganizational Unit Name (eg, section) []:SalesCommon Name (e.g. server FQDN or YOUR name) []:$HOSTEmail Address []:[email protected]

これで CA を⼿に⼊れました。サーバ鍵(server key)と証明書署名要求(CSR; certificate signing request)を

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.3 Dockerデーモンのソケットを守る

Page 87: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 87 -

作成しましょう。接続先のDocker ホスト名が Common Name(例:サーバのFQDNや⾃分⾃⾝の名前)に⼀致しているのを確認します。

以下の例にある $HOST は、⾃分のDocker デーモンが動いているDNSホスト名に置き換えてください。

$ openssl genrsa -out server-key.pem 4096Generating RSA private key, 4096 bit long modulus.....................................................................++.................................................................................................++e is 65537 (0x10001)$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr

次に公開鍵をCAで署名しましょう。TLS接続はDNS名と同様に、IPアドレスでも通信可能にできます。その場合は、証明書に情報を追加する必要

があります。例えば、 10.10.10.20と 127.0.0.1を使う場合は次のようにします。

$ echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf

$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out server-cert.pem -extfile extfile.cnfSignature oksubject=/CN=your.host.comGetting CA Private KeyEnter pass phrase for ca-key.pem:

クライアント認証⽤に、クライアント鍵と証明書署名要求を作成します。

$ openssl genrsa -out key.pem 4096Generating RSA private key, 4096 bit long modulus.........................................................++................++e is 65537 (0x10001)$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr

クライアント認証⽤の鍵を実装するには、追加設定ファイルを作成します。

$ echo extendedKeyUsage = clientAuth > extfile.cnf

次は公開鍵に署名します。

$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out cert.pem -extfile extfile.cnf

Signature oksubject=/CN=clientGetting CA Private KeyEnter pass phrase for ca-key.pem:

cert.pemと server-cert.pemを⽣成したら、証明書署名要求を安全に削除できます。

$ rm -v client.csr server.csr

デフォルトの umaskは022のため、秘密鍵は⾃分と同じグループから読み書き可能です。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.3 Dockerデーモンのソケットを守る

Page 88: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 88 -

何らかのアクシデントから⾃分の鍵を守るため、書き込みパーミッションを削除します。⾃分だけしか読み込めないようにするには、ファイルモードを次のように変更します。

$ chmod -v 0400 ca-key.pem key.pem server-key.pem

証明書は誰でも読み込めても問題ありませんが、予期しないアクシデントによる影響を避けるため、書き込み権限を削除します。

$ chmod -v 0444 ca.pem server-cert.pem cert.pem

あとは Docker デーモンを、⾃分たちの CA を使って署名した信頼できるクライアントしか接続できないようにします。

$ docker daemon --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \-H=0.0.0.0:2376

これはDocker に接続する時、証明書の認証を必要とするものです。認証には先ほどのクライアント鍵、証明書、信頼できるCAを使います。

$ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \-H=$HOST:2376 version

【警告】上記の例では docker クライアントの実⾏に sudo が不要か、あるいは認証に使うユーザが docker グループに属しています。つまり、鍵を使って Docker デーモンにアクセス可能にするとは、デーモンを動かしているマシンの root 権限を与えるのを意味します。これらの鍵は rootパスワード同様に保護してください!

8.3.2 デフォルトで安全に

Docker クライアントの接続をデフォルトで安全にしたい場合は、⾃分のホームディレクトリ直下の .docker ディレクトリにファイルを移動できます。そして、環境変数 DOCKER_HOST と DOCKER_TLS_VERIFY を使います(毎回-H=tcp://$HOST;2376や --tlsverifyを実⾏する代わりになります )。

$ mkdir -pv ~/.docker$ cp -v {ca,cert,key}.pem ~/.docker$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

こうしておけば、デフォルトで Docker は安全に接続します。

$ docker ps

8.3.3 他のモード

双⽅向認証を有効にしたくない場合、他のフラグと組み合わせてDocker を実⾏できます。

デーモン・モード

tlsverify、tlscacert、lscert、tlskeyをセット:クライアントを認証する tls、tlscert、tlskey:クライアントを認証しない

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.3 Dockerデーモンのソケットを守る

Page 89: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 89 -

クライアント・モード

tls:サーバをベースとした公開/デフォルトCAプールで認証 tlsverify、tlscacert:サーバをベースとしたCA認証 tls、tlscert、tlskey:クライアント認証を使い、サーバ側を指定したCAでは認証しない tlsverify、tlscacert、tlscert、tlskey :クライアント証明書と、サーバ側で指定した CA で認証する

クライアントがクライアント証明書を送信したら、⾃分の鍵を ~/.docker/{ca,cert,key}.pemに移動します。あるいは、別の場所に保管し、環境変数 DOCKER_CERT_PATHでも指定できます。

$ export DOCKER_CERT_PATH=~/.docker/zone1/$ docker --tlsverify ps

curl を使って Docker ポートに安全に接続

curlをAPIリクエストのテストに使うには、コマンドラインで3つの追加フラグが必要です。

$ curl https://$HOST:2376/images/json \--cert ~/.docker/cert.pem \--key ~/.docker/key.pem \--cacert ~/.docker/ca.pem

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 8.3 Dockerデーモンのソケットを守る

Page 90: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 90 -

これまで Docker を HTTPS で動かす ⽅法を学びました。デフォルトでは Docker はネットワークで使えないUnix ソケットについてと、Docker クライアントとデーモンが安全に通信できるように、HTTPS 上でTLS を有効化すべきという内容でした。TLS はレジストリのエンドポイントにおける認証を確実なものとし、かつ、レジストリからあるいはレジストリへの通信を暗号化します。このセクションでは、Docker レジストリ(例:サーバ)とDocker デーモン(例:クライアント)間でのトラフ

ィックを暗号化する⽅法と、証明書をベースとしたクライアント・サーバ認証の仕⽅を扱います。認証局(CA; Certificate Authority)のルート証明書をレジストリに設定する⽅法と、クライアント側でTLS証

明書を使って認証する⽅法を紹介します。

任意の証明書を使うように設定するには、 /etc/docker/certs.dディレクトリの下に、レジストリのホスト名と同じ名前のディレクトリ(例:localhost)を作成します。このディレクトリをCAルートとして、全ての*.crtファイルを追加します。

認証に関する root 証明書が⾜りなければ、Docker はシステムのデフォルトを使います(例:ホスト側のルートCAセット)。

任意のリポジトリにアクセスするには、Docker が1つ以上の <ファイル名>.key/cert のセットを認識する必要があります。

複数の証明書があれば、アルファベット順で処理を⾏います。もし、認証エラー(例: 403、404、5xx、等)があれば、次の証明書で処理を試みます。

以下は、複数の証明書がある場合の設定です。

/etc/docker/certs.d/ <-- 証明書のディレクトリ└── localhost <-- ホスト名

├── client.cert <-- クライアントの証明書(certificate)├── client.key <-- クライアント鍵└── localhost.crt <-- 認証局によるレジストリ証明書への署名

なお、この例は典型的なオペレーティング・システム上で使う場合を想定したものです。OS が提供する証明書チェーン作成に関するドキュメントを確認すべきでしょう。

まず、OpenSSLの genrsaと reqコマンドを使ってRSA鍵を⽣成し、それを証明書の作成に使います。

$ openssl genrsa -out client.key 4096$ openssl req -new -x509 -text -key client.key -out client.cert

これらのTLSコマンドが⽣成する証明書は、Linux上で動作するものです。Mac OS Xに含まれているOpenSSLのバージョンでは、Dockerが必要とする証明書のタイプと互換性はありません。

docs.docker.jp 16/06/04

Page 91: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 91 -

Docker デーモンは .crt ファイルを CA 証明書として認識し、 .cert ファイルをクライアント証明書として認識します。CA証明書が正しい .crt 拡張⼦ではなく .cert 拡張⼦になれば、Docker デーモンは次のようなエラーメッセージをログに残します。

Missing key KEY_NAME for client certificate CERT_NAME. Note that CA certificates should use theextension .crt.

docs.docker.jp 16/06/04

Page 92: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps ://g i thub . com/b lockbr idge/b lockbr idge -docker -vo lume

- 92 -

9 章

9章 Docker Engine の拡張

プラグインを追加することによりDocker を拡張できます。このセクションは以下の話題を扱います。

Docker プラグインの理解 Docker ボリューム・プラグインを書く Docker ネットワーク・プラグイン 認証 Docker プラグインAPI

サードパーティー製のプラグインを読み込むと、Docker Engineの機能を拡張できます。このページではプラグインの種類についてと、いくつかの Docker 向けボリュームとネットワークのプラグインのリンクを紹介します。

プラグインは Docker の機能性を拡張します。拡張機能には複数の種類があります。例えば、ボリューム・プラグインは、複数のホストを横断して存在する Docker ボリュームを有功にします。ネットワーク・プラグインはネットワークの管(plumbing)を提供するでしょう。現時点の Docker はボリュームとネットワーク・ドライバのプラグインをサポートしています。近いうちに、他

のプラグインの種類もサポートするでしょう。

9.1.2 プラグインのインストール

設定⽅法は、各プラグインのドキュメントをご覧ください。

9.1.3 プラグインを探す

次のようなプラグインがあります。

Blockbridge plugin*1 はボリューム・プラグインです。コンテナをベースとした持続型のストレージ向けオプション、その拡張セットへのアクセスを提供します。1つまたは複数のDocker 環境で、テナントの分離、⾃動プロビジョニング、暗号化、安全な削除、スナップショット、QoSといった機能を提供します。

docs.docker.jp 16/06/04

Page 93: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/rancher/convoy

*2 ht tps : //c lu s te rhq .com/docke r-p lug in/

*3 ht tps : //g i thub . com/ca lave ra/docker -vo lume-g lus te r f s

*4 ht tps : //g i thub . com/ca lave ra/docker -vo lume-keywhiz

*5 ht tps ://g i thub . com/gondor/docke r-vo lume-ne tshare

*6 ht tps : //g i thub . com/ l ibopens torage/opens torage

*7 ht tps ://g i thub . com/pachyderm/pachyderm/tree/mas ter/ s r c/cmd/pfs - vo lume-dr iver

*8 ht tps : //g i thub . com/emccode/rexrayc l i

*9 ht tps : //g i thub . com/cont iv/vo lp lug in

*10 ht tps : //g i thub .com/cont iv/netp lug in

- 93 -

Convoy plugin*1 はボリューム・プラグインです。device mapper やNSFを含む様々なストレージ・バックエンドに対応します。スタンドアローンのバイナリはシンプルな Go ⾔語で書かれています。スナップショット、バックアップ、リストアといったベンダ固有の拡張をサポートしたフレームワークを提供します。

Flocker plugin*2 は Docker 対応の複数ホストで、ボリュームをポータブルに持ち運ぶためのプラグインです。これにより、データベースや他のステートフル(状態を持たない)なコンテナを、クラスタ上のマシンにまたがって実⾏できるようにします。

GlusterFS plugin*3 はDocker がGlusterFSを使って複数ホストのボリュームを管理可能にするプラグインです。

Kyewhiz plugin*4 は Keywhiz を中央リポジトリとして、証明書やシークレット(秘密情報)の管理を提供するプラグインです。

Netshare plugin*5 はNFS v3/v4、AWS FEC、CIFSファイルシステムでボリュームを管理するプラグインです。

OpenStorage Plugin*6 はクラスタ検出ボリューム・プラグインであり、ファイルやブロック・ストレージにおけるボリューム管理ソリューションを提供します。扱えるのは、ベンダ中⽴の拡張機能です。例えばCoS、暗号化、スナップショットです。サンプル・ドライバがベースにしているのは、FUSE、NFS、NBD、EBSなどです。

Pachyderm PFS plugin*7 は Go ⾔語で書かれたボリューム・プラグインです。PFS (Pachyderm FileSystem) リポジトリにマウントできる機能を提供します。Docker コンテナがなくても、ボリュームに対するコミットを⾏えるようにします。

REX-Ray plugin*8 はGo⾔語で書かれたボリューム・プラグインです。ES2、OpenStack、XtreamIO、ScaleIOを含む多くのプラットフォームに対応した⾼度なストレージ機能を提供します。

Contiv Volume Plugin*9 はオープンソースのボリューム・プラグインです。cephをベースとした技術により、マルチ・テナントで、永続型、分散したストレージを提供します。

Contiv Networking*10 はオープンソースの libnetworkプラグインであり、マルチ・テナントのマイクロサービスのデプロイにおけるインフラとセキュリティ・ポリシーを提供します。この環境では、コンテナに対

docs.docker.jp 16/06/04

Page 94: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/weaveworks/docker -p lug in

- 94 -

する負担無しに、物理ネットワークの統合をもたらします。Contiv NetworkingはDocker 1.9以降で利⽤可能な リモート・ドライバとIPAM APIを実装しています。

Weave Network Plugin*1 はDocker コンテナを結ぶ仮想ネットワークを作成します。これは複数のホストやクラウドをまたがり、アプリケーションの⾃動的な発⾒を可能にします。Weave network は弾⼒性(resilient)があり、分散耐性(partition tolerant)があり、安全で、部分的なネットワークでも利⽤できます。他のツールによる環境と異なり、全ての設定が極めて単純です。

9.1.4 プラグインのトラブルシューティング

プラグインを読み込んだ後で Docker に問題が起こったら、プラグインの作者に助けを求めてください。Dockerチームはあなたを助けられません(訳者注:Docker コミュニティ外のツールのため)。

9.1.5 プラグインを書くには

Docker プラグインを書くことに興味があれば、あるいは、⽔⾯下でどのような処理がされているかに興味があれば、docker プラグイン・リファレンスをご覧ください。

docs.docker.jp 16/06/04

Page 95: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/docker/ l ibnetwork/b lob/mas te r/docs/remote .md

- 95 -

9.2 Docker ネットワーク・プラグインDocker ネットワーク・プラグインは、Docker が広範囲のネットワーク技術のサポートによりデプロイできるよ

うに拡張されています。XVLAN、IPVLAN、MACVLAN、あるいはこれらとも全く異なります。ネットワーク・ドライバ・プラグインは LibNetwork プロジェクトによってサポートされています。各ネットワーク・プラグインは LibNetwork の「リモート・ドライバ」であり、これは Docker とプラグイン基盤を共有するものです。効果的なのは、プラグイン基盤の共有によって、他のプラグインを同じように扱え、かつ同様のプロトコルを扱えることです。

9.2.1 ネットワーク・ドライバ・プラグインを使う

ネットワーク・ドライバ・プラグインのインストール実⾏は、個々のプラグインに依存します。そのため、プラグインをインストールするには、各プラグインの開発者から指⽰を得てください。ネットワーク・ドライバを実⾏しても、内部ネットワーク・ドライバのように扱えない可能性があります。ネッ

トワーク対応のDocker コマンドでドライバを操作します。例えば、次のようなコマンドです。

$ docker network create --driver weave mynet

ネットワーク・ドライバのプラグイン⼀覧は、 「9.1.3 プラグインを探す」をご覧ください。mynet ネットワークは weave の所有となりましたので、以下に続くコマンドは、プラグインの管理するネットワ

ークに対して送信されます。

$ docker run --net=mynet busybox top

9.2.2 ネットワーク・プラグインを書くには

ネットワーク・プラグインの実装は、Docker プラグイン API のネットワーク・プラグイン・プロトコルをご覧ください。

9.2.3 ネットワーク・プラグイン・プロトコル

ネットワーク・ドライバ・プロトコルとは、プラグイン・アクティベーション・コール(plugin activation call)の追加です。詳細については libnetworkの該当ドキュメント*1 をご覧ください。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 9.2 Dockerネットワーク・プラグイン

Page 96: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //c lu s te rhq .com/docke r-p lug in/

- 96 -

9.3 Docker ボリューム・プラグインを書くDocker ボリューム・プラグインとは、Amazon EBS のような外部のストレージ・システムと統合した環境に

Docker をデプロイできるようにします。そして、単⼀のDocker ホスト上で、データ・ボリュームを使う間はその⼀貫性をもたらします。詳しい情報はプラグインのドキュメントをご覧ください。

9.3.1 コマンドラインの変更

ボリューム・プラグインを使うには docker runコマンドで -vと --volume-driverフラグを指定します。 -vフラグはボリューム名を受け付け、 --volume-driverフラグはドライバの種類を指定します。例えば、次のように実⾏します。

$ docker run -ti -v volumename:/data --volume-driver=flocker busybox sh

このコマンドは、ユーザがボリュームで使う名前を volumenameとしてボリューム・プラグインに渡しています。volumenameは /で始まってはいけません。ユーザが volumename を指定したら、プラグインは1つのコンテナが稼働し続ける間、あるいはコンテナのホス

ト上における外部ボリュームをプラグインに関連づけます。これを使えば、例えばステートフルなコンテナを、あるサーバから別のサーバに移せます。volumenameと volumedriverを同時に使うよう指定したら、ユーザはFlocker*1 のような外部プラグインで単⼀ホ

スト上のボリュームやEBSのようなボリュームを管理します。

9.3.2 ボリューム・ドライバの作成

コンテナが作成⽤エンドポイント(/containers/create)の volumeDriver フィールドにおいて、string タイプでドライバ名を指定します。デフォルトの値は "local"です(デフォルトのドライバは、localボリュームです)。

9.3.3 ボリューム・プラグイン・プロトコル

プラグインは⾃⾝を VolumeDriverとして登録した時に有効化されます。その後、Docker デーモンがファイルシステム上に、コンテナが使うための書き込み可能なパスを提供します。Docker デーモンはユーザのコンテナが指定したパスに対し、マウントの拘束(バインド)を扱います。

/VolumeDriver.Create

リクエスト :

{"Name": "volume_name","Opts": {}

}

プラグインはユーザが作成を望むボリュームを、ユーザが指定した名前で作成するよう命令します。プラグインは実際にファイルシステムのボリュームを明⽰する必要がありません(マウントがコールされるまで)。Opts はドライバ固有のオプションをユーザがリクエストする箇所です。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 9.3 Docker ボリューム・プラグインを書く

Page 97: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 97 -

応答 :

{"Err": null

}

エラーが発⽣した場合は、エラー⽂字列が表⽰されます。

/VolumeDriver.Remove

リクエスト :

{"Name": "volume_name"

}

ディスクから特定のボリュームを削除します。このリクエストはユーザから docker rm -vを呼び出された時、コンテナに関連するボリュームを削除します。応答 :

{“Err”: null

}

エラーが発⽣した場合は、エラー⽂字列が表⽰されます。

/VolumeDriver.Mount

リクエスト :

{"Name": "volume_name"

}

Docker でプラグインがボリュームを必要とする場合は、ユーザがボリューム名を指定する必要があります。これは、コンテナが開始される度に必要です。既に作成されているボリューム名で呼び出されると、プラグインは既にマウントされている箇所に対して、新しいマウント・リクエストとプロビジョンが⾏われると、アンマウント・リクエストが呼び出され、プロビジョニングが取り消されるまで追跡します。応答 :

{"Mountpoint": "/path/to/directory/on/host","Err": null

}

ボリュームが利⽤可能になったり、あるいはエラーが発⽣したりする場合には、ホスト・ファイルシステム上のパスを返します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 9.3 Docker ボリューム・プラグインを書く

Page 98: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 98 -

/VolumeDriver.Path

リクエスト :

{"Name": "volume_name"

}

Docker はホスト上のボリュームのパスを覚えておく必要があります。応答 :

{"Mountpoint": "/path/to/directory/on/host","Err": null

}

ボリュームが利⽤可能になったり、あるいはエラーが発⽣したりする場合には、ホスト・ファイルシステム上のパスを返します。リクエスト :

{"Name": "volume_name"

}

Docker ホストに指定した名前のボリュームを使わないことを指⽰します。これはコンテナが停⽌すると呼び出されます。その時点でプラグインはデプロビジョンが安全に⾏われているとみなします。レスポンス

{"Err": null

}

エラーが発⽣したら、エラー⽂字列を返します。

docs.docker.jp 16/06/04

Docker Engine ユーザガイド〜活⽤編 v1.11 9.3 Docker ボリューム・プラグインを書く

Page 99: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //g i thub . com/docker/docker

- 99 -

10 章

10 章 その他のドキュメント

あなたの質問がここになければ、 [email protected] まで遠慮なくお送りください。あるいは、 リポジトリ*1 をフォークし、ドキュメントのソースを⾃分⾃⾝で編集し、それらで貢献することもできます。

Docker は 100%⾃由に使えます。オープンソースであり、何も⽀払わなくても利⽤できます。

Apache License Version 2.0 を使っています。こちらをご覧ください:https://github.com/docker/docker/blob/master/LICENSE

現時点のDocker は Linux 上でしか動きません。しかしVirtualBox を使えば、仮想マシン上でDocker を動かせるため、どちらの環境でも便利に扱えるでしょう。具体的な⽅法はMac OS XとMicrosoft Windowsのインストールガイドをご覧ください。どちらの場合でも、OS上に仮想マシン内でDocker Machine を実⾏するための、⼩さなLinuxディストリビューションをインストールします。

Docker Machineを通して仮想マシン上のDocker デーモンをリモート操作する場合は、ドキュメントのサンプルで、dockerコマンドの前にある sudoを⼊⼒しないでください 。

相互補完します。仮想マシンはハードウェア・リソースの塊を割り当てるのに⼀番便利です。コンテナの操作はプロセス・レベルであり、ソフトウェアのデリバリをまとめることができるため、軽量かつパーフェクトです。

Docker 技術は LXC の置き換えではありません。「LXC」は Linux カーネルの機能を参照しており(特に名前空間とコントロール・グループ)、あるプロセスから別のプロセスに対するサンドボックスを可能とし、リソースの割り当てを制御するものです。これらはカーネル機能のローレベルを基礎としています。⼀⽅、Docker は複数の強⼒な機能を持つハイレベルなツールです。

docs.docker.jp 16/06/04

Page 100: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 100 -

マシンをまたがるポータブルなデプロイ。Docker はアプリケーションを構築するためのフォーマットを定義し、その全ての依存関係を1つのオブジェクトにすることで、Docker が利⽤可能なあらゆるマシン上に移動できるようにします。そして、アプリケーションが同じような環境で動作できるようにするのを保証します。LXC によって実装されるプロセスはサンドボックス(砂場)であり、ポータブルなデプロイの準備としては、重要な環境です。しかしながら、ポータブルなデプロイには⼗分とは⾔えません。もしあなたが私にカスタム LXC 設定を施したアプリケーションを送ってきたとしても、おそらく私のマシン上では動作しないでしょう。なぜなら、マシン固有の情報が紐付いているからです。例えばネットワーク、ストレージ、ログ保存、ディストリビューション等です。Docker は、これらマシン固有の情報を抽象化しますので、同じDocker コンテナであれば間違いなく実⾏できます。マシンが異なり、環境が変わっていたとしても、コンテナに対して変更を加える必要がありません。

アプリケーション中心型。Docker が最適化されているのはマシンに対してというよりも、アプリケーションのデプロイに対してです。これは API やユーザ・インターフェース、設計哲学やドキュメントにも反映されています。対照的に lxc の場合は、コンテナを軽量なマシンとして扱うための補助スクリプトに注⼒しています。ここで⾔うマシンというのは、基本的なサーバのことであり、より速く起動し、メモリを必要としない環境です。私たちはLXCよりもコンテナのほうが、より多くの利点があると考えています。

自動構築(Automatic Build)。Docker には、 開発者向けにソース・コードからコンテナを⾃動的に構築する機能があります。これは構築ツールやパッケージングにあたるアプリケーションの依存性を完全に管理します。マシンの設定に関係無く、make、maven、chef、puppet、salt、Debian パッケージ、RPM、ソースのtar ボール等を⾃由に扱えます。

バージョン管理。Docker には Git のようにコンテナのバージョン推移を追跡する機能があり、バージョン間の差分を調べ、新しいバージョンをコミットしたり、ロールバックしたり等ができます。また履歴を辿ることで、誰によって何が組み込まれたかを把握できます。そのため、開発元からプロダクションのサーバに⾄るまでの流れを完全に追跡できます。またDocker には git pullのようにアップロード回数とダウンロード回数を記録する機能があるため、コンテナの新しいバージョンを送信するとは、単に差分を送信するだけです。

再利用可能なコンポーネント。コンテナは特別なコンポーネントを「ベース・イメージ」として利⽤できます。これは⼿動もしくは⾃動構築の⼀部で使えます。例えば、望ましいPython環境を⽤意しておけば、10以上もの異なるアプリケーションの基盤になります。あるいは、望ましい PostgreSQL をセットアップしておけば、⾃分の将来のプロジェクトで再利⽤可能になるでしょう。このような使い⽅ができます。

共有。Docker はDocker Hubというパブリック・レジストリにアクセスします。そこでは数千⼈もの⼈たちが便利なイメージをアップロードしています。Redis、CouchDB、PostgreSQLといったイメージから、IRCバウンサーや Rails アプリケーション・サーバや、Hadoop向けや、様々なディストリビューション向けのベース・イメージがあります。また、公式の「標準ライブラリ(standard library)」にはレジストリという名前の、Docker チームによって管理されている便利なコンテナがあります。レジストリ⾃⾝はオープンソースでアリ、誰もが⾃分⾃⾝でレジストリに対して、プライベートなコンテナの保管や転送が可能になります。例えば内部のサーバへデプロイすることも可能です。

ツールのエコシステム。Docker はコンテナの作成と開発のために、⾃動化・カスタマイズ化のAPI を定義しています。Docker を互換性のある⾮常に多くのツールと連携できます。PaaS⾵のデプロイ(Dokku、Deis、Flynn)、複数ノードのオーケストレーション(Maestro、Salt、Mesos、OpenStack Nova)、ダッシュボード管理(docker-ui、Openstack Horizon、Shipyard)、設定管理(Chef、Puppet)、継続的インテグレーション(Jenkins、Strider、travis)等です。コンテナを基盤としたツール標準として、Docker は⾃⾝を迅速に起動できます。

docs.docker.jp 16/06/04

Page 101: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tp ://s tackover f low.com/ques t ions/16047306/how- i s-docker- io-d i f fe rent - f rom-a-normal -v i r tua l -machine

- 101 -

StackOverflowの回答に、違いについての素晴らしい説明*1 があります。

コンテナのアプリケーションがディスクに書き込んだあらゆるデータは、コンテナを削除しない限りデータも削除されることはありません。コンテナを停⽌したとしても、コンテナのファイルシステムは⼀貫性を保ちます。

今⽇に世界中で⼤きなサーバ・ファームのいくつかは、コンテナを基盤としています。Google やTwitter のように⼤きなウェブのデプロイ環境や、Heroku や dotCloud のように全てをコンテナ技術上で実⾏します。これら数百から数千、もしくは数百万ものコンテナを並列で実⾏します。

現時点で推奨する⽅法は、Docker ネットワーク機能を通してコンテナに接続する⽅法です。詳細については「Docker ネットワークの働き」のセクションをご覧ください。またサービスのポータビリティをフレキシブルにするには、アンバサダ・リンク・パターンも便利です。

http://supervisord.org/ のようなスーパーバイザや、runit、s6、daemontools によって実現できます。Docker はプロセス管理⽤デーモンを起動し、その後、追加プロセスをフォークして実⾏します。プロセス管理デーモンが動く限り、コンテナも同様に動き続けます。具体的な例については、supervisord の使い⽅ をご覧ください。

Linux:

Ubuntu 12.04, 14.04 等 Fedora 19/20+ RHEL 6.5+ CentOS 6+ Gentoo ArchLinux openSUSE 12.3+ CRUX 3.0+ 等

Cloud:

Amazon EC2 Google Compute Engine

docs.docker.jp 16/06/04

Page 102: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

*1 ht tps : //www.docker . com/secur i t y/

*2 secur i t y@docker . com

* 3

ht tp : / /b log .docke r . com/2014/01/docke r -code-con t r ibut ions - requ i r e -deve loper -ce r t i fi c a te -o f -or ig in/

*4 ht tps ://groups .goog le . com/forum/# ! top ic/docker -dev/L2RBSPDu1L0

*5 ht tps : //www.deb ian .o rg/secur i t y/

- 102 -

Microsoft Azure Rackspace 等

プロジェクトのセキュリティ・ポリシーについてはサイト*1 から確認できます。セキュリティ問題については、こちらのメールボックス*2 までお知らせください。

DCO (Developer ʼ s Certificate of Origin) については、こちらのブログ投稿*3 をご覧ください。

このディスカッションの詳細についてはdocker-devメーリングリストの議論*4 をご覧ください。全てのプログラムは擬似的に第三者のライブラリに依存しています。よくあるのは、動的なリンクや、ある種の

パッケージ依存性です。そのため、複数のプログラムが同じライブラリを必要とするなら、インストールは⼀度で済みます。しかしながら、いくつかのプログラムは、特定バージョンのライブラリに依存するため、⾃分⾃⾝でサード・パ

ーティー製のライブラリを同梱しています。例えば、Node.js は OpenSSL を同梱していますし、MongoDB は V8とBoost(他にも)を同梱しています。Docker イメージの作成にあたり、ライブラリの同梱は使い易いものです。しかし、システム・ライブラリに含

まれるデフォルトのものを使わず、⾃分⾃⾝でプログラムを構築すべきでしょうか?システム・ライブラリに関する重要なポイントは、ディスクやメモリ使⽤量の節約のためではありません。セキ

ュリティのためなのです。全ての主要なディストリビューションは深刻なセキュリティを抱えています。そのため、専⽤のセキュリティ・チームを持ち、脆弱性が発⾒されれば対処を⾏い、⼀般に情報を開⽰します(これら⼿順の具体例はDebian Security Information*5 をご覧ください)。しかし、上流の開発者によっては、常に同じ⼿順が踏まれるわけではありません。Docker イメージの構築時、ソースからプログラムを構築する前に、同梱したいライブラリがあるのであれば、

上流の開発者がセキュリティの脆弱性に関する便利な情報を提供しているかどうか、彼らが適時ライブラリを更新するかどうか確認すべきです。彼らが対処しないならば、あなたが⾃分⾃⾝(そして、あなたのイメージの利⽤者)でセキュリティ脆弱性を対処することになります。他⼈によって作成されたパッケージを使う場合も同様です。パッケージに関するセキュリティのベスト・プラク

ティスと同様に、チャンネルが情報を提供しているか確認すべきでしょう。「全てが中に⼊っている」(all-in-one).deb や .rpm のダウンロードとインストールをする場合、OpenSSLライブラリの脆弱性であるHeartbleedバグを抱えているものをコピーされていないかどうか、それを確認する⽅法はありません。

docs.docker.jp 16/06/04

Page 103: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 103 -

Docker イメージをDebianとUbuntu上で構築する時、次のようなエラーがでることがあります。

unable to initialize frontend: Dialog

イメージの構築時、これらのエラーが出ても処理を中断しませんが、インストール時のプロセスでダイアログ・ボックスを表⽰しようとしても、実⾏できなかったという情報を表⽰しています。通常、これらのエラーは安全であり、無視して構いません。Dockerfile の中で環境変数 DEBIAN_FRONTEND を変更して使い、これらエラーの回避のために使っている⽅がいま

す。

ENV DEBIAN_FRONTEND=noninteractive

これはインストール時にダイアログ・ボックスを開こうとして、エラーがあっても停⽌しないようにします。これは良い考えかもしれませんが、⼀⽅で影響があるかもしれません。DEBIAN_FRONTEND 環境変数はイメージか

らコンテナを構築するにあたり、全てのイメージに対し変更設定が継承されます。対象のイメージを使おうとする⼈たちが、ソフトウェアをインタラクティブに設定する時に、インストーラは何らダイアログ・ボックスを表⽰しないため、問題が起こりうる場合があります。このような状況のため、DEBIAN_FRONTENDを noninteractiveに指定するのは「お飾り」の変更であるため、私た

ちはこのような変更を推奨しません。本等にこの値を変更する必要がある場合は、あとでデフォルト値に差し戻してください。

このメッセージが表⽰される主な理由は、サービスは既にローカルホスト上に結びついているからです。その結果、コンテナの外から届いたリクエストは破棄されます。この問題を解決するには、ローカルホスト上のサービスの設定を変更し、サービスが全ての IP アドレスからのリクエストを受け付けるようにします。この設定の仕⽅が分からなければ、各OSのドキュメントをご覧ください。

docker-machine 利⽤時に Cannot connect to ....というエラーが出ます

エラー「Cannot connect to the Docker daemon. Is the docker daemon running on this host」が表⽰されるのは、Docker クライアントが仮想マシンに接続できない時です。つまり、docker-machine配下で動く仮想マシンが動作していないか、クライアントが操作時点でマシンを適切に参照できない場合を表します。docker-machine ls コマンドを使って docker マシンが動作しているかどうかを各⻄、必要があれば

docker-machine startコマンドで起動します。

$ docker-machine lsNAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORSdefault - virtualbox Stopped Unknown

$ docker-machine start default

Docker クライアントはマシンと通信する必要があります。これには docker-machine envコマンドを使います。実⾏例:

$ eval "$(docker-machine env default)"$ docker ps

docs.docker.jp 16/06/04

Page 104: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 104 -

以下からも答えを探せます。

Docker user mailinglist https://groups.google.com/d/forum/docker-user Docker developer mailinglist https://groups.google.com/d/forum/docker-dev IRC, docker on freenode irc://chat.freenode.net#docker GitHub https://github.com/docker/docker Ask questions on Stackoverflow http://stackoverflow.com/search?q=docker Join the conversation on Twitter http://twitter.com/docker

他にもお探しですか? ユーザガイドをご覧ください。

docs.docker.jp 16/06/04

Page 105: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 105 -

以下は廃⽌された機能の⼀覧です。

docker login の -e および --email フラグ

廃止リリース:v1.11

削除目標リリース:v1.13

docker login コマンドから、ユーザ名が指定されなかった場合に、対象レジストリのアカウントに⾃動で関連づける機能が削除されます。この変更に伴いemail フラグは必要ではなくなり、将来的に廃⽌します。--security-optフラグでキーと値の分割にコロン・セパレータ( :)を使えなくなります。これは --storage-opt

のような他のフラグと同様、イコール記号( =)で指定することになります。

イベント API における不明確なフィールド

廃止リリース:v1.10

イベント API をより優れた構造にするため、ID、Status、From フィールドを廃⽌しました。新しいフォーマットに関してはイベントAPIのドキュメントをご覧ください。

docker tag の -f フラグ

廃止リリース:v1.10

削除目標リリース:v1.12

様々なdocker コマンド間でタグの付け⽅を統⼀するため、docker tag コマンドの -fフラグを廃⽌しました。イメージのタグを別のものに変える時、 -fオプションの指定は不要です。また、対象のタグが既に利⽤中であれば、docker コマンドに -f フラグが無くてもエラーになりません。

廃止リリース:v1.10

削除目標リリース:v1.12

POST /containers/{name}/start における HostConfig の指定は、コンテナ作成時の定義( POST

/containers/create)に置き換えられました。

docker ps の「before」「since」オプション

廃止リリース: v1.10.0

削除目標リリース:v1.12

docker ps --beforeと docker ps --sinceオプションを廃⽌しました。代わりに docker ps --filter=before=...

と docker ps --filter=since=...をお使いください。

コマンドラインの短縮オプション

廃止リリース:v1.9

削除目標リリース:v1.11

以下の短縮オプションを廃⽌するため、⻑いオプションを使うべきです。

docker run -c (--cpu-shares)docker build -c (--cpu-shares)docker create -c (--cpu-shares)

docs.docker.jp 16/06/04

Page 106: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 106 -

ログ⽤のドライバを指定するタグ

廃止リリース:v1.9

削除目標リリース:v1.11

異なったログ保存⽤(ロギング)ドライバを横断して使えるよう、標準化するためにログのタグ機能が⽣まれました。ドライバを指定するタグのオプションは標準的な tagオプションが望ましくなるため、syslog-tag、gelf-tag、fluentd-tagは廃⽌されました。

docker --log-driver=syslog --log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}"

廃止リリース:v1.8

削除目標リリース:v1.10

外部実装の内部(built-in)LXC 実⾏ドライバを廃⽌しました。lxc-conf フラグとAPIも削除予定です。

古いコマンドライン・オプション

廃⽌リリース:v1.8.0削除⽬標リリース:v1.10-dフラグと --daemonは daemonサブコマンドに移⾏するため、廃⽌されます。

docker daemon -H ...

コマンドライン・オプションのうち、以下のシングル・ダッシュ(-opt)派⽣を廃⽌し、新しいダブル・ダッシュ(--opt)に変わります。

docker attach -nostdindocker attach -sig-proxydocker build -no-cachedocker build -rmdocker commit -authordocker commit -rundocker events -sincedocker history -notruncdocker images -notruncdocker inspect -formatdocker ps -beforeIddocker ps -notruncdocker ps -sinceIddocker rm -linkdocker run -cidfiledocker run -cpusetdocker run -dnsdocker run -entrypointdocker run -exposedocker run -linkdocker run -lxc-confdocker run -ndocker run -privilegeddocker run -volumes-fromdocker search -notruncdocker search -stars

docs.docker.jp 16/06/04

Page 107: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 107 -

docker search -tdocker search -trusteddocker tag -force

以下のダブル・ダッシュのオプションは、置き換えずに廃⽌です。

docker run --networkingdocker ps --since-iddocker ps --before-iddocker search --trusted

バージョン 1.9 にフラグ(--disable-legacy-registry=false)を追加しました。これは docker デーモンが v1レジストリと pull、push、login させないようにします。デフォルトは廃⽌された v1 プロトコルと通信しないよう無効化しています。

Docker Content Trust ENV パスフレーズの変数名を変更

廃止リリース:v1.9

削除目標リリース:v1.10

バージョン1.9におけるDocker Content Trust のオフライン鍵(Offline key)はルート鍵(Root key)に、タギング鍵(Tagging key)はリポジトリ鍵(Repository key)に名称変更されました。この名称変更により、関係する環境変数も変わります。

DOCK E R _ CONT ENT _ T R U S T _ O F F L I N E _ P A S S P H R A S E をDOCKER_CONTENT_TRUST_ROOT_PASSPHRASE に変更します

DOCK E R _ CONT ENT _ T R U S T _ T A GG I NG _ P A S S P H R A S E をDOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE に変更します。

docs.docker.jp 16/06/04

Page 108: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 108 -

各 Engine をリリースする度に、前のバージョンとの下位互換性を持つように努めています。全てのケースにおいて、機能を廃⽌するのは2つ先のバージョンというポリシーを持っており、廃⽌機能のページでドキュメント化しています。残念ながら、Docker は⾮常に動いているプロジェクトであり、新しく導⼊した機能は変更や互換性を弱めてし

まうかもしれません。このページでは各エンジンのバージョンごとに⽂書化しています。

10.3.1 Engine 1.10

1.10 のリリースにあたり、2つの破壊的変更(breaking change)があります。

Registry

Registry 2.3 はイメージのマニフェストという改良を取り込んだため、破壊的変更をもたらしました。Engine 1.10からRegistry 2.3 にイメージを送信しても、古いバージョンのEngine で digest 値を計算したものは取得できません。docker pullを実⾏しても、次のようなエラーが表⽰されます。

Error response from daemon: unsupported schema version 2 for tag TAGNAME

Docker Content Trust は、このdigest 値に強く依存しています。そのため、Engine 1.10のコマンドラインでRegistry 2.3にイメージを送信したとしても、Docker Content Trust を有効化した古いEngine⽤のCLI(バージョン1.10より⼩さい)では、イメージを取得(pull)できません。Registry の古いバージョン(2.3より⼩さい)を使っている場合は、どのエンジンのCLIを使って送受信(push、

pull)しても問題ありません。ただし、Content Trust を使っていない場合に限ります。

Docker Content Trust

現在のEngine 1.10よりも古いバージョンでは、key delegation(鍵の権限委譲)のためリポジトリからイメージを取得(pull)できません。key delegation機能は⼿動で有効化する必要があります。

docs.docker.jp 16/06/04

Page 109: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 109 -

Docker Engineバージョン1.10以降は、ディスク上にイメージ・データを割り当てる⽅式が完全に変わります。従来は、各イメージとレイヤに対してランダムな UUID を割り当てていました。バージョン 1.10 からは、イメージとレイヤ・データの安全なハッシュ値を元にしたIDを使い、中⾝を指定できる⼿法を実装しました。新しい⼿法は、利⽤者を更に安全にします。組み込まれた⽅式は ID の衝突を防⽌し、pull・push・load・save

を実⾏した後のデータを保証します。また、レイヤの共有を改善しました。たとえ同時に構築していなくても、多くのイメージ間でレイヤを⾃由に共有できるようになります。イメージに対して内容に関する情報を割り当てることで、既にダウンロード済みのイメージがあるかどうかの検

出も容易になります。これはイメージとレイヤが分離しているためであり、オリジナルの構築チェーンに含まれる各イメージを、それぞれ取得(pull)する必要はありません。また、構築命令のためにレイヤを作成する必⽤がなくなったため、ファイルシステムを変更しません。連想機能(content addressability;コンテント・アドレッサビィティ)とは、新しい配布機能の基礎です。イメ

ージの取得(pull)と送信(push)の⼿法は、ダウンロード/アップロード・マネージャの概念を扱うために調整されました。これにより、イメージの送受信がより安定し、並列リクエスト時の問題を軽減します。ダウンロード・マネージャはダウンロードの失敗時にリトライできるようになり、ダウンロードにおける適切な優先度付けも⾏えるようにもなりました。更に、新しいマニフェスト・フォーマットも導⼊しました。これは連想機能をベースにしています。これは連想

イメージ(content addressable image)の設定やレイヤのチェックサムを直接参照できます。この新しいマニフェスト・フォーマットにより、複数のアーキテクチャやプラットフォームのためにマニフェスト・リストが利⽤できるでしょう。新しいマニフェスト・フォーマットへの移⾏は、完全に透過的です。

10.4.1 アップグレードの準備

現在のイメージを新しいモデルで利⽤できるようにするには、連想ストレージ(content addressable storage)への移⾏が必要です。すなわち、現在のデータの安全なチェックサムを計算することを意味します。Docker Engine 1.10の初回起動時は、現時点における全てのイメージ、タグ、コンテナが⾃動的に新しい基盤上

に移⾏します。そのため、コンテナを読み込む前に、デーモンは現時点のデータに対するチェックサムを全て計算する必要があります。計算が終わったら、全てのイメージとタグは新しい安全なIDに更新されます。これは非常に単純な操作ですが、各ファイルに対する SHA256 チェックサムを計算するため、多くのイメージ・

データがあれば計算に時間を消費します。データの移⾏プロセスにかかる時間は、およそ平均して1秒あたり100MBと想定されます。この処理の間、Docker デーモンはリクエストに応答できません。

⼀度だけの処理が許容できるのであれば、Docker Engineのアップグレードと、デーモンの再起動により、イメージの移⾏が透過的に⾏われます。しかしながら、デーモンの停⽌時間を最⼩化したい場合は、古いデーモンを動かしたまま移⾏ツールを使えます。このツールは現在のイメージを全て探し出し、それらのチェックサムを計算します。デーモンのアップグレード

と再起動を⾏った後、移⾏するイメージに対するチェックサム・データが既に存在していれば、デーモンは計算処理を⾏いません。移⾏とアップグレード期間中に新しいイメージが追加されている場合は、1.10 へのアップグレードのプロセス中で処理されます。移⾏ツールはこちらからダウンロードできます 。https://github.com/docker/v1.10-migrator/releases移⾏ツールは Docker イメージとしても実⾏することができます。移⾏⽤ツールのイメージを実⾏している間、

このコンテナに対して Docker のデータを直接公開する必要があります。

docs.docker.jp 16/06/04

Page 110: はじめに DockerEngineユーザガイド〜活⽤編 この …docker.jp/PDF/docker-engine-practical-userguide-ja-beta1.pdfPDFの評価 として公開しました。Dockerは活発な

- 110 -

$ docker run --rm -v /var/lib/docker:/var/lib/docker docker/v1.10-migrator

devicemapper ストレージ・ドライバを使っている場合は、 --privileged フラグを指定することで、ツールがストレージ・デバイスにアクセス可能となります。

docs.docker.jp 16/06/04