Docker Engine Swarmモード入門チュートリアル – クラスタオーケストレーションの基本
「Swarm」と聞くとパンクロックバンドの名前のように響きますが、実際はDockerに新たに搭載されたオーケストレーション機構、正確には既存のオーケストレーション機能の大幅な強化版です。簡潔にまとめると、古いバージョンのDockerでは、Dockerクラスタを構築するためにSwarmを手動でセットアップする必要がありました。しかしバージョン1.12以降、Docker Engineにはネイティブ実装が組み込まれ、シームレスなクラスタ構築が可能になっています。これこそが本記事のテーマです。
このチュートリアルでは、Dockerのオーケストレーション機能が何をしてくれるのか、その魅力を実際に体験してもらいます。網羅的な解説ではありませんが、クラスタリングへの第一歩を踏み出すには十分な内容となっています。
技術概要
詳細で有用なDocker公式ドキュメントを繰り返し説明するのは野暮なので、ここでは技術の概要だけを簡単に紹介します。まずDockerがありますよね。次に、1台のサーバーだけでなく複数のサーバーをDockerホストとして使い、それらを同じ論理的なエンティティとして扱いたいとします。そこで必要になるのがクラスタリングです。
まずは「1ノードのクラスタ」から始めましょう。ホスト上でswarmを初期化すると、そのホストはクラスタのマネージャーになります。技術的に言えば、これは1ノードからなるコンセンサスグループであり、その背後にある数学的ロジックはRaftアルゴリズムに基づいています。マネージャーはタスクのスケジューリングを担当し、ワーカーノードがswarmに参加するとタスクが委譲されます。これを制御するのがNode APIです。「API」という言葉は好みませんが、ここでは使わざるを得ません。
もう一つの重要な構成要素がService APIです。これにより、マネージャーノードはswarm内のすべてのノードに分散サービスを作成できます。サービスは「レプリケート(replicated)」モード、つまりロードバランシング機構によってクラスタ全体に分散されるか、「グローバル(global)」モード、つまり各ノードで1インスタンスずつ実行されるかを選択できます。
内部ではさらに多くの仕組みが動いていますが、入門としては十分でしょう。それでは、実際に手を動かしてみましょう。対象プラットフォームはCentOS 7.2です。これが少し興味深いのは、このチュートリアルを執筆した時点ではリポジトリにDocker 1.10しかなく、swarmを使うためにフレームワークを手動でアップグレードする必要があったからです。これについては別のチュートリアルで解説します。また、続編ガイドでは新しいノードをクラスタに参加させ、Fedoraを使った非対称な構成も試す予定です。ここでは正しいセットアップが済んでいるものとして、クラスタサービスを起動してみましょう。
イメージとサービスのセットアップ
ここでは、単一のIPアドレス経由で複数インスタンスがコンテンツを配信する、ロードバランスされたApacheサービスを構築します。ごく標準的な構成で、クラスタ構成を採用する典型的な理由——可用性、冗長性、水平スケーリング、パフォーマンス——もよく分かります。もちろんネットワーキングやストレージへの考慮も必要ですが、それらは本ガイドの範囲を超えるため割愛します。
実際のDockerfileテンプレートは公式リポジトリのhttpd配下にあります。始めるのに最小限のセットアップで十分です。イメージのダウンロード方法や自作イメージの作成方法などの詳細は、冒頭でリンクした入門ガイドを参照してください。
docker build -t my-apache2 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM httpd:2.4
Trying to pull repository docker.io/library/httpd ...
2.4: Pulling from docker.io/library/httpd
8ad8b3f87b37: Pull complete
c95e1f92326d: Pull complete
96e8046a7a4e: Pull complete
00a0d292c371: Pull complete
3f7586acab34: Pull complete
Digest: sha256:3ad4d7c4f1815bd1c16788a57f81b413...a915e50a0d3a4
Status: Downloaded newer image for docker.io/httpd:2.4
---> fe3336dd034d
Step 2 : COPY ../public-html/ /usr/local/apache2/htdocs/
...
先に進む前に、まず単一インスタンスを起動し、コンテナがエラーなしで作成され、Webサーバーに接続できることを確認しておきましょう。確認できたら、分散サービスを作成します。
docker run -dit --name my-running-app my-apache2
IPアドレスを確認してブラウザでアクセスし、結果をチェックしてください。
Swarmの初期化とセットアップ
次のステップはswarmを起動することです。以下は最も基本的なコマンドで、Docker公式ブログの例ともよく似ています。
docker service create --name frontend --replicas 5 -p 80:80/tcp my-apache2:latest
ここで何をしているのでしょうか?「frontend」という名前のサービスを5つのコンテナインスタンスで作成しています。同時に、ホスト側のポート80とコンテナ側のポート80をバインドし、新しく作成したApacheイメージを使用しています。しかし、これを実行すると次のエラーが表示されます。
docker service create --name frontend --replicas 5 -p 80:80/tcp my-apache2:latest
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
これは、現在のホスト(ノード)がswarmマネージャーとして設定されていないことを意味します。swarmを初期化するか、既存のswarmに参加する必要があります。まだ存在しないので、ここでは初期化を行いましょう。
docker swarm init
Swarm initialized: current node (dm58mmsczqemiikazbfyfwqpd) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-4ofd46a2nfyvrqwu8w5oeetukrbylyznxla
9srf9vxkxysj4p8-eu5d68pu5f1ci66s7w4wjps1u \
10.0.2.15:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
出力はかなり自己説明的です。swarmが作成され、新しいノードは正しいトークンを使って参加する必要があります。ファイアウォールルールが必要な場合に備えて、IPアドレスとポートも明示されています。さらに、マネージャーをswarmに追加することも可能です。それでは、service createコマンドを再実行しましょう。
docker service create --name frontend --replicas 5 -p 80:80/tcp my-apache2:latest
6lrx1vhxsar2i50is8arh4ud1
接続テスト
次に、サービスが実際に動作しているか確認しましょう。ある意味、以前VagrantとCoreOSで行ったことと似ています。結局のところ、概念はほぼ同一であり、同じアイデアの異なる実装にすぎません。まず、docker psが正しい出力を表示するはずです。作成したサービスの複数のレプリカが表示されていることを確認してください。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
NAMES
cda532f67d55 my-apache2:latest "httpd-foreground"
2 minutes ago Up 2 minutes 80/tcp frontend.1.2sobjfchdyucschtu2xw6ms9a
75fe6e0aa77b my-apache2:latest "httpd-foreground"
2 minutes ago Up 2 minutes 80/tcp frontend.4.ag77qtdeby9fyvif5v6c4zcpc
3ce824d3151f my-apache2:latest "httpd-foreground"
2 minutes ago Up 2 minutes 80/tcp frontend.2.b6fqg6sf4hkeqs86ps4zjyq65
eda01569181d my-apache2:latest "httpd-foreground"
2 minutes ago Up 2 minutes 80/tcp frontend.5.0rmei3zeeh8usagg7fn3olsp4
497ef904e381 my-apache2:latest "httpd-foreground"
2 minutes ago Up 2 minutes 80/tcp frontend.3.7m83qsilli5dk8rncw3u10g5a
デフォルト以外の異なるポートでもテストしましたが、こちらも問題なく動作します。サーバーへの接続方法には多くの選択肢があります。localhostでも、dockerインターフェースのIPアドレスと適切なポートの組み合わせでも接続できます。以下の例ではポート1080を使用しています。
ここまでは、非常に大雑把でシンプルな最初の一歩にすぎません。本当の課題は、最適化されたスケーラブルなサービスの構築にありますが、それには適切な技術的なユースケースが必要です。また、docker infoやdocker service (inspect|ps)といったコマンドを活用して、クラスタの動作状況をより深く把握することをおすすめします。
起こりうる問題
Dockerとswarmを試していると、小さな(あるいはそうでもない)問題に遭遇することがあります。例えば、SELinuxが不正な操作を検知して警告を出すかもしれません。ただし、これらのエラーや警告が作業の大きな妨げになることはないはずです。
「docker: 'service' is not a docker command」エラー
レプリケートされたサービスを開始するためのコマンドを実行すると、「docker: 'service' is not a docker command」というエラーが表示されることがあります。これは、インストールされているDockerのバージョンが適切でないことを意味します(-vオプションで確認できます)。対処法については続編のチュートリアルで解説します。
docker service create --name frontend --replicas 5 -p 80:80/tcp my-apache2:latest
docker: 'service' is not a docker command.
タグが認識されないエラー
次のようなエラーが表示されることもあります。
docker service create -name frontend -replicas 5 -p 80:80/tcp my-apache2:latest
Error response from daemon: rpc error: code = 3 desc = ContainerSpec: "-name" is not a valid repository/tag
この件については複数の議論スレッドがあります。実はこのエラーは無害な場合も少なくありません。ブラウザからコマンドをコピーした際に、ハイフンが正しく解析されなかった可能性があります。原因はそれだけのことです。
さらなる読み物
このトピックについては、Docker 1.12以前のStandalone Swarm実装や現行のDocker Engineなど、まだ語るべきことがたくさんあります。ぜひ時間をかけて以下の資料を読んでみてください。
- Docker Swarm overview(スタンドアロンSwarmインストール向け)
- Build a Swarm cluster for production(スタンドアロンセットアップ向け)
- Install and create a Docker Swarm(スタンドアロンセットアップ向け)
- Docker engine swarm overview(バージョン1.12向け)
- Getting started with swarm mode(バージョン1.12向け)
まとめ
以上です。現時点では大げさな内容ではありませんが、本記事はきっと役立つはずです。いくつかの重要な概念を取り上げ、swarmモードの仕組みと動作の概要を説明し、独自のWebサーバーイメージをダウンロード・作成して、そのクラスタ化された複数インスタンスを実行することに成功しました。今回はシングルノードでの構成でしたが、今後はマルチノードへと拡張していきます。また、いくつかのよくある問題への対処法も紹介しました。
このガイドが面白いと感じてもらえたら幸いです。以前のDocker関連の記事と併せて読めば、イメージの操作、ネットワーキングスタック、ストレージ、そして今回のクラスタ構築について、しっかりとした理解が得られるはずです。まだウォーミングアップ段階です。ぜひ楽しんでください。Dockerの新しいチュートリアルでお会いしましょう。
それでは、また。
-
KVMのストレージ管理を徹底解説!ストレージプールとボリュームの作成チュートリアル
さて、先日、Kernel-based Virtual Machine(KVM)という技術をご紹介しました。KVMは無料かつオープンソースの仮想化ソリューションで、VirtualBoxやVMware製品の代わりとして、あるいはそれらと併用して使うこともできます。前回は基本的な管理操作を扱いましたが、ストレージとネットワークについては別のチュートリアルに回すことにしました。 今回は、KVMにおけるストレージ管理について、より踏み込んだガイドをお届けします。内容はVirtualBoxで行ったものと似ており、仮想ディスクの追加・縮小・拡張などが含まれます。さらに、NFSストレージやNTFSフォーマット
-
VirtualBoxでディスクをクローンする方法【VBoxManage活用チュートリアル】
仮想化を業務でも趣味でも利用している方なら、VirtualBoxという強力かつ多用途な無料ソリューションを目にしたことがあるかもしれません。VirtualBoxは、デスクトップユーザーに対して、あらゆる形でOSを展開できる大きな柔軟性を提供してくれます。さらに、単なる趣味として仮想化を楽しんでいるだけでなく、仮想化を通じて新しいOSを学ぼうとする熱心なソフトウェア愛好家の方であれば、次のような場面に必ず直面することでしょう。それは「大量の仮想マシンを展開する必要がある」というシナリオです。一台ずつインストール作業を行う時間的な余裕はないはずです。実際、大規模に環境を展開する際に手動で一つずつマ