Docker Swarm ユーザガイド v1.1 - beta1

このガイドについて

はじめに

DockerSwarmユーザガイド〜基礎編

このガイドについて
Docker ドキュメント（https://docs.docker.com/）の⽇本語翻訳版（http://docs.docker.jp/）をもとに、Docker
Swarm に関連する箇所を電⼦データ化しました。

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

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

履歴 2016 年 6 ⽉ 2 ⽇ Swarm ユーザガイド v1.1 beta1 を公開- 1 -docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

このガイドについて目次

このガイドについて
免責事項
履歴

1

1

1

1.1 概 要7

1.1.1 Swarm ク ラ ス タ 作 成 を 理 解

7

1.1.2 デ ィ ス カ バ リ ・ サ ー ビ ス

8

1.1.3 ⾼ 度 な ス ケ ジ ュ ー リ ン グ

8

1.1.4 Swarm API

8

1.1.5 ヘ ル プ を 得 る に は

8

2.1 Docker Swarm の ⼊ ⼿ ⽅ 法

92.1.1 イ ン タ ラ ク テ ィ ブ な コ ン テ ナ で ク ラ ス タ を 作 成
コ ン テ ナ で Swarm イ メ ー ジ を 実 ⾏
なぜイメージを使うのですか？
2.1.2 Swarm バ イ ナ リ の 実 ⾏

9

9

10

11

なぜバイナリを使うのですか？

11

2.2 Swarm を 検 証 環 境 で 試 す に は

12

2.2.1 Docker Toolbox の イ ン ス ト ー ル

12

2.2.2 Docker Engine で ３ つ の VM を 作 成

12

2.2.3 Swarm デ ィ ス カ バ リ ・ ト ー ク ン の 作 成
2.2.4 Swarm マ ネ ー ジ ャ と ノ ー ド の 作 成
2.2.5 Swarm ク ラ ス タ を 管 理
2.2.6 更 に 詳 し く

13

14

15

16

2.3 プ ロ ダ ク シ ョ ン で Swarm 利 ⽤ 時 の 考 慮
2.3.1 セ キ ュ リ テ ィ

17Swarm ⽤ の TLS 設 定

17ネットワークのアクセス制御
2.3.2 ⾼ 可 ⽤ 性 （ HA）

18

Swarm マ ネ ー ジ ャ HA

19

デ ィ ス カ バ リ ・ サ ー ビ ス HA
複数のクラウド

17

17

20

21

プロダクション環境の分離

21

オペレーティング・システムの選択

22

- 2 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3.3 性 能

このガイドについて

22

コンテナ・ネットワーク

22

スケジューリング・ストラテジ
2.3.4 ク ラ ス タ の 所 有

2223

2.4 プ ロ ダ ク シ ョ ン ⽤ の Swarm ク ラ ス タ 構 築
2.4.1 動 作 条 件
2.4.2 ⼿ 順

24

24

24

ステップ１：ネットワーク・セキュリティのルールを追加
ステップ２：インスタンス作成

25

ス テ ッ プ ３ ： 各 ノ ー ド に Engine を イ ン ス ト ー ル

25

ステップ４：ディスカバリ・バックエンドのセットアップ
ス テ ッ プ ５ ： Swarm ク ラ ス タ の 作 成ス テ ッ プ ６ ： Swarm と 通 信

24

26

27

28

ス テ ッ プ ７ ： Swarm の フ ェ イ ル オ ー バ を テ ス ト

28

2.5 Docker Machine で Swarm ク ラ ス タ 構 築
2.5.1 何 が 必 要 で す か ？

30

30

2.5.2 Swarm ト ー ク ン を ホ ス ト 上 で ⽣ 成
2.5.3 Swarm ノ ー ド の プ ロ ビ ジ ョ ン

31

2.5.4 Machine で ノ ー ド 環 境 に 接 続

3130

3.1 ア プ リ ケ ー シ ョ ン の ア ー キ テ ク チ ャ を 学 ぶ
3.1.1 サ ン プ ル の 背 景 を 学 ぶ

33

3.1.2 ア プ リ ケ ー シ ョ ン の ア ー キ テ ク チ ャ を 理 解
3.1.3 Swarm ク ラ ス タ の ア ー キ テ ク チ ャ
次のステップ

33

33

34

36

3.2 イ ン フ ラ の デ プ ロ イ
3.2.1 構 築 ⼿ 順 に つ い て
3.2.2 ⼿ 順

37
37

37

タ ス ク １ ： keystore（ キ ー ス ト ア ） サ ー バ の 作 成
タ ス ク ２ ： Swarm マ ネ ー ジ ャ の 作 成
タスク３：ロードバランサの追加

38

39

タ ス ク ４ ： 他 の Swarm ノ ー ド を 作 成
次のステップ3741

44

3.3 ア プ リ ケ ー シ ョ ン の デ プ ロ イ
3.3.1 ⼿ 順

45

45

タスク１：ボリュームとネットワークのセットアップ
タスク２：コンテナ化したマイクロサービスの起動
タ ス ク ３ ： 作 業 内 容 の 確 認 と /etc/hosts の 更 新タスク４：アプリケーションのテスト

45

46

47

49
- 3 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

このガイドについて

追 加 作 業 ： Docker Compose で デ プ ロ イ
次のステップ

49

52

3.4 ア プ リ ケ ー シ ョ ン の ト ラ ブ ル シ ュ ー ト
3.4.1 Swarm マ ネ ー ジ ャ 障 害

53

53

3.4.2 Consul（ デ ィ ス カ バ リ ・ バ ッ ク エ ン ド ） 障 害
3.4.3 障 害 の 取 り 扱 い

54

3.4.4 Interlock ロ ー ド バ ラ ン サ 障 害

54

3.4.5 ウ ェ ブ （ web-vote-app） 障 害

54

3.4.6 Redis 障 害

53

55

3.4.7 ワ ー カ （ vote-worker） 障 害
3.4.8 Postgres 障 害

55

55

3.4.9 results-app 障 害
3.4.10 イ ン フ ラ 障 害

55
55

4.1 Docker Swarm の ⾼ 可 ⽤ 性

58

4.1.1 プ ラ イ マ リ と レ プ リ カ の セ ッ ト ア ッ プ
前提条件

58

58

プライマリ・マネージャの作成

58

２つのレプリカ（複製）を作成

59

クラスタ内のマシン⼀覧

59

4.1.2 フ ェ イ ル オ ー バ 動 作 の テ ス ト
⾃動フェイルオーバを待つ
プライマリに切り替え

60

60

61

4.2 Swarm と コ ン テ ナ の ネ ッ ト ワ ー ク

62

4.2.1 Swarm ク ラ ス タ に カ ス タ ム ・ ネ ッ ト ワ ー ク を 作 成
4.2.2 ネ ッ ト ワ ー ク の ⼀ 覧

62

4.2.3 ネ ッ ト ワ ー ク の 作 成

62

4.2.4 ネ ッ ト ワ ー ク の 削 除

63

62

4.3 Docker Swarm デ ィ ス カ バ リ

64

4.3.1 分 散 キ ー バ リ ュ ー ・ ス ト ア の 利 ⽤

64

ホステット・ディスカバリ・キーストアを使⽤

64

分 散 キ ー バ リ ュ ー ・ デ ィ ス カ バ リ に TLS を 使 う

65

4.3.2 静 的 な フ ァ イ ル ま た は ノ ー ド ・ リ ス ト
ファイルを作成する場合

66

66

ノード・リストを指定する場合

66

Docker Hub の ホ ス テ ッ ド ・ デ ィ ス カ バ リ

67

4.3.3 新 し い デ ィ ス カ バ リ ・ バ ッ ク エ ン ド に 貢 献

68

5.1 Swarm と TLS の 概 要
5.1.1 TLS の 概 念 を 学 ぶ

69
69
- 4 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

このガイドについて

5.1.2 Docker Engine で TLS 認 証 を 使 う に は
5.1.3 Docker と Swarm の TLS モ ー ド

71

外部のサードパーティー製の証明局

71

社内にある証明局

70

71

⾃⼰署名した証明書

71

5.2 Docker Swarm の TLS 設 定
5.2.1 始 め る 前 に
5.2.2 ⼿ 順

73

74

74

ステップ１：動作環境のセットアップ

74

ス テ ッ プ ２ ： 認 証 局 (CA)サ ー バ の 作 成

74

ステップ３：鍵の作成と署名

75

ステップ４：鍵のインストール

77

ス テ ッ プ ５ ： Engine デ ー モ ン に TLS 設 定
ス テ ッ プ ６ ： Swarm ク ラ ス タ の 作 成

7980

ス テ ッ プ ７ ： TLS を 使 う Swarm マ ネ ー ジ ャ の 作 成ス テ ッ プ ８ ： Swarm マ ネ ー ジ ャ の 設 定 を 確 認

81

ス テ ッ プ ９ ： TLS を 使 う Engilne CLI の 設 定

8280

6.1 フ ィ ル タ

84

6.1.1 設 定 可 能 な フ ィ ル タ
6.1.2 ノ ー ド ・ フ ィ ル タ

84

85

constraint（ 制 限 ） フ ィ ル タ を 使 う
ノード制限の例

85

85

health フ ィ ル タ を 使 う

87

6.1.3 コ ン テ ナ ・ フ ィ ル タ

87

アフィニティ（親密さ）フィルタを使う
名前アフィニティの例

87

イメージ・アフィニティの例

88

ラベル・アフィニティの例

89

dependency フ ィ ル タ を 使 う

89

port フ ィ ル タ を 使 う

8790

ホスト・ネットワーキング機能とノード・ポート・フィルタを使う
6.1.4 フ ィ ル タ 表 現 の 書 き ⽅

91

92

6.2 ス ト ラ テ ジ
6.2.1 Spread ス ト ラ テ ジ の 例
2.6.2 BinPack ス ト ラ テ ジ の 例

94
94
95

6.3 再 ス ケ ジ ュ ー ル ・ ポ リ シ ー
6.3.1 再 ス ケ ジ ュ ー ル ・ ポ リ シ ー

96
96

6.3.2 再 ス ケ ジ ュ ー ル ・ ロ グ の 確 認

96
- 5 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

このガイドについて

7.1 Swarm コ マ ン ド ラ イ ン ・ リ フ ァ レ ン ス

97swarm - Docker ネ イ テ ィ ブ の ク ラ ス タ リ ン グ ・ シ ス テ ム
オプション
コマンド

97

98

create - デ ィ ス カ バ リ ・ ト ー ク ン の 作 成
list - ク ラ ス タ 上 の ノ ー ド ⼀ 覧
引数

100

101

manage - Swarm マ ネ ー ジ ャ の 作 成

102

102

オプション

103

join - Swarm ノ ー ド の 作 成
引数

99

100

オプション

引数

97

107

107

オプション

108

help - コ マ ン ド に 関 す る 情 報 の 表 ⽰

1097.2 Docker Swarm API
エンドポイントが無い場合

110
110

異なる動作をするエンドポイント

110

- 6 -

docs.docker.jp

16/06/02

１章

1 章 DockerSwarm概要

1.1 概要スウォーム

Docker Swarm は Docker に対応するネイティブなクラスタリング⽤ツールです。Docker Swarm は標準 Docker
API で操作できます。そのため、Docker ホスト群を集め、１つの仮想 Docker ホストとして扱えます。既に Docker
デーモンと通信可能なツールであれば、Swarm を使うだけで、意識せずに複数のホストにスケール可能になります。
以下のツールをサポートしていますが、これだけに限りません。

 Dokku Docker Compose
 Krane Jenkins
そしてもちろん、Swarm は Docker クライアントでの操作もサポートします。
他の Docker プロジェクトと同様に、Docker Swarm は “ swap, plug, and play ”（交換して、取り付けて、実⾏）
プ ラ ガ ブ ルの原理に従います。開発初期においては、API はバックエンドを取り替え可能（pluggable）となるよう開発する⽅
針に落ち着きました。つまり、Docker Swarm が利⽤するスケジューリングのバックエンドとは、任意に置き換え可能であるのを意味します。Swarm の取り替え可能な設計により、多くの場⾯でスムーズかつ独創的な体験を提供
メ ソ ス

します。また、Mesos のような、より強⼒なバックエンドに取り替えれば、⼤規模なプロダクション（本番環境）
へのデプロイも可能となります。

1.1.1 Swarm クラスタ作 成を理 解
⾃分のネットワーク上で Swarm クラスタ（訳注；” Swarm ”=群れ、の意味）を形成するには、まず Docker Swarm
イメージを取得します。それから Docker で Swarm マネージャを設定し、Docker Swarm を実⾏したい全てのノードを設定します。この作業には以下の⼿順が必要です。

 Swarm マネージャと各々のノードと通信ができるよう TCP ポートを開く 各々のノードに Docker をインストールする
 クラスタを安全にするため、TLS 証明書を作成・管理する- 7 -docs.docker.jp

16/06/02

管理者が経験を積み始めるため、または、プログラマが Docker Swarm に貢献し始めるためには、⼿動でのインストールが最適な⽅法です。あるいは docker-machine を使って Swarm をインストールする⽅法もあります。
Docker Machine を使えば、Docker Swarm をクラウド・プロバイダや⾃分のデータセンタに素早くインストー
ルできます。ローカルのマシン上に VirtualBox をインストールしていれば、ローカル環境上で Docker Swarm を素早く構築し、試すことができます。Docker Machine はクラスタを安全にするために、証明書を⾃動⽣成します。
初めて Docker Swarm を使うのであれば、Docker Machine を使う⽅法が⼀番です。推奨する⽅法で進めるには「Swarm を検証環境で試すには」のセクションをお読みください。
⼿動でのインストールや開発に対する貢献に興味があれば、「プロダクション⽤の Swarm クラスタ構築」のセクションをご覧ください。

1.1.2 ディスカバリ・サービス
コンテナ内のサービスを動的に設定・管理するには、Docker Swarm とディスカバリ⽤のバックエンドを使います。利⽤可能なバックエンドに関する情報は、「ディスカバリ・サービス」のセクションをお読みください。

1.1.3 高 度なスケジューリング
⾼度なスケジューリングについては、「strategies（ストラテジ）」と「ﬁlters（フィルタ）」の各セクションをお読みください。

1.1.4 Swarm API
Docker Swarm API は Docker リモート API と互換性があります。そのため、新しいエンドポイントの追加時には、Swarm も同時にエンドポイントを拡張します。

1.1.5 ヘ ルプ を得るにはDocker Swarm はまだ開発途上であり、活発に開発中です。ヘルプが必要な場合、貢献したい場合、あるいはプロジェクトの同志と対話したい場合のため、私たちは多くのコミュニケーションのためのチャンネルを開いています。

 バグ報告や機能リクエストは、GitHub の issue トラッカー*1 をご利⽤ください。
 プロジェクトのメンバとリアルタイムに会話したければ、IRC の#docker-swarm チャンネルにご参加ください。
*2

 コードやドキュメントの変更に貢献したい場合は、GitHub でプルリクエスト をお送りください。
より詳細な情報やリソースについては、私たちのヘルプ⽤ページ*3 をご覧ください。

*1 https://github.com/docker/swarm/issues*2 https://github.com/docker/swarm/pulls*3 https://docs.docker.com/project/get-help/- 8 -docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.1 Docker Swarmの⼊⼿⽅法

２章

2 章 セットアップ・導入ガイド

2.1 Docker Swarm の入手方法
Docker Swarm クラスタを作成する⽅法は、swarm が実⾏可能なイメージをコンテナとして使うか、あるいは、実⾏可能な swarm バイナリをシステム上にインストールする⽅法があります。このページは２つの⽅法を紹介し、それぞれの賛否を議論します。

2.1.1 イ ンタラクティブなコンテナでクラスタを作成
クラスタの作成には、Docker Swarm 公式イメージを使えます。イメージは Docker 社が構築したものであり、適切な⾃動構築を通して定期的に更新しています。イメージを使うには、Docker Engine の docker run コマンドを通してコンテナを実⾏します。Swarm クラスタを作成・管理するため、イメージには複数のオプションとサブコマンドがあります。
イメージを初めて使う時、Docker Engine はイメージが⾃分の環境に既に存在しているかどうか確認します。
Docker はデフォルトで swarm:latest バージョンを実⾏しますが、latest 以外のタグも指定できます。イメージがローカルにダウンロード済みでも、Docker Hub 上に新しいバージョンが存在していれば、Docker Engine は新しいイメージをダウンロードします。

コ ンテナ で Swarm イメージを 実行
1. Docker Engine を実⾏しているホスト上のターミナルを開きます。
2. Mac か Windows を使っている場合は、Docker Machine コマンドで Docker Engine ホストを起動し、ターミ
ナルの環境を対象ホストに向ける必要があります。動作確認は次のようにします。
$ docker-machine ls
NAME
ACTIVE URL
default *virtualbox

STATE
Running

URL
tcp://192.168.99.100:2376

SWARM

DOCKER
v1.9.1ERRORS

これは Docker Engine ホスト上で動いている default 仮想マシンの環境を指し⽰しています。
2. swarm イメージを使ってコマンドを実⾏します。

- 9 -docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.1 Docker Swarmの⼊⼿⽅法

最も簡単なコマンドはイメージのヘルプ表⽰です。次のコマンドはイメージで利⽤可能なオプションの全てを表⽰します。
$ docker run swarm --help
Unable to find image 'swarm:latest' locallylatest: Pulling from library/swarm
d681c900c6e3: Pull complete
188de6f24f3f: Pull complete
90b2ffb8d338: Pull complete
237af4efea94: Pull complete
3b3fc6f62107: Pull complete
7e6c9135b308: Pull complete
986340ab62f0: Pull complete
a9975e2cc0a3: Pull complete
Digest: sha256:c21fd414b0488637b1f05f13a59b032a3f9da5d818d31da1a4ca98a84c0c781b
Status: Downloaded newer image for swarm:latest
使い方: swarm [オプション] コマンド [引数...]
Docker ネイティブのクラスタリング・システム
Version: 1.0.1 (744e3a3)
オプション:--debug
デバッグ・モード [$DEBUG]--log-level, -l "info"
ログレベル (選択肢: debug, info, warn, error, fatal, panic)--help, -h
ヘルプ表示--version, -v
バージョンを表示
コマンド:
create, c クラスタの作成
list, l クラスタの一覧
manage, m docker クラスタの管理
join, j docker クラスタへ参加
help, h コマンド一覧、あるいは特定のコマンドのヘルプを表示
コマンド 'swarm コマンド名 --help' で詳細情報を表示。
この例では swarm イメージが Engine ホスト上に存在していないため、Engine はイメージをダウンロードします。
ダウンロード後、イメージは help サブコマンドを実⾏し、ヘルプ・テキストを表⽰します。ヘルプを表⽰した後、swarm イメージが終了し、ターミナル上のコマンドラインに戻ります。
3. Engine ホスト上で実⾏しているコンテナ⼀覧を表⽰します。
$ docker ps
CONTAINER ID
PORTS

IMAGE
NAMES

COMMAND

CREATEDSTATUS

Swarm は動作していません。swarm イメージはコマンドを実⾏して終了したからです。

な ぜイメ ージ を使う のです か？
Swarm コンテナを使う⽅法は、他の⼿法と⽐べて３つの重要な利点があります。

 イメージを使えば、システム上にバイナリのインストールが不要。
- 10 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.1 Docker Swarmの⼊⼿⽅法

 docker run コマンドを実⾏するだけで、常に最新バージョンのイメージを毎回取得。
 コンテナはホスト環境と Swarm を分離。シェル上のパスや環境変数の指定・調整が不要。
Swarm イメージの実⾏は Swarm クラスタの作成・管理のために推奨されている⽅法です。Docker の全ドキュ
メントおよびチュートリアルで使われている⽅法がこちらです。

2.1.2 Swarm バイナリの実行
ホストのオペレーティング・システム（OS）上で直接 Swarm バイナリを実⾏する前に、ソースコードからバイ
ナリをコンパイルするか、信頼できる別の場所からコピーする必要があります。その作業の後、Swarm のバイナリを実⾏します。
ソースコードから Swarm をコンパイルするには、CONTRIBUTING.md*1 の⼿順をご覧ください。

な ぜバイナ リを 使うの ですか ？
他の⽅法に⽐べ、Swarm バイナリには利点が１つあります。もしあなたが swarm プロジェクトに貢献している開発者であれば、「コンテナ化」したバイナリを実⾏しなくても、コードに対する変更をテスト可能です。
ホスト OS 上で Swarm バイナリを実⾏する場合は、不利な点が３つあります。

 ソースからコンパイルする⼿間。
 Docker コンテナによってもたらされる隔離などの利点は、バイナリには無い。
 ⼤部分の Docker ドキュメントやチュートリアルは、バイナリで実⾏する⽅法では説明していない。
加えて、Swarm ノードは Engine を使いませんので、ノード上では Docker Engine CLI のような Docker ベースのソフトウェア・ツールで扱えません。

*1 http://github.com/docker/swarm/blob/master/CONTRIBUTING.md- 11 -

docs.docker.jp

16/06/02

2.2 Swarm を検証環境で試すにはこのセクションでは、Docker Swarm という Docker ⽤のネイティブなクラスタリング・ツールを使う⽅法を紹介します。
作業では、Docker Machine がインストールされた Docker Toolbox と、コンピュータ上の他のツールをいくつか使います。Docker Machine は Docker Engine ホスト群をプロビジョン（⾃動構築）するために使います。そして、Docker クライアントはホストに接続するために使います。ここでのホストとは、ディスカバリ・トークンを作成する場所であり、Swarm マネージャとノードでクラスタを作成・管理するための場所もあります。
準備が完了したら、ローカルの Mac か Windows コンピュータで動く VirtualBox 上で Docker Swarm を起動します。この Swarm 環境は個⼈的な開発環境（サンドボックス）として使えます。
Docker Swarm を Linux 上で使う場合は、「プロダクション⽤の Swarm クラスタ構築」のセクションをご覧ください。

2.2.1 Docker Toolbox のインストール
Docker Toolbox*1 のダウンロードとインストールをします。
Toolbox はローカルの Windows や Mac OS X コンピュータ上に便利なツールをインストールします。この練習では、３つのツールを使います。

 Docker Machine：Docker Engine を実⾏する仮想マシンをデプロイします。
 VirtualBox：Docker Machine を使い、仮想マシンのホストをデプロイします。
 Docker クライアント：ローカルのコンピュータから仮想マシン上の Docker Engine に接続します。また、
docker コマンドで Swarm クラスタを作成します。
以下のセクションでは各ツールの詳細を説明します。以降は仮想マシン（Virtual Machine）を VM と略します。

2.2.2 Docker Engine で３つ の VM を作成
ここでは Docker Machine を使い、Docker Engine を動かす３つの VM を作成（プロビジョン）します。
1. ⾃分のコンピュータ上のターミナルを開きます。Docker Machine で VirtualBox 上の VM ⼀覧を表⽰します。
$ docker-machine ls
NAME
ACTIVE DRIVER
default*
virtualbox

STATE
Running

URL
tcp://192.168.99.100:2376

SWARM

2. オプション：システム・リソースを節約するために、使っていない仮想マシンを停⽌します。例えば、defaultという名前の VM を停⽌するには、次のようにします。
$ docker-machine stop default
3. manager（マネージャ）という名前の VM を作成・実⾏します。
$ docker-machine create -d virtualbox manager*1 https://www.docker.com/docker-toolbox- 12 -

docs.docker.jp

16/06/02

4. agent1 （エージェント１）という名前の VM を作成・実⾏します。
$ docker-machine create -d virtualbox agent1
5. agent2（エージェント２）という名前の VM を作成・実⾏します。
$ docker-machine create -d virtualbox agent2
各 create コマンドの実⾏時、boot2docker.iso と呼ばれる VM イメージの最新版がローカルにコピーされているかどうか（⾃動的に）確認します。ファイルが存在しないか最新版でなければ、Docker Machine は Docker Hubからイメージをダウンロードします。それから Docker Machine は boot2docker.iso を使い、Docker Engine を⾃動的に実⾏する VM を作成します。
トラブルシューティング：コンピュータやホストが Docker Hub にアクセスできなければ、
docker-machine や docker run コマンドは失敗します。そのような場合、サービスが利⽤可能かど
うか Docker Hub ステータス・ページ*1 を確認します。その次は、⾃分のコンピュータがインターネットに接続しているか確認します。あるいは VirtualBox のネットワーク設定で、ホストがイン
ターネット側に接続可能かどうかを確認してください。

2.2.3 Swarm ディスカバリ・トークンの作成
ここでは Docker Hub 上にあるディスカバリ・バックエンドを使い、⾃分のクラスタ⽤のユニークなディスカバ
リ・トークンを作成します。このディスカバリ・バックエンドは、⼩規模の開発環境やテスト⽬的のためであり、
プロダクション向けではありません。Swarm マネージャとノードを起動後、ディスカバリ・バックエンドにノードをクラスタのメンバとして登録します。クラスタとユニークなトークンを結び付けるのが、このバックエンドの役
割です。ディスカバリ・バックエンドはクラスタのメンバのリストを最新情報に更新し続け、その情報を Swarm
マネージャと共有します。Swarm マネージャはこのリストを使いノードに対してタスクを割り当てます。
1. コンピュータ上の Docker クライアントを Docker Engine が動いている manager に接続します*2。
$ eval $(docker-machine env manager)以降の⼿順では、クライアント側の docker コマンドは manager 上の Docker Engine に送信します。
2. Swarm クラスタに対するユニーク ID を作成します。
$ docker run --rm swarm create.
.
.
Status: Downloaded newer image for swarm:latest
0ac50ef75c9739f5bfeeaf00503d4e6e
docker run コマンドは最新（latest）の swarm を取得し、コンテナとして実⾏します。引数 create は Swarm コ*1 http://status.docker.com/*2

訳者注：環境を指し⽰す状況であり、実際には接続を維持しません。コマンド実⾏時に、都度、アクセスします。

- 13 -

docs.docker.jp

16/06/02

ンテナを Docker Hub ディスカバリ・サービスに接続し、ユニークな Swarm ID を取得します。この ID を「ディスカバリ・トークン」（discovery token）と呼びます。トークンは出⼒（アウトプット）されるだけであり、ホスト上のファイルには保管されません。 --rm オプションは⾃動的にコンテナを削除するものです。コンテナが終了
したら、コンテナのファイルシステムを⾃動的に削除します。
トークンを利⽤しなければ、およそ⼀週間後にディスカバリ・サービスによって削除されます。
3. 先ほどの出⼒されたディスカバリ・トークンを安全な場所にコピーします。

2.2.4 Swarm マネージャとノードの作成
ここでは、各ホストに接続し、Swarm マネージャまたはノードを作成します。
1. ３つの VM の IP アドレスを取得します。例：$ docker-machine ls
NAME
ACTIVE DRIVER
agent1
virtualbox
agent2
virtualbox
manager *virtualbox

