このチュートリアルでは、Alibaba Cloud上でコンテナを扱う際にDocker Composeを使用して実践的な経験を積むことに焦点を当てています。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
前提条件
すでに最新バージョンのDockerがインストールされているサーバー/VPSにアクセスする必要があります。このチュートリアルでは、CentOSとDockerでAlibaba Cloud Elastic Compute Service (ECS)インスタンスを使用します。
このチュートリアルに従うために大規模なインスタンスを購入する必要はありません。後のチュートリアルで6つのコンテナの大群を実行している場合でも、合計512MBのRAMしかないサーバーが必要になります。
このチュートリアルでは CentOS を使用していますが、Debian や Ubuntu を使用することもできます。このチュートリアルの大部分はDocker Composeコマンドを使用しているので、どのようなLinuxディストリビューションでも動作します。
Docker、イメージ、コンテナ、そしてdocker-composeとdocker ps -aの使用について、非常に基本的な理解が必要です。docker-composeの概念を大まかに理解するためには、3回くらいはdocker-composeを使ったことがある必要があります。
このチュートリアルの目的は、非常に簡単なdocker-composeファイルをいくつか作成することです。使っていくうちに、Docker-composeの概念の理解が深まっていくでしょう。
クリーンアップの準備
コンテナをいくつか(できれば何も実行していない)だけ実行している場合は、本当に役立つでしょう。そうすれば、docker ps -a の出力リストから簡単にチュートリアルコンテナを見つけることができます。
そこで、コンテナを停止し、docker-compose upで作成されたコンテナを削除します。
(何も持っていない場合はこのステップをスキップしてください)
docker-compose down -t 0 --remove-orphans
そこで、実行する必要のないコンテナをすべて停止してプルーニングしてください。
(開発環境で)これを素早く行うには、以下のようにします。
docker stop $(docker ps -a -q) #stop all containers
すべてのコンテナを削除するには、次のように実行します。
docker rm -f $(docker ps -a -q) # remove ALL containers
ディレクトリとエディタを分ける
docker-compose のファイルは別のディレクトリに置いた方が良いでしょう。docker-composeサービス/スタックまたはスウォームごとに1つのディレクトリを作成します: 整然とした、整理された、小さく、効率的で、これらの属性のために完全に理解しやすいです。
したがって、入力します。
mkdir compose-tuts
cd compose-tuts
Linuxディストロでよく使われているエディタにはvimとnanoの2つがあります。私は nano の方が好きですが、vim でも十分に動作します。
nanoをインストールするには
Debian / Ubuntu .
apt install nano
CentOS .
yum install nano
Nanoビギナーズガイド:
* nano filename-to-edit ... this starts the nano editor
* cursor keys move around as expected
* cut tutorials text from alibaba tutorials web pages work as expected
* pasting into your docker-compose file work as expected
* press F3 to save your work
* press F2 to exit the editor.
以上、docker-composeのチュートリアル5つすべてにnanoを使うために知っておくべきことを紹介しました。
イメージ
これはDockerfilesのimageと同じように動作します。image はコンテナをビルドするイメージを指定します。
以下の演習ではこれを使っています。
tmpfs
引用元: https://docs.docker.com/compose/compose-file/#tmpfs
tmpfs はコンテナ内の(RAM内の)一時ファイルシステムをマウントします。それは単一の値でもリストでも構いません。2つの一時ファイルシステムのリストを使ってデモをしてみましょう。
以下の内容を docker-compose.yml に追加します。
nano docker-compose.yml
version: "3.7"
services:
alpine:
image: alpine:3.8
command: sleep 600
tmpfs:
- /my-run:size=10M
- /my-app-tmp:size=20M
docker-compose up は、docker-compose.yml ファイルに定義されているサービスを起動します。
docker exec は実行中のコンテナに入ります。
実行してください。
docker-compose up -d -t 0
docker exec -it compose-tuts_alpine_1 /bin/sh
2つのテンポラリファイルシステムのサイズを確認する必要があります。
/ # df -h /my*
Filesystem Size Used Available Use% Mounted on
tmpfs 20.0M 0 20.0M 0% /my-app-tmp
tmpfs 10.0M 0 10.0M 0% /my-run
完璧です。ご希望のサイズで取り付けました。使用率はゼロです。
15Mのゼロを/my-runに書き込んでみます(サイズは10M)
/ # dd if=/dev/zero of=/my-run/output.dat bs=1M count=15
dd: writing '/my-run/output.dat': No space left on device
11+0 records in
10+0 records out
/ # echo $?
1
dd コマンドはエラーを表示しませんが、**$? **は最後のコマンドの終了ステータスを表示します: この場合は 1 : エラーを意味します。
dfをもう一度実行してください。
/ # df -h /my*
Filesystem Size Used Available Use% Mounted on
tmpfs 20.0M 0 20.0M 0% /my-app-tmp
tmpfs 10.0M 10.0M 0 100% /my-run
/docker-compose は tmpfs を正しいサイズで作成することに成功し、期待通りに動作しています。
15Mのゼロを/my-app-tmp(サイズ20M)に書き込んでみましょう。
/ # dd if=/dev/zero of=/my-app-tmp/output.dat bs=1M count=15
15+0 records in
15+0 records out
/ # echo $?
0
echo $? my-app-tmpが使用しているサイズを確認してみましょう。
/ # df -h /my*
Filesystem Size Used Available Use% Mounted on
tmpfs 20.0M 15.0M 5.0M 75% /my-app-tmp
tmpfs 10.0M 10.0M 0 100% /my-run
15Mを使用しています。完璧です。
コンテナ内で動作するアプリケーションに必要な正しいサイズのtmpfsを定義する方法がわかりました。
ddコマンドの詳細については、man ddを使用することができます。
ネタバレ: if = 入力ファイル、of = 出力ファイル、bs = ブロックサイズ。シンプルです。
env_file と環境
env_fileとenvironmentはコンテナに環境変数を追加します。
環境セクションで宣言された環境変数は env_file の値を上書きします。
ほぼすべての Linux アプリケーションは環境変数を持っているので、それをコンテナに注入する方法を知っておく必要があります。(私が知っている中で、これを必要としないアプリケーションは hello word アプリケーションだけです)
これがどのように動作するかを確認するために、いくつかの準備作業が必要です。
1、環境ファイルを作成します。
2、docker-compose でこれらのファイルを参照します。
3、環境変数が期待通りに定義されているかどうかを確認するために、/exec コンテナを入力します。
カレントディレクトリにあるこれらのファイルに以下の環境変数を追加します。
myvars.env
ENV_VAR_A=1
ENV_VAR_B=10
ENV_VAR_C=apple
ENV_VAR_F=CentOS
mynewvars.env
ENV_VAR_A=2
ENV_VAR_C=pear
ENV_VAR_D=Docker
3番目のファイルについては、入力を節約するために、以下のテキストを切り取ってシェルプロンプトに貼り付けてください。
cat <<EOT >> mybestvars.env
ENV_VAR_A=3
ENV_VAR_B=333
ENV_VAR_C=lemon
ENV_VAR_E=Kubernetes
EOT
(catはすべてのENV行をmybestvars.envに送ります)
詳しくはこちらをご覧ください: https://www.tldp.org/LDP/abs/html/here-docs.html
似たような名前の変数がどのようにオーバーライドされるか、もうお分かりでしょうか?
docker-compose.yml に次のように追加します。
nano docker-compose.yml
version: "3.7"
services:
alpine:
image: alpine:3.8
command: sleep 600
env_file:
- myvars.env
- mynewvars.env
- mybestvars.env
environment:
- ENV_VAR_A=42
- ENV_VAR_E=Apache web server
実行します。
docker-compose up -d -t 0
docker exec -it compose-tuts_alpine_1 /bin/sh
表示されているようにprintenvを実行します。
/ # printenv
HOSTNAME=1c8abf6141ec
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_VAR_A=42
ENV_VAR_B=333
ENV_VAR_C=lemon
PWD=/
ENV_VAR_D=Docker
ENV_VAR_E=Apache web server
ENV_VAR_F=CentOS
/ # exit
それらの値はどのようにして決定されたのでしょうか?
ENV_VAR_A=42 ... docker-compose ファイルの environment: の値。
環境: の値は、これら3つのファイルで設定されているすべての値を上書きします。
ENV_VAR_B=333 ... the value from the last file: mybestvars.env
ENV_VAR_C=lemon ... the value from the last file: mybestvars.env
ENV_VAR_D=Docker ... value from mynewvars.env: never overridden anywhere
ENV_VAR_E=Apache web server... the value from environment: in the docker-compose file.
ENV_VAR_F=CentOS ... value from first file: myvars.env : never overridden anywhere
これが環境変数の仕組みです。後のファイルは、前のファイルにある同様の名前の変数を上書きします。しかし、docker-compose ファイルの environment: は 全てを上書きします。
これら3つのファイルはコンテナには存在しませんが、その内容は環境変数の中で生きています。
重要: HOSTシェルで作成した3つの環境ファイルは重要です。これらは docker-compose ファイルの一部であり、docker-compose ファイルと一緒にソース管理下に置いておく必要があります。
extra_hosts
extra_hosts は、コンテナ内の /etc/hosts ファイル内のホスト名とその ip アドレスをリンクします。
以下を docker-compose.yml に追加します。
nano docker-compose.yml
version: "3.7"
services:
alpine:
image: alpine:3.8
command: sleep 600
extra_hosts:
- "myhost:123.242.195.42"
- "myotherhost:150.31.209.42"
実行します。
docker-compose up -d -t 0
docker exec -it compose-tuts_alpine_1 /bin/sh
以下のコマンドを入力してください: ip r : ルーティングテーブルを表示し、cat /etc/hosts はhostsファイルの内容を表示します。
Dockerはコンテナがこれら2つの新しいホストを見つけられるようにするためにルーティングテーブルに何も追加しません。それは、/etc/hosts ファイルにこれら 2 つのマッピングを追加するだけです。
/ # ip r
default via 172.22.0.1 dev eth0
172.22.0.0/16 dev eth0 scope link src 172.22.0.2
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
123.242.195.42 myhost
150.31.209.42 myotherhost
172.22.0.2 024481ed6ce7
/ # exit
これらのホスト名のマッピングは固定の IP アドレスのみを含むことができます。
最後のランダムなホスト名がこのコンテナのホスト名です。CONTAINER プロンプトで hostname コマンドを実行すると、これがホスト名として表示されます。
ヘルスチェック
Dockerfile のヘルスチェックに慣れているのであれば、docker-compose のヘルスチェックは簡単です。
docker-compose.ymlに以下を追加してください。
nano docker-compose.yml
version: "3.7"
services:
alpine:
image: alpine:3.8
command: sleep 600
healthcheck:
test: exit 0
interval: 1s
timeout: 1s
retries: 3
start_period: 0s
実行します。
docker-compose up -d -t 0
docker ps -a
スピーディーなコンピュータを持っている場合は、このように表示されます:health checks ... still starting.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2979837d1a56 alpine:3.8 "sleep 600" 3 seconds ago Up 1 second (health: starting)
遅いコンピュータ/サーバでは、正常にヘルスチェックを完了するまでにdocker ps -aコマンドを何度も実行しなければなりません。(healthy)
docker ps -a
出力します。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7ceefcc2ad2 alpine:3.8 "sleep 600" 6 seconds ago Up 4 seconds (healthy) compose-tuts_alpine_1
docker-compose.ymlを編集して、10行目あたりを以下のように修正します。
test: exit 1
これで、ヘルスチェックは完全に失敗します-エラー終了コード1。
再実行してください。
docker-compose up -d -t 0
docker ps -a
docker ps -a
docker ps -a
数秒でわかるようになります:(unhealthy)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed54a3189e7a alpine:3.8 "sleep 600" 6 seconds ago Up 5 seconds (unhealthy) compose-tuts_alpine_1
アプリケーションに応じて、それぞれの特定のアプリケーションに適した正確なヘルスチェックを決定する必要があります。
また、適切な間隔とタイムアウト値を決定する必要があります。
両方とも 1 秒というのは、本番環境では低すぎます。ここでは、クイックテストとデモのためだけに1秒を使用しています。
同様に、start_period は実生活ではゼロにすることはできません。ヘルスチェックを実行する前に、まずアプリケーションを起動する時間を与えるべきです。
ヘルスチェックの詳細については、Alibaba Cloudの公式ドキュメントを参照してください。コンテナサービスのベストプラクティス - Dockerコンテナのヘルスチェック
Dockerコミュニティでは、ヘルスチェックを含むいくつかのインスタンスイメージを https://github.com/docker-library/healthcheck で提供しています。
これらの例ではソフトウェアを使用していなくても、自分の健康診断書の書き方について非常に良いアイデアを得ることができます。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