ウェビナーシリーズ
この記事は、クラウドでのコンテナー化されたワークロードのデプロイと管理に関するウェビナーシリーズを補足するものです。 このシリーズでは、コンテナのライフサイクル管理、マルチコンテナアプリケーションのデプロイ、ワークロードのスケーリング、Kubernetesの理解など、コンテナの基本事項を取り上げ、ステートフルアプリケーションを実行するためのベストプラクティスを紹介します。
このチュートリアルには、シリーズの2番目のセッションであるコンテナ化されたアプリケーションの構築で説明されている概念とコマンドが含まれています。
序章
前回のチュートリアルDockerのインストールと構成方法では、DockerコンテナーをDockerイメージに変換する1つの方法について説明しました。 私たちが使用した方法は機能しましたが、それが常に画像を構築するための最適な方法であるとは限りません。
多くの場合、既存のコードをコンテナイメージに取り込み、コードベースの最新バージョンと同期するDockerイメージを作成するための反復可能で一貫性のあるメカニズムが必要になります。
Dockerfile は、Dockerイメージを構築するための宣言的で一貫した方法を提供することにより、これらの要件に対応します。
さらに、一緒にデプロイおよび管理される複数の異種コンテナーで構成されるアプリケーション全体をコンテナー化する必要がある場合があります。
Docker Compose は、Dockerfileと同様に、宣言型のアプローチを採用して、ネットワークとストレージの要件を含むテクノロジースタック全体を定義する方法を提供します。 これにより、コンテナ化されたアプリケーションの構築が容易になるだけでなく、それらの管理とスケーリングも容易になります。
このチュートリアルでは、Node.jsとMongoDBに基づくサンプルWebアプリケーションを使用してDockerfileからDockerイメージを構築し、Dockerコンテナーを許可するカスタムネットワークを作成します通信し、DockerComposeを使用してコンテナー化されたアプリケーションを起動およびスケーリングします。
前提条件
このチュートリアルに従うには、次のものが必要です。
- このUbuntu16.04初期サーバーセットアップチュートリアルに従ってセットアップされた1つのUbuntu16.04ドロップレット。これには、sudo非rootユーザーとファイアウォールが含まれます。
- このウェビナーシリーズの最初のチュートリアルに従ってインストールされたDockerCommunityEditionの最新バージョン。
ステップ1—Dockerfileを使用してイメージを構築する
まずホームディレクトリに移動し、 Git を使用して、GitHubの公式リポジトリからこのチュートリアルのサンプルWebアプリケーションのクローンを作成します。
- cd ~
- git clone https://github.com/janakiramm/todo-app.git
これにより、サンプルアプリケーションがという名前の新しいディレクトリにコピーされます todo-app
.
切り替える todo-app
と使用 ls
ディレクトリの内容を表示します。
- cd todo-app
- ls
新しいディレクトリには、2つのサブディレクトリと2つのファイルが含まれています。
app
-サンプルアプリケーションのソースコードが保存されているディレクトリcompose
-DockerCompose構成ファイルが保存されているディレクトリDockerfile
-Dockerイメージをビルドするための手順を含むファイルREADME.md
-サンプルアプリケーションの1文の要約を含むファイル
ランニング cat Dockerfile
次のことを示しています。
FROM node:slim
LABEL maintainer = "jani@janakiram.com"
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY ./app/ ./
RUN npm install
CMD ["node", "app.js"]
このファイルの内容をさらに詳しく見てみましょう。
FROM
カスタムイメージを構築しているベースイメージを示します。 この例では、画像はに基づいていますnode:slim
、 public Node.js image には、実行に必要な最小限のパッケージのみが含まれていますnode
.LABEL
は、説明情報を追加するために通常使用されるキーと値のペアです。 この場合、メンテナのメールアドレスが含まれています。RUN
コンテナ内でコマンドを実行します。 これには、ディレクトリの作成や、基本的なLinuxコマンドの実行によるコンテナの初期化などのタスクが含まれます。 最初RUN
このファイルのコマンドは、ディレクトリを作成するために使用されます/usr/src/app
ソースコードを保持します。WORKDIR
すべてのコマンドが実行されるディレクトリを定義します。 これは通常、コードがコピーされるディレクトリです。COPY
ホストマシンからコンテナイメージにファイルをコピーします。 この場合、全体をコピーしていますapp
画像へのディレクトリ。- 二番目
RUN
コマンドが実行されますnpm install
で定義されているようにアプリケーションの依存関係をインストールしますpackage.json
. CMD
コンテナの実行を維持するプロセスを実行します。 この例では、を実行しますnode
パラメータ付きapp.js
.
次に、からイメージを作成します。 Dockerfile
. 使用 -t
レジストリのユーザー名、画像名、およびオプションのタグで画像にタグを付けるように切り替えます。
- docker build -t sammy/todo-web .
出力は、画像が Successfully built
適切にタグ付けされています。
Output from docker build -tSending build context to Docker daemon 8.238MB
Step 1/7 : FROM node:slim
---> 286b1e0e7d3f
Step 2/7 : LABEL maintainer = "jani@janakiram.com"
---> Using cache
---> ab0e049cf6f8
Step 3/7 : RUN mkdir -p /usr/src/app
---> Using cache
---> 897176832f4d
Step 4/7 : WORKDIR /usr/src/app
---> Using cache
---> 3670f0147bed
Step 5/7 : COPY ./app/ ./
---> Using cache
---> e28c7c1be1a0
Step 6/7 : RUN npm install
---> Using cache
---> 7ce5b1d0aa65
Step 7/7 : CMD node app.js
---> Using cache
---> 2cef2238de24
Successfully built 2cef2238de24
Successfully tagged sammy/todo-web:latest
イメージが作成されたことを確認するには、 docker images
指図。
- docker images
ここでは、画像のサイズと、画像が作成されてからの経過時間を確認できます。
Output from docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
sammy/todo-web latest 81f5f605d1ca 9 minutes ago 236MB
サンプルWebアプリケーションを実行するためのMongoDBコンテナーも必要なので、それをマシンに取得しましょう。
- docker pull mongo:latest
出力は、ダウンロードステータスとともにどのイメージがプルされたかを正確に報告します。
Output from docker pulllatest: Pulling from library/mongo
Digest: sha256:18b239b996e0d10f4ce2b0f64db6f410c17ad337e2cecb6210a3dcf2f732ed82
Status: Downloaded newer image for mongo:latest
これで、サンプルアプリケーションを実行するために必要なものがすべて揃ったので、コンテナが相互に通信できるようにするカスタムネットワークを作成しましょう。
ステップ2—コンテナをリンクするネットワークを作成する
Webアプリケーションとデータベースコンテナを個別に起動する場合は、 docker run
コマンド、彼らはお互いを見つけることができないでしょう。
理由を確認するには、Webアプリケーションのデータベース構成ファイルの内容を表示してください。
- cat app/db.js
Mongoose — Node.jsのMongoDBオブジェクトモデリングライブラリ—をインポートし、新しいデータベーススキーマを定義した後、Webアプリケーションはホスト名でデータベースに接続しようとします。 db
、まだ存在していません。
var mongoose = require( 'mongoose' );
var Schema = mongoose.Schema;
var Todo = new Schema({
user_id : String,
content : String,
updated_at : Date
});
mongoose.model( 'Todo', Todo );
mongoose.connect( 'mongodb://db/express-todo' );
同じアプリケーションに属するコンテナがお互いを確実に検出するには、同じネットワーク上でそれらを起動する必要があります。
Dockerは、インストール中に作成されたデフォルトネットワークに加えて、カスタムネットワークを作成する機能を提供します。
次のコマンドを使用して、現在使用可能なネットワークを確認できます。
- docker network ls
Dockerによって作成された各ネットワークは、ドライバーに基づいています。 次の出力では、 bridge
ドライバーに基づいています bridge
. The local
scopeは、ネットワークがこのホストでのみ使用可能であることを示します。
Output from docker network lsNETWORK ID NAME DRIVER SCOPE
5029df19d0cf bridge bridge local
367330960d5c host host local
f280c1593b89 none null local
次に、という名前のカスタムネットワークを作成します todo_net
アプリケーションの場合は、そのネットワークでコンテナを起動します。
- docker network create todo_net
出力は、作成されたネットワークのハッシュを示します。
Output from docker network createC09f199809ccb9928dd9a93408612bb99ae08bb5a65833fefd6db2181bfe17ac
ここで、使用可能なネットワークを再度リストします。
- docker network ls
ここで、 todo_net
使用する準備ができています。
Output from docker network lsNETWORK ID NAME DRIVER SCOPE
c51377a045ff bridge bridge local
2e4106b07544 host host local
7a8b4801a712 none null local
bc992f0b2be6 todo_net bridge local
使用する場合 docker run
コマンドを使用すると、このネットワークを参照できます。 --network
スイッチ。 特定のホスト名でWebコンテナとデータベースコンテナの両方を起動してみましょう。 これにより、コンテナがこれらのホスト名を介して相互に接続できるようになります。
まず、MongoDBデータベースコンテナを起動します。
- docker run -d \
- --name=db \
- --hostname=db \
- --network=todo_net \
- mongo
そのコマンドを詳しく見ると、次のことがわかります。
- The
-d
スイッチはコンテナをデタッチモードで実行します。 - The
--name
と--hostname
スイッチは、ユーザー定義の名前をコンテナーに割り当てます。 The--hostname
スイッチは、Dockerによって管理されるDNSサービスにもエントリを追加します。 これは、ホスト名でコンテナを解決するのに役立ちます。 - The
--network
switchは、デフォルトのブリッジネットワークではなくカスタムネットワークでコンテナを起動するようにDockerEngineに指示します。
からの出力として長い文字列を見ると docker run
コマンドを実行すると、コンテナが正常に起動されたと見なすことができます。 ただし、これはコンテナが実際に実行されていることを保証するものではありません。
Output docker runaa56250f2421c5112cf8e383b68faefea91cd4b6da846cbc56cf3a0f04ff4295
を確認します db
コンテナが稼働している docker logs
指図。
- docker logs db
これにより、コンテナログが次のように出力されます。 stdout
. ログの最後の行は、MongoDBの準備ができていることを示しています。 waiting for connections
.
Output from docker logs2017-12-10T02:55:08.284+0000 I CONTROL [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=db
. . . .
2017-12-10T02:55:08.366+0000 I NETWORK [initandlisten] waiting for connections on port 27017
それでは、Webコンテナを起動して確認しましょう。 今回は、 --publish=3000:3000
ホストのポートを公開します 3000
コンテナの港へ 3000
.
- docker run -d \
- --name=web \
- --publish=3000:3000 \
- --hostname=web \
- --network=todo_net \
- sammy/todo-web
以前と同様に、出力として長い文字列を受け取ります。
また、このコンテナが稼働していることを確認しましょう。
- docker logs web
出力は、 Express —テストアプリケーションのベースとなっているNode.jsフレームワーク—が listening on port 3000
.
Output from docker logsExpress server listening on port 3000
Webコンテナがdbコンテナと通信できることを確認します ping
指図。 これを行うには、 docker exec
インタラクティブなコマンド(-i
)疑似TTYに接続されたモード(-t
).
- docker exec -it web ping db
コマンドは標準を生成します ping
出力し、2つのコンテナが相互に通信できることを通知します。
Output from docker exec -it web ping dbPING db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.210 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.095 ms
...
プレス CTRL+C
停止するには ping
指図。
最後に、Webブラウザをポイントしてサンプルアプリケーションにアクセスします http://your_server_ip:3000
. Containers Todo Example というラベルの付いたWebページと、Todoタスクを入力として受け入れるテキストボックスが表示されます。
名前の競合を回避するために、コンテナを停止し、リソースをクリーンアップできるようになりました。 docker rm
と docker network remove
コマンド。
- docker rm -f db
- docker rm -f web
- docker network remove todo_net
この時点で、2つの別々のコンテナーで構成されるコンテナー化されたWebアプリケーションができました。 次のステップでは、より堅牢なアプローチを検討します。
ステップ3—マルチコンテナーアプリケーションのデプロイ
リンクされたコンテナーを起動することはできましたが、マルチコンテナーアプリケーションを処理するための最も洗練された方法ではありません。 関連するすべてのコンテナを宣言し、それらを1つの論理ユニットとして管理するためのより良い方法が必要です。
Docker Composeは、開発者がマルチコンテナアプリケーションを処理するために利用できるフレームワークです。 Dockefileと同様に、スタック全体を定義するための宣言型メカニズムです。 次に、Node.jsおよびMongoDBアプリケーションをDockerComposeベースのアプリケーションに変換します。
DockerComposeをインストールすることから始めます。
- sudo apt-get install -y docker-compose
調べてみましょう docker-compose.yaml
サンプルWebアプリケーションにあるファイル compose
ディレクトリ。
- cat compose/docker-compose.yaml
The docker-compose.yaml
ファイルはすべてをまとめます。 これは、MongoDBコンテナを定義します db:
ブロック、Node.jsWebコンテナ web:
ブロック、およびのカスタムネットワーク networks:
ブロック。
で注意してください build: ../.
ディレクティブ、私たちは作成を指している Dockerfile
の中に app
ディレクトリ。 これにより、Webコンテナを起動する前にイメージをビルドするようにComposeに指示します。
version: '2'
services:
db:
image: mongo:latest
container_name: db
networks:
- todonet
web:
build: ../.
networks:
- todonet
ports:
- "3000"
networks:
todonet:
driver: bridge
今、に変更します compose
ディレクトリを作成し、アプリケーションを起動します。 docker-compose up
指図。 と同じように docker run
、 -d
スイッチは、コンテナをデタッチモードで起動します。
- cd compose
- docker-compose up -d
出力は、DockerComposeがというネットワークを作成したことを報告します compose_todonet
両方のコンテナを起動しました。
Output from docker-compose up -dCreating network "compose_todonet" with driver "bridge"
Creating db
Creating compose_web_1
明示的なホストポートマッピングを提供していないことに注意してください。 これにより、Docker Composeはランダムなポートを割り当てて、ホスト上のWebアプリケーションを公開します。 次のコマンドを実行すると、そのポートを見つけることができます。
- docker ps
Webアプリケーションがホストポートで公開されていることがわかります 32782
.
Output from docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6700761c0a1e compose_web "node app.js" 2 minutes ago Up 2 minutes 0.0.0.0:32782->3000/tcp compose_web_1
ad7656ef5db7 mongo:latest "docker-entrypoint..." 2 minutes ago Up 2 minutes 27017/tcp db
Webブラウザを次の場所に移動してこれを確認します http://your_server_ip:32782
. これにより、ステップ2の最後に表示されたとおりにWebアプリケーションが表示されます。
マルチコンテナアプリケーションがDockerComposeを介して稼働している状態で、アプリケーションの管理とスケーリングを見てみましょう。
ステップ4—アプリケーションの管理とスケーリング
Docker Composeを使用すると、ステートレスWebアプリケーションを簡単にスケーリングできます。 10個のインスタンスを起動できます web
単一のコマンドでコンテナ。
- docker-compose scale web=10
出力により、作成および開始されたインスタンスをリアルタイムで監視できます。
Output from docker-compose scaleCreating and starting compose_web_2 ... done
Creating and starting compose_web_3 ... done
Creating and starting compose_web_4 ... done
Creating and starting compose_web_5 ... done
Creating and starting compose_web_6 ... done
Creating and starting compose_web_7 ... done
Creating and starting compose_web_8 ... done
Creating and starting compose_web_9 ... done
Creating and starting compose_web_10 ... done
を実行して、Webアプリケーションが10インスタンスにスケーリングされていることを確認します docker ps
.
- docker ps
Dockerがそれぞれを公開するためにランダムなポートを割り当てていることに注意してください web
ホスト上のコンテナ。 これらのポートのいずれかを使用して、アプリケーションにアクセスできます。
Output from docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cec405db568d compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32788->3000/tcp compose_web_9
56adb12640bb compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32791->3000/tcp compose_web_10
4a1005d1356a compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32790->3000/tcp compose_web_7
869077de9cb1 compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32785->3000/tcp compose_web_8
eef86c56d16f compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32783->3000/tcp compose_web_4
26dbce7f6dab compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32786->3000/tcp compose_web_5
0b3abd8eee84 compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32784->3000/tcp compose_web_3
8f867f60d11d compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32789->3000/tcp compose_web_6
36b817c6110b compose_web "node app.js" About a minute ago Up About a minute 0.0.0.0:32787->3000/tcp compose_web_2
6700761c0a1e compose_web "node app.js" 7 minutes ago Up 7 minutes 0.0.0.0:32782->3000/tcp compose_web_1
ad7656ef5db7 mongo:latest "docker-entrypoint..." 7 minutes ago Up 7 minutes 27017/tcp db
同じコマンドでWebコンテナをスケールインすることもできます。
- docker-compose scale web=2
今回は、余分なインスタンスがリアルタイムで削除されているのがわかります。
Output from docker-composeStopping and removing compose_web_3 ... done
Stopping and removing compose_web_4 ... done
Stopping and removing compose_web_5 ... done
Stopping and removing compose_web_6 ... done
Stopping and removing compose_web_7 ... done
Stopping and removing compose_web_8 ... done
Stopping and removing compose_web_9 ... done
Stopping and removing compose_web_10 ... done
最後に、インスタンスを再確認します。
- docker ps
出力は、インスタンスが2つだけ残っていることを確認します。
Output from docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36b817c6110b compose_web "node app.js" 3 minutes ago Up 3 minutes 0.0.0.0:32787->3000/tcp compose_web_2
6700761c0a1e compose_web "node app.js" 9 minutes ago Up 9 minutes 0.0.0.0:32782->3000/tcp compose_web_1
ad7656ef5db7 mongo:latest "docker-entrypoint..." 9 minutes ago Up 9 minutes 27017/tcp db
これで、アプリケーションを停止できます。また、以前と同様に、リソースをクリーンアップして、名前の競合を回避することもできます。
- docker-compose stop
- docker-compose rm -f
- docker network remove compose_todonet
結論
このチュートリアルでは、DockerfilesとDockerComposeを紹介しました。 イメージを構築するための宣言型メカニズムとしてDockerfileから始め、次にDockerネットワーキングの基本を探りました。 最後に、DockerComposeを使用してマルチコンテナーアプリケーションをスケーリングおよび管理しました。
新しいセットアップを拡張するには、別のコンテナー内で実行されている Nginxリバースプロキシを追加して、使用可能なWebアプリケーションコンテナーの1つにリクエストをルーティングします。 または、DigitalOceanのブロックストレージおよびロードバランサーを利用して、コンテナー化されたアプリケーションに耐久性とスケーラビリティをもたらすことができます。