STATE
Running
Running
Running

URL
tcp://192.168.99.102:2376
tcp://192.168.99.103:2376
tcp://192.168.99.100:2376

SWARM

DOCKER
v1.9.1v1.9.1v1.9.1ERRORS

2. クライアントは manager を実⾏する Docker Engine を指し⽰しているままでしょう。次の構⽂は manager 上
で Swarm コンテナをプライマリ Swarm マネージャとして実⾏します。
$ docker run -d -p <your_selected_port>:3376 -t -v /var/lib/boot2docker:/certs:ro swarm manage \-H 0.0.0.0:3376 --tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/server.pem \--tlskey=/certs/server-key.pem token://<cluster_id>
例：$ docker run -d -p 3376:3376 -t -v /var/lib/boot2docker:/certs:ro swarm manage \-H 0.0.0.0:3376 --tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/server.pem \--tlskey=/certs/server-key.pem swarm manage token://0ac50ef75c9739f5bfeeaf00503d4e6e-p オプションは、コンテナのポート 3376 をホスト上の 3376 に割り当てています。-v オプションは TLS 証明
書が⼊っているディレクトリ（manager VM 上の/var/lib/boot2docker）をマウントします。これは Swarm マネージャの中では読み込み専⽤（read-only）モードで扱われます。
3. Docker クライアントを agent1 に接続します。
$ eval $(docker-machine env agent1)
4. 次の構⽂は agent1 上で Swarm コンテナをエージェントとして起動します。IP アドレスは VM のものに書き換えます。
$ docker run -d swarm join --addr=<ノードの ip>:<例：$ docker run -d swarm join --addr=192.168.99.102:2376 token://0ac50ef75c9739f5bfeeaf00503d4e6e- 14 -

docs.docker.jp

16/06/02

5. Docker クライアントを agent2 に接続します。
$ eval $(docker-machine env agent2)
6. agent2 上で Swarm コンテナをエージェントとして起動します。
$ docker run -d swarm join --addr=192.168.99.103:2376 token://0ac50ef75c9739f5bfeeaf00503d4e6e

2.2.5 Swarm クラスタを管理
ここではクラスタに接続し、Swarm マネージャとノードの情報を⾒ていきます。Swarm に対してコンテナ実⾏を命令し、どのノードで動作しているかを確認します。
1. Docker クライアントを Swarm に接続するため、DOCKER_HOST 環境変数を更新します。
$ DOCKER_HOST=<manager_ip>:<your_selected_port>
この例では manager の IP アドレスは 192.168.99.100 です。Swarm マネージャ⽤のポートは 3376 を選びました。
$ DOCKER_HOST=192.168.99.100:3376
Docker Swarm は標準 Docker API を使うため、Docker クライアントで接続できます。他にも Docker Compose
や、Dokku、Jenkins、Krane などのツールが利⽤できます。
2. Swarm に関する情報を取得します。
$ docker info
実⾏したら、Swarm 上にあるマネージャ１つと、エージェント・ノード２つの情報を表⽰します。
3. Swarm 上で実⾏中のイメージを確認します。
$ docker ps
4. Swarm 上でコンテナを実⾏します。
$ docker run hello-world
Hello from Docker.
.
.
.
5. docker ps コマンドを使い、どのノードでコンテナが実⾏されているかを確認します。実⾏例：$ docker ps -a
CONTAINER ID
PORTS
0b0628349187
minutes ago
.
.
.

IMAGE

COMMAND
NAMES
hello-world"/hello"agent1- 15 -

CREATEDSTATUS

20 minutes ago

Exited (0) 20

docs.docker.jp

16/06/02この例では、swarm1 上で hello-world が動いていました。
Docker Swarm がコンテナをどのノードで実⾏するかを決めるには、デフォルトでは「spread」（スプレッド）ス
トラテジを使います。複数のコンテナを実⾏する場合、スプレッド・ストラテジはコンテナの実⾏数が最も少ないノードに対してコンテナを割り当てます。

2.2.6 更 に詳しく
ここまでは次の作業を⾏いました。

 Swarm ディスカバリ・トークンの作成
 Docker Machine を使って Swarm ノードを作成
 Swarm を使ってコンテナを実⾏ Swarm に関連する概念と技術を学んだ
この他にも Docker Swarm には多くの特徴や能⼒があります。より詳しい情報は、Swarm のランディング・ペ
ージ*1（英語）や引き続き Swarm ドキュメントをご覧ください。

*1 https://www.docker.com/docker-swarm- 16 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

2.3 プロダクションで Swarm 利用時の考慮
このセクションは Docker Swarm クラスタを計画・デプロイ・管理の⼿助けとなるガイダンスを提供します。
想定しているのは、ビジネスにおけるクリティカルなプロダクション環境です。次のハイレベルな項⽬を扱います。

 セキュリティ ⾼可⽤性（HA）
 性能
 クラスタの所有

2.3.1 セ キュリティ
Docker Swarm クラスタを安全にする様々な⽅法があります。このセクションは以下の内容を扱います。

 TLS を使った認証
 ネットワークのアクセス制御
これらのトピックだけでは完全ではありません。広範囲にわたるセキュリティ・アーキテクチャにおける⼀部分です。セキュリティ・アーキテクチャに含まれるのは、セキュリティ・パッチ、強⼒なパスワード・ポリシー、ロールをベースとしたアクセス制御、SELinux や AppArmor のように厳格な監査を⾏う技術、等々です。

Swarm 用 の TLS 設 定
Swarm クラスタ内にある全てのノードは、Docker Engine デーモンの通信⽤にポートを開く必要があります。そのため、中間者攻撃（man-in-the-middle attacks）のように、通常のネットワークに関連するセキュリティの問題をもたらします。対象のネットワークがインターネットのような信頼できない環境であれば、これらの危険性が倍増します。危険性を逓減するために、Swarm と Engine は TLS 認証（Transport Layer Security）をサポートしています。
Engine デーモンおよび Swarm マネージャは、TLS を使う設定をすることで、署名された Docker Engine クラ
イアントからのみ通信を受け付けるようにできます。Engine と Swarm は組織内部の認証局（CA; Certiﬁcate
Authorities）だけでなく、外部のサード・パーティー製による認証局もサポートしています。
Engine と Swarm が TLS に使うデフォルトのポート番号： Engine デーモン：2376/tcp
 Swarm マネージャ：3376/tcp
Swarm に TLS 設定を⾏うための詳しい情報は、「Swarm と TLS の概要」セクションをご覧ください。

ネットワ ーク のアクセス制 御プロダクションにおけるネットワークは複雑であり、通常は特定のトラフィックのみがネットワーク上に流れる
ように固定します。以下のリストは Swarm クラスタの各コンポーネントが公開しているポート情報です。ファイ
アウォールや、他のネットワーク・アクセス管理リストの設定に、これらが使えるでしょう。
Swarm マネージャ： Inbound 80/tcp (HTTP)：docker pull コマンドが動作するために使います。Docker Hub からイメージを取得するためには、インターネット側のポート 80 を通す通信の許可が必要です。
- 17 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

 Inbound 2375/tcp：Docker Engine CLI が Engine デーモンと直接通信します。
 Inbound 3375/tcp：Docker Engine CLI が Swarm マネージャと通信します。
 Inbound 22/tcp：SSH を経由したリモート管理を⾏います。
サービス・ディスカバリ：
 Inbound 80/tcp (HTTP)：docker pull コマンドが動作するために使います。Docker Hub からイメージを取得するためには、インターネット側のポート 80 を通す通信の許可が必要です。
 Inbound （ディスカバリ・サービス用のポート番号）：バックエンド・ディスカバリ・サービス（consul、
etcd、zookeeper）が公開するポートの設定が必要です。
 Inbound 22/tcp：SSH を経由したリモート管理を⾏います。
Swarm ノード ： Inbound 80/tcp (HTTP)：docker pull コマンドが動作するために使います。Docker Hub からイメージを取得するためには、インターネット側のポート 80 を通す通信の許可が必要です。
 Inbound 2375/tcp：Docker Engine CLI が Engine デーモンと直接通信します。
 Inbound 22/tcp：SSH を経由したリモート管理を⾏います。
その他、ホスト横断コンテナ・ネットワーク ： Inbound 7946/tcp：他のコンテナ・ネットワークから発⾒（ディスカバリ）されるために必要です。
 Inbound 7946/udp：他のコンテナ・ネットワークから発⾒（ディスカバリ）されるために必要です。
 Inbound /tcp：キーバリュー・ストアのサービス⽤ポートに接続します。
 7489/udp：コンテナのオーバレイ・ネットワーク⽤です。
もしもファイアウォールがネットワーク・デバイスとの接続状態を検出（state aware）すると、TCP 接続を確⽴するための応答を許可します。デバイスが検出できなければ、23768 〜 65525 までのエフェメラル・ポート（訳者注：短時間のみ利⽤するポート）を⾃分でオープンにする必要があります。エフェメラル・ポートのルールという、セキュリティ設定の追加のみが、既知の Swarm デバイス上のインターフェースからの接続を受け付けるようにします。
Swarm クラスタが TLS ⽤の設定を⾏っている場合、2375 は 2376 に、3375 は 3376 に置き換えます。
クラスタ作成やクラスタ管理、クラスタ上でコンテナをスケジューリングといった Swarm クラスタの操作には、先ほどのリストにあるポートの調整が必要です。アプリケーションに関連する通信のために、追加で通信⽤ポートの公開も必要になる場合があります。
Swarm クラスタのコンポーネントは、別のネットワークに接続する可能性があります。例えば、多くの組織が管理⽤のネットワークとプロダクション⽤のネットワークを分けています。ある Docker Engine クライアントは管理
ネットワーク上に存在しており、Swarm マネージャ、ディスカバリ・サービス⽤インスタンスやノードが１つまたは複数のネットワークにあるかもしれません。ネットワーク障害を埋め合わせるために、Swarm マネージャ、ディスカバリ・サービス、ノードが複数のプロダクション⽤ネットワークを横断することも可能です。先ほどのポート番号の⼀覧は、皆さんのネットワーク基盤チームがネットワークを効率的・安全に設定するために役⽴つでしょう。

2.3.2 高 可用性（HA）
全てのプロダクション環境は⾼可⽤性（HA; Highly available）であるべきでしょう。つまり、⻑期間にわたる継続的な運⽤を意味します。⾼可⽤性を実現するのは、個々のコンポーネントで障害が発⽣しても切り抜ける環境です。
回復⼒のある⾼可⽤性 Swarm クラスタを構築するために、以下のセクションでは、いくつかの技術やベストプ
ラクティスについて議論します。これらクラスタは、要求の厳しいプロダクションにおけるアプリケーションやワークロードで利⽤可能です。

- 18 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

Swarm マ ネージ ャ HA
Swarm マネージャは Swarm クラスタに対する全ての命令を受け付ける責任を持ちます。それと、クラスタ内のリソースをスケジューリングする役割があります。もしも Swarm マネージャが利⽤不可能になれば、再び Swarm
マネージャが使えるようになるまでクラスタに対する操作が不可能になります。これは⼤きくスケールするビジネスにおいては致命的なシナリオであり、許されません。
Swarm が提供する HA 機能は、Swarm マネージャで発⽣しうる障害を緩和します。クラスタ上に複数の Swarm
マネージャを設定することで、Swarm の HA 機能を利⽤できます。３つの Swarm マネージャがアクティブ／パッシブ（活動中／受け⾝）を形成します。この時、１つのマネージャが プライマリ であり、残りの全てがセカンダ
リになります。
Swarm のセカンダリ・マネージャは ウォーム・スタンバイ として扱われます。つまり、プライマリ Swarm マ
ネージャのバックグラウンドで動作することを意味します。セカンダリ Swarm マネージャはオンラインのままであり、プライマリ Swarm マネージャと同様、クラスタに対するコマンドを受け付けます。しかしながら、セカンダリが受信したコマンドはプライマリに転送され、その後に実⾏されます。プライマリ Swarm マネージャが落ちたとしても、残ったセカンダリの中から新しいプライマリが選出されます。
HA Swarm マネージャの作成時は、障害範囲 (failure domains)の影響を受けないよう、可能な限り分散するよう注意を払う必要があります。障害範囲とは、デバイスまたはサービスに対する致命的な問題が発⽣すると影響があるネットワーク区分です。仮にクラスタが Amazon Web Services のアイルランド・リージョン（eu-west-1）で動いているとします。３つの Swarm マネージャを設定するにあたり（１つはプライマリ、２つはセカンダリ）、次の図のように各アベイラビリティ・ゾーンに置くべきでしょう。

この設定であれば、Swarm クラスタは２つのアベイラビリティ・ゾーンが失われても稼働し続けられます。あな
たのアプリケーションが障害を乗り越えるためには、アプリケーションの障害範囲も重複しないよう設計する必要があります。
事業部で需要の⾼いアプリケーション向けに Swarm クラスタを使う場合は、３つ以上の Swarm マネージャを準備すべきです。そのように設定しておけば、１つのマネージャがメンテナンスのために停⽌しても、あるいは障害に直⾯したとしても、クラスタを管理・運⽤し続けられます。
- 19 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

ディスカ バリ・ サービ ス HA
ディスカバリ・サービスは Swarm クラスタにおける重要なコンポーネントです。ディスカバリ・サービスが使えなくなると、適切なクラスタ操作ができなくなります。例えば、ディスカバリ・サービスが動作しなくなったら、クラスタに新しいノードの追加といった操作や、クラスタ設定に関する問い合わせに失敗します。これはビジネスにおけるクリティカルなプロダクション環境では許容できません。
Swarm は４つのバックエンド・ディスカバリ・サービスをサポートしています。

 ホステッド（プロダクション向けではない） Consul
 etcd Zookeeper
Consul、etcd、Zookeeper はどれもプロダクションにふさわしく、⾼可⽤性のために設定されるべきです。HA向けのベスト・プラクティスを設定するためには、これら各サービスのツールを使うべきでしょう。
事業部で⾼い需要のアプリケーション向けに Swarm を使う場合は、５つ以上のディスカバリ・サービス・イン
スタンスの⽤意を推奨します。これはレプリケーション/HA で⽤いられている（Paxos や Raft のような）技術が強⼒なクォーラム（quorum）を必要とするためです。５つのインスタンスがあれば、１つがメンテナンスや予期しない障害に直⾯しても、強⼒なクォーラムを形成し続けられます。
⾼い可⽤性を持つ Swarm ディスカバリ・サービスを作成する場合には、各ディスカバリ・サービス・インスタンスを可能な限り障害範囲を重複しないようにすべきでしょう。例えば、クラスタを Amazon Web Service のアイ
ルランド・リージョン（eu-west-1）で動かしているとします。３つのディスカバリ・サービス⽤インスタンス設
定する時、それぞれを各アベイラビリティ・ゾーンに置くべきです。
次の図は HA を設定した Swarm クラスタ設定を表しています。３つの Swarm マネージャと３つのディスカバリ
・サービス・インスタンスが３つの障害領域（アベイラビリティ・ゾーン）に展開してます。また、Swarm ノード
は３つの障害領域を横断しています。２つのアベイラビリティ・ゾーンで障害が発⽣したとしても、Swarm クラス
タは停⽌しない設定を表しています。

- 20 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

複 数のク ラウド
Swarm クラスタを複数のクラウド・プロバイダを横断するよう設計・構築できます。これはパブリック・クラウ
ドでも、オンプレミスの基盤でもです。次の図は Swarm クラスタを AWS と Azure に横断しています。

このアーキテクチャは究極の可⽤性を提供しているように⾒えるかもしれませんが、考慮すべき複数の要素があります。ネットワークのレイテンシ（応答遅延）は問題になりがちです。パーティショニング（分割）も問題になりうるでしょう。クラウド・プラットフォームにおいて信頼性、⾼スピード、低いレイテンシを実現する技術の考慮が必要となるでしょう。例えば AWS ダイレクト・コネクトや Azure ExpressRoute といった技術です。
このように、プロダクションを複数のインフラに横断する検討する場合は、あなたのシステム全体にわたるテス
トを確実に⾏うべきでしょう。

プ ロダク ション 環境の 分離
開発、ステージング、プロダクションのような複数の環境を、１つの Swarm クラスタ上で動かせるでしょう。
そのためには Swarm ノードをタグ付けし、production や staging 等のようにタグ付けされたコンテナを制約フィルタ（constraint ﬁlter）で使う⽅法があります。しかしながら、これは推奨しません。ビジネスにおけるクリティ
カルなプロダクション環境において⾼いパフォーマンスが必要な時は、エアギャップ・プロダクション環境の⼿法を推奨します。
例えば、多くの会社では、プロダクション⽤に分離された専⽤環境にデプロイするでしょう。専⽤環境とは、ネットワーク、ストレージ、計算資源、その他のシステムです。デプロイは別の管理システムやポリシーで⾏われます。その結果、プロダクション・システム等にログインするために、別のアカウント情報を持つ必要があります。
- 21 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

この種の環境では、プロダクション専⽤の Swarm クラスタへデプロイする義務があるでしょう。プロダクションのハードウェア基盤で Swarm クラスタを動かし、そこでプロダクションにおける管理・監視・監査・その他のポリシーに従うことになります。

オ ペレ ーティ ング・ システムの 選択
Swarm 基盤が依存するオペレーティング・システムの選択には重要な考慮をすべきです。考慮こそがプロダクシ
ョン環境における核⼼となります。
開発環境とプロダクション環境でオペレーティング・システムを変えて使う会社は珍しくありません。よくあるのが、開発環境では CentOS を使いますが、プロダクション環境では Red Hat Enterprise Linux (RHEL)を使う場合です。しばしコストとサポートのバランスが決め⼿になります。CentOS Linux は⾃由にダウンロードして利⽤できますが、商⽤サポートのオプションは僅かなものです。⼀⽅の RHEL であればサポートに対してライセンスのコストが想定されますが、Red Hat による世界的な商⽤サポートが受けられます。
プロダクション向けの Swarm クラスタで使うオペレーティング・システムの選定にあたっては、開発環境とス
テージング環境で使っているものに近いものを選ぶべきでしょう。コンテナが根本となる OS を抽象化するといえども、避けられない課題があるためです。例えば、Docker コンテナのネットワークには Linux カーネル 3.16 以上が必要です。開発・ステージング環境でカーネル 4.x 系を使っていても、プロダクションが 3.14 であれば何らかの問題が発⽣します。
他にも考慮すべき点として、⼿順、デプロイの順序、プロダクション⽤オペレーティング・システムへのパッチ
適⽤の可能性があるでしょう。

2.3.3 性 能
重要な商⽤アプリケーションを扱う環境にとって、性能（パフォーマンス）が⾮常に重要です。以下のセクショ
ンでは⾼性能な Swarm クラスタを構築する⼿助けとなるような議論と⼿法を紹介します。

コ ンテナ ・ネットワ ーク
Docker Engine のコンテナ・ネットワークがオーバレイ・ネットワークであれば、複数の Engine ホスト上を横断して作成可能です。そのためには、コンテナ・ネットワークがキーバリュー（KV）
・ストアを必要とします。これは Swarm クラスタのディスカバリ・サービスで情報を共有するために使います。しかしながら、最⾼の性能と障害の分離のためには、コンテナ・ネットワーク⽤と Swarm ディスカバリ⽤に別々の KV インスタンスをデプロイすべきでしょう。特に、ビジネスにおけるクリティカルなプロダクション環境においては重要です。
Engine のコンテナ・ネットワークは Linux カーネルの 3.16 以上を必要とします。より⾼いカーネル・バージョンの利⽤が望ましいのですが、新しいカーネルには不安定さというリスクが増えてしまいます。可能であれば、皆さんがプロダクション環境で既に利⽤しているカーネルのバージョンを使うべきです。もしも Linux カーネル 3.16以上をプロダクションで使っていなければ、可能な限り早く使い始めるべきでしょう。

スケジュ ーリング・ス トラ テジ
スケジューリング・ストラテジとは、Swarm がコンテナを開始する時に、どのノードか、どのクラスタ上で実⾏するかを決めるものです。

 spread binpack random （プロダクション向けではありません）
⾃分⾃⾝で書くこともできます。
spread （スプレッド）はデフォルトのストラテジです。クラスタ上の全てのノードにわたり、均⼀な数のコンテ- 22 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.3 プロダクションでSwarm利⽤時の考慮

ナになるようバランスを取ろうとします。⾼い性能を必要とするクラスタでは良い選択肢です。コンテナのワーク
ロードをクラスタ全体のリソースに展開するからです。リソースには CPU、メモリ、ストレジ、ネットワーク帯域が含まれます。
もし Swarm ノードで障害が発⽣したら、Swarm は障害領域を避けてコンテナを実⾏するようにバランスを取ります。しかしながら、コンテナの役割には注意が払われないため、関係なく展開されます。そのため、サービス展
開先を複数の領域に分けたくても、Swarm は把握できません。このような操作を⾏うには、タグと制限（constraint）
を使うべきです。
binpack（ビンバック）ストラテジは、ノードに次々とコンテナをスケジュールするのではなく、可能な限り１つのノード上にコンテナを詰め込もうとします。
つまり、binpack はクラスタを使い切るまで全てのクラスタ・リソースを使いません。そのため、binpack スト
ラテジの Swarm クラスタ上で動作するアプリケーションによっては、性能が出ないかもしれません。しかしながら、binpack は必要なインフラとコストの最⼩化のために良い選択肢です。例えば 10 ノードのクラスタがあり、それぞれ 16 CPU・128 GB のメモリを持っていると想像してみましょう。コンテナのワークロードが必要になるのは、6 CPU と 64 GB のメモリとします。spread ストラテジであれば、クラスタ上の全てのノードにわたってバランスを取ります。⼀⽅、binpack ストラテジであれば、コンテナが１つのノード上を使い切ります。そのため、追加ノードを停⽌することで、コストの節約ができるかもしれません。

2.3.4 ク ラスタの所有所有者が誰なのかというのは、プロダクション環境において極めて重要です。Swarm クラスタでプロダクションの計画、ドキュメントか、デプロイに⾄る全てにおける熟慮と合意が重要になります。

 プロダクションの Swarm 盤に対し、誰が予算を持っているのか？
 プロダクションの Swarm ラスタを誰が管理・運⽤するのか？
 プロダクションの Swarm 盤に対する監視は誰の責任か？
 プロダクションの Swarm 基盤のパッチあてやアップグレードは誰の責任か？
 24 時間対応やエスカレーション⼿順は？
このリストは完全ではありません。何が答えなのかは、皆さんの組織やチーム構成によって様々に依存します。
ある会社は DevOps の流れに従うかもしれませんし、そうではない場合もあるでしょう。重要なのは、皆さんの会
社がどのような状況なのかです。プロダクション⽤ Swarm クラスタの計画、デプロイ、運⽤管理に⾄るまで、全ての要素の検討が重要です。

- 23 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築

2.4 プロダクション用の Swarm クラスタ構築
⾼い可⽤性を持つ Docker Swarm クラスタのデプロイ⽅法を紹介します。この例では Amazon Web Services(AWS)をプラットフォームとして使いますが、他のプラットフォーム上でも Docker Swarm クラスタを同じようにデプロイできます。この例では、以下の⼿順で進めます。

 動作条件の確認
 基本的なネットワーク・セキュリティの確保
 ノードの作成
 各ノードに Engine をインストール
 ディスカバリ・バックエンドの設定
 Swarm クラスタの作成
 Swarm との通信
 Swarm マネージャの⾼可⽤性試験
 追加情報
⼀般的な Swarm の導⼊⽅法については「2.2 Swarm を検証環境で試すには」をご覧ください。

2.4.1 動 作条件

 Amazon Web Services (AWS) アカウント 以下の AWS 機能やツールに慣れている：
 エラスティック・クラウド（EC2）ダッシュボード バーチャル・プライベート・クラウド（VPC）ダッシュボード
 VPC セキュリティ・グループ
 EC2 インスタンスに SSH で接続

2.4.2 手 順
ステップ １： ネット ワーク・セキ ュリティのル ール を追加
AWS は VPC ネットワークに対して許可するネットワーク通信を「セキュリティ・グループ」で指定します。初期状態の default セキュリティ・グループは、インバウンドの通信を全て拒否し、アウトバンドの通信を全て許可
し、インスタンス間の通信を許可するルール群です。
ここに SSH 接続とコンテナのイメージを取得（インバウンド）する２つのルールを追加します。このルール設
定は Engine、Swarm、Consul のポートを少々は守ります。プロダクション環境においては、セキュリティ度合い
によって更に制限するでしょう。Docker Engine のポートを無防備にしないでください。
AWS のホーム・コンソール画⾯から、以下の作業を進めます：
1. ［VPC - 独⽴したクラウドリソース］をクリックします。
VPC ダッシュボードが開きます。

- 24 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築

2. ［セキュリティグループ］をクリックします。
3. ［default］セキュリティ・グループを選び、default VPC にセキュリティ・グループを関連付けます。
4. 以下の２つのルールを追加します。
タイプ

プロトコル ポート範囲

SSH
HTTP

TCP
TCP

22
80

送信元
0.0.0.0/0
0.0.0.0/0

SSH 接続はホストに接続するためです。HTTP はコンテナ・イメージをホストにダウンロードするためです。

ステップ ２： インスタ ンス作 成
このステップではデフォルトのセキュリティ・グループで５つの Linux ホストを作成します。作業は３種類のノードをデプロイする例です
ノードの説明名前

Swarm のプライマリとセカンダリ・マネージャ
Swarm ノード
ディスカバリ・バックエンド

manager0 , manager1
node0 , node1
consul0

インスタンスの作成は、以下の⼿順で進めます。
1. EC2 ダッシュボードを開き、各 EC2 インスタンスを同時に起動します。

 ［ステップ１］では：Amazon マシン・イメージ (AMI)を選択します。
「Amazon Linux AMI」を探します。
 ［ステップ５］では：インスタンスにタグを付けます。各インスタンスの Value に名前を付けます。
 manager0
 manager1
 consul0
 node0 node1 ［ステップ６］では：セキュリティ・グループを設定します。既存のセキュリティグループから「default」
を探します。
2. インスタンスの起動を確認します。

ステップ ３： 各ノー ドに Engine をイ ンストー ル
このステップでは、各ノードに Docker Engine をインストールします。Engine をインストールすることで、Swarm
マネージャは Engine CLI と API を経由してノードを割り当てます。
SSH で各ノードに接続し、以下の⼿順を進めます。
1. yum パッケージを更新します。
「y/n/abort」プロンプトに注意します。
- 25 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築$ sudo yum update
2. インストール⽤スクリプトを実⾏します。
$ curl -sSL https://get.docker.com/ | sh
3. Docker Engine が Swarm ノードのポート 2375 で通信可能な指定で起動します。
$ sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
4. Docker Engine が正常にインストールされたことを確認します。
$ sudo docker run hello-world「Hello World」メッセージが画⾯に表⽰され、エラーではない⽂字列が表⽰されます。
5. ec2-user に root 権限を与えます。
$ sudo usermod -aG docker ec2-user
6. logout を実⾏します。

トラ ブルシュー ティ ング

 docker コマンドを実⾏してもホスト上で docker が動作しているかどうか訊ねる表⽰が出るのは、ユーザがroot 権限を持っていない可能性があります。そうであれば、sudo を使うか、ユーザに対して root 権限を付与します。
 この例では、Docker Engine が動作するインスタンスを元にして、他のインスタンス⽤に使う AMI イメー
ジを作成しません。作成したとしても問題になるでしょう。
 ホスト上で docker run コマンドを実⾏しても Docker Hub に接続できない場合は、コンテナ・イメージの取得に失敗するでしょう。そのような場合、VPC に関連付けられているセキュリティ・グループのルールを参照し、インバウンドの通信（例：HTTP/TCP/80/0.0.0.0.0/0）が許可されているか確認します。また、Docker Hub ステータス・ページ でサービスが利⽤可能かどうか確認します。

ステップ ４： ディス カバリ ・バ ック エン ドのセ ットア ップ
ここでは最⼩のディスカバリ・バックエンドを作成します。Swarm マネージャとノードは、このバックエンドをクラスタ上のメンバを認識するために使います。また、Swarm マネージャはコンテナを実⾏可能なノードがどれかを識別するためにも使います。
簡単さを保つために、Swarm マネージャが動いているホストのうちどれか１つで consul デーモンを起動します。
1. 始めるにあたり、以下のコマンドをテキスト・ファイルにコピーしておきます。
$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
2. SSH で manager0 と consul0 インスタンスに接続します。
- 26 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築$ ifconfig
3. 出⼒結果から inet addr の eth0 にある IP アドレスをコピーします。
4. SSH で manager0 と consul0 インスタンスに接続します。
5. ⼿順１で実⾏したコマンドを、コマンドラインに貼り付けます。
$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
consul ノードを⽴ち上げ実⾏することで、クラスタ⽤のディスカバリ・バックエンドを提供します。このバックエンドの信頼性を⾼めるには、３つの consul ノードを使った⾼可⽤性クラスタを作成する⽅法があります。詳細
情報へリンクを、このセクションの最後をご覧ください（consul ノードのクラスタを作成する前に、VPC セキュ
リティ・グループに対し、必要なポートに対するインバウンド通信を許可する必要があります）。

ステップ ５： Swarm クラスタの作 成
ディスカバリ・バックエンドを作った後は、Swarm マネージャを作成できます。このステップでは⾼い可⽤性を持つ設定のため、２つの Swarm マネージャを作成します。１つめのマネージャを Swarm のプライマリ・マネージャ (primary manager) とします。ドキュメントのいくつかはプライマリを「マスタ」と表現していますが、置き換えてください。２つめのマネージャはレプリカ（replica）を提供します。もしもプライマリ・マネージャが利⽤できなくなれば、クラスタはレプリカからプライマリ・マネージャを選出します。
1. ⾼可⽤性 Swarm クラスタのプライマリ・マネージャを作成するには、次の構⽂を使います。
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager0_ip>:4000
consul://<consul_ip>
特定のマネージャは「manager0 & consul0」インスタンスの consul ノードでもあるので、 <manager0_ip>と<consul_ip> を同じ IP アドレスに書き換えます。例：$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication \--advertise 172.30.0.161:4000 consul://172.30.0.161:8500
2. docker ps を⼊⼒します。
出⼒結果から Swarm クラスタと consul コンテナが動いているのを確認します。それから manager0 と consul0
インスタンスから切断します。
3. manager1 インスタンスに接続し、ifconfig で IP アドレスを取得します。
$ ifconfig
4. 以下のコマンドを実⾏し、セカンダリ Swarm マネージャを起動します。
コマンドを実⾏前に <manager1_ip> の部分は書き換えてください。実⾏例：$ docker run -d swarm manage -H :4000 --replication \--advertise <manager1_ip>:4000 consul://172.30.0.161:8500- 27 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築

5. docker ps を実⾏し、swarm コンテナの実⾏を確認します。
6. node0 と node1 に接続し、それぞれをクラスタに追加（join）します。
a. ifconfig コマンドでノードの IP アドレスを確認します。
b. 各コンテナで、次の構⽂を使って Swarm コンテナを起動します。
$ docker run -d swarm join --advertise=<node_ip>:2375 consul://<consul_ip>:8500
実⾏例：$ docker run -d swarm join – advertise=172.30.0.69:2375 consul://172.30.0.161:8500
あなたの⼩さな Swarm クラスタが起動し、複数のホスト上で実⾏中になりました。信頼性や収容能⼒を⾼めるには、Swarm マネージャやノードを更に追加し、ディレクトリ・バックエンドの可⽤性を⾼めることも可能です。

ステップ ６： Swarm と通信
Swarm API を使って Swarm と通信し、マネージャとノードに関する情報を取得できます。Swarm API はスタン
ダード Docker API とよく似ています。この例では SSL を使って manager0 と consul0 ホストに再び接続します。
そしてコマンドを Swarm マネージャに対して割り当てます。
1. クラスタ内のマスタとノードの情報を取得します。
$ docker -H :4000 info
出⼒結果から、マスタの役割がプライマリ（Role: primary）であることと、各ノードの情報が分かります。
2. Swarm 上でアプリケーションを実⾏します。
$ docker -H :4000 run hello-world
3. Swarm ノード上でアプリケーションが動いているのを確認します。
$ docker -H :4000 ps

ステップ ７： Swarm のフェイル オー バをテ スト
レプリカ・インスタンスへの継承を確認するために、プライマリ・マネージャをシャットダウンします。これが選出のきっかけとなり、レプリカがプライマリ・マネージャになります。停⽌したマネージャを再び起動したら、今度はこちらがレプリカになります。
1. manage0 インスタンスに SSH 接続します。
2. swarm コンテナのコンテナ ID もしくはコンテナ名を取得します。
$ docker ps- 28 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.4 プロダクション⽤のSwarmクラスタ構築

3. プライマリ・マスタをシャットダウンするため、 <id_name> の部分をコンテナ ID あるいはコンテナ名に置き換えます（例：「8862717fe6d3」または「trusting_lamarr」）。
$ docker rm -f <id_name>
4. swarm マスタを起動します。例：$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise 172.30.0.161:4000
consul://172.30.0.161:237
5. Engine デーモンのログを確認します。 <id_name> は新しいコンテナ ID かコンテナ名に置き換えます。
$ sudo docker logs <id_name>
出⼒から次のような２つのエントリが確認できます。
time="2016-02-02T02:12:32Z" level=info msg="Leader Election: Cluster leadership lost"time="2016-02-02T02:12:32Z" level=info msg="New leader elected: 172.30.0.160:4000"
6. クラスタのマスタとノードに関する情報を取得するには、次のように実⾏します。
$ docker -H :4000 info
master1 ノードに接続し、info や logs コマンドを実⾏できます。そうすると、新しいリーダーが適切なエント
リを返します。

- 29 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.5 Docker MachineでSwarmクラスタ構築

2.5 Docker Machine で Swarm クラスタ構築
Docker Machine を使って Docker Swarm クラスタをプロビジョン（⾃動構築）できます。Docker Machine とは Docker のプロビジョニング・ツールです。Machine はホストをプロビジョンし、そこに Docker Engine をインストールし、Docker CLI クライアント⽤の設定を⾏います。Machine で Swarm ⽤のオプションを指定したら、プ
ロビジョニングの過程で Swarm クラスタ⽤の設定も迅速に⾏えます。
このセクションでは、Machine で基本的な Swarm クラスタを構築するために必要なコマンドを紹介します。ローカルの Mac もしくは Windows 上に環境を構築します。流れを理解してしまえば、クラウド・プロバイダ上や、あるいは会社のデータセンタ内にも Swarm クラスタをセットアップできるようになるでしょう。
Swarm クラスタの構築が初めてであれば、まず Swarm について学び、「2.2 Swarm を検証環境で試すには」や「2.4 プロダクション⽤の Swarm クラスタ構築」を読んでおく必要があります。Machine を使うのが初めてであれ
ば、Machine を使う前に概要の理解が望ましいでしょう。

2.5.1 何 が必要ですか？
Mac OS X や Windows で Docker Toolbox を使ってインストールしていた場合は、既に Docker Machine がインストール済みです。インストールの必要があれば、Mac OS X または Windows のページをご覧ください。
Machine を使ったインストールをサポートしているのは、AWS、Digital Ocean、Google Cloud Platform、IBM
SoftLayer、Microsoft Azure、Hyper-V、OpenStack、RackSpace、VirtualBox、VMware Fusion、vCloud Air、vSphereです。このページの例では VirtualBox 上で boot2docker.iso イメージを使った仮想マシンをいくつか起動します。
このイメージは Docker Engine を実⾏するための最⼩ディストリビューションです。
Toolbox をインストールしたら、VirtualBox と必要に応じて boot2docker.iso イメージが⽤意されます。また、Machine がサポートするあらゆるシステム上へプロビジョン可能です。
この例では Mac OS X もしくは Windows の利⽤を想定していますが、Docker Machine は Linux
システム上も直接インストール可能です 。

2.5.2 Swarm トークンをホスト上で生成
Swarm の設定を始める前に、Docker Engine の動くホストをプロビジョニングする必要があります。Machineをインストールしたホスト上のターミナルを開きます。それから local という名称のホストをプロビジョニングするため、次のように実⾏します。
docker-machine create -d virtualbox local
この例では VirtualBox を指定していますが、Digital Ocean やデータセンタ内のホストでも簡単に作成できます。
local の値はホスト名です。作成したら、⾃分のターミナル上で local ホストと通信できるように、環境変数を指定します。
eval "$(docker-machine env local)"
各 Swarm ホストでは、Engine の設定時にトークンも指定します。このトークンは Swarm ディスカバリ・バッ
クエンドが Swarm クラスタの適切なノードであることを認識するために必要です。クラスタ⽤のトークンを作成するには、swarm イメージを実⾏します。
docker run swarm create- 30 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.5 Docker MachineでSwarmクラスタ構築

Unable to find image 'swarm' locally
1.1.0-rc2: Pulling from library/swarm
892cb307750a: Pull complete
fe3c9860e6d5: Pull complete
cc01ef3f1fbc: Pull complete
b7e14a9c9c72: Pull complete
3ec746117013: Pull complete
703cb7acfce6: Pull complete
d4f6bb678158: Pull complete
2ad500e1bf96: Pull complete
Digest: sha256:f02993cd1afd86b399f35dc7ca0240969e971c92b0232a8839cf17a37d6e7009
Status: Downloaded newer image for swarm
0de84fa62a1d9e9cc2156111f63ac31f ←この文字列がトークン
swarm create コマンドの出⼒結果がクラスタ⽤のトークンです。このトークンを安全な場所にコピーして覚えておきます。このトークンは、Swarm ノードのプロビジョニング時や、そのノードをクラスタに追加する時のクラス
タ ID として使います。トークンは、この後で環境変数 SWARM_CLUSTER_TOKEN として参照します。

2.5.3 Swarm ノードのプロビジョン
クラスタの全てのノードは Engine をインストールしている必要があります。Machine で SWARM_CLUSTER_TOKENを使えば、Machine でコマンドを１つ実⾏するだけで、Engine のホストをプロビジョニングし、Swarm のノードとして設定された状態にします。新しい仮想マシンを Swarm マネージャ・ノードの swarm-manager として作成します。
docker-machine create \-d virtualbox \--swarm \--swarm-master \--swarm-discovery token://SWARM_CLUSTER_TOKEN \swarm-manager
次に追加⽤のノードをプロビジョニングします。ここでも SWARM_CLUSTER_TOKEN を指定する必要があります。そして、各ホストには HOST_NODE_NAME でユニークな名前を付ける必要があります。
docker-machine create \-d virtualbox \--swarm \--swarm-discovery token://SWARM_CLUSTER_TOKEN \HOST_NODE_NAME
例えば、HOST_NODE_NAME には node-01 のような名前を指定するでしょう。
ここまで実⾏したコマンドは Docker Hub が提供している Docker Swarm のホステッド・ディス
カバリ・サービスに依存しています。もしも Docker Hub あるいはネットワークに問題があれば、これらのコマンド実⾏に失敗するでしょう。サービスが利⽤可能かどうか、Docker Hub ステータ
ス・ページをご確認ください。Docker Hub で問題がある場合は復旧まで待つか、あるいは、別のディスカバリ・バックエンドの設定をご検討ください。

2.5.4 Machine でノード環境に接続
Machine 接続先のホストを環境変数で指定するには、env サブコマンドの利⽤が⼀般的です。

- 31 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

2.5 Docker MachineでSwarmクラスタ構築

eval "$(docker-machine env local)"Docker Machine には、env コマンドで Swarm ノードに接続するための、特別な --swarm フラグがあります。
docker-machine env --swarm HOST_NODE_NAME
export DOCKER_TLS_VERIFY="1"export DOCKER_HOST="tcp://192.168.99.101:3376"
export DOCKER_CERT_PATH="/Users/mary/.docker/machine/machines/swarm-manager"
export DOCKER_MACHINE_NAME="swarm-manager"# Run this command to configure your shell:# eval $(docker-machine env --swarm HOST_NODE_NAME)
シェル上の操作を swarm-manager という名称の Swarm ノードに切り替えるには、次のように実⾏します。
eval "$(docker-machine env --swarm swarm-manager)"
これで Docker CLI を使ってクラスタと相互に通信できるようになりました。
docker info
Containers: 2
Images: 1
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 1
swarm-manager: 192.168.99.101:2376└ Status: Healthy└ Containers: 2└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 1.021 GiB└ Labels: executiondriver=native-0.2, kernelversion=4.1.13-boot2docker,
operatingsystem=Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Nov 20 19:33:59 UTC 2015,
provider=virtualbox, storagedriver=aufs
CPUs: 1
Total Memory: 1.021 GiB
Name: swarm-manager- 32 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.1 アプリケーションのアーキテクチャを学ぶ

３章

3 章 Swarm のスケール

ここで扱うサンプルは、Swarm クラスタ上に投票アプリケーションをデプロイします。例では典型的な開発プロ
セスを使って説明します。インフラを構築すると、Swarm クラスタの作成やクラスタ上にアプリケーションをデプロイできるようになります。
投票アプリケーションの構築と⼿動でデプロイした後、Docker Compose ファイルを作成します。あなた（もしくは誰か）はこのファイルを使い、アプリケーションの更なるデプロイやスケールが可能になります。
このサンプルは、新⼈ネットワーク管理者向けに書かれています。基本的な Linux システムのスキルを持ち、ssh
経験、Amazon が提供する AWS サービスに対する理解があることでしょう。また、Git のような知識があれば望ましいのですが、必須ではありません。以下の⼿順でサンプルを進めていくのに、約１時間ほどかかります。

3.1 アプリケーションのアーキテクチャを学ぶ
このセクションでは、Swarm をスケールさせるサンプルについて学びます。

3.1.1 サ ンプルの背景を学ぶ
あなたの会社はペットフード会社であり、スーパーボウルのコマーシャル枠を購⼊しようとしています。コマー
シャルでは、視聴者に対して調査のために⽝か猫かの投票を呼びかけます。あなたはウェブ投票システムを開発します。
この調査では 100 万⼈もの⼈々が投票してもウェブサイトが⽌まらないようにする必要があります。結果をリア
ルタイムで知る必要は無く、結果は会社のプレスリリースで公開します。しかし、どれだけ投票されたかは、投票の度に確実に把握する必要があります。

3.1.2 ア プリケーションのアーキテクチャを理解
投票アプリケーションは複数のマイクロサービスで構成されます。並列なウェブ・フロントエンドを使い、ジョブを⾮同期のバックグラウンド・ワーカに送ります。アプリケーションは任意に⼤きくスケール可能な設計です。
次の図はアプリケーションのハイレベルなアーキテクチャです。

- 33 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.1 アプリケーションのアーキテクチャを学ぶ

全てのサーバで Docker Engine が動いています。アプリケーション全体は完全に Docker 化（Dockerized）しており、全てのサービスをコンテナ内で実⾏します。
フロントエンドはロードバランサと N 台のフロントエンド・インスタンスで構成します。各フロントエンドは
ウェブ・サーバと Redis キューで構成します。ロードバランサは任意の数のウェブ・コンテナを背後で扱えます（frontend01 〜 frontendN）。Web コンテナは２つの選択肢から投票するシンプルな Python アプリケーションです。キューに⼊った投票は datasotre 上の Redis コンテナに送られます。
フロントエンドの背後にはワーカ層があり、別々のノードが動いています。この層は次の機能があります。

 Redis コンテナをスキャン 投票のキューを回収 重複投票を防ぐために投票結果を複製
 結果を Postgres データベースにコミットする
フロントエンドと同様に、ワーカ層も任意にスケールできます。ワーカの数とフロントエンドの数は、お互い独⽴しています。
Docker 化したマイクロサービスのアプリケーションを、コンテナ・ネットワークにデプロイします。コンテナ
・ネットワークは Docker Engine の機能です。これは複数の Docker ホスト上を横断して複数のコンテナ間で通信を可能にします。

3.1.3 Swarm クラスタのアーキテクチャ
アプリケーションをサポートするのは、次の図のように、１つの Swarm マネージャと４つのノードで構成する- 34 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.1 アプリケーションのアーキテクチャを学ぶ

設計の Swarm クラスタです。

クラスタの４つのノード全てで Docker デーモンが動作します。Swarm マネージャと ロードバランサも同様です。Swarm マネージャはクラスタの⼀部であり、アプリケーションの範囲外であると考えます。１つのホスト上でConsul サーバはキーストア（keystore）として動作します。これは Swarm ディスカバリ⽤と、コンテナ・ネット
ワーク⽤の両⽅のためです。ロードバランサはクラスタ内に設置可能ですが、今回のサンプルでは扱いません。
サンプルとアプリケーションのデプロイを完了したら、皆さんの環境は下図のようになります。

- 35 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.1 アプリケーションのアーキテクチャを学ぶ

この図にあるように、クラスタの各ノードでは次のコンテナを実⾏します。
frontend01：
 コンテナ：voitng-app（投票アプリ）
 コンテナ：Swarm エージェント
frontend02：
 コンテナ：voitng-app（投票アプリ）
 コンテナ：Swarm エージェント
worker01：
 コンテナ：voitng-app-worker（投票ワーカ・アプリ）
 コンテナ：Swarm エージェント
dbstore： コンテナ：voting-app-result-app（投票結果⽤アプリ）
 コンテナ：db (Postgres 9.4)
 コンテナ：redis
 コンテナ：Swarm エージェント
アプリケーションのデプロイ時、ローカル・システムを設定したら、ローカルのブラウザ上でアプリケーション
をテスト可能です。プロダクションでは、もちろんこの⼿順は不要です。

次のステップこれでアプリケーションのアーキテクチャを理解しました。デプロイするにあたり、どのようなネットワーク設定をサポートする必要があるのか理解したと思います。次のステップでは、このサンプルが使うネットワーク・イ
ンフラをデプロイします。

- 36 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

3.2 インフラのデプロイ
このステップでは、複数の Docker ホストを作成し、そこでアプリケーション・スタックを実⾏します。進む前に、アプリケーション・アーキテクチャを学ぶ必要があります。

3.2.1 構 築手順について以降のサンプルを実⾏する想定システムは、Mac あるいは Windows です。システム上で Docker Machine を経
由して VirtualBox 仮想マシンをローカルにプロビジョニングし、Docker Engine の docker コマンドを使えるようにします。作業は６つの VirtualBox 仮想マシンをインストール予定です。
今回のサンプルでは Docker Machine を使いますが、任意のインフラ上で実⾏できます。希望するインフラ上であれば、どこでも環境を構築できる設計です。例えば、Azure や Digital Ocean などのようなパブリックのクラウ
ド・プラットフォーム上で実⾏できるだけでなく、データセンタ上のオンプレミスや、ノート PC 上のテスト環境
ですら動かせます。
なお、これらの⼿順では複数の値を設定するにあたり、⼀般的な bash コマンド代⼊技術を使います。次のコマンドを例に考えましょう。
$ eval $(docker-machine env keystore)
Windows 環境では、このような代⼊指定に失敗します。Widows 上で実⾏する場合は、この$(docker-machine env
keystore)を実際の値に置き換えてください。

3.2.2 手 順
タスク１ ：keystore（ キース トア） サー バの作 成Docker コンテナ・ネットワークと Swarm ディスカバリを有効化するために、キーバリュー・ストアのデプロイが必要です。キーストアはディスカバリ・バックエンドとして、Swarm マネージャが使うクラスタのメンバ⼀覧を常に更新し続けます。Swarm マネージャはこの⼀覧を使い、ノードにタスクを割り当てます。
オーバレイ・ネットワークはキーバリュー・ストアが必要です。キーバリュー・ストアはネットワーク状態を保持するために使います。ネットワーク状態には、ディスカバリ、ネットワーク、エンドポイント、IP アドレス等を
含みます。
*1

様々なバックエンドをサポートしています。今回のサンプルでは Consul コンテナ を使います。
1. keystore という名称の「マシン」を作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=consul" keystore
Engine デーモンにオプションを指定するには --engine-opt フラグを使います。Engine インスタンスをラベル付けするのに使います。
2. ローカルのシェルを keystore Docker ホストに接続します。
$ eval $(docker-machine env keystore)*1 https://www.consul.io/- 37 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

3. consul コンテナを起動します。
$ docker run --restart=unless-stopped -d -p 8500:8500 -h consul progrium/consul -server -bootstrap-p フラグはコンテナ上のポート 8500 を公開します。これは Consul サーバがリッスンするためです。また、サーバ上では他のポートも公開します。確認するには docker ps コマンドを使います。
$ docker ps
CONTAINER ID

IMAGE

NAMES
372ffcbc96ed
progrium/consul
8301-8302/udp, 0.0.0.0:8500->8500/tcp

...

PORTS

...
53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp,
dreamy_ptolemy

4. curl コマンドを使い、ノードが応答するかテストします。
$ curl $(docker-machine ip keystore):8500/v1/catalog/nodes[{"Node":"consul","Address":"172.17.0.2"}]

タスク２ ：Swarm マ ネージ ャの作 成
このステップでは、Swarm マネージャを作成し、keystore インスタンスに接続します。Swarm マネージャ・コ
ンテナは Swarm クラスタの⼼臓部です。Docker コマンドを受け取り、クラスタに送り、クラスタ間のスケジュー
リングをする役割を持ちます。実際のプロダクションへのデプロイでは、⾼可⽤性(HA)のためにセカンダリのSwarm レプリカ・マネージャを設定すべきでしょう。
--eng-opt フラグを使い cluster-store と cluster-advertise オプションが keystore サーバを参照するようにします。これらのオプションは後にコンテナ・ネットワークの作成時に使います。
1. manager ホストを作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=manager" \--engine-opt="cluster-store=consul://$(docker-machine ip keystore):8500" \--engine-opt="cluster-advertise=eth1:2376" manager
デーモンに対して manager ラベルも指定します。
2. ローカルのシェルを manager Docker ホストに向けます。
$ eval $(docker-machine env manager)
3. Swarm マネージャのプロセスを開始します。
$ docker run --restart=unless-stopped -d -p 3376:2375 \-v /var/lib/boot2docker:/certs:ro \swarm manage --tlsverify \--tlscacert=/certs/ca.pem \--tlscert=/certs/server.pem \--tlskey=/certs/server-key.pem \consul://$(docker-machine ip keystore):8500
このコマンドは boot2docker.iso あるいはマネージャ⽤の TLS 証明書を作成します。これはクラスタ上の他マ- 38 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

シンにマネージャが接続する時に使います。
4. ホスト上で Docker デーモンのログを参照し、正常に動いているか確認します。
$ docker-machine ssh manager<-- 出力を省略 -->docker@manager:~$ tail /var/lib/boot2docker/docker.log
time="2016-04-06T23:11:56.481947896Z" level=debug msg="Calling GET /v1.15/version"time="2016-04-06T23:11:56.481984742Z" level=debug msg="GET /v1.15/version"time="2016-04-06T23:12:13.070231761Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:12:33.069387215Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:12:53.069471308Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:13:13.069512320Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:13:33.070021418Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:13:53.069395005Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:14:13.071417551Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
time="2016-04-06T23:14:33.069843647Z" level=debug msg="Watch triggered with 1 nodes" discovery=consul
出⼒内容から consul と manager が正常に通信できているのが分かります。
5. Docker ホストから抜けます。
docker@manager:~$ exit

タスク３ ：ロ ードバ ランサ の追加
Interlock*1 アプリケーションと Nginx をロードバランサとして使います。ロードバランサ⽤のホストを作る前に、
Nginx で使う設定を作成します。
1. ローカルホスト上に config ディレクトリを作成します。
2. config ディレクトリに変更します。
$ cd config
3. Swarm マネージャ・ホストの IP アドレスを取得します。
例：$ docker-machine ip manager
192.168.99.101
4. 任意のエディタで config.toml ファイルを作成し、次の内容をファイルに書き込みます。

*1 https://github.com/ehazlett/interlock- 39 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

ListenAddr = ":8080"
DockerURL = "tcp://SWARM_MANAGER_IP:3376"
TLSCACert = "/var/lib/boot2docker/ca.pem"
TLSCert = "/var/lib/boot2docker/server.pem"
TLSKey = "/var/lib/boot2docker/server-key.pem"[[Extensions]]
Name = "nginx"
ConfigPath = "/etc/conf/nginx.conf"
PidPath = "/etc/conf/nginx.pid"
MaxConn = 1024
Port = 80
5. 設定ファイルにおいて、SWARM_MANAGE_IP は⼿順３で取得した manager の IP アドレスに書き換えてください。
この値はロードバランサがマネージャのイベント・ストリームを受信するために使います。
6. config.toml ファイルを保存して閉じます。
7. ロードバランサ⽤にマシンを作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=interlock" loadbalancer
8. 環境を loadbalancer に切り替えます。
$ eval $(docker-machine env loadbalancer)
9. interlock コンテナを起動します。
$ docker run \
-P \
-d \
-ti \
-v nginx:/etc/conf \-v /var/lib/boot2docker:/var/lib/boot2docker:ro \-v /var/run/docker.sock:/var/run/docker.sock \-v $(pwd)/config.toml:/etc/config.toml \--name interlock \ehazlett/interlock:1.0.1 \-D run -c /etc/config.toml
このコマンドは現在のディレクトリにある config.toml ファイルを読み込みます。コマンド実⾏後、イメージを実⾏しているのを確認します。
$ docker ps
CONTAINER ID
IMAGE
PORTS
NAMES
d846b801a978
ehazlett/interlock:1.0.1
0.0.0.0:32770->8080/tcp interlock

COMMAND

CREATEDSTATUS"/bin/interlock -D ru"

2 minutes ago

Up 2 minutes

イメージが実⾏中でなければ、docker ps -a を実⾏してシステム上で起動した全てのイメージを表⽰します。そして、コンテナが起動に失敗していれば、ログを取得できます。
- 40 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ$ docker logs interlock
INFO[0000] interlock 1.0.1 (000291d)
DEBU[0000] loading config from: /etc/config.toml
FATA[0000] read /etc/config.toml: is a directory
このエラーであれば、通常は config.toml ファイルがある同じ config ディレクトリ内で docker run を実⾏したのが原因でしょう。コマンドを実⾏し、次のような衝突が表⽰する場合があります。
docker: Error response from daemon: Conflict. The name "/interlock" is already in use by container
d846b801a978c76979d46a839bb05c26d2ab949ff9f4f740b06b5e2564bae958. You have to remove (or rename) that
container to be able to reuse that name.
このような時は、docker rm interlock で interlock コンテナを削除し、再度試みてください。
10. ロードバランサ上で nginx コンテナを起動します。
$ docker run -ti -d \-p 80:80 \--label interlock.ext.name=nginx \--link=interlock:interlock \-v nginx:/etc/conf \--name nginx \nginx nginx -g "daemon off;" -c /etc/conf/nginx.conf

タスク４ ：他 の Swarm ノ ード を作成
Swarm クラスタのホストを「ノード」と呼びます。既にマネージャ・ノードを作成しました。ここでの作業は、各ノード⽤の仮想ホストを作成します。３つのコマンドが必要です。

 Docker Machine でホストを作成
 ローカル環境から新しい環境に切り替え
 ホストを Swarm クラスタに追加
Mac あるいは Windows 以外で構築している場合、swarm ノードに追加するには join コマンドを実⾏するだけです。それだけで Consul ディスカバリ・サービスに登録します。また、ノードの作成時には次の例のようにラベ
ルを付けます。
--engine-opt="label=com.function=frontend01"
これらのラベルはアプリケーション・コンテナを開始した後に使います。以降のコマンドで、各ノードに対してラベルを適⽤します。
1. frontend01 ホストを作成し、Swarm クラスタに追加します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=frontend01" \--engine-opt="cluster-store=consul://$(docker-machine ip keystore):8500" \--engine-opt="cluster-advertise=eth1:2376" frontend01$ eval $(docker-machine env frontend01)$ docker run -d swarm join --addr=$(docker-machine ip frontend01):2376 \- 41 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

consul://$(docker-machine ip keystore):8500
2. frontend02 仮想マシンを作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=frontend02" \--engine-opt="cluster-store=consul://$(docker-machine ip keystore):8500" \--engine-opt="cluster-advertise=eth1:2376" frontend02$ eval $(docker-machine env frontend02)$ docker run -d swarm join --addr=$(docker-machine ip frontend02):2376 \consul://$(docker-machine ip keystore):8500
3. worker01 仮想マシンを作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=worker01" \--engine-opt="cluster-store=consul://$(docker-machine ip keystore):8500" \--engine-opt="cluster-advertise=eth1:2376" worker01$ eval $(docker-machine env worker01)$ docker run -d swarm join --addr=$(docker-machine ip worker01):2376 \consul://$(docker-machine ip keystore):8500
4. dbstore 仮想マシンを作成します。
$ docker-machine create -d virtualbox --virtualbox-memory "2000" \--engine-opt="label=com.function=dbstore" \--engine-opt="cluster-store=consul://$(docker-machine ip keystore):8500" \--engine-opt="cluster-advertise=eth1:2376" dbstore$ eval $(docker-machine env dbstore)$ docker run -d swarm join --addr=$(docker-machine ip dbstore):2376 \consul://$(docker-machine ip keystore):8500
5. 動作確認をします。
この時点では、アプリケーションが必要なインフラをデプロイ完了しました。テストは、次のようにマシンが実⾏しているか⼀覧表⽰します。
$ docker-machine ls
NAME
ACTIVE
dbstorefrontend01
frontend02
keystoreloadbalancer manager
worker01*

DRIVER
virtualbox
virtualbox
virtualbox
virtualbox
virtualbox
virtualbox
virtualbox

STATE
Running
Running
Running
Running
Running
Running
Running

URL
tcp://192.168.99.111:2376
tcp://192.168.99.108:2376
tcp://192.168.99.109:2376
tcp://192.168.99.100:2376
tcp://192.168.99.107:2376
tcp://192.168.99.101:2376
tcp://192.168.99.110:2376

SWARM

DOCKERv1.10.3
v1.10.3
v1.10.3
v1.10.3
v1.10.3
v1.10.3
v1.10.3

ERRORS

6. Swarm マネージャが全てのノードを⼀覧表⽰するのを確認します。
$ docker -H $(docker-machine ip manager):3376 info
Containers: 4
Running: 4
Paused: 0
Stopped: 0- 42 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

Images: 3
Server Version: swarm/1.1.3
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 4
dbstore: 192.168.99.111:2376└ Status: Healthy└ Containers: 1└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.004 GiB└ Labels: com.function=dbstore, executiondriver=native-0.2, kernelversion=4.1.19-boot2docker,
operatingsystem=Boot2Docker 1.10.3 (TCL 6.4.1); master : 625117e - Thu Mar 10 22:09:02 UTC 2016,provider=virtualbox, storagedriver=aufs└ Error: (none)└ UpdatedAt: 2016-04-07T18:25:37Z
frontend01: 192.168.99.108:2376└ Status: Healthy└ Containers: 1└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.004 GiB└ Labels: com.function=frontend01, executiondriver=native-0.2, kernelversion=4.1.19-boot2docker,
operatingsystem=Boot2Docker 1.10.3 (TCL 6.4.1); master : 625117e - Thu Mar 10 22:09:02 UTC 2016,provider=virtualbox, storagedriver=aufs└ Error: (none)└ UpdatedAt: 2016-04-07T18:26:10Z
frontend02: 192.168.99.109:2376└ Status: Healthy└ Containers: 1└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.004 GiB└ Labels: com.function=frontend02, executiondriver=native-0.2, kernelversion=4.1.19-boot2docker,
operatingsystem=Boot2Docker 1.10.3 (TCL 6.4.1); master : 625117e - Thu Mar 10 22:09:02 UTC 2016,provider=virtualbox, storagedriver=aufs└ Error: (none)└ UpdatedAt: 2016-04-07T18:25:43Z
worker01: 192.168.99.110:2376└ Status: Healthy└ Containers: 1└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.004 GiB└ Labels: com.function=worker01, executiondriver=native-0.2, kernelversion=4.1.19-boot2docker,
operatingsystem=Boot2Docker 1.10.3 (TCL 6.4.1); master : 625117e - Thu Mar 10 22:09:02 UTC 2016,provider=virtualbox, storagedriver=aufs└ Error: (none)└ UpdatedAt: 2016-04-07T18:25:56ZPlugins:
Volume:Network:
Kernel Version: 4.1.19-boot2docker
Operating System: linux
Architecture: amd64
CPUs: 4
Total Memory: 8.017 GiB
Name: bb13b7cf80e8- 43 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.2 インフラのデプロイ

このコマンドは Swarm ポートに対して処理しているため、クラスタ全体の情報を返します。操作対象は Swarm
マネージャあり、ノードではありません。

次 のステップ
キーストア、ロードバランサ、Swarm クラスタのインフラが動きました。これで投票アプリケーションの構築と実⾏ができます。

- 44 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

3.3 アプリケーションのデプロイ
これまでロードバランサ、ディスカバリ・バックエンド、Swarm クラスタをデプロイ しました。次は投票アプ
リケーションをデプロイしましょう。ここで「Docker 化したアプリケーション」を起動し始めます。
次の図は最終的なアプリケーション設定であり、voteapp オーバレイ・コンテナ・ネットワークも含みます。

この⼿順ではコンテナをネットワークに接続します。この voteapp ネットワークは Consul ディスカバリ・バッ
クエンドを使う全ての Docker ホスト上で利⽤可能です。interlock、nginx、consul、swarm manager コンテナは
voteapp オーバレイ・コンテナ・ネットワークの⼀部なのでご注意ください。

3.3.1 手 順
タスク１ ：ボ リューム とネットワ ークの セット アッ プ
このアプリケーションはオーバレイ・コンテナ・ネットワークとコンテナ・ボリュームに依存します。Docker
Engine は２つの機能を提供します。Swarm manager インスタンス上でどちらも作成可能です。
1. ローカル環境を Swarm manager ホストに向けます。
$ eval $(docker-machine env manager)
クラスタ・ノード上でネットワークを作成したら、ネットワーク全体で参照可能になります。
2. voteapp コンテナ・ネットワークを作成します。
$ docker network create -d overlay voteapp
3. db ストアに切り替えます。

- 45 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ$ eval $(docker-machine env dbstore)
4. db ストア・ノードで新しいネットワークを確認します。
$ docker network ls
NETWORK ID
NAME
e952814f610a
voteapp
1f12c5e7bcc4
bridge3ca38e887cd8
none
3da57c44586b
host

DRIVERoverlaybridgenull
host

5. db-data という名称のコンテナ・ボリュームを作成します。
$ docker volume create --name db-data

タスク２ ：コ ンテナ 化した マイク ロサー ビス の起動
この時点で、マイクロサービスのコンポーネントを起動し、アプリケーションを起動する準備が整いました。ア
プリケーション・コンテナによっては、Docker Hub にある既存イメージを直接ダウンロードして実⾏できます。
その他、⾃分でカスタマイズしたイメージを実⾏したい場合は、構築する必要があります。以下はどのコンテナがカスタム・イメージを使っているか、使っていないかの⼀覧です。

 ロードバランサ・コンテナ：既存イメージ（ehazlett/interlock）
 Redis コンテナ：既存イメージ（公式 redis イメージ） Postgres (PostgreSQL)コンテナ：既存イメージ（公式 postgres イメージ）
 Web コンテナ：カスタム構築イメージ
 Worker コンテナ：カスタム構築イメージ
 Results コンテナ：カスタム構築イメージ
このセクションではクラスタ上のホストに対して、コマンドでこれらコンテナを起動します。 Swarm マネージャに対して命令するためには、各コマンドで -H フラグを使います。
コン ス ト レイ ント

コマンドには -e も含みます。これは Swarm に制限（constraint）を指定するためです。制限はマネージャに対して、function（機能）のラベルに⼀致するノードの指定で使います。ラベルはノードを作成時に設定します。以降のコマンド実⾏時に、制約の値を確認します。
1. Postgres データベース・コンテナを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-v db-data:/var/lib/postgresql/data \-e constraint:com.function==dbstore \--net="voteapp" \--name db postgres:9.4
2. Redis コンテナを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-p 6379:6379 \-e constraint:com.function==dbstore \--net="voteapp" \--name redis redis- 46 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

redis の名前は重要なため、変更しないでください。
3. ワーカ・アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-e constraint:com.function==worker01 \--net="voteapp" \--net-alias=workers \--name worker01 docker/example-voting-app-worker
4. results アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-p 80:80 \--label=interlock.hostname=results \--label=interlock.domain=myenterprise.com \-e constraint:com.function==dbstore \--net="voteapp" \--name results-app docker/example-voting-app-result-app
5. 各フロントエンド・ノード上に、２つの投票アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-p 80:80 \--label=interlock.hostname=vote \--label=interlock.domain=myenterprise.com \-e constraint:com.function==frontend01 \--net="voteapp" \--name voting-app01 docker/example-voting-app-voting-app
そして、別のフロントエンド・ノード上で実⾏します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-p 80:80 \--label=interlock.hostname=vote \--label=interlock.domain=myenterprise.com \-e constraint:com.function==frontend02 \--net="voteapp" \--name voting-app02 docker/example-voting-app-voting-app

タスク３ ：作 業内容 の確認 と/etc/hosts の更 新
このステップでは、Nginx コンテナの設定が適切に⾏われているかを確認します。ロードバランサの動作確認のため、ローカルの /etc/hosts ファイルを変更します。
1. loadbalancer ノードに変更します。
$ eval $(docker-machine env loadbalancer)
2. nginx の設定を表⽰し、内容を確認します。
$ docker exec interlock cat /etc/conf/nginx.conf- 47 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ... 出力を省略 ...
upstream results.myenterprise.com {zone results.myenterprise.com_backend 64k;
server 192.168.99.111:80;}
server {listen 80;
server_name results.myenterprise.com;
location / {proxy_pass http://results.myenterprise.com;}}
upstream vote.myenterprise.com {zone vote.myenterprise.com_backend 64k;
server 192.168.99.109:80;
server 192.168.99.108:80;}
server {listen 80;
server_name vote.myenterprise.com;
location / {proxy_pass http://vote.myenterprise.com;}}
include /etc/conf/conf.d/*.conf;}
http://vote.myenterprise.com サイトの設定は、どちらかのフロントエンド・ノードを指し⽰します。
http://results.myenterprise.com にリクエストしたら、example-voting-app-result-app が稼働している dbstore
ノードに移動します。
1. ローカルホスト上で /etc/hosts ファイルを編集し、これらサイトの名前解決の⾏を追加します。
2. /etc/hosts ファイルを保存して閉じます。
3. nginx コンテナの再起動。
現在の Interlock サーバの設定が Nginx の設定を反映していません。そのため、⼿動で再起動の必要があります。
$ docker restart nginx- 48 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

タスク４ ：ア プリケ ーショ ンのテ スト
これでアプリケーションをテストできます。
1. ブラウザを開き、サイト http://vote.myenterprise.com に移動します。
投票ページ「Cats vs Dogs!」が画⾯に表⽰されます。
2. ２つの選択肢のうち、どちらかに投票します。
3. サイト http://results.myenterprise.com に移動し、結果を表⽰します。
4. 他の選択肢に投票します。
投票した結果が画⾯上に表⽰されます。

追 加作業 ：Docker Compose で デプロ イ
これまでは、各アプリケーションのコンテナを個々に起動しました。しかし、複数コンテナの起動や依存関係の順番に従った起動は、とても煩雑です。例えば、データベースはワーカが起動する前に動いているべきでしょう。
Docker Compose はマイクロサービス・コンテナと依存関係を Compose ファイルで定義します。そして、Compose ファイルを使って全てのコンテナを⼀⻫に起動します。これは追加作業（extra credit）です。
1. 始める前に、起動した全てのコンテナを停⽌します。
a. （作業対象の）ホストをマネージャに向けます。
$ DOCKER_HOST=$(docker-machine ip manager):3376
b. Swarm 上のアプリケーション全てを⼀覧します。
c. 各コンテナを停⽌・削除します。
2. このチュートリアルに従って、⾃分で Compose ファイルの作成を試みます。
Compose ファイルはバージョン２形式を使うのがベストです。各 docker run コマンドを docker-compose.yml
ファイル内のサービスに置き換えます。例えば、次のコマンドがあります。
$ docker -H $(docker-machine ip manager):3376 run -t -d \-e constraint:com.function==worker01 \--net="voteapp" \--net-alias=workers \--name worker01 docker/example-voting-app-worker
これは、次の Compose ファイルに書き換え可能です。

- 49 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

worker:image: docker/example-voting-app-worker
networks:
voteapp:aliases:- workers
通常、Compose はファイルに現れる逆順でサービスの起動を試みます。そのため、あるサービスを他のサービスよりも前に実⾏するには、ファイル中の最後尾にサービスを記述する必要があります。アプリケーションがボリ
ュームやネットワークを使う場合は、ファイルの末尾で宣⾔します。
3. 結果がファイル*1 と⼀致しているか確認します。
4. 問題が無ければ、システム上に docker-compose.yml ファイルを保存します。
5. DOCKER_HOST を Swarm マネージャに向けます。
$ DOCKER_HOST=$(docker-machine ip manager):3376
6. docker-compose.yml と同じディレクトリで、サービスを起動します。
$ docker-compose up -dCreating network "scale_voteapp" with the default driverCreating volume "scale_db-data" with default driver
Pulling db (postgres:9.4)...
worker01: Pulling postgres:9.4... : downloaded
dbstore: Pulling postgres:9.4... : downloaded
frontend01: Pulling postgres:9.4... : downloaded
frontend02: Pulling postgres:9.4... : downloaded
Creating db
Pulling redis (redis:latest)...
dbstore: Pulling redis:latest... : downloaded
frontend01: Pulling redis:latest... : downloaded
frontend02: Pulling redis:latest... : downloaded
worker01: Pulling redis:latest... : downloaded
Creating redis
Pulling worker (docker/example-voting-app-worker:latest)...
dbstore: Pulling docker/example-voting-app-worker:latest... : downloaded
frontend01: Pulling docker/example-voting-app-worker:latest... : downloaded
frontend02: Pulling docker/example-voting-app-worker:latest... : downloaded
worker01: Pulling docker/example-voting-app-worker:latest... : downloaded
Creating scale_worker_1
Pulling voting-app (docker/example-voting-app-voting-app:latest)...
dbstore: Pulling docker/example-voting-app-voting-app:latest... : downloaded
frontend01: Pulling docker/example-voting-app-voting-app:latest... : downloaded
frontend02: Pulling docker/example-voting-app-voting-app:latest... : downloaded
worker01: Pulling docker/example-voting-app-voting-app:latest... : downloaded
Creating scale_voting-app_1
Pulling result-app (docker/example-voting-app-result-app:latest)...
dbstore: Pulling docker/example-voting-app-result-app:latest... : downloaded*1 https://docs.docker.com/swarm/swarm_at_scale/docker-compose.yml- 50 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

frontend01: Pulling docker/example-voting-app-result-app:latest... : downloaded
frontend02: Pulling docker/example-voting-app-result-app:latest... : downloaded
worker01: Pulling docker/example-voting-app-result-app:latest... : downloaded
Creating scale_result-app_1
7. docker ps コマンドで Swarm クラスタ上のコマンドを確認します。
$ docker -H $(docker-machine ip manager):3376 ps
CONTAINER ID
IMAGE
COMMAND
CREATEDSTATUS
PORTS
NAMES
b71555033caa
docker/example-voting-app-result-app "node server.js"
6 seconds ago
Up 4 seconds
192.168.99.104:32774->80/tcp
frontend01/scale_result-app_1
cf29ea21475d
docker/example-voting-app-worker"/usr/lib/jvm/java-7-" 6 seconds ago
Up 4 seconds
worker01/scale_worker_1
98414cd40ab9
redis"/entrypoint.sh redis" 7 seconds ago
Up 5 seconds
192.168.99.105:32774->6379/tcp frontend02/redis
1f214acb77ae
postgres:9.4"/docker-entrypoint.s" 7 seconds ago
Up 5 seconds
5432/tcp
frontend01/db
1a4b8f7ce4a9
docker/example-voting-app-voting-app "python app.py"
7 seconds ago
Up 5 seconds
192.168.99.107:32772->80/tcp
dbstore/scale_voting-app_1
サービスを⼿動で起動した時は、voting-app インスタンスは２つのフロントエンド・ノード上で動作していました。今回はいくつ起動していますか？
8. アプリケーションをスケールするため、voting-app インスタンスを追加します。
$ docker-compose scale voting-app=3
Creating and starting 2 ... done
Creating and starting 3 ... done
スケールアップ後は、クラスタ上のコンテナ⼀覧を再び表⽰します。
9. loadbalancer ノードに変更します。
$ eval $(docker-machine env loadbalancer)
10. Nginx サーバを再起動します。
$ docker restart nginx
11. http://vote.myenterprise.com と http://results.myenterprise.com を再び表⽰して、投票の動作を確認します。
12. 各コンテナのログを表⽰できます。
$ docker logs scale_voting-app_1* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)* Restarting with stat
* Debugger is active!
* Debugger pin code: 285-809-660
192.168.99.103 - - [11/Apr/2016 17:15:44] "GET / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:15:44] "GET /static/stylesheets/style.css HTTP/1.0" 304 192.168.99.103 - - [11/Apr/2016 17:15:45] "GET /favicon.ico HTTP/1.0" 404 - 51 -docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.3 アプリケーションのデプロイ

192.168.99.103 - - [11/Apr/2016 17:22:24] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:37] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:39] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:40] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:41] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:43] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:44] "POST / HTTP/1.0" 200 192.168.99.103 - - [11/Apr/2016 17:23:46] "POST / HTTP/1.0" 200 このログは、ある投票アプリケーション・コンテナの状況を表⽰しています。

次 のステップ
おめでとうございます。マイクロサービスをベースとしたアプリケーションを Swarm クラスタ上に⼿動でデプ
ロイできました。もちろん、全てが上⼿く⾏くとは限りません。どのようにスケールするアプリケーションをデプロイするかを学びましたので、次は Swarm クラスタ上で⼤規模アプリケーション実⾏時のトラブルシューティン
グを学ぶべきでしょう。

- 52 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.4 アプリケーションのトラブルシュート

3.4 アプリケーションのトラブルシュート
何事も失敗するのが、⼈⽣における現実です。これを前提に、障害が発⽣したらどのように対処すべきか考えるのは重要です。以下のセクションでは、いくつかの障害シナリオを扱います。

 Swarm マネージャ障害
 Consul（ディスカバリ・バックエンド）障害 Interlock ロードバランサ障害
 ウェブ（web-vote-app）障害
 Redis 障害
 ワーカ（vote-worker）障害 Postgres 障害
 results-app 障害
 インフラ障害

3.4.1 Swarm マネージャ障害
現在の設定では、Swarm クラスタには１つのホスト上で１つのマネージャ⽤コンテナしかありません。コンテナが終了したりノード障害が発⽣したりしますと、クラスタを管理できなくなるだけでなく、修復や⼊れ替えも不可
能になります。
Swarm マネージャ・コンテナが予期せず終了して障害になった場合、Docker は⾃動的にコンテナの再起動を試みます。これはコンテナ起動時に --restart=unless-stopped に切り替える設定をしたからです。
Swarm マネージャが利⽤不可能になれば、アプリケーションは現状の設定で実⾏し続けます。しかし、Swarm
マネージャが使えるようになるまで、ノードやコンテナをプロビジョンできなくなります。
Docker Swarm は Swarm マネージャの⾼可⽤性をサポートしています。そのため、１つのクラスタ上に２つ以上のマネージャを追加可能です。あるマネージャがプライマリ・マネージャとして選ばれたら、その他のものはセカンダリになります。プライマリ・マネージャで障害が発⽣したら、他のセカンダリから新しいプライマリ・マネ
ージャが選び出され、クラスタの操作をし続けることが可能になります。⾼可⽤性に対応した Swarm マネージャ
を複数デプロイする場合は、インフラ上で複数の領域を横断する障害発⽣を考慮したほうが良いでしょう。

3.4.2 Consul（ディスカバリ・バ ックエンド）障害
この Swarm クラスタは、クラスタのディスカバリ・サービスとして、１つのノード上で Consul コンテナを１つデプロイしました。このセットアップ⽅法では、もし Consul コンテナを終了するかノード障害が発⽣しても、現在の状態のままアプリケーションを実⾏できるかもしれません。しかしながら、クラスタ管理に関する処理は障害になります。障害範囲は、クラスタ上に新しいコンテナの登録ができなくなり、クラスタに対して設定確認も⾏えません。
consul コンテナが予期せず終了して障害になった場合、Docker は⾃動的にコンテナの再起動を試みます。これはコンテナ起動時に --restart=unless-stopped に切り替える設定をしたからです。
consul、etcd、Zookeeper の各ディスカバリ・サービス・バックエンドは、様々な⾼可⽤性のオプションをサポートしています。これらには Paxos/Raft クォーラムが組み込まれています。⾼可⽤性に対応した設定をするには、あなたが選んだディスカバリ・サービス・バックエンドに対する既存のベスト・プラクティスを確認すべきです。
⾼可⽤性のために複数のディスカバリ・サービス・バックエンドをデプロイするのであれば、インフラ上で複数の領域に横断した障害発⽣への対処を考えるべきです。
- 53 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.4 アプリケーションのトラブルシュート

１つのディスカバリ・バックエンド・サービスで Swarm クラスタを操作する場合、このサービスが停⽌すると修復不可能になります。そのような場合は、新しいディスカバリ・バックエンド⽤のインスタンスを起動し直し、クラスタの各ノード上で Swarm エージェントを実⾏し直す必要があります。

3.4.3 障 害の取り扱い
コンテナの障害には様々な理由が考えられます。しかしながら、Swarm はコンテナで障害が発⽣しても再起動を試みません。
コンテナの障害発⽣時、⾃動的に再起動する⽅法の１つは、コンテナ起動時に --restart=unless-stopped フラ
グを付けることです。これはローカルの Docker デーモンに対して、コンテナで不意な終了が発⽣した場合に再起動するよう命令します。これが正常に機能するのは、コンテナを実⾏するノードと Docker デーモンが正常に稼働し続ける状況のみです。コンテナを実⾏するホスト⾃⾝で障害が発⽣したら、コンテナを再起動できません。あるいは、Docker デーモン⾃⾝が障害となっているでしょう。
別の⽅法としては、外部のツール（クラスタ外にあるツール）を使ってアプリケーションの状態を監視し、適切なサービス・レベルを維持する⽅法があります。サービス・レベルとは「少なくともウェブサーバのコンテナ 10動かす」といったものです。このシナリオでは、ウェブ・コンテナの実⾏数が 10 以下になれば、ツールが何らかの⽅法で⾜りない数だけコンテナの起動を試みます。
今回のサンプル投票アプリケーションでは、フロントエンドはロードバランサがあるためスケーラブル（スケール可能）です。２つのウェブ・コンテナで障害が発⽣すると（あるいは実⾏している AWS ホスト⾃⾝での障害が起これば）、ウェブ・コンテナに対するリクエストがあってもロードバランサは障害対象へのルーティングを停⽌し、別の経路に振り分けできます。ロードバランサの背後にｎ個のウェブ・コンテナを起動できますので、この⽅法は⾼い拡張性を持つと⾔えるでしょう。

3.4.4 Interlock ロードバランサ障害
今回の例では、１つのノード上で１つの interlock ロードバランサを実⾏する環境を構築しました。このセットアップ⽅法では、コンテナが終了するかノード障害が発⽣したら、アプリケーションはサービスに対するリクエス
トを受け付けできなくなり、アプリケーションが利⽤不可能になります。
interlock コンテナが不意に終了すると障害になり、Docker は⾃動的に再起動を試みます。これはコンテナ起動
時に --restart=unless-stopped フラグを付け付けたからです。
⾼可⽤性のある Interlock ロードバランサを構築可能です。複数のノード上に複数の Interlock コンテナを実⾏する⽅法があります。後は DNS ラウンドロビンの使⽤や、その他の技術により、Interlock コンテナに対するアクセ
スを負荷分散します。この⽅法であれば、１つの Interlock コンテナやノードがダウンしたとしても、他のサービスがリクエストを処理し続けます。
複数の Interlock ロードバランサをデプロイする場合は、インフラ上で複数の領域に横断した障害発⽣への対処を考えるべきです。

3.4.5 ウェ ブ（web-vote-app）障害
今回の環境では、２つのノードで２つのウェブ投票⽤コンテナを実⾏するように設定しました。これらは Interlock
ロードバランサの背後にあるため、受信した接続は両者にまたがって分散されます。
もし１つのウェブコンテナもしくはノードで障害が発⽣しても、ロードバランサは⽣存しているコンテナに全てのトラフィックを流し続けますので、サービスは継続します。障害のあったインスタンスが復旧するか、あるいは追加した所に切り替えれば、受信したリクエストを適切に処理するようロードバランサの設定を変更します。
最も⾼い可⽤性を考えるのであれば、２つのフロントエンド・ウェブ・サービス（frontend01 と frontend02）
をインフラ上の異なった障害ゾーンへデプロイすることになるでしょう。あるいは、更なるデプロイの検討も良いかもしれません。
- 54 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.4 アプリケーションのトラブルシュート

3.4.6 Redis 障害
redis コンテナで障害が発⽣したら、⼀緒に動作している web-vote-app コンテナも正常に機能しなくなります。
⼀番良い⽅法は対象インスタンスの正常性を監視するよう設定し、各 Redis インスタンスに対して正常な書き込みができるかどうか確認することです。もし問題のある redis インスタンスが発⾒されれば、web-vote-app と redisの連係を切り離し、復旧作業にあたるべきです。

3.4.7 ワ ーカ（vote-worker）障害
ワーカ・コンテナが終了するか、実⾏しているノードで障害が発⽣したら、redis コンテナは worker コンテナが復旧するまで投票キューを保持します。ワーカが復旧するまでその状態が維持され、投票も継続できます。
もし worker01 コンテナが不意に停⽌して障害になれば、Docker は⾃動的に再起動を試みます。これはコンテナ
起動時に --restart=unless-stopped フラグを付けたからです。

3.4.8 Postgres 障害
今回のアプリケーションでは HA や Postgres のレプリケーションを実装していません。つまり Postgres コンテ
ナの喪失とは、アプリケーションの障害だけでなく、データの損失または⽋損を引き起こす可能性があります。何らかの Postgres HA やレプリケーションのような実装をすることが望ましい解決策です。

3.4.9 results-app 障 害
results-app コンテナが終了したら、コンテナが復旧するまで結果をブラウザで表⽰できなくなります。それでも
投票データを集めてカウントを継続できるため、復旧は純粋にコンテナを⽴ち上げるだけで済みます。
results-app コンテナは起動時に --restart=unless-stopped フラグを付けています。つまり Docker デーモンは⾃動的にコンテナの再起動を試みます。たとえそれが管理上の停⽌だったとしてもです。

3.4.10 インフラ障害
アプリケーションの障害は、その⽀えとなるインフラによって様々な要因があります。しかしながら、いくつかのベストプラクティスは移⾏の⼿助けや障害の緩和に役⽴つでしょう。
⽅法の１つは、可能な限り多くの障害領域にインフラのコンポーネントを分けてデプロイします。AWS のようなサービスでは、しばしインフラの分散や、複数のリージョン AWS アベイラビリティ・ゾーン（AZ）を横断することです。
Swarm クラスタのアベイラビリティ・ゾーンを増やすには：

 HA ⽤の Swarm マネージャを、異なった AZ にある H ノードにデプロイ
 HA ⽤の Consul ディスカバリ・サービスを、異なった AZ にある HA ノードにデプロイ 全てのスケーラブルなアプリケーションのコンポーネントを、複数の AZ に横断させる
この設定を反映したものが、次の図です。

- 55 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.4 アプリケーションのトラブルシュート

この⼿法であれば AZ 全体を喪失しても、クラスタとアプリケーションを処理可能です。
しかし全く⽌まらない訳ではありません。アプリケーションによっては AWS リージョンを横断して分散されているかもしれません。私たちのサンプルでは、クラスタとアプリケーションを us-west-1 リージョンにデプロイし、データを us-east-1 に置いています。この状態から、更にクラウド・プロバイダを横断するデプロイや、あるいはパブリック・クラウド・プロバイダや⾃分のデータセンタにあるオンプレミスに対して分散することもできるでしょう！
以下の図はアプリケーションとインフラを AWS と Microsoft Azure にデプロイしたものです。ですが、クラウ
ドプロバイダはデータセンタにあるオンプレミスに置き換えても構いません。これらのシナリオでは、ネットワー
クのレイテンシと信頼性がスムーズに動作させるための鍵となります。

- 56 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

3.4 アプリケーションのトラブルシュート- 57 -

docs.docker.jp

16/06/02

４章

4 章 管理とネットワーク

4.1 Docker Swarm の高可用性
Docker Swarm の Swarm マネージャは、クラスタ全体に対する責任を持ち、スケール時は複数 Docker ホストのリソースを管理します。もし Swarm マネージャが停⽌したら、新しいマネージャを作成し、サービス中断に対処しなくてはいけません。
高可用性 (High Availability ) 機能により、Docker Swarm は管理インスタンスのフェイルオーバを丁寧に処理します。この機能を使うには、プライマリ・マネージャ (primary manager) を作成し、複数のレプリカ (replica)イ
ンスタンスを作成できます。
プライマリ・マネージャは、Docker Swarm クラスタとの主な接点です。また、バックアップに⽤いるレプリカ
・インスタンスの作成・通信もできます。レプリカにリクエストしたら、プライマリ・マネージャを⾃動的にプロキシします。プライマリ・マネージャで障害が起これば、レプリカが主導権を取ります。このような⽅法で、クラスタと通信し続けられます。

4.1.1 プ ライマリとレプリカのセットアップ
このセクションは、複数のマネージャを使って Docker Swarm をセットアップする⽅法を説明します。

前 提条件
ここでは Consul、etcd、Zookeeper クラスタのいずれかが必要です。今回の⼿順では、Consul サーバが192.168.42.10:8500 で動作しているものと想定します。サンプルの Swarm は３台のマシンで構成されているものとします。

 manager-1 は 192.168.42.200 上で動作
 manager-2 は 192.168.42.201 上で動作
 manager-3 は 192.168.42.202 上で動作

プ ライマ リ・マ ネージャの 作成
swarm manager コマンドで --replication と --advertise フラグを指定し、プライマリ・マネージャを作成します。
- 58 -

docs.docker.jp

16/06/02

user@manager-1 $ swarm manage -H :4000 <tls-config-flags> --replication \--advertise 192.168.42.200:4000 consul://192.168.42.10:8500/nodes
INFO[0000] Listening for HTTP addr=:4000 proto=tcp
INFO[0000] Cluster leadership acquired
INFO[0000] New leader elected: 192.168.42.200:4000[...]--replication フラグは、Swarm に対して複数のマネージャ設定における⼀部であると伝えます。また、このプ
ライマリ・マネージャは、他のプライマリの役割を持つマネージャ・インスタンスと競合します。プライマリ・マ
ネージャとは、クラスタ管理の権限を持ち、ログを複製し、クラスタ内で発⽣したイベントを複製します。
--advertise オプションは、プライマリ・マネージャのアドレスを指定します。ノードがプライマリに選ばれた
時、Swarm はこのアドレスをクラスタの通知⽤（advertise）に使います。先ほどのコマンド出⼒から分かるように、
新しく選ばれたプライマリ・マネージャは指定したアドレスを使います。

２ つのレ プリカ （複 製）を 作成
プライマリ・マネージャを作ったら、次はレプリカを作成できます。
user@manager-2 $ swarm manage -H :4000 <tls-config-flags> --replication \--advertise 192.168.42.201:4000 consul://192.168.42.10:8500/nodes
INFO[0000] Listening for HTTP
addr=:4000 proto=tcp
INFO[0000] Cluster leadership lost
INFO[0000] New leader elected: 192.168.42.200:4000[...]
このコマンドは 192.168.42.201:4000 上にレプリカ・マネージャを作成します。これは 192.168.42.200:4000 をプライマリ・マネージャとみなしています。
追加で、 ３つめのマネージャ・インスタンスを作成します。
user@manager-3 $ swarm manage -H :4000 <tls-config-flags> --replication--advertise 192.168.42.202:4000 consul://192.168.42.10:8500/nodes
INFO[0000] Listening for HTTP
addr=:4000 proto=tcp
INFO[0000] Cluster leadership lost
INFO[0000] New leader elected: 192.168.42.200:4000[...]
プライマリ・マネージャとレプリカを構成した後は、通常通りに Swarm エージェントを作成できます。

ク ラスタ 内の マシン 一覧
docker info を実⾏したら、次のような出⼒が得られます。
user@my-machine $ export DOCKER_HOST=192.168.42.200:4000 # manager-1 を指し示す
user@my-machine $ docker info
Containers: 0
Images: 25
Storage Driver:Role: Primary <--------- manager-1 is the Primary manager
Primary: 192.168.42.200
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
swarm-agent-0: 192.168.42.100:2375└ Containers: 0- 59 -

docs.docker.jp

16/06/02

└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.053 GiB└ Labels: executiondriver=native-0.2, kernelversion=3.13.0-49-generic, operatingsystem=Ubuntu
14.04.2 LTS, storagedriver=aufs
swarm-agent-1: 192.168.42.101:2375└ Containers: 0└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.053 GiB└ Labels: executiondriver=native-0.2, kernelversion=3.13.0-49-generic, operatingsystem=Ubuntu
14.04.2 LTS, storagedriver=aufs
swarm-agent-2: 192.168.42.102:2375└ Containers: 0└ Reserved CPUs: 0 / 1└ Reserved Memory: 0 B / 2.053 GiB└ Labels: executiondriver=native-0.2, kernelversion=3.13.0-49-generic, operatingsystem=Ubuntu
14.04.2 LTS, storagedriver=aufs
Execution Driver:
Kernel Version:Operating System:
CPUs: 3
Total Memory: 6.158 GiB
Name:
ID:
Http Proxy:
Https Proxy:
No Proxy:
この情報は manager-1 が現在のプライマリであると⽰しています。そして、このプライマリへ接続するのに使うアドレスが表⽰されています。

4.1.2 フェイルオーバ動作のテスト
フェイルオーバ動作をテストするには、特定のプライマリ・マネージャを停⽌します。Ctrl-C や kill を実⾏したら、現在のプライマリ・マネージャ（manager-1）は停⽌します。

自 動フェイル オーバ を待つ
直後に、他のインスタンスが障害を検出し、レプリカがプライマリ・マネージャの主導権を得ます。
例えば、manager-2 のログを確認します。
user@manager-2 $ swarm manage -H :4000 <tls-config-flags> --replication --advertise 192.168.42.201:4000
consul://192.168.42.10:8500/nodes
INFO[0000] Listening for HTTP
addr=:4000 proto=tcp
INFO[0000] Cluster leadership lost
INFO[0000] New leader elected: 192.168.42.200:4000
INFO[0038] New leader elected: 192.168.42.201:4000
INFO[0038] Cluster leadership acquired<--- 新しいプライマリ・マネージャに選出された[...]
これはプライマリ・マネージャ manager-1 で障害が発⽣しました。その後、192.168.42.201:4000 のアドレスを持つ manager-2 のレプリカが障害を検出したため、主導権を（manager-1 から）取り上げてリーダーに選出されました。理由は manager-2 が⼗分な速さで、プライマリ・マネージャとして選出⼿続きを実質的に⾏ったからです。
その結果、manager-2 がクラスタ上のプライマリ・マネージャになりました。
manager-3 を⾒れば、次のようなログが表⽰されるでしょう。

- 60 -

docs.docker.jp

16/06/02

user@manager-3 $ swarm manage -H :4000 <tls-config-flags> --replication \--advertise 192.168.42.202:4000 consul://192.168.42.10:8500/nodes
INFO[0000] Listening for HTTP
addr=:4000 proto=tcp
INFO[0000] Cluster leadership lost
INFO[0000] New leader elected: 192.168.42.200:4000
INFO[0036] New leader elected: 192.168.42.201:4000 <--- manager-2 が新しいプライマリ・マネージャに[...]
この時点で、新しい DOCKER_HOST の値を指定する必要があります。

プ ライマ リに切 り替 え
DOCKER_HOST をプライマリとしての manager-2 に切り替えるには、次のようにします。
user@my-machine $ export DOCKER_HOST=192.168.42.201:4000 # manager-2 を指定
user@my-machine $ docker info
Containers: 0
Images: 25
Storage Driver:Role: Replica <--------- manager-2 はレプリカ
Primary: 192.168.42.200
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
docker コマンドは Docker Swarm プライマリ・マネージャ、あるいは、あらゆるレプリカ上で実⾏できます。
好みによって、 何らかの仕組みを使うことにより、DOCKER_HOST が現在のプライマリ・マネージャを常に⽰すようにも可能です。そうしておけば、フェイルオーバ発⽣の度に、Docker Swarm に対する接続を失うことは無いでしょう。

- 61 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.2 Swarmとコンテナのネットワーク

4.2 Swarm とコンテナのネットワーク
Docker Swarm は Docker のネットワーク機能と完全な互換性があります。互換性の中には複数のホストに対するマルチホスト・ネットワーク機能も含まれます。これは複数の Docker ホストを横断するカスタム・コンテナ・
ネットワークを作成する機能です。
Swarm をカスタム・ネットワークで使う前に、Docker コンテナ・ネットワークの概念に関する情報をお読みください。また、「マルチホスト・ネットワーク機能を始める」セクションのサンプルも試すべきでしょう。

4.2.1 Swarm クラスタにカスタム・ネットワークを作成
マルチホスト・ネットワーク機能を使うにはキーバリュー・ストアが必要です。キーバリュー・ストアはネット
ワークの情報を保持する場所です。ここにはディスカバリ情報、ネットワーク、エンドポイント、IP アドレス等が含まれます。Docker の libkv プロジェクトの成果により、Docker は Consul、Etcd、ZooKeeper の各キーバリュー*1・ストア・バックエンドをサポートします。詳細は libkv プロジェクト をご覧ください。
カスタム・ネットワークを作成するには、キーバリュー・ストア・バックエンドを選択し、⾃分のネットワーク
上に実装する必要があります。それから、Docker Engine デーモンの設定を変更し、キーバリュー・ストアにデータを保管できるようにします。キーバリュー・ストア⽤のサーバを参照するには --cluster-store と--cluster-advertise という２つのパラメータが必要です。
Swarm の各ノード上にあるデーモンの設定変更・再起動を⾏えば、ネットワーク作成の準備が整います。

4.2.2 ネットワークの一覧
以下は、クラスタ上に２のノード node-0 と node-1 がある場合の例です。Swarm ノードからネットワーク⼀覧を表⽰しています。
$ docker network ls
NETWORK ID
NAME
3dd50db9706d
node-0/host
09138343e80e
node-0/bridge
8834dbd552e5
node-0/none
45782acfe427
node-1/host
8926accb25fd
node-1/bridge
6382abccd23d
node-1/none

DRIVER
hostbridgenull
hostbridgenull

このように、各ネットワーク名の接頭語がノード名になっていることが分かります。

4.2.3 ネットワークの作成
デフォルトの Swarm クラスタは、ネットワーク全体を範囲とする overlay ネットワーク・ドライバを使います。
ネットワーク全体を範囲とするドライバを使えば、Swarm クラスタ全体を横断するネットワークを作成できます。
Swarm で overlay ネットワーク作成時は -d オプションを省略できます。
$ docker network create swarm_network
42131321acab3233ba342443Ba4312$ docker network ls
NETWORK ID
NAME
3dd50db9706d
node-0/host
09138343e80e
node-0/bridge

DRIVER
hostbridge*1 https://github.com/docker/libkv- 62 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

8834dbd552e5
42131321acab
45782acfe427
8926accb25fd
6382abccd23d
42131321acab

node-0/none
node-0/swarm_network
node-1/hostnode-1/bridge
node-1/none
node-1/swarm_network

4.2 Swarmとコンテナのネットワーク

null
overlayhost
bridgenull
overlay

ここで表⽰されているように、２つのノード上に node-0/swarm_network と node-1/swarm_network という同じ IDを持つネットワークがあります。これはクラスタに作成したネットワークであり、全てのノード上でアクセス可能なものです。
ローカルな範囲でネットワークを作成したい場合は（例えば、ブリッジ・ドライバを使いたい時）、 <ノード名>/<
名前> の形式でなければ、ランダムに選んだノード上でネットワークを作成します。
$ docker network create node-0/bridge2 -b bridge
921817fefea521673217123abab223$ docker network create node-1/bridge2 -b bridge5262bbfe5616fef6627771289aacc2$ docker network ls
NETWORK ID
NAME
DRIVER
3dd50db9706d
node-0/host
host09138343e80e
node-0/bridge
bridge8834dbd552e5
node-0/none
null
42131321acab
node-0/swarm_network overlay
921817fefea5
node-0/bridge2
bridge45782acfe427
node-1/host
host
8926accb25fd
node-1/bridge
bridge6382abccd23d
node-1/none
null
42131321acab
node-1/swarm_network overlay
5262bbfe5616
node-1/bridge2
bridge4.2.4 ネットワークの削除
ネットワークの削除は、ネットワーク ID かネットワーク名を使えます。異なる２つのネットワークが同じ名前の場合は、 <ノード名>/<名前> を使えます。
$ docker network rm swarm_network
42131321acab3233ba342443Ba4312$ docker network rm node-0/bridge2
921817fefea521673217123abab223$ docker network ls
NETWORK ID
NAME
3dd50db9706d
node-0/host
09138343e80e
node-0/bridge
8834dbd552e5
node-0/none
45782acfe427
node-1/host
8926accb25fd
node-1/bridge
6382abccd23d
node-1/none
5262bbfe5616
node-1/bridge2

DRIVER
hostbridgenull
hostbridgenull
bridgeswarm_network は各ノードから削除されましたが、bridge2 は node-0 からのみ削除されました。

- 63 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.3 Docker Swarm ディスカバリ

4.3 Docker Swarm ディスカバリ
Docker Swarm は複数のディスカバリ・バックエンドに対応しています。Docker Swarm はホステット・ディス
カバリ・サービス（hosted discovery service）が利⽤可能です。このサービスはクラスタ上の IP アドレスの⼀覧を保持します。このセクションでは利⽤可能な様々なホステット・ディスカバリを紹介します。

4.3.1 分 散キーバリュー・ストアの利用
Swarm でノードをディスカバリ（発⾒）するのに推奨される⽅法は、Docker による libkv プロジェクトの利⽤です。libkv プロジェクトとは既存の分散キーバリュー・ストア上の抽象化レイヤです。この原稿を書いている時点で、プロジェクトがサポートしているのは次の通りです。

 Consul 0.5.1 以上
 Etcd 2.0 以上
 ZooKeeper 3.4.5 以上
libkv についてやサポートしているバックエンドに対する技術的な詳細は、 libkv プロジェクト*1 をご覧ください。

ホ ステッ ト・ ディス カバリ ・キーストア を使用

1. 各ノードで Swarm エージェントを起動します。
ノードの IP アドレスは Swarm マネージャがアクセス可能であれば⼗分であり、パブリックな IP アドレスを持つ必要はありません。⼤きなクラスタになれば、Swarm に対するノードの参加が、ディスカバリ時に過負荷となる可能性があります。例えば、沢⼭のノードをスクリプトで登録する場合や、ネットワーク障害から復旧する時です。
この影響によりディスカバリが失敗するかもしれません。そのような場合は、 --delay オプションで遅延上限を指定できます。そうすると、Swarm への登録がランダムに遅延して⾏われますが、指定した時間を上回ることはあり
ません。
Etcd:
swarm join --advertise=<node_ip:2375> etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>
Consul:swarm join --advertise=<node_ip:2375> consul://<consul_addr>/<optional path prefix>
ZooKeeper:swarm join --advertise=<node_ip:2375> zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix>
2. Swarm マネージャをサーバもしくはノート PC 上で起動します。
Etcd:*1 https://github.com/docker/libkv- 64 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.3 Docker Swarm ディスカバリ

swarm manage -H tcp://<swarm_ip:swarm_port> etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>
Consul:swarm manage -H tcp://<swarm_ip:swarm_port> consul://<consul_addr>/<optional path prefix>
ZooKeeper:swarm manage -H tcp://<swarm_ip:swarm_port> zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path
prefix>3. 通常の Docker コマンドを実⾏します。
docker -H tcp://<swarm_ip:swarm_port> info
docker -H tcp://<swarm_ip:swarm_port> run ...
docker -H tcp://<swarm_ip:swarm_port> ps
docker -H tcp://<swarm_ip:swarm_port> logs ...
...
4. クラスタ上のノード⼀覧を表⽰します。
Etcd:
swarm list etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix><node_ip:2375>
Consul:swarm list consul://<consul_addr>/<optional path prefix><node_ip:2375>
ZooKeeper:swarm list zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix><node_ip:2375>

分 散キー バリュ ー・ ディス カバリ に TLS を 使う
分散キーバリュー・ストアと安全に通信できるようにするため、TLS を利⽤できます。ストアへ安全に接続するには、Swarm クラスタにノードが join（参加）する時に使う証明書を⽣成しなくてはいけません。証明書に対応しているのは Consul と Etcd のみです。以下は Consul を使う例です。
swarm join \--advertise=<node_ip:2375> \--discovery-opt kv.cacertfile=/path/to/mycacert.pem \--discovery-opt kv.certfile=/path/to/mycert.pem \--discovery-opt kv.keyfile=/path/to/mykey.pem \consul://<consul_addr>/<optional path prefix>
これは Swarm の manage と list コマンドを使う場合も同様です。

- 65 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.3 Docker Swarm ディスカバリ

4.3.2 静 的なファイルまたはノード・リスト
ディスカバリ・バックエンドとして静的なファイルもしくはノードのリストを使えます。このファイルは Swarm
マネージャがアクセス可能なホスト上に置く必要があります。あるいは、Swarm 起動時にオプションでノードのリストを指定することもできます。
静的なファイルあるいは nodes オプションは IP アドレスの範囲指定をサポートしています。特定のパターンで範囲を指定するには、例えば 10.0.0.[10:200] を指定したら、10.0.0.10 から 10.0.0.200 までのノードを探そうとします。以下は file（ファイル）ディスカバリ⼿法を使う例です。
$ echo "10.0.0.[11:100]:2375" >> /tmp/my_cluster$ echo "10.0.1.[15:20]:2375">> /tmp/my_cluster$ echo "192.168.1.2:[2:20]375" >> /tmp/my_cluster
あるいはノードの直接指定でディスカバリするには、次のように実⾏します。
swarm manage -H <swarm_ip:swarm_port> "nodes://10.0.0.[10:200]:2375,10.0.1.[2:250]:2375"

フ ァイル を作成 する場合

1. ファイルを編集し、各⾏にノードの情報を追加します。
echo <node_ip1:2375> >> /opt/my_cluster
echo <node_ip2:2375> >> /opt/my_cluster
echo <node_ip3:2375> >> /opt/my_cluster
この例では /opt/my_cluster というファイルを作成しています。任意のファイル名を指定できます。
2. Swarm マネージャを何らかのマシン上で実⾏します。
swarm manage -H tcp://<swarm_ip:swarm_port> file:///tmp/my_cluster
3. 通常の Docker コマンドを使います。
docker -H tcp://<swarm_ip:swarm_port> info
docker -H tcp://<swarm_ip:swarm_port> run ...
docker -H tcp://<swarm_ip:swarm_port> ps
docker -H tcp://<swarm_ip:swarm_port> logs ...
...
4. クラスタ上のノード⼀覧を表⽰します。
$ swarm list file:///tmp/my_cluster <node_ip1:2375> <node_ip2:2375> <node_ip3:2375>

ノ ード・ リスト を指 定する場 合

1. マシンもしくはノート PC 上でマネージャを起動します。
swarm manage -H <swarm_ip:swarm_port> nodes://<node_ip1:2375>,<node_ip2:2375>- 66 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.3 Docker Swarm ディスカバリ

あるいは、次のように実⾏します。
swarm manage -H <swarm_ip:swarm_port> <node_ip1:2375>,<node_ip2:2375>
2. 通常の Docker コマンドを実⾏します。
docker -H <swarm_ip:swarm_port> info
docker -H <swarm_ip:swarm_port> run ...
docker -H <swarm_ip:swarm_port> ps
docker -H <swarm_ip:swarm_port> logs ...
3. クラスタ上のノード⼀覧を表⽰します。
$ swarm list file:///tmp/my_cluster<node_ip1:2375><node_ip2:2375><node_ip3:2375>

Docker Hub のホ ステッ ド・ディスカ バリ【警告】Docker Hub ホステット・ディスカバリ・サービスはプロダクションでの利⽤が推奨されていません。これはテストや開発環境での利⽤を想定しています。プロダクション環境においては、
ディスカバリ・バックエンドの項⽬をご覧ください。

この例は Docker Hub のホステッド・ディスカバリ・サービスを使います。Docker Hub のホステッド・ディス
カバリ・サービスを使うには、インターネットに接続している必要があります。次のようにして Swarm クラスタを作成します。
1. まずクラスタを作成します。
# クラスタを作成$ swarm create
6856663cdefdec325839a4b7e1de38e8 # <- これが各自の <クラスタ ID> です
2. 各ノードを作成し、クラスタに追加します。
各ノードで Swarm エージェントを起動します。Swarm Manager がアクセス可能であれば、<node_ip> はパブリックである必要はありません（例：192.168.0.x）。
$ swarm join --advertise=<node_ip:2375> token://<cluster_id>
3. Swarm マネージャを起動します。
これはあらゆるマシン上だけでなく、⾃分のノート PC 上でも実⾏できます。
$ swarm manage -H tcp://<swarm_ip:swarm_port> token://<cluster_id>
4. 通常の Docker コマンドでクラスタと通信します。
- 67 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

4.3 Docker Swarm ディスカバリ

docker -H tcp://<swarm_ip:swarm_port> info
docker -H tcp://<swarm_ip:swarm_port> run ...
docker -H tcp://<swarm_ip:swarm_port> ps
docker -H tcp://<swarm_ip:swarm_port> logs ...
...
5. クラスタのノード情報⼀覧を表⽰します。
swarm list token://<cluster_id><node_ip:2375>

4.3.3 新 しいディスカバリ・バ ックエンドに貢献
あなたも Swarm 向けの新しいディスカバリ・バックエンドに貢献できます。どのようにするかは、Docker Swarm
リポジトリにある discovery README*1 をお読みください。

*1 https://github.com/docker/swarm/blob/master/discovery/README.md- 68 -

docs.docker.jp

16/06/02

５章

5 章 セキュリティ

5.1 Swarm と TLS の概要
Swam クラスタの全てのノードでは、それぞれの Docker デーモンが通信⽤のポートを公開（バインド）する必
要があります。そのため、これがセキュリティ上の懸念となるのは明らかです。インターネットのような信頼を疑うべきネットワークにおいて、懸念は倍増します。これらのリスクを減らすため、Docker Swarm と Docker Engineのデーモンは TLS（Transport Layer Security；トランスポート・レイヤ・セキュリティ）をサポートしています。
TLS は SSL（Secure Sockets Layer）の後継であり、この２つは相互に互換性があります。この記事の中では、Docker は TLS を使います。

5.1.1 TLS の概念を学ぶ
先へ進む前に、TLS と PKI (Public Key Infrastructure；公開鍵基盤) の基本概念を理解しておくことが重要です。
公開鍵基盤はセキュリティに関連する技術・ポリシー・⼿続きを組み合わせたものです。これらが電⼦証明書の作成や管理に使われます。認証や暗号化のような仕組みにおいて、これらの証明書とインフラの安全なデジタル通信が使われます。
もしかすると、次の例えが分かりやすいかもしれません。個⼈を認識する⼿段としてパスポートを使うことは⼀般的です。通常のパスポートには個⼈を特定するための写真や⽣体情報が記録されています。また、パスポートには有効な国名だけでなく、有効・無効に関する⽇付も記録されています。この仕組みと電⼦証明は⾮常に似ています。ある電⼦証明書を展開したのが、次のテキストです。
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 9590646456311914051 (0x8518d2237ad49e43)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=CA, L=Sanfrancisco, O=Docker Inc
Validity
Not Before: Jan 18 09:42:16 2016 GMT
Not After : Jan 15 09:42:16 2026 GMT
Subject: CN=swarm- 69 -

docs.docker.jp

16/06/02

この証明書で swarm という名称のコンピュータを識別します。証明書の有効期間は 2016 年 1 ⽉から 2026 年 1
⽉までです。そしてこれを発⾏したのは⽶国カリフォルニア州を拠点としている Docker, Inc.です。
パスポートを使った個⼈認証が使われるのは、⾶⾏機の搭乗や、板を囲まれた税関においてです。電⼦証明書はネットワーク上のコンピュータを認証するために使います。
公開鍵基盤（PKI）とは、電⼦証明書を有効に機能させるため、その背後で使われる技術・ポリシー・⼿順の組
み合わせなのです。PKI によって提供される技術・ポリシー・⼿続きには、以下の項⽬が含まれます。

 証明書を安全に要求するためのサービス
 要求された証明書が、実在しているかどうか確認するための⼿順
 証明書の実体が、適格かどうか決めるための⼿順
 証明書を発⾏する技術と⼿順
 証明書を破棄する技術と⼿順

5.1.2 Docker Engine で TLS 認証を使うにはこのセクションは Docker Engine と Swarm のセキュリティを⾼めるために、 PKI と証明書を使う⽅法を学びます。
TLS 認証を使うためには、Docker Engine CLI と Docker Engine デーモンの両⽅で設定が必要です。TLS の設定を⾏うというのは、Docker Engine CLI と Docker Engine デーモン間の全ての通信を、信頼のある電⼦証明書で署名された状態で⾏うことを意味します。Docker Engine CLI は Docker Engine デーモンと通信する前に、電⼦証明書の提出が必要です。
また、Docker Engine デーモンも Docker Engine CLI が使う証明証を信頼する必要があります。信頼とは、通常は第三者の信頼機関によって担保されます。下図は Docker Engine CLI とデーモンが TLS 通信に必要となる設定です。

サーティフィケイト

オーソリティ

図中における信頼できる第三者とは認証局（CA; Certiﬁcate Authority）サーバです。認証局（CA）とは、パスポートを例にすると国に相当します。認証局は証明証を作成・署名・発⾏・無効化します。Docker Engine デーモ
ンを実⾏するホスト上では、信頼を確⽴するために、認証局のルート証明書をインストールします。Docker Engine- 70 -

docs.docker.jp

16/06/02

CLI は認証局のサーバに対して証明書を要求します。認証局サーバはクライアントに対して証明書の署名・発⾏を⾏います。
Docker Engine CLI はコマンドを実⾏する前に、この（認証局で署名された）証明書を Docker Engine デーモンに送ります。デーモンは証明書を調査します。その証明書がデーモンの信頼する認証局が署名したものであれば、デーモンは⾃動的に信頼します。証明書が適切であるとみなすと（証明書が有効期間内であり、破棄されたものでないと分かれば）、Docker Engine デーモンは信頼できる Engine CLI からの要求とみなしコマンドを受け付けます。
Docker Engine CLI はシンプルなクライアントです。Docker Engine デーモンと通信するために Docker リモー
ト API を使います。Docker リモート API を利⽤可能なクライアントであれば、どれも TLS が使えます。例えば、TLS をサポートしている Docker ユニバーサル・コントロール・プレーン (UCP) に他のクライアントからもアクセス可能です。他のクライアントとは、Docker リモート API を使うサードパーティー製のプロダクトでも、同様に設定ができます。

5.1.3 Docker と Swarm の TLS モード
Docker Engine デーモンが認証に使う証明書について学んできました。重要なのは、Docker Engine デーモンとクライアントで利⽤できる TLS 設定には３種類あることに注意すべきです。

 外部のサードパーティー製の証明局(CA) 社内にある証明局(CA) 証明書に対する⾃⼰署名
どの証明局(CA) を使うかにより、実際の設定内容が異なります。

外 部のサ ードパ ーティ ー製の 証明 局
外部の証明局とは、信頼できる第三者による会社を指します。そこが証明書の作成、発⾏、無効化、その他の管理を⾏います。信頼されているという⾔葉が意味するのは、⾼いレベルのセキュリティを実現・維持し、ビジネスに対する成功をもたらすものです。また、外部の認証局のルート証明書をインストールすることにより、皆さんのコンピュータやサーバも信頼できうるものとします。
外部のサードパーティー認証局を使うえば、その認証局によって、皆さんの証明書が作成・署名・発⾏・無効化など管理が⾏われます。通常はサービスの利⽤に料⾦が発⽣します。しかし、エンタープライズ・クラスの安定したソリューションを考慮した、⾼度な信頼をもたらすでしょう。

社 内にあ る証明 局
多くの組織で、その組織内で認証局や PKI を運⽤することが選ばれています。そのために OpenSSL もしくはMicrosoft Active Directory を使うのが⼀般的な例です。このような場合、皆さんの会社⾃⾝が⾃信で証明機関を運⽤しています。この利点は、⾃分⾃⾝が証明局ですので、更なる PKI を管理できる点です。
外部のサードパーティー認証局が提供するサービスを使い、⾃⾝の認証局や PKI を必要に応じて運⽤できます。
これには証明書の作成・発⾏・破棄などの管理が含まれています。全てを⾃分たちで運⽤するとコストやオーバヘッドが必要となるでしょう。しかし、⼤規模な企業であれば、全てサードパーティーによるサービスを使うよりはコストを削減できるかもしれません。
⾃分たち⾃⾝で認証局や PKI の内部運⽤・管理を考えているのであれば、企業における認証局を実現するため、⾼い可⽤性や⾼いセキュリティについて考慮が必要になるでしょう。

自 己署名 した証 明書
その名前の通り、⾃⼰署名した証明書とは、信頼できる認証局の代わりに、⾃分⾃⾝の秘密鍵で署名するものです。これは低いコストかつ簡単に使えるものです。もし⾃分⾃⾝で署名した証明書を適切に運⽤したいのであれば、- 71 -

docs.docker.jp

16/06/02

証明書を使わないのも良い⽅法かもしれません。
なぜならば、⾃⼰署名した証明書が本来の PKI を損ねる可能性があるためです。この⼿法はスケールしませんし、他の選択肢に⽐べますと、多くの点で不利です。不利な点の１つに、⾃分⾃⾝で⾃⼰署名した証明書を無効化できません。これだけでなく、他にも制限があるため、⾃⼰署名の証明書は、この３つの選択肢の中で最低のセキュリティと考えられます。信頼できないネットワーク上でプロダクション⽤のワークロードを公開する必要があれば、⾃⼰署名の証明書の利⽤は推奨されません。

- 72 -

docs.docker.jp

16/06/02

5.2 Docker Swarm の TLS 設定
この⼿順では下図のように、Swarm クラスタに Swarm マネージャと認証局（CA）の２つのノードを作成します。
全ての Docker Engine ホスト（client、swarm、node1、node2）は、認証局の証明書のコピーと、⾃分⾃⾝で認証局の署名をしたキーペアのコピーも持ちます。

以下の⼿順で作業を進めていきます。

 ステップ１：動作環境のセットアップ ステップ２：認証局(CA)サーバの作成
 ステップ３：鍵の作成と署名
 ステップ４：鍵のインストール
 ステップ５：Engine デーモンに TLS 設定
 ステップ６：Swarm クラスタの作成
 ステップ７：TLS を使う Swarm マネージャの作成
 ステップ８：Swarm マネージャの設定を確認 ステップ 9：TLS を使う Engilne CLI の設定- 73 -

docs.docker.jp

16/06/02

5.2.1 始 める前にこのセクションは OpenSSL で⾃分⾃⾝で認証局(CA)を作成する⼿順を含みます。これは簡単な社内の認証局やPKI と似ています。しかしながら、プロダクション級の内部の認証局・PKI としては使うべきではありません。以降の⼿順は検証⽤（デモンストレーション）⽬的のみです。つまり、皆さんが既に適切な証明局や証明書をお持ちであれば、Docker Swarm で TLS を利⽤する際には置き換えてお読みください。

5.2.2 手 順
ステップ １： 動作環 境のセ ットア ップ
この⼿順を進めるには、５つの Linux サーバの起動が必要です。これらのサーバは物理と仮想を組み合わせても構いません。以下の表はサーバ名と役割の⼀覧です。
サーバ名

説明

ca
swarm
node1
node2
client

認証局(CA)サーバとして動作
Swarm マネージャとして動作
Swarm ノードとして動作
Swarm ノードとして動作
リモートの Docker Engine クライアントとして動作

５台全てのサーバに SSH 接続が可能なのを確認し、DNS の名前解決でお互いに通信できるようにします。特に、次の２点に気を付けます。

 Swarm マネージャと Swarm ノード間は TCP ポート 2376 を開く
 Docker Engine クライアントと Swarm マネージャ間は TCP ポート 3376 を開く
既に使⽤中であれば、他のポートも選べます。この例ではこれらのポートを使う想定です。
各サーバは Docker Engine と互換性のあるオペレーティング・システムを実⾏します。簡単にするため、以降のステップでは全てのサーバを Ubuntu 14.04 LTS で動かすと想定します。

ステップ ２： 認証局 (CA)サ ーバの 作成

既に認証局にアクセス可能で証明書があるならば、それらを使ったほうが便利です。その場合、次のステップにスキップしてください。

このステップでは Linux サーバを認証局として設定します。認証局は鍵の作成と署名に使います。読者が既存の（外部または企業の）認証局へのアクセスや証明書が無くても、このステップでは必要な環境のインストールと証明書を使えるようにします。しかし、プロダクションへのデプロイには適切では「ない」モデルです。
1. 認証局サーバのターミナルに⼊り、root に昇格します。
$ sudo su
2. 認証局⽤の秘密鍵 ca-priv-key.pem を作成します。
# openssl genrsa -out ca-priv-key.pem 2048
Generating RSA private key, 2048 bit long modulus...........................................................+++- 74 -

docs.docker.jp

16/06/02

.....+++
e is 65537 (0x10001)
3. 認証局⽤の公開鍵 ca.pem を作成します。
公開鍵の作成は、直前の⼿順で作成した秘密鍵を元にします。
# openssl req -config /usr/lib/ssl/openssl.cnf -new -key ca-priv-key.pem -x509 -days 1825 -out ca.pem
You are about to be asked to enter information that will be incorporated
into 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 blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
----Country Name (2 letter code) [AU]:US<output truncated>
公開鍵・秘密鍵のペアを持つ認証局のサーバを設定しました。
# openssl rsa -in ca-priv-key.pem -noout -text
公開鍵（認証済み）を調べるには、次のようにします。
# openssl x509 -in ca.pem -noout -text`
次のコマンドは、認証局の公開鍵情報を⼀部表⽰します。
# openssl x509 -in ca.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 17432010264024107661 (0xf1eaf0f9f41eca8d)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=CA, L=Sanfrancisco, O=Docker Inc
Validity
Not Before: Jan 16 18:28:12 2016 GMT
Not After : Jan 13 18:28:12 2026 GMT
Subject: C=US, ST=CA, L=San Francisco, O=Docker Inc
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:00:d1:fe:6e:55:d4:93:fc:c9:8a:04:07:2d:ba:f0:
55:97:c5:2c:f5:d7:1d:6a:9b:f0:f0:55:6c:5d:90:<output truncated>
後ほど、他のインフラ上にあるサーバの鍵に対する署名で使います。

ステップ ３： 鍵の作 成と署 名
これで認証局が動きました。次は Swarm マネージャ、Swarm ノード、リモートの Docker Engine クライアント
⽤の鍵ペアを作成する必要があります。鍵ペア作成の命令と⼿順は、全てのサーバで同⼀です。次の鍵を作成します。
- 75 -

docs.docker.jp

16/06/02

ca-priv-key.pem
ca.pemnode.csr

node-priv.key
node-cert.pem

認証局の秘密鍵であり、安全に保つ必要があります。後ほど環境上にある他ノード⽤の新
しい鍵の署名で使います。ca.pem ファイルと認証局の鍵ペアを構成します。
認証局の公開鍵であり、証明書（certiﬁcate）とも呼ばれます。このファイルは環境上全てのノード上にインストールします。つまり、全てのノードは認証局が署名した信頼できる鍵を持っています。ca-priv-key.pem ファイルと認証局の鍵ペアを構成します。
証明書署名要求（certiﬁcate signing request；CSR）です。認証局に対して個々のノードごとに新しい鍵ペアを作成時 CSR を効率的に使います。認証局は指定した CSR から情報を取得し、ノード⽤の公開鍵と秘密鍵の鍵ペアを作成します。
認証局で署名した秘密鍵。ノードはリモートの Docker Engine との認証に使います。
node-cert.pem ファイルとノードの鍵ペアを構成します。
認証局で署名した証明書。今回のサンプルでは使いません。node-priv.key ファイルとノードの鍵ペアを構成します。

以下で紹介するのは、ノード全てに対する鍵を作成するコマンドの使い⽅です。認証局サーバ上のディレクトリ
で、この⼿順を進めます。
1. 認証局サーバのターミナルにログインし、root に昇格します。
$ sudo su
2. Swarm マネージャ⽤の秘密鍵 swarm-priv-key.pem を作成します。
# openssl genrsa -out swarm-priv-key.pem 2048
Generating RSA private key, 2048 bit long modulus............................................................+++........+++
e is 65537 (0x10001)
3. 証明書署名要求(CSR) swarm.csr を作成します。
# openssl req -subj "/CN=swarm" -new -key swarm-priv-key.pem -out swarm.csr
この⼿順はデモンストレーション⽬的専⽤です。ご注意ください。実際のプロダクション環境における CSR 作
成⼿順とは若⼲異なります。
4. 前のステップで作成した CSR を元に、証明書 swarm-cert.pem を作成します。
# openssl x509 -req -days 1825 -in swarm.csr -CA ca.pem -CAkey ca-priv-key.pem -CAcreateserial \-out swarm-cert.pem -extensions v3_req -extfile /usr/lib/ssl/openssl.cnf<省略># openssl rsa -in swarm-priv-key.pem -out swarm-priv-key.pem
これで Swarm マネージャの鍵ペアを作成しました。
5. これまでのステップを各インフラ上（node1、node2、client）で繰り返します。
各ノードで鍵ペアの作成時は、 swarm の値を各ノードのものへ置き換えてください。

- 76 -

docs.docker.jp

16/06/02

サーバ名

秘密鍵

CSR

swarm
node1
node2

node1-priv-key.pem node1.csr
node2-priv-key.pem node2.csr
client-priv-key.pem client.csr

証明書
node1-cert.pem
node2-cert.pem
client-cert.pem

6. ⾃分の作業⽤ディレクトリ上に、以下のファイルがあるのを確認します。
# ls -ltotal 64
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root

root
root
root
root
root
root
root
root
root
root
root
root
root
root
root

1679 Jan 16 18:27 ca-priv-key.pem
1229 Jan 16 18:28 ca.pem
17 Jan 18 09:56 ca.srl
1086 Jan 18 09:56 client-cert.pem
887 Jan 18 09:55 client.csr
1679 Jan 18 09:56 client-priv-key.pem
1082 Jan 18 09:44 node1-cert.pem
887 Jan 18 09:43 node1.csr
1675 Jan 18 09:44 node1-priv-key.pem
1082 Jan 18 09:49 node2-cert.pem
887 Jan 18 09:49 node2.csr
1675 Jan 18 09:49 node2-priv-key.pem
1082 Jan 18 09:42 swarm-cert.pem
887 Jan 18 09:41 swarm.csr
1679 Jan 18 09:42 swarm-priv-key.pem

それぞれの鍵の内容を⾃分で確認できます。秘密鍵を調べるには、次のようにします。
openssl rsa -in <key-name> -noout -text
公開鍵の確認は、次のようにします。
openssl x509 -in <key-name> -noout -text
次のコマンドは、Swarm マネージャ公開鍵 swarm-cert.pem の内容を表⽰する⼀部です。
# openssl x509 -in ca.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 9590646456311914051 (0x8518d2237ad49e43)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=CA, L=Sanfrancisco, O=Docker Inc
Validity
Not Before: Jan 18 09:42:16 2016 GMT
Not After : Jan 15 09:42:16 2026 GMT
Subject: CN=swarm<出力を省略>ステップ ４： 鍵のイ ンストー ル
このステップは、インフラ上の各サーバに鍵をインストールします。各サーバは３つのファイルが必要です。

- 77 -

docs.docker.jp

16/06/02

 認証局公開鍵（ca.pem）のコピー
 ⾃分の秘密鍵
 ⾃分の公開鍵（証明書）
以下の⼿順では、認証局サーバから各サーバに scp を使い、３つのファイルをコピーします。コピーの段階で、各ノードごとにファイル名を変更します。
オリジナル名

コピー名

ca.pem<サーバ名>-cert.pem<サーバ名>-priv-key.pem

ca.pemcert.pem
key.pem

1. 認証局サーバのターミナルにログインし、root に昇格します。
$ sudo su
2. Swarm マネージャ上で ~/.certs ディレクトリを作成します。
$ ssh ubuntu@swarm 'mkdir -p /home/ubuntu/.certs'
3. 認証局から Swarm マネージャ・サーバに鍵をコピーします。
$ scp ./ca.pem ubuntu@swarm:/home/ubuntu/.certs/ca.pem$ scp ./swarm-cert.pem ubuntu@swarm:/home/ubuntu/.certs/cert.pem$ scp ./swarm-priv-key.pem ubuntu@swarm:/home/ubuntu/.certs/key.pem

scp コマンドの動作には認証情報の指定が必要になるかもしれません。例えば、AWS EC2 インス
タンスは証明書ベースでの認証を使います。公開鍵 nigel.pem を関連付けている EC2 インスタン
スにファイルをコピーするには、scp コマンドを次のように変更します。
scp -i /path/to/nigel.pem ./ca.pem ubuntu@swarm:/home/ubuntu/.certs/ca.pem

4. インフラ上の各サーバに対して２つの⼿順を繰り返します。

 node1
 node2
 client
5. 動作確認をします。
コピーが完了したら、各マシンは以下の鍵を持ちます。

- 78 -

docs.docker.jp

16/06/02

インフラ上の各ノードでは、 /home/ubuntu/.certs/ ディレクトリに次のファイルがあるでしょう。
# ls -l /home/ubuntu/.certs/
total 16
-rw-r--r-- 1 ubuntu ubuntu 1229 Jan 18 10:03 ca.pem-rw-r--r-- 1 ubuntu ubuntu 1082 Jan 18 10:06 cert.pem-rw-r--r-- 1 ubuntu ubuntu 1679 Jan 18 10:06 key.pem

ステップ ５： Engine デ ーモ ンに TLS 設定
先ほどのステップでは、各 Swarm ノードで必要な鍵をインストールしました。このステップでは、ネットワー
ク上で通信可能に調整し、TLS を使う通信のみ受け付けるようにします。このステップが終われば、Swarm ノー
ドは TCP ポート 2376 をリッスンし、TLS を使う接続のみ受け付けます。
node1 と node2（Swarm ノード）上で以下の作業を⾏います。
1. node1 のターミナルを開き、root に昇格します。
$ sudo su
2. Docker Engine 設定ファイルを編集します。
以降の⼿順を Ubuntu 14.04 LTS で進めるのであれば、設定ファイルは /etc/default/docker です。Docker
Engine の設定ファイルは、お使いの Linux ディストリビューションに依存します。
3. DOCKER_OPTS ⾏に以下のオプションを追加します。
-H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/home/ubuntu/.certs/ca.pem--tlscert=/home/ubuntu/.certs/cert.pem --tlskey=/home/ubuntu/.certs/key.pem ←１行で入力
4. Docker Engine デーモンを再起動します。
- 79 -

docs.docker.jp

16/06/02

$ service docker restart
5. node2 でも同様の設定を繰り返します。

ステップ ６： Swarm クラ スタの 作成
次は Swarm クラスタを作成します。以降の⼿順では、２つのノードを持つ Swarm クラスタを、デフォルトのホ
ステッド・ディスカバリ・バックエンドで作成します。デフォルトのホステッド・ディスカバリは Docker Hub を使います。また、プロダクション環境での利⽤は⾮推奨です。
1. Swarm マネージャ⽤ノードのターミナルにログインします。
2. TOKEN 環境変数にユニークな ID を取り込み、クラスタを作成します。
$ sudo export TOKEN=$(docker run --rm swarm create)
Unable to find image 'swarm:latest' locallylatest: Pulling from library/swarm
d681c900c6e3: Pulling fs layer<省略>
986340ab62f0: Pull complete
a9975e2cc0a3: Pull complete
Digest: sha256:c21fd414b0488637b1f05f13a59b032a3f9da5d818d31da1a4ca98a84c0c781b
Status: Downloaded newer image for swarm:latest
3. node1 をクラスタに追加します。
TCP ポート 2376 を指定します。2375 ではありません。
$ sudo docker run -d swarm join --addr=node1:2376 token://$TOKEN
7bacc98536ed6b4200825ff6f4004940eb2cec891e1df71c6bbf20157c5f9761
4. node2 をクラスタに追加します。
$ sudo docker run -d swarm join --addr=node2:2376 token://$TOKEN
db3f49d397bad957202e91f0679ff84f526e74d6c5bf1b6734d834f5edcbca6c

ステップ ７： TLS を 使う Swarm マネ ージ ャの作 成

1. TLS を有効にした新しいコンテナを起動します。
$ docker run -d -p 3376:3376 -v /home/ubuntu/.certs:/certs:ro swarm manage \--tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/cert.pem --tlskey=/certs/key.pem \--host=0.0.0.0:3376 token://$TOKEN
このコマンドは swarm イメージを元にした新しいコンテナを起動します。そして、サーバ側のポート 3376 をコンテナ内のポート 3376 に割り当てます。コンテナは Swarm の manage プロセスを実⾏し、オプションとして--tlsverify、--tlscacert、--tlscert、--tlskey を指定します。これらのオプションは TLS 認証を強制するものであり、Swarm マネージャの TLS 鍵の場所を指定します。

- 80 -

docs.docker.jp

16/06/02

2. docker ps コマンドを実⾏し、Swarm マネージャ⽤コンテナが起動して実⾏中かを確認します。
$ docker ps
CONTAINER ID

IMAGE

COMMAND

CREATEDSTATUS

PORTS

7 seconds ago

Up 7 seconds

2375/tcp,

NAMES
035dbf57b26e swarm
0.0.0.0:3376->3376/tcp"/swarm manage --tlsv"
compassionate_lovelace

これで Swarm クラスタが TLS を使う設定になりました。

ステップ ８： Swarm マネージャの 設定 を確認
TLS を使う Swarm クラスタを構築しました。次は、Docker Engine CLI で動作するかを確認します。
1. client サーバのターミナルを開きます。
2. docker version コマンドを実⾏します。
コマンドの実⾏には、クライアント証明書の場所指定が必須です。
$ sudo docker --tlsverify --tlscacert=/home/ubuntu/.certs/ca.pem \--tlscert=/home/ubuntu/.certs/cert.pem --tlskey=/home/ubuntu/.certs/key.pem -H swarm:3376 version
Client:Version:
1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5
Built:Fri Nov 20 13:12:04 UTC 2015
OS/Arch:linux/amd64
Server:Version:API version:
Go version:
Git commit:
Built:
OS/Arch:swarm/1.0.1
1.21
go1.5.2
744e3a3
linux/amd64

Server バージョンの出⼒は “ swarm/1.0.1 ” を表⽰します。つまり、Swarm マネージャに対するコマンドの実⾏が成功したのを意味します。
3. TLS の指定が無くてもコマンドが動作するか確認します。
今回は Swarm マネージャ⽤の証明書を指定しません。
$ sudo docker -H swarm:3376 version:
Version:
1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5
Built:Fri Nov 20 13:12:04 UTC 2015
OS/Arch:linux/amd64- 81 -

docs.docker.jp

16/06/02

Get http://swarm:3376/v1.21/version: malformed HTTP response "\x15\x03\x01\x00\x02\x02".
* Are you trying to connect to a TLS-enabled daemon without TLS?
サーバ側のコマンドを拒否したと表⽰されます。つまり、サーバ（Swarm マネージャ）と通信できるのは TLSを⽤いるクライアントのみです。

ステップ ９： TLS を 使う Engilne CLI の設定
コマンド実⾏時に TLS オプションを指定しなくても良いよう、Engine 側に設定できます。設定のためには、
Docker Engine クライアントがデフォルトで TLS を使うように、Docker Engine のホストの設定をします。
そのためには、クライアントの鍵を⾃分の ~/.docker 設定ディレクトリに置きます。システム上で他にも Engine
コマンドを使っているユーザがいる場合は、それぞれのアカウントでも同様に ~/.docker の設定が必要です。以降
は、ubuntu ユーザで Docker Engine クライアントを使う⼿順です。
1. client サーバのターミナルを開きます。
2. ubuntu ユーザのホームディレクトリに .docker ディレクトリが存在しなければ作成します。
$ mkdir /home/ubuntu/.docker
3. /home/ubuntu/.certs にある Docker Engine クライアントの鍵を、 /home/ubuntu/.docker にコピーします。
$ cp /home/ubuntu/.certs/{ca,cert,key}.pem /home/ubuntu/.docker
4. アカウントの ~/.bash_profile を編集します。
5. 以下の環境変数を指定します。
変数

説明

DOCKER_HOST
DOCKER_TLS_VERIFYDOCKER_CERT_PATH

全ての Engine ⽤コマンドが送信する Docker ホストと TCP ポートを指定します。
Engine に TLS を使うと伝えます。
TLS 鍵の場所を指定します。

例：
export DOCKER_HOST=tcp://swarm:3376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/home/ubuntu/.docker/
6. ファイルを保存して閉じます。
7. 新しい環境変数をファイルから読み込みます。
$ source ~/.bash_profile
8. docker version コマンドを実⾏して動作確認します。
$ docker version
Client:Version:
1.9.1
API version: 1.21
- 82 -

docs.docker.jp

16/06/02

Go version:
Git commit:
Built:
OS/Arch:Server:Version:API version:
Go version:
Git commit:
Built:
OS/Arch:go1.4.2
a34a1d5
Fri Nov 20 13:12:04 UTC 2015
linux/amd64

swarm/1.0.1
1.21
go1.5.2
744e3a3
linux/amd64

コマンド実⾏結果のサーバ情報にある部分から、Docker クライアントは TLS を使う Swarm マネージャに命令していると分かります。
おつかれ様でした。これで TLS を使う Docker Swarm クラスタができました。

- 83 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

６章

6 章 高度なスケジューリング

⾼度なスケジューリングを学ぶためには、 ストラテジとフィルタのドキュメントをご覧ください。

6.1 フィルタ
フィルタ（ﬁlter）とは Docker Swarm スケジューラに対して、ノードを使ってコンテナの作成・実⾏をするか伝えます。

6.1.1 設 定可能なフィルタ
フィルタはノード・フィルタ（node ﬁlter）とコンテナ設定フィルタ（container conﬁguration ﬁlter）の２種類に分けられます。ノード・フィルタは Docker ホストの特徴、あるいは Docker デーモンの設定によって処理します。コンテナ設定フィルタはコンテナの特徴、あるいはホスト上で利⽤可能なイメージによって処理します。
各フィルタには名前があります。ノード・フィルタは、以下の２つです。
コンストレイント constraint（ノードの制限）
ヘ ル ス

 health（ノードが正常かどうか）
コンテナ設定フィルタは以下の通りです。
アフィニティ

 affinity（親密さ）ディペンデンシー dependency（依存関係）
 port（ポート）swarm manage コマンドで Swarm マネージャの起動する時、全てのフィルタが指定可能です。もしも Swarm に対して利⽤可能なフィルタを制限したい場合は、 --filter フラグと名前のサブセットを指定します。
$ swarm manage --filter=health --filter=dependency- 84 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

コンテナ設定フィルタに⼀致するのは全てのコンテナが対象でです。フィルタが適⽤されるのは停⽌しているコンテナも含みます。コンテナによって使⽤されているノードを解放するには、ノード上からコンテナを削除する必要があります。

6.1.2 ノ ード・フィルタ
コンテナ作成時とイメージ構築時に、constraint か health フィルタを使い、コンテナをスケジューリングするノード群を選択できます。

constraint（制限 ）フィル タを使 う
ノード制限（constraint；制限・制約の意味）は Docker のデフォルトのタグやカスタム・ラベルを参照します。
デフォルトのタグとは docker info の情報を元にします。しばし Docker ホストの設定状態に関連付けられます。
現在以下の項⽬をデフォルト・タグとして利⽤できます。

 node ノードを参照するための ID もしくは名前 storagedriver executiondriver kernelversion
 operatingsystem
カスタム・ノード・ラベルは docker daemon 起動時に追加できます。実⾏例：$ docker daemon --label com.example.environment="production" --label
com.example.storage="ssd"
そして、クラスタ上でコンテナの起動時に、これらのデフォルト・タグかカスタム・ラベルを使って制限（constraint）を指定可能です。Swarm スケジューラはクラスタ上に条件が⼀致するノードを探し、そこでコンテナを起動します。この⼿法は、いくつもの実践的な機能になります。

 ホスト・プロパティを指定した選択（storage=ssd のように、特定のハードウェアにコンテナをスケジュールするため）
 ノードの基盤に、物理的な場所をタグ付けする（region=us-east のように、指定した場所でコンテナを強制的に実⾏）
 論理的なクラスタの分割（environment=production のように、プロパティの違いによりクラスタを複数のサブクラスタに分割）

ノ ード制 限の例
ノードに対してカスタム・ラベルを指定するには、docker 起動時に --label オプションのリストを指定します。
例として、node-1 に storage=ssd ラベルを付けて起動します。
$ docker -d --label storage=ssd$ swarm join --advertise=192.168.0.42:2375 token://XXXXXXXXXXXXXXXXXX
node-2 を storage=disk としても起動できます。
$ docker -d --label storage=disk- 85 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

$ swarm join --advertise=192.168.0.43:2375 token://XXXXXXXXXXXXXXXXXX
ノードがクラスタに登録されたら、Swarm マネージャは個々のタグを取得します。マネージャは新しいコンテナ
をスケジューリングする時に、ここで取得したタグの情報を使って処理します。
先ほどのサンプルを例に進めましょう。クラスタには node-1 と node-2 があります。このクラスタ上に MySQL
サーバ・コンテナを実⾏できます。コンテナの実⾏時、constraint（制限）を使い、データベースが良い I/O 性能を得られるようにできます。そのためには、フラッシュ・ドライブを持つノードをフィルタします。
$ docker tcp://<manager_ip:manager_port> run -d -P -e constraint:storage==ssd --name db mysql
f8b693db9cd6$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

この例では、マネージャは全てのノードの中から storage-ssd 制限に⼀致するノードを探し、そこに対してリソース管理を適⽤します。ここではホストがフラッシュ上で動いている node-1 のみが選ばれました。
クラスタのフロントエンドとして Nginx の実⾏をお考えでしょうか。この例では、フロントエンドはディスクのログを記録するだけですので、フラッシュ・ドライブを使いたくないでしょう。
$ docker tcp://<manager_ip:manager_port> run -d -P -e constraint:storage==disk --name frontend nginx
963841b138d8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
963841b138d8
nginx:latest"nginx"192.168.0.43:49177->80/tcp
node-2/frontend
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

Up About a minuterunning

スケジューラは storage=disk ラベルを付けて起動済みの node-2 で起動します。
最後に、docker build の構築時の引数としてもノード制限を利⽤できます。今度もフラッシュ・ドライブを避けてみましょう。
$ mkdir sinatra$ cd sinatra$ echo "FROM ubuntu:14.04" > Dockerfile$ echo "MAINTAINER Kate Smith <ksmith@example.com>" >> Dockerfile$ echo "RUN apt-get update && apt-get install -y ruby ruby-dev" >> Dockerfile$ echo "RUN gem install sinatra" >> Dockerfile$ docker build --build-arg=constraint:storage==disk -t ouruser/sinatra:v2 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu:14.04---> a5a467fddcb8
Step 2 : MAINTAINER Kate Smith <ksmith@example.com>---> Running in 49e97019dcb8---> de8670dcf80e
Removing intermediate container 49e97019dcb8
Step 3 : RUN apt-get update && apt-get install -y ruby ruby-dev---> Running in 26c9fbc55aeb- 86 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

---> 30681ef95fff
Removing intermediate container 26c9fbc55aeb
Step 4 : RUN gem install sinatra---> Running in 68671d4a17b0---> cd70495a1514
Removing intermediate container 68671d4a17b0
Successfully built cd70495a1514$ docker images
REPOSITORY
dockerswarm/swarm
ouruser/sinatra
ubuntuTAG
managerv2
14.04

IMAGE ID
8c2c56438951
cd70495a1514
a5a467fddcb8

CREATED
2 days ago
35 seconds ago
11 days ago

SIZE
795.7 MB318.7 MB187.9 MB

health フィル タを使 う
ノード health フィルタは障害の発⽣したノードにコンテナをスケジュールするの防ぎます。対象のノードはダウンしているか、クラスタ・ストアとの通信ができないことが考えられます。

6.1.3 コ ンテナ・フィルタ
コンテナの作成時、３種類のコンテナ・フィルタを使えます。
アフィニティ

 affinity（親密さ）ディペンデンシー dependency（依存関係）
 port（ポート）ア フィニティ （親密 さ） フィ ルタ を使う
アフィニティ（aﬃnity ＝親密さ）フィルタを使えば、コンテナ間を「集めて」作成できます。例えばコンテナを実⾏する時に、次の３つの親密さを元にして Swarm に対してスケジュールできます。

 コンテナ名か ID イメージのあるホスト
 コンテナに適⽤したカスタム・ラベル
これらのアフィニティ（親密さ）とは、コンテナを同じネットワーク・ノード上で実⾏することです。それぞれどのノード上で実⾏しているかどうか、知る必要がありません。

名 前アフィ ニティの 例
新しいコンテナを、既存のコンテナ名や ID を元にしてスケジューリングできます。例えば、frontend という名
前のノードで nginx を実⾏します。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 --name frontend nginx
87c4376856a8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
87c4376856a8
nginx:latest"nginx"192.168.0.42:80->80/tcp
node-1/frontend- 87 -

CREATEDSTATUSLess than a second ago

running
docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

それから、 -e affinity:container==frontend フラグを使い、２つめのコンテナを frontend の隣にスケジュールします。
$ docker tcp://<manager_ip:manager_port> run -d --name logger -e affinity:container==frontend logger
87c4376856a8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
87c4376856a8
nginx:latest"nginx"192.168.0.42:80->80/tcp
node-1/frontend
963841b138d8
logger:latest"logger"node-1/logger

CREATEDSTATUSLess than a second ago

running

Less than a second ago

running

コンテナ名のアフィニティ指定によって、logger コンテナは frontend コンテナと同じ node-1 コンテナで実⾏されることになります。frontend という名前だけでなく、次のように ID を使った指定もできますdocker run -d --name logger -e affinity:container==87c4376856a8

イ メージ ・ア フィ ニティ の例
コンテナを起動する時、特定のイメージをダウンロード済みのノードのみにスケジュールすることができます。
例えば、２つのホストに redis イメージをダウンロードし、３つめのホストに mysql イメージをダウンロードしたい場合があるでしょう。
$ docker -H node-1:2375 pull redis$ docker -H node-2:2375 pull mysql$ docker -H node-3:2375 pull redis
node-1 と node-3 のみが redis イメージを持っています。 -e affinity:image==redis フィルタを使い、これらのノード上でスケジュールします。
$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis2 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis3 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis4 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis5 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis6 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis7 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> run -d --name redis8 -e affinity:image==redis redis$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
87c4376856a8
redis:latest"redis"node-1/redis1
1212386856a8
redis:latest"redis"node-1/redis2
87c4376639a8
redis:latest"redis"node-3/redis3
1234376856a8
redis:latest"redis"node-1/redis4
86c2136253a8
redis:latest"redis"- 88 -

CREATEDSTATUSLess than a second ago

running

Less than a second ago

running

Less than a second ago

running

Less than a second ago

running

Less than a second ago

running
docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

87c3236856a8
87c4376856a8
963841b138d8

6.1 フィルタ

node-3/redis5"redis"node-3/redis6
redis:latest"redis"node-3/redis7
redis:latest"redis"node-1/redis8
redis:latest

Less than a second ago

running

Less than a second ago

running

Less than a second ago

running

ここで⾒えるように、コンテナがスケジュールされるのは redis イメージを持っているノードのみです。イメー
ジ名に加えて、特定のイメージ ID も指定できます。
$ docker images
REPOSITORYVIRTUAL SIZE
redis
111.1 MBTAG

IMAGE ID

CREATEDlatest06a1f75304ba

2 days ago$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==06a1f75304ba redis

ラ ベル・ アフィニ ティの 例
ラベル・アフィニティによって、コンテナのラベルで引き寄せたセットアップが可能です。例えば、nginx コン
テナに com.example.type=frontend ラベルを付けて起動します。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 --label com.example.type=frontend nginx
87c4376856a8$ docker tcp://<manager_ip:manager_port> ps --filter "label=com.example.type=frontend"
CONTAINER ID
IMAGE
COMMAND
CREATEDSTATUS
PORTS
NAMES
87c4376856a8
nginx:latest"nginx"Less than a second ago running192.168.0.42:80->80/tcp
node-1/trusting_yonath
それから、 -e affinity:com.example.type==frontend を使って、com.example.type==frontend ラベルを持つコンテナの隣にスケジュールします。
$ docker tcp://<manager_ip:manager_port> run -d -e affinity:com.example.type==frontend logger
87c4376856a8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
87c4376856a8
nginx:latest"nginx"192.168.0.42:80->80/tcp
node-1/trusting_yonath
963841b138d8
logger:latest"logger"node-1/happy_hawking

CREATEDSTATUSLess than a second ago

running

Less than a second ago

runninglogger コンテナは、最終的に node-1 に置かれます。これはアフィニティに com.example.type==frontend ラベルを指定しているからです。

dependency フィルタ を使 う
コンテナの依存関係（dependency）フィルタは、既にスケジューリング済みのコンテナと同じ場所でスケジューリングするという依存関係をもたらします。現時点では、以下の依存関係を宣⾔できます。
- 89 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

 --volumes-from=dependency(共有ボリューム)
 --link=dependency:alias(リンク機能)
 --net=container:dependency(共有ネットワーク)
Swarm は依存関係のあるコンテナを同じノード上に置こうとします。もしそれができない場合（依存関係のあるコンテナが存在しない場合や、ノードが⼗分なリソースを持っていない場合）、コンテナの作成を拒否します。
必要であれば、複数の依存関係を組み合わせることもできます。例えば、 --volumes-from=A --net=container:B
は、コンテナ A と B を同じノード上に置こうとします。しかし、これらのコンテナが別々のノードで動いているな
ら、Swarm はコンテナのスケジューリングを⾏いません。

port フィ ルタを 使う
ポート（port）フィルタが有効であれば、コンテナのポート利⽤がユニークになるよう設定します。Docker Swarm
は対象のポートが利⽤可能であり、他のコンテナのプロセスにポートが専有されていないノードを選びます。ホスト側にポート番号を割り当てたい場合や、ホスト・ネットワーキング機能を使っている場合は、対象ポートの明⽰が必要になるかもしれません。
ブリッジ・ モー ドでの 例
デフォルトでは、コンテナは Docker のブリッジ・ネットワーク上で動作します。ブリッジ・ネットワーク上で
port フィルタを使うには、コンテナを次のように実⾏します。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
87c4376856a8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
87c4376856a8
nginx:latest"nginx"node-1/prickly_engelbart

PORTS
192.168.0.42:80->80/tcp

NAMES

Docker Swarm はポート 80 が利⽤可能であり他のコンテナ・プロセスに専有されていないノードを探します。
この例では node-1 にあたります。ポート 80 を使⽤する他のコンテナを起動しようとしても、Swarm は他のノードを選択します。理由は node-1 では既にポート 80 が使われているからです。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
963841b138d8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
963841b138d8
nginx:latest "nginx"
87c4376856a8
nginx:latest "nginx"
node-1/prickly_engelbart

PORTS
192.168.0.43:80->80/tcp
192.168.0.42:80->80/tcp

NAMES
node-2/dreamy_turing

同じコマンドを繰り返しますと node-3 が選ばれます。これは node-1 と node-2 の両⽅でポート 80 が使⽤済みのためです。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
963841b138d8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE
COMMAND
f8b693db9cd6 nginx:latest"nginx"

PORTS
192.168.0.44:80->80/tcp- 90 -

NAMES
docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

node-3/stoic_albattani
963841b138d8 nginx:latest
87c4376856a8 nginx:latest
node-1/prickly_engelbart

6.1 フィルタ

"nginx""nginx"192.168.0.43:80->80/tcp
192.168.0.42:80->80/tcp

node-2/dreamy_turing

最終的に、Docker Swarm は他のコンテナがポート 80 を要求しても拒否するでしょう。クラスタ上の全てのノードでポートが使えないためです。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
2014/10/29 00:33:20 Error response from daemon: no resources available to schedule container
各ノード中のポート 80 は、各コンテナによって専有されています。これはコンテナ作成時からのものであり、コンテナを削除するとポートは解放されます。コンテナが exited（終了）の状態であれば、まだポートを持っている状態です。もし node-1 の prickly_engelbart が停⽌したとしても、ポートの情報は削除されないため、node-1
上でポート 80 を必要とする他のコンテナの起動を試みても失敗します。nginx インスタンスを起動するには、
prickly_engelbart コンテナを再起動するか、あるいは prickly_engelbart コンテナを削除後に別のコンテナを起動します。

ホ スト・ ネッ トワー キング 機能 とノー ド・ポ ート・ フィルタ を使 う
コンテナ実⾏時に --net=host を指定したら、デフォルトの bridge モードとは違い、host モードはどのポートも拘束しません。そのため、host モードでは公開したいポート番号を明⽰する必要があります。このポート公開には Dockerfile で EXPOSE 命令を使うか、コマンドラインで --expose を指定します。Swarm は host モードで新しいコンテナを作成しようとする時にも、これらの情報を利⽤します。
例えば、以下のコマンドは３つのノードのクラスタで nginx を起動します。
$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
640297cb29a7$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
7ecf562b1b3f$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
09a92f582bc2
docker ps コマンドを実⾏してもポートをバインド（拘束）している情報が表⽰されないのは、全てのノードで host
ネットワークを利⽤しているためです。
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
640297cb29a7
nginx:1"nginx -g 'daemon ofbox3/furious_heisenberg
7ecf562b1b3f
nginx:1"nginx -g 'daemon ofbox2/ecstatic_meitner
09a92f582bc2
nginx:1"nginx -g 'daemon ofbox1/mad_goldstine

CREATEDSTATUSLess than a second ago

Up 30 seconds

Less than a second ago

Up 28 seconds

46 seconds ago

Up 27 seconds

４つめのコンテナを起動しようとしても、Swarm は処理を拒否します。
$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
FATA[0000] Error response from daemon: unable to find a node with port 80/tcp available in the Host mode
しかしながら、例えばポート 81 のように、異なった値のポートをバインドするのであれば、コマンドを実⾏で- 91 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

きます。
$ docker tcp://<manager_ip:manager_port> run -d -p 81:80 nginx:latest
832f42819adc$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
CREATED
PORTS
NAMES
832f42819adc
nginx:1"nginx -g 'daemon of Less than a second ago
second 443/tcp, 192.168.136.136:81->80/tcp box3/thirsty_hawking
640297cb29a7
nginx:1"nginx -g 'daemon of 8 seconds ago
box3/furious_heisenberg
7ecf562b1b3f
nginx:1"nginx -g 'daemon of 13 seconds ago
box2/ecstatic_meitner
09a92f582bc2
nginx:1"nginx -g 'daemon of About a minute ago
box1/mad_goldstine

STATUSUp Less than a
Up About a minute
Up About a minute
Up About a minute

6.1.4 フィルタ表現の書き方
ノード constraint やコンテナ affinity フィルタをノードに適⽤するには、コンテナがフィルタ表現を使うため
環境変数の指定が必要です。例：$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==~redis redis
表現は次のような記述⽅式です。
<フィルタ・タイプ>:<キー><演算子><値><フィルタ・タイプ> は affinity か constraint のキーワードのどちらかです。使いたいフィルタのタイプによって異なります。
<キー> は英数字のパターンであり、先頭はアルファベットかアンダースコアです。 <キー> に相当するのは以下の条件です。

 container キーワード
 node キーワード
 デフォルト・タグ（node 制限）
 カスタム・メタデータ・ラベル（node あるいは containers）<オペレータ>（演算⼦）は == か != のどちらかです。デフォルトではフィルタ処理はハード・エンフォース（hardenforced:強制）です。指定した表現に⼀致しなければ、マネージャはコンテナをスケジュールしません。 ~ （チルダ）を使い 「ソフト」表現を作成できます。こちらはフィルタ条件に⼀致しなくても、スケジューラ⾃⾝のス
トラテジに従ってコンテナを実⾏します。
<値> は英数字、ドット、ハイフン、アンダースコアと、以下を組み合わせせた⽂字列です。

 部分⼀致、例えば abc*。
 /regexp/ 形式の正規表現。Go ⾔語の正規表現構⽂をサポート。
現時点の Swarm は、以下のような命令をサポートしています。

- 92 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.1 フィルタ

 constraint:node==node1 は、ノード node1 に⼀致。
 constraint:node!=node1 は、node1 をのぞく全てのノードに⼀致。
 constraint:region!=us* は、us が付いているリージョン以外のノードに⼀致。
 constraint:node==/node[12]/ は、node1 と node2 に⼀致。
 constraint:node==/node\d/ は、node + 10 進数の１⽂字に⼀致。
 constraint:node!=/node-[01]/ は、node-0 と node-1 以外の全てのノードに⼀致。
 constraint:node!=/foo\[bar\]/ は、foo[var] 以外の全てのノードに⼀致。
 constraint:node==/(?i)node1/ は、⼤⽂字・⼩⽂字を区別しない node1 に⼀致。そのため、NoDe1 や NODE1も⼀致する。
 affinity:image==~redis は、redis に⼀致する名前のイメージがあるノード上でコンテナを実⾏。
 constraint:region==~us* は、*us に⼀致するリージョンのノードを探す。
 affinity:container!=~redis* は、 redis* という名前を持つコンテナが動いていないノードで node5 コン
テナをスケジュール。

- 93 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.2 ストラテジ

6.2 ストラテジ
Docker Swarm スケジューラは、複数のストラテジ（strategy；方針）機能でノードを順位付けします。選択したストラテジによって、Swarm が順位を算出します。Swarm で新しいコンテナを作成する時は、選択したストラ
テジに従って、コンテナを置くために最も順位の⾼いノードを算出します。
順位付けのストラテジを選択するには、swarm manage コマンドに --strategy フラグを使い、ストラテジ値を指定します。現時点でサポートしている値は次の通りです。
スプレッド

 spreadビンパック

 binpack
ラ ン ダ ム randomspread と binpack ストラテジは、ノードで利⽤可能な CPU、RAM、実⾏中のコンテナ数から順位を算出します。
random ストラテジは計算をしません。ノードをランダムに選択するもので、主にデバッグ⽤に使います。
あなたの会社の必要性に従ってクラスタを最適化するのが、ストラテジを選択する⽬的（ゴール）です。
spread ストラテジの下では、Swarm はノードで実⾏中のコンテナ数に応じて最適化します。pinback ストラテジ
は利⽤するノードが最も少なくなるよう最適化します。random ストラテジでは、利⽤可能な CPU やメモリに関わらずランダムにノードを選びます。
spread ストラテジを使えば、結果として多くのマシンに幅広く展開します。このストラテジの利点は、ノードがダウンしても、失われるのは⼩数のコンテナだけです。
binpack は分散しないストラテジです。これは、使っていないマシンに⼤きなコンテナを動かす余地を残すためです。この binpack ストラテジの利点は、できるだけ少ないマシンしか使わないよう、Swarm はノードに多くのコンテナを詰め込みます。
もし --strategy を指定しなければ、Swarm はデフォルトで spread を使います6.2.1 Spread ストラテジの例
この例では、Swarm は spread ストラテジでノードを最適化し、多くのコンテナを起動してみます。このクラス
タは、node-1 と node-2 は 2GB のメモリ、2CPU であり、他のノードではコンテナは動いていません。このスト
ラテジでは node-1 と node-2 は同じ順位です。
新しいコンテナを実⾏する時は、クラスタ上で同じランキングのノードが存在しますので、そこからランダムに
node-1 をシステムが選びます。
$ docker tcp://<manager_ip:manager_port> run -d -P -m 1G --name db mysql
f8b693db9cd6$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

次は別のコンテナで 1GB のメモリを使います。
$ docker run tcp://<manager_ip:manager_port> -d -P -m 1G --name frontend nginx
963841b138d8$ docker tcp://<manager_ip:manager_port> ps- 94 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.2 ストラテジ

CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
963841b138d8
nginx:latest"nginx"192.168.0.42:49177->80/tcp
node-2/frontend
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

Up About a minuterunningコンテナ frontend は node-2 で起動します。これは直前に実⾏したノードだからです。もし２つのノードがあって、同じメモリや CPU であれば、spread ストラテジは最後にコンテナを実⾏したノードを選びます。

2.6.2 BinPack ストラテジの例
この例では、node-1 と node-2 いずれも 2GB のメモリを持ち、コンテナを実⾏していないとします。ノードが同じ時、コンテナの実⾏は、今回はクラスタから node-1 が選ばれたとします$ docker run tcp://<manager_ip:manager_port> -d -P -m 1G --name db mysql
f8b693db9cd6$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

これで再び、1GB のメモリを使う別のコンテナを起動してみましょう。
$ docker run tcp://<manager_ip:manager_port> -d -P -m 1G --name frontend nginx
963841b138d8$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID
IMAGE
COMMAND
PORTS
NAMES
963841b138d8
nginx:latest"nginx"192.168.0.42:49177->80/tcp
node-1/frontend
f8b693db9cd6
mysql:latest"mysqld"
192.168.0.42:49178->3306/tcp
node-1/db

CREATEDSTATUSLess than a second ago

running

Up About a minuterunning

システムは node-1 上で新しい frontend コンテナを起動します。これはノードは既に集約するようになっているためです。これにより、2GB のメモリが必要なコンテナは node-2 で動きます。
もし２つのノードが同じメモリと CPU であれば、binpack ストラテジは最もコンテナが実⾏しているノードを選択します。

- 95 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

6.3 再スケジュール・ポリシー

6.3 再スケジュール・ポリシー
Docker Swarm で再スケジュール・ポリシーを設定できます。再スケジュール・ポリシーとは、コンテナを実⾏中のノードが落ちた時、再起動するかどうかを決めます。

6.3.1 再 スケジュール・ポリシー
コンテナ起動時に再スケジュール・ポリシー（reschedule policy）を設定できます。設定をするには reschedule
環境変数を指定するか、com.docker.swarm.reschedule-policy ラベルを指定します。ポリシーを指定しなければ、再スケジュール・ポリシーは off になります。つまり、ノードで障害が発⽣しても Swarm はコンテナを再スケジ
ュールしません（再起動しません）。
on-node-failure ポリシーを環境変数 reschedule で設定するには、$ docker run -d -e reschedule:on-node-failure redis
com.docker.swarm.reschedule-policy ラベルで同じポリシーを設定するには、$ docker run -d -l 'com.docker.swarm.reschedule-policy=["on-node-failure"]' redis

6.3.2 再 スケジュール・ログの確認
docker logs コマンドを使って再スケジュールしたコンテナの動作を確認できます。確認するには、次の構⽂を使います。
docker logs SWARM マネージャのコンテナ ID
コンテナの再スケジュールに成功したら、次のようなメッセージを表⽰します。
Rescheduled container 2536adb23 from node-1 to node-2 as 2362901cb213da321
Container 2536adb23 was running, starting container 2362901cb213da321
同様に、新しいノード上で新しいコンテナの起動に失敗したら、ログには次のように表⽰します。
Failed to start rescheduled container 2362901cb213da321- 96 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

７章

7 章 リファレンス

7.1 Swarm コマンドライン・リファレンス
swarm - Docker ネイティブのクラスタリング・システム
swarm コマンドは Docker Engine のホスト上に Swarm コンテナを起動し、指定されたサブコマンドに応じたタ
スクを処理します。
swarm は次の構⽂で使います。
$ docker run swarm [オプション] コマンド [引数...]
例えば、swarm で manage サブコマンドを使えば Swarm マネージャを作成します。この時、クラスタ上にある他のマネージャと可⽤性を持たせるには：$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication \--advertise 172.30.0.161:4000 consul://172.30.0.165:8500

オ プションswarm コマンドには以下のオプションがあります。

 --debug : デバッグ・モードを有効にします。Swarm ノードのデバッグ⽤に使うメッセージを表⽰します。
例： time=“ 2016-02-17T17:57:40Z ” level=fatal msg=“ discovery required to join a cluster. See ʻ swarm
join ‒ help ʼ.” 。このオプションは環境変数 ${DEBUG} でも指定可能です。
 --log-level "<値>" または -l "<値>" : ログレベルを指定します。 <値> に⼊るのは debug、info、warn、
error、fatal、panic です。デフォルト値は info です。
 --experimental : 実験的機能を有効にします。
 --help または -h : ヘルプを表⽰します。
 --version または -v : バージョン情報を表⽰します。例： $ docker run swarm ‒ version swarm version
1.1.0 (a0fd82b)- 97 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

コ マンドswarm コマンドには以下のサブコマンドがあります。

 create, c : ディスカバリ・トークンの作成
 list, l : Docker クラスタのノード⼀覧を表⽰
 manage, m : Swarm マネージャの作成
 join, j : Swarm ノードの作成
 help, h : Swarm コマンドの⼀覧を表⽰するか、各コマンドに対するヘルプを表⽰。

- 98 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

create - ディスカバリ・トークンの作成
create コマンドを実⾏したら、Docker Hub ホステット・ディスカバリ・バックエンドを使い、クラスタ⽤のユ
ニークなディスカバリ・トークンを作成します。
$ docker run --rm swarm create
86222732d62b6868d441d430aee4f055
後は Swarm マネージャやノード作成時に manage あるいは join コマンドで、このディスカバリ・トークンを<discovery> の引数として使います（例： token://86222732d62b6868d441d430aee4f055 ）。ディスカバリ・サービ
ス・バックエンドを通して、Swarm マネージャはクラスタ上のノードを認識するために利⽤します。
このディスカバリ・トークンは、ドキュメントによっては clouster_id と記述されているかもしれません。
【警告】Docker Hub のホステッド・ディスカバリ・バックエンドはプロダクション環境での利⽤が推奨されていません。純粋にテスト・開発⽬的での利⽤を意図しています。

具体的な利⽤⽅法や他のバックエンドに関する情報は「4.3 Docker Swarm ディスカバリ」をご覧ください。

- 99 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

list - クラスタ上のノード一覧
list を使うとクラスタ上のノード⼀覧を表⽰します。
クラスタのノードを表⽰するには、次の構⽂を使います。
docker run swarm list [オプション] <discovery>
次の例は <discovery> 引数を使う構⽂の例です。
etcd:
swarm list etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix> <node_ip:port>
Consul:swarm list consul://<consul_addr>/<optional path prefix> <node_ip:port>
ZooKeeper:swarm list zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix> <node_ip:port>

引数list コマンドは引数が１つだけあります。
<discovery> - ディス カバリ ・バ ック エンド
list コマンドの使⽤時、 <discovery> 引数を使って以下のバックエンドを指定可能です。

 token://<token>
 consul://<ip1>/<path> etcd://<ip1>,<ip2>,<ip2>/<path> file://<path/to/file> zk://<ip1>,<ip2>/<path> [nodes://]<iprange>,<iprange>
それぞれの項⽬は：

 <token> は Docker Hub のホステッド・ディスカバリ・サービスによって⽣成されるトークンです。このトークンを作成するには create コマンドを使います。
【警告】Docker Hub のホステッド・ディスカバリ・バックエンドは、プロダクション環境での利⽤が推奨されていません。テストもしくは開発⽤での利⽤を想定しています。

 ip1、ip2、ip3 はディスカバリ・バックエンド⽤ノードの IP アドレスとポート番号を指定します。
 path（オプション）はディスカバリ・バックエンドのキーバリュー・ストアのパスを指定します。複数のクラスタを１つのバックエンドで管理する場合は、各クラスタごとにキーバリューのペアを記述する必要があります。
- 100 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

 path/to/file は Swarm マネージャとクラスタのメンバであるノード情報の⼀覧と、それぞれの静的な IP
アドレスのリストを指定したファイルのパスを指定します。
 iprange は特定のポート番号を利⽤する IP アドレスの範囲を指定します。
実⾏例：

 ディスカバリ・トークン： token://0ac50ef75c9739f5bfeeaf00503d4e6e
 Consul ノード： consul://172.30.0.165:8500<discovery> は環境変数 $SWARM_DISCOVERY でも指定可能です。
より詳しい情報やサンプルについては、「4.3 Docker Swarm ディスカバリ」をご覧ください。

オ プション
list コマンドには以下のオプションがあります。
--timeout - タイムア ウト 期間--timeout="<期間>秒" はタイムアウトまでの感覚を秒で指定します。これは、ディスカバリ・バックエンドが⼀覧を返すまで待つ時間です。デフォルトの間隔は 10s です。
--discovery-opt - ディス カバ リ・ オプション
ディスカバリ・オプションに --discovery-opt <value> を使い、 TLS 設定で使⽤するファイル（CA 公開鍵証
明書、証明書）のパスや、分散キーバリュー・ストアのディスカバリ・バックエンドを指定します。このオプショ
ンは複数回利⽤可能です。例：--discovery-opt kv.cacertfile=/path/to/mycacert.pem \--discovery-opt kv.certfile=/path/to/mycert.pem \--discovery-opt kv.keyfile=/path/to/mykey.pem \より詳しい情報は「4.3 Docker Swarm ディスカバリ」をご覧ください。

- 101 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

manage - Swarm マネージャの作成
動作条件：Swarm マネージャで manage を使う前に、ディスカバリ・バックエンドの構築が必要です。
manage コマンドは Swarm マネージャを作成します。マネージャはクラスタに対するコマンド受信と、Swarm ノードにコンテナを割り当てる役割があります。⾼可⽤性クラスタ⽤に複数の Swarm マネージャの作成も可能です。
Swarm マネージャを作成するには、以下の構⽂を使います。
$ docker run swarm manage [オプション] <discovery>
例えば、Swarm マネージャを manage で作成時に、他のマネージャと⾼可⽤性クラスタを形成するには、次のよ
うに実⾏します。
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication \--advertise 172.30.0.161:4000 consul://172.30.0.165:8500
あるいは、Swarm マネージャ作成時、Docker クライアントと Swarm ノード間で TLS 認証を有効にするには、
次のように実⾏します。
$ docker run -d -p 3376:3376 -v /home/ubuntu/.certs:/certs:ro swarm manage \--tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/cert.pem --tlskey=/certs/key.pem \--host=0.0.0.0:3376 token://$TOKEN

引数
manage コマンドは引数を１つだけ指定できます。
<discovery> - ディス カバリ ・バ ック エンド
Swarm マネージャを作成する前に、ディスカバリ・トークンの作成とディスカバリ・バックエンドのセットアップが必要です。
Swarm ノードの作成時、 <discovery> 引数を使って以下のバックエンドを指定可能です。

 token://<token>
 consul://<ip1>/<path> etcd://<ip1>,<ip2>,<ip2>/<path> file://<path/to/file> zk://<ip1>,<ip2>/<path> [nodes://]<iprange>,<iprange>
それぞれの項⽬は：

 <token> は Docker Hub のホステッド・ディスカバリ・サービスによって⽣成されるトークンです。このトークンを作成するには create コマンドを使います。
 ip1、ip2、ip3 はディスカバリ・バックエンド⽤ノードの IP アドレスとポート番号を指定します。
 path（オプション）はディスカバリ・バックエンドのキーバリュー・ストアのパスを指定します。複数のクラスタを１つのバックエンドで管理する場合は、各クラスタごとにキーバリューのペアを記述する必要があります。
- 102 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

 path/to/file は Swarm マネージャとクラスタのメンバであるノード情報の⼀覧と、それぞれの静的な IP
アドレスのリストを指定したファイルのパスを指定します。
 iprange は特定のポート番号を利⽤する IP アドレスの範囲を指定します。
以下は <discovery> 引数の指定例です：

 ディスカバリ・トークン： token://0ac50ef75c9739f5bfeeaf00503d4e6e
 Consul ノード： consul://172.30.0.165:8500<discovery> は環境変数$SWARM_DISCOVERY でも指定可能です。
より詳しい情報やサンプルについては、「4.3 Docker Swarm ディスカバリ」をご覧ください。

オ プション
manage コマンドには以下のオプションがあります：

strategy - スケジュール 先のスト ラテジ--strategy "<値>" を使い、Docker Swarm スケジューラに対して何のストラテジを使うか指定します。
"値" の場所には：

 spread - 最も利⽤可能なリソースが多い Swarm ノードに対し、各コンテナを割り当てます。
 binpack - 割り当てられた Swarm ノードのリソースが溢れる前に、別のノードに割り当てます。
 random - ランダムな Swarm ノードにコンテナを割り当てます。
デフォルトでは、スケジューラは spread ストラテジを使います。
より詳しい情報はや例は「4.3 Docker Swarm ストラテジ」をご覧ください。

--ﬁlter 、 -f - スケジューラ・フィルタ--filter <値> もしくは -f <値> で、コンテナを作成・実⾏時、どのノードを使うかを Docker Swarm スケジューラに対して指定します。
<値> の場所には：

 health - ディスカバリ・バックエンドと通信可能な実⾏中ノードを使います。
 port - コンテナにポートを割り当てるために、適切なポート番号が利⽤可能なノード（つまり、他のコンテナやプロセスにポートが専有されていない環境）を使います。
 dependency - 依存関係を宣⾔しているコンテナの場合、依存関係のあるコンテナが起動しているノードを使います。
 affinity - アフィニティが宣⾔されたコンテナの場合は、アフィニティが同⼀のノードを使います。
- 103 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

 constraint - 制約（constraint）が宣⾔されたコンテナの場合は、同⼀の制約を持つノードを使います。
複数のスケジューラ・フィルタを使うには、次のようにします。
--filter <value> --filter <value>より詳しい情報や例は「6.1 フィルタ」をご覧ください。

--host , -H - リッス ンする IP ／ポ ート--host <IP>:<ポート> もしくは -H <ip>:<ポート> を使い、マネージャがメッセージを受信するための IP アドレ
スとポート番号を指定します。ip の部分に 0 を使うか省略したら、manager はデフォルトのホスト IP を使います。
例： --host=0.0.0.0:3376 または -H :4000 。
--host は環境変数$SWARM_HOST でも指定できます。

--replication - Swarm マネ ージ ャ複 製の有効化
⾼可⽤性クラスタでは、プライマリとセカンダリ・マネージャ間で、Swarm マネージャの複製（レプリケーション）を可能にします。プライマリからセカンダリにクラスタ情報のミラーを複製します。つまりプライマリ・マネ
ージャで障害が起これば、セカンダリがプライマリ・マネージャになれます。

--replication-ttl - リ ーダー障 害発生 時のロック解除時間--replication-ttl "<遅延>s" を使い、遅延時間を秒で指定します。これはセカンダリ・マネージャがプライマ
リ・マネージャがダウンまたは到達可能と通知する時間です。この通知をトリガとして、セカンダリ・マネージャの誰がプライマリ・マネージャになるのか選出されます。デフォルトの遅延は 15 秒です。

--advertise , --addr - Docker Engine のアドバタイズ用 IP とポート番号--advertise <ip>:<ポート> か --addr <ip>:<ポート> を使い Docker Engine のアドバタイズ（Advertise; 周知⽤）
IP アドレスとポート番号を指定します。例： --advertise 172.30.0.161:4000 。他の Swarm マネージャは、対象の Swarm マネージャに接続するため、ここで指定した IP アドレスとポート番号を使う必要があります。
--advertise は環境変数$SWARM_ADVERTISE でも指定できます。

--tls - TLS の有 効化--tls を使い TLS（トランスポート・レイヤ・セキュリティ）を有効化します。 --tlsverify を使う場合は --tlsの使⽤は不要です。

--tlscacert - 証明 局(CA) の公開 鍵フ ァイルのパス--tlscacert=<path/file> を使い証明局（CA）⽤の公開鍵（証明書）のパスとファイル名を指定します。例：--tlscacert=/certs/ca.pem 。指定したら、マネージャが信頼するのは、同じ証明局で署名された証明書を使っているリモート環境のみです。

--tlscert - ノー ドの TLS 証 明書フ ァイル のパス--tlskey を使い、マネージャの証明書（CA によって署名済み）のファイル名とパスを指定します。例：--tlskey=/certs/key.pem 。
- 104 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス--tlskey - ノー ドの TLS 鍵フ ァイル のパス--tlskey を使いマネージャの秘密鍵（CA によって署名済み）のファイル名とパスを指定します。例：--tlskey=/certs/key.pem 。

--tlsverify - TLS を使 いリ モート 環境 を確認--tlsverify を使い TLS 通信を有効化し、同⼀の証明局（CA）で署名された証明書を持っているマネージャ、ノード、クライアントのみ通信を許可します。 --tlsverify を使えば、 --tls を使う必要はありません。

--engine-refresh-min-interval - Engine の最小リフレッシュ間隔を指定--engine-refresh-min-interval "<間隔>s" を使い、Engine を例フレッシュするまでの最⼩間隔を秒単位で指定します。デフォルトでは、この間隔は 30 秒です。
プライマリ・マネージャが Engine をリフレッシュするというのは、クラスタ上にある Engine の情報を更新することです。マネージャはこの情報を Engine が正常（healthy）かどうか決めるた
めに使います。接続できなければ、マネージャは対象ノードを障害（unhealthy）とみなします。
マネージャは指定した間隔ごとに再度 Engine 情報の更新を試みます。規定回数の再試⾏してEngine が応答するのであれば、再び Engine を正常（healthy）とみなします。もしそうでなけれ
ば、マネージャは再試⾏を停⽌し、対象の Engine を無視します。

--engine-refresh-max-interval - Engine 最大リフレッシュ間隔を指定--engine-refresh-max-interval "<間隔>秒" を使い、リフレッシュまでの最⼤間隔を秒単位で指定します。デフォルトでは、この間隔は 60 秒です。

--engine-failure-retry - Engine のリ トライ失敗回数--engine-failure-retry "数値" を使い、Engine が障害とみなすまでの再試⾏の回数を指定します。デフォルト
では、3 回再試⾏します。

--engine-refresh-retry - 廃止 予定
廃⽌予定； --engine-failure-retry "数値" の代わりに --engine-failure-retry を使います。デフォルトは 3です。

--heartbeat - ハー トビー ト間 隔--heartbeat "<間隔>s" を使い、マネージャとプライマリ・マネージャ間のハードビート間隔を秒単位で指定します。ハードビートとはマネージャが正常で到達可能であるかを確認します。デフォルトでは、この間隔は 60 秒です。

--api-enable-cors , --cors - リ モー ト API の CORS ヘッダを 有効 化--api-remote-cors か --cors を使い CORS (cross-origin resource sharing)ヘッダをリモート API に⼊れます。

--cluster-driver , -c - 使用 するク ラスタ・ドライバ--cluster-driver "ドライバ" か -c "<ドライバ>" を使い、使⽤するクラスタ・ドライバを指定します。 <ドライバ> に指定できるのは、以下のどちらかです。
- 105 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

 swarm は Docker Swarm ドライバです。
 mesos-experimental は Mesos クラスタ・ドライバです。
デフォルトは swarm ドライバです。
Mesos ドライバの利⽤に関する詳しい情報は、Using Docker Swarm and Mesos*1 をご覧ください。

--cluster-opt - クラ スタ ・ド ライバのオ プション
複数のクラスタ・ドライバのオプションを --cluster-opt <値> --cluster-opt <値> の形式で指定できます。
<値> の場所に⼊る項⽬は以下の通りです：

 swarm.overcommit=0.05 - リソースをオーバー・コミットする割合（パーセント）を指定します。デフォ
ルト値は 0.05 であり、５パーセントを意味します。
 swarm.createretry=0 - コンテナ作成に何度失敗すると障害とみなすかを指定します。デフォルトの値は 0
回の再試⾏です。
 mesos.address= - バインドする Mesos のアドレスを指定します。このオプションは環境変数$SWARM_MESOS_ADDRESS でも指定できます。
 mesos.checkpointfailover=false - Mesos のチェックポインティング（checkpointing）を有効化します。
これは、以前まで使っていたエクゼキュータの状態が復旧したら、スレーブが再接続できるようにします。
この時、ディスク I/O を消費します。このオプションは環境変数$SWARM_MESOS_CHECKPOINT_FAILOVER でも指定できます。デフォルト値は false（無効）です。
 mesos.port= - Mesos がバインドするポートを指定します。このオプションは環境変数$SWARM_MESOS_PORT
でも指定できます。
 mesos.offertimeout=30s - Mesos がタイムアウトと判断する秒を指定します。このオプションは環境変数$SWARM_MESOS_OFFER_TIMEOUT でも指定できます。デフォルトの値は 30s です。
 mesos.offerrefusetimeout=5s - Mesos がリソースの再利⽤ができないと判断する秒を指定します。このオ
プションは環境変数$SWARM_MESOS_OFFER_REFUSE_TIMEOUT でも指定できます。デフォルトの値は 5s です。
 mesos.tasktimeout=5s - Mesos のタスク作成までのタイムアウトを秒で指定します。このオプションは環
境変数$SWARM_MESOS_TASK_TIMEOUT でも指定できます。デフォルトの値は 5s です。
 mesos.user= - Mesos フ レ ー ム ワ ー ク の ユ ー ザ 名 を 指 定 し ま す 。 こ の オ プ シ ョ ン は 環 境 変 数$SWARM_MESOS_USER でも指定できます。

--discovery-opt - ディス カバ リ・ オプション--discovery-opt <値> を使いディスカバリオプションを指定します。これには Consul や etcd ディスカバリ・サービスが使⽤する TLS ファイル（CA 公開鍵証明書、証明書、プライベート鍵）の指定も含みます。ディスカバリ
・オプションは何度も指定できます。例：--discovery-opt kv.cacertfile=/path/to/mycacert.pem \--discovery-opt kv.certfile=/path/to/mycert.pem \--discovery-opt kv.keyfile=/path/to/mykey.pem \より詳しい情報は「4.3 Docker Swarm ディスカバリ」をご覧ください。

*1 https://github.com/docker/swarm/blob/master/cluster/mesos/README.md- 106 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

join - Swarm ノードの作成
動作条件：Swarm マネージャで manage を使う前に、ディスカバリ・バックエンドの構築が必要です。
join コマンドは Swarm ノードを作成します。Swarm ノードはクラスタ内でコンテナを実⾏する場所という役割があります。⼀般的なクラスタは複数の Swarm ノードを持ちます。
Swarm ノードを作成するには、次の構⽂を使います。
$ docker run swarm join [OPTIONS] <discovery>
例えば、Swarm ノードを⾼可⽤性クラスタ対応マネージャに接続するには、次のように実⾏します。
$ docker run -d swarm join --advertise=172.30.0.69:2375 consul://172.30.0.161:8500
あるいは、Swarm ノード作成時、Docker Swarm ノード間で TLS 認証の有効化は、次のように実⾏します。
$ sudo docker run -d swarm join --addr=node1:2376 token://86222732d62b6868d441d430aee4f055

引数join コマンドは引数を１つだけ指定できます。
<discovery> - ディス カバリ ・バ ック エンド
Swarm マネージャを作成する前に、ディスカバリ・トークンの作成とディスカバリ・バックエンドのセットアップが必要です。
Swarm ノードの作成時、 <discovery> 引数を使って以下のバックエンドを指定可能です。

 token://<token>
 consul://<ip1>/<path> etcd://<ip1>,<ip2>,<ip2>/<path> file://<path/to/file> zk://<ip1>,<ip2>/<path> [nodes://]<iprange>,<iprange>
それぞれの項⽬は：

 <token> は Docker Hub のホステッド・ディスカバリ・サービスによって⽣成されるトークンです。このトークンを作成するには create コマンドを使います。
 ip1、ip2、ip3 はディスカバリ・バックエンド⽤ノードの IP アドレスとポート番号を指定します。
 path（オプション）はディスカバリ・バックエンドのキーバリュー・ストアのパスを指定します。複数のクラスタを１つのバックエンドで管理する場合は、各クラスタごとにキーバリューのペアを記述する必要があります。
 path/to/file は Swarm マネージャとクラスタのメンバであるノード情報の⼀覧と、それぞれの静的な IP
アドレスのリストを指定したファイルのパスを指定します。
 iprange は特定のポート番号を利⽤する IP アドレスの範囲を指定します。
- 107 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

以下は <discovery> 引数の指定例です：

 ディスカバリ・トークン： token://0ac50ef75c9739f5bfeeaf00503d4e6e
 Consul ノード： consul://172.30.0.165:8500<discovery> は環境変数$SWARM_DISCOVERY でも指定可能です。
より詳しい情報やサンプルについては、「4.3 Docker Swarm ディスカバリ」をご覧ください。

オ プション
join コマンドには以下のオプションがあります：--advertise , --addr - Docker Engine のアドバタイズ用 IP とポート番号--advertise <ip>:<ポート> か --addr <ip>:<ポート> を使い Docker Engine のアドバタイズ（Advertise; 周知⽤）
IP アドレスとポート番号を指定します。例： --advertise 172.30.0.161:4000 。他の Swarm マネージャは、対象の Swarm マネージャに接続するため、ここで指定した IP アドレスとポート番号を使う必要があります。
--advertise は環境変数$SWARM_ADVERTISE でも指定できます。

--heartbeat - ハー トビー ト間 隔--heartbeat "<間隔>s" を使い、マネージャとプライマリ・マネージャ間のハードビート間隔を秒単位で指定します。ハードビートとはマネージャが正常で到達可能であるかを確認します。デフォルトでは、この間隔は 60 秒です。

--ttl - エフェメ ラル ・ノー ドの 期限を 設定--ttl "<間隔>s" を使い、エフェメラル・ノードに対する TTL (time-to-live) 間隔を秒数で指定します。デフォ
ルトの間隔は 180s です。

--delay - 一斉 登録し ないよう ランダム遅延を [0s,delay] で指定--delay "間隔
" の形式で、ディスカバリバックエンドがノードを登録するまで、ランダムに遅延させる最⼤秒数を指定します。多数のノードをデプロイする時、ランダムに登録間隔の遅延を発⽣することで、ディスカバリ
・バックエンドが飽和しないように（応答不能にならないように）します。

--discovery-opt - ディス カバ リ・ オプション--discovery-opt <値> を使いディスカバリオプションを指定します。これには Consul や etcd ディスカバリ・サービスが使⽤する TLS ファイル（CA 公開鍵証明書、証明書、プライベート鍵）の指定も含みます。ディスカバリ
・オプションは何度も指定できます。例：--discovery-opt kv.cacertfile=/path/to/mycacert.pem \--discovery-opt kv.certfile=/path/to/mycert.pem \--discovery-opt kv.keyfile=/path/to/mykey.pem \より詳しい情報は「4.3 Docker Swarm ディスカバリ」をご覧ください。

- 108 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.1 Swarmコマンドライン・リファレンス

help - コマンドに関する情報の表示
help コマンドは各コマンドの使い⽅に関する情報を表⽰します。
例えば、Swarm のオプション⼀覧を表⽰するには、次のように実⾏します：$ docker run swarm --help
特定の Swarm コマンドのオプションに対する引数⼀覧を確認するには、次のように実⾏します。
$ docker run swarm <コマンド> --help
実⾏例：$ docker run swarm list --help
Usage: swarm list [OPTIONS] <discovery>
List nodes in a cluster
Arguments:<discovery>

discovery service to use [$SWARM_DISCOVERY]* token://<token>* consul://<ip>/<path>* etcd://<ip1>,<ip2>/<path>* file://path/to/file* zk://<ip1>,<ip2>/<path>* [nodes://]<ip1>,<ip2>

Options:--timeout "10s"timeout period--discovery-opt [--discovery-opt option --discovery-opt option] discovery options- 109 -

docs.docker.jp

16/06/02

Docker Swarm ユーザガイド v1.1 - beta1

7.2 Docker Swarm API

7.2 Docker Swarm API
Docker Swarm API は Docker リモート API と広範囲の互換性があります。このセクションは、Swarm API とDocker リモート API 間の違いに関する概要を説明します。

エンドポイントが無い場合
いくつかのエンドポイントは未実装のため、その場合は 404 エラーを返します。
POST "/images/create" : "docker import" flow not implement

異なる動作をするエンドポイント

 GET "/containers/{name:.*}/json" : Node 追加時の新しいフィールドです。
"Node": {"Id": "ODAI:IC6Q:MSBL:TPB5:HIEE:6IKC:VCAM:QRNH:PRGX:ERZT:OK46:PMFX","Ip": "0.0.0.0","Addr": "http://0.0.0.0:4243","Name": "vagrant-ubuntu-saucy-64",},
 GET "/containers/{name:.*}/json" : HostIP が 0.0.0.0 の場合、実際のノード IP アドレスに置き換えます。
 GET "/containers/json" : コンテナ名の前にノード名が付きます。
 GET "/containers/json" : HostIP が 0.0.0.0 の場合、実際のノード IP アドレスに置き換えます。
 GET "/containers/json" : 公式 swarm イメージを使ってコンテナを起動した場合、デフォルトでは表⽰しません。表⽰するには all-1 を使います。
 GET "/images/json" : – filter node=<ノード名> を使うことで、特定のノードのイメージ情報を表⽰します。
 POST "/containers/create" : HostConfig の CpuShares 設定で、コンテナに対する CPU コアの割当数を指定します。

- 110 -

docs.docker.jp

16/06/02