前書き

CoreOSを使用すると、マシンのクラスター全体でDockerコンテナーでサービスを簡単に実行できます。 そのための手順には、通常、サービスの1つまたは複数のインスタンスを開始し、CoreOSの分散キーと値のストアである「+ etcd +」に各インスタンスを登録することが含まれます。

このパターンを利用することで、関連サービスはインフラストラクチャの状態に関する貴重な情報を取得し、この知識を使用して独自の動作を通知できます。 これにより、重要な `+ etcd +`の値が変更されるたびに、サービスが自身を動的に設定することが可能になります。

このガイドでは、「+ confd +」と呼ばれるツールについて説明します。このツールは、分散キー/値ストアの変更を監視するために特別に作成されています。 Dockerコンテナー内から実行され、構成の変更とサービスのリロードをトリガーするために使用されます。

前提条件と目標

このガイドを使用するには、CoreOSとそのコンポーネント部分の基本的な理解が必要です。 以前のガイドでは、CoreOSクラスターをセットアップし、クラスターの管理に使用されるいくつかのツールに精通しました。

以下は、この記事を始める前に読むべきガイドです。 これらのガイドで説明されている一部のサービスの動作を変更するため、資料を理解することは重要ですが、このガイドを使用するときは新たに始める必要があります。

さらに、これから使用する管理ツールのいくつかについて詳しく知るには、次のガイドをご覧ください。

テンプレート化されたメイン+サイドキックサービスは、このガイドで設定するフロントエンドサービスの基礎となるため、「フレキシブルサービスの作成方法」ガイドはこのガイドにとって特に重要です。 前述のように、上記のガイドではApacheおよびsidekickサービスの作成について説明していますが、このガイドには構成を変更して、最初から簡単に開始できるようにします。 このガイドでは、これらのサービスの修正バージョンを作成します。

このチュートリアルでは、Nginxを使用して新しいアプリケーションコンテナーを作成することに焦点を当てます。 これは、テンプレートファイルから生成できるさまざまなApacheインスタンスのリバースプロキシとして機能します。 Nginxコンテナは `+ confd +`で設定され、サイドキックサービスが担当するサービス登録を監視します。

このシリーズで使用してきたのと同じ3つのマシンクラスターから始めます。

  • coreos-1

  • coreos-2

  • coreos-3

上記のガイドを読み終え、3台のマシンクラスタを利用できるようになったら、続行します。

バックエンドApacheサービスの構成

まず、バックエンドのApacheサービスをセットアップします。 これは主に前のガイドの最後の部分を反映していますが、若干の微妙な違いがあるため、ここで手順全体を実行します。

CoreOSマシンの1つにログインして開始します。

Apacheコンテナのセットアップ

基本的なApacheコンテナを作成することから始めます。 これは実際には最後のガイドと同じであるため、Docker Hubアカウントで既にそのイメージを使用できる場合は、これを再度行う必要はありません。 このコンテナは、Ubuntu 14.04コンテナイメージに基づいています。

次のように入力して、ベースイメージをプルダウンし、コンテナーインスタンスを開始できます。

docker run -i -t ubuntu:14.04 /bin/bash

コンテナが起動すると、 `+ bash `セッションにドロップされます。 ここから、ローカルの ` apt `パッケージインデックスを更新し、 ` apache2 +`をインストールします。

apt-get update
apt-get install apache2 -y

また、デフォルトページを設定します。

echo "<h1>Running from Docker on CoreOS</h1>" > /var/www/html/index.html

コンテナは必要な状態にあるため、ここで終了できます。

exit

次のように入力して、Docker Hubにログインするか、アカウントを作成します。

docker login

Docker Hubアカウントのユーザー名、パスワード、メールアドレスを入力する必要があります。

次に、先ほど残したインスタンスのコンテナIDを取得します。

docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
       ubuntu:14.04        "/bin/bash"         2 minutes ago       Exited (0) 4 seconds ago                       jolly_pare

上記の強調表示されたフィールドは、コンテナIDです。 自分のコンピューターに表示される出力をコピーします。

次に、そのコンテナーID、Docker Hubユーザー名、およびイメージの名前を使用してコミットします。 ここでは「apache」を使用します。

docker commit  /apache

新しいイメージをDocker Hubにプッシュします。

docker push /apache

これで、このファイルをサービスファイルで使用できます。

Apacheサービステンプレートユニットファイルの作成

コンテナが利用可能になったので、テンプレートユニットファイルを作成して、 `+ fleet `と ` systemd +`がサービスを正しく管理できるようにします。

始める前に、整理された状態を維持できるようにディレクトリ構造を設定しましょう。

cd ~
mkdir static templates instances

これで、テンプレートファイルを `+ templates +`ディレクトリ内に作成できます。

vim templates/[email protected]
[Unit]
Description=Apache web server service on port %i

# Requirements
Requires=etcd.service
Requires=docker.service
[email protected]%i.service

# Dependency ordering
After=etcd.service
After=docker.service
[email protected]%i.service

[Service]
# Let processes take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill apache.%i
ExecStartPre=-/usr/bin/docker rm apache.%i
ExecStartPre=/usr/bin/docker pull /apache
ExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PRIVATE_IPV4}:%i:80 \
/apache /usr/sbin/apache2ctl -D FOREGROUND

# Stop
ExecStop=/usr/bin/docker stop apache.%i

[X-Fleet]
# Don't schedule on the same machine as other Apache instances
[email protected]*.service

ここで行った変更の1つは、パブリックインターフェイスの代わりにプライベートインターフェイスを使用することです。 すべてのApacheインスタンスには、オープンWebからの接続を処理する代わりに、Nginxリバースプロキシを介してトラフィックが渡されるため、これは良い考えです。 DigitalOceanでプライベートインターフェイスを使用する場合、スピンアップしたサーバーには、作成時に「プライベートネットワーク」フラグが選択されている必要があります。

また、Dockerファイルを正しくプルダウンするために、Docker Hubユーザー名を参照するように「++」を変更することを忘れないでください。

Sidekickテンプレートユニットファイルの作成

ここで、相棒サービスについても同じことを行います。 これは、後で必要になる情報を見込んで少し変更します。

エディターでテンプレートファイルを開きます。

vim templates/[email protected]

このファイルでは次の情報を使用します。

[Unit]
Description=Apache web server on port %i etcd registration

# Requirements
Requires=etcd.service
[email protected]%i.service

# Dependency ordering and binding
After=etcd.service
[email protected]%i.service
[email protected]%i.service

[Service]

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Start
## Test whether service is accessible and then register useful information
ExecStart=/bin/bash -c '\
 while true; do \
   curl -f ${COREOS_PRIVATE_IPV4}:%i; \
   if [ $? -eq 0 ]; then \
     etcdctl set /services/apache/${COREOS_PRIVATE_IPV4} \'${COREOS_PRIVATE_IPV4}:%i\' --ttl 30; \
   else \
     etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}; \
   fi; \
   sleep 20; \
 done'

# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}

[X-Fleet]
# Schedule on the same machine as the associated Apache service
[email protected]%i.service

上記の構成は、前のガイドの構成とはいくつかの点で異なります。 `+ etcdctl set +`コマンドによって設定された値を調整しました。 JSONオブジェクトを渡す代わりに、単純なIPアドレスとポートの組み合わせを設定しています。 この方法で、この値を直接読み取って、このサービスに到達するために必要な接続情報を見つけることができます。

また、他のファイルで行ったように、プライベートインターフェイスを指定するために情報を調整しました。 このオプションを使用できない場合は、これを公開のままにします。

サービスをインスタンス化する

次に、これらのサービスの2つのインスタンスを作成しましょう。

まず、シンボリックリンクを作成しましょう。 作成した `+〜/ instances +`ディレクトリに移動し、それらが実行されるポートを定義するためにリンクします。 ポート7777で1つのサービスを実行し、ポート8888で別のサービスを実行します。

cd ~/instances
ln -s ../templates/[email protected] [email protected]
ln -s ../templates/[email protected] [email protected]
ln -s ../templates/[email protected] [email protected]
ln -s ../templates/[email protected] [email protected]

これで、 `〜/ instances +`ディレクトリを ` fleet +`に渡すことでこれらのサービスを開始できます:

fleetctl start ~/instances/*

インスタンスの起動後(これには数分かかる場合があります)、サイドキックが作成した `+ etcd +`エントリを確認できるはずです。

etcdctl ls --recursive /
/coreos.com
/coreos.com/updateengine
/coreos.com/updateengine/rebootlock
/coreos.com/updateengine/rebootlock/semaphore
/services
/services/apache

これらのエントリのいずれかの値を要求すると、IPアドレスとポート番号を取得していることがわかります。

etcdctl get /services/apache/10.132.249.206
10.132.249.206:8888

「+ curl +」を使用してページを取得し、正しく機能していることを確認できます。 これは、プライベートネットワーキングを使用するようにサービスを設定した場合にのみ、マシン内から機能します。

curl 10.132.249.206:8888
<h1>Running from Docker on CoreOS</h1>

これで、バックエンドインフラストラクチャがセットアップされました。 次のステップは、 `+ confd `に精通し、 ` etcd `の ` / services / apache +`の場所を監視して、変更のたびにNginxを再構成できるようにすることです。

Nginxコンテナーの作成

Apacheサービスに使用したのと同じUbuntu 14.04ベースからNginxコンテナーを開始します。

ソフトウェアのインストール

次のように入力して、新しいコンテナを起動します。

docker run -i -t ubuntu:14.04 /bin/bash

ローカルの `+ apt `パッケージキャッシュを更新し、Nginxをインストールします。 基本イメージにはこれが含まれておらず、GitHubから一時的に安定した ` confd `パッケージを取得する必要があるため、 ` curl +`もインストールする必要があります。

apt-get update
apt-get install nginx curl -y

これで、ブラウザのGitHubで「+ confd +」のhttps://github.com/kelseyhightower/confd/releases [リリースページ]にアクセスできます。 最新の安定版リリースへのリンクを見つける必要があります。 この記事の執筆時点では、https://github.com/kelseyhightower/confd/releases/tag/v0.5.0 [v0.5.0]ですが、これは変更されている可能性があります。 ツールのLinuxバージョンのリンクを右クリックし、「リンクアドレスのコピー」または同様のオプションが利用可能なものを選択します。

次に、Dockerコンテナーに戻り、コピーしたURLを使用してアプリケーションをダウンロードします。 これを `+ / usr / local / bin `ディレクトリに配置します。 出力ファイルとして「 confd +」を選択する必要があります。

cd /usr/local/bin
curl -L https://github.com/kelseyhightower/confd/releases/download/0.5.0<^>-linux-amd64 -o confd

次に、ファイルを実行可能にして、コンテナ内で使用できるようにします。

chmod +x confd

また、この機会に `+ confd `が期待する設定構造を作成する必要があります。 これは ` / etc +`ディレクトリ内にあります:

mkdir -p /etc/confd/{conf.d,templates}

Confd構成ファイルを作成してEtcd値を読み取る

アプリケーションがインストールされたので、 `+ confd +`の設定を開始する必要があります。 まず、構成ファイルまたはテンプレートリソースファイルを作成します。

`+ confd `の設定ファイルは、特定の ` etcd +`値をチェックし、変更が検出されたときにアクションを開始するようにサービスを設定するために使用されます。 これらはhttps://github.com/toml-lang/toml[TOML]ファイル形式を使用します。これは使いやすく、かなり直感的です。

`+ nginx.toml +`と呼ばれる設定ディレクトリ内にファイルを作成することから始めます:

vi /etc/confd/conf.d/nginx.toml

ここで構成ファイルを作成します。 次の情報を追加します。

[template]

# The name of the template that will be used to render the application's configuration file
# Confd will look in `/etc/conf.d/templates` for these files by default
src = "nginx.tmpl"

# The location to place the rendered configuration file
dest = "/etc/nginx/sites-enabled/app.conf"

# The etcd keys or directory to watch.  This is where the information to fill in
# the template will come from.
keys = [ "/services/apache" ]

# File ownership and mode information
owner = "root"
mode = "0644"

# These are the commands that will be used to check whether the rendered config is
# valid and to reload the actual service once the new config is in place
check_cmd = "/usr/sbin/nginx -t"
reload_cmd = "/usr/sbin/service nginx reload"

上記のファイルには、いくつかの基本的なアイデアを説明するコメントが含まれていますが、以下のオプションについては確認できます。

Directive Required? Type Description

src

Yes

String

The name of the template that will be used to render the information. If this is located outside of /etc/confd/templates, the entire path is should be used.

dest

Yes

String

The file location where the rendered configuration file should be placed.

keys

Yes

Array of strings

The etcd keys that the template requires to be rendered correctly. This can be a directory if the template is set up to handle child keys.

owner

No

String

The username that will be given ownership of the rendered configuration file.

group

No

String

The group that will be given group ownership of the rendered configuration file.

mode

No

String

The octal permissions mode that should be set for the rendered file.

check_cmd

No

String

The command that should be used to check the syntax of the rendered configuration file.

reload_cmd

No

String

The command that should be used to reload the configuration of the application.

prefix

No

String

A part of the etcd hierarchy that comes before the keys in the keys directive. This can be used to make the .toml file more flexible.

作成したファイルは、 `+ confd `インスタンスがどのように機能するかについていくつかの重要なことを教えてくれます。 Nginxコンテナは、 ` / etc / confd / templates / nginx.conf.tmpl `に保存されているテンプレートを使用して、 ` / etc / nginx / sites-enabled / app.conf `に配置される設定ファイルをレンダリングします。 ファイルには ` 0644 +`のパーミッションセットが付与され、所有権はルートユーザーに付与されます。

`+ confd `アプリケーションは、 ` / services / apache `ノードで変更を探します。 変更が見られると、 ` confd +`はそのノードの下で新しい情報を照会します。 次に、Nginxの新しい構成をレンダリングします。 設定ファイルの構文エラーをチェックし、ファイルが配置された後にNginxサービスをリロードします。

テンプレートリソースファイルが作成されました。 Nginx構成ファイルのレンダリングに使用される実際のテンプレートファイルで作業する必要があります。

Confdテンプレートファイルを作成する

テンプレートファイルについては、 `+ confd +`プロジェクトのhttps://github.com/kelseyhightower/confd/blob/master/docs/templates-interation-example.md[GitHub documentation]の例を使用して開始します。

上記の構成ファイルで参照したファイルを作成します。 このファイルを `+ templates +`ディレクトリに置きます:

vi /etc/confd/templates/nginx.tmpl

このファイルでは、基本的に標準のNginxリバースプロキシ設定ファイルを再作成します。 ただし、Goのテンプレート構文を使用して、「+ confd 」が「 etcd +」から取得する情報の一部を置換します。

まず、「上流」サーバーでブロックを構成します。 このセクションは、Nginxがリクエストを送信できるサーバーのプールを定義するために使用されます。 形式は一般的に次のようなものです。

upstream  {
   server :;
   server :;
   server :;
}

これにより、リクエストを「++」に渡すことができ、Nginxはリクエストを渡す定義済みサーバーの1つを選択します。

テンプレートファイルの背後にある考え方は、Apache WebサーバーのIPアドレスとポート番号について「+ etcd +」を解析することです。 したがって、アップストリームサーバーを静的に定義する代わりに、ファイルのレンダリング時にこの情報を動的に入力する必要があります。 これを行うには、動的コンテンツにhttp://golang.org/pkg/text/template/[Go templates]を使用します。

これを行うには、代わりにこれをブロックとして使用します。

upstream apache_pool {
{{ range getvs "/services/apache/*" }}
   server {{ . }};
{{ end }}
}

何が起こっているのかを少し説明しましょう。 `+ apache_pool +`と呼ばれるサーバーのアップストリームプールを定義するブロックを開きました。 内部では、二重括弧を使用してGo言語コードを開始することを指定します。

これらの括弧内で、関心のある値が保持される「+ etcd 」エンドポイントを指定します。 リストを反復可能にするために ` range +`を使用しています。

これを使用して、「+ etcd」の「+ / services / apache」の場所の下から取得したすべてのエントリを「+ range」ブロックに渡します。 その後、挿入された値を示す「\ {\ {」および「}}」内の単一のドットを使用して、現在の反復でキーの値を取得できます。 これを範囲ループ内で使用して、サーバープールにデータを入力します。 最後に、 `+ {{end}} +`ディレクティブでループを終了します。

注意:ループ内の `+ server +`ディレクティブの後に必ずセミコロンを追加してください。 これを忘れると、設定が機能しなくなります。

サーバープールを設定したら、プロキシパスを使用して、すべての接続をそのプールに転送できます。 これは、リバースプロキシとしての標準サーバーブロックになります。 注意すべき1つのことは、 `+ access_log +`です。これは、一時的に作成するカスタム形式を使用します。

upstream apache_pool {
{{ range getvs "/services/apache/*" }}
   server {{ . }};
{{ end }}
}

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   access_log /var/log/nginx/access.log upstreamlog;

   location / {
       proxy_pass http://apache_pool;
       proxy_redirect off;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }
}

これはポート80のすべての接続に応答し、それらを「+ etcd 」エントリを見ることによって生成される「 apache_pool +」にあるサーバーのプールに渡します。

サービスのこの側面を処理している間、デフォルトのNginx構成ファイルを削除して、後で競合が発生しないようにする必要があります。 デフォルトの設定を有効にするシンボリックリンクを削除します。

rm /etc/nginx/sites-enabled/default

また、テンプレートファイルで参照したログ形式を構成する良い機会です。 これは設定の `+ http +`ブロックに入れなければなりません。これはメインの設定ファイルで利用可能です。 今すぐ開きます:

vi /etc/nginx/nginx.conf

ログに記録する情報を定義するために、 `+ log_format +`ディレクティブを追加します。 訪問しているクライアントと、リクエストが渡されるバックエンドサーバーを記録します。 これらの手順にかかる時間に関するデータを記録します。

. . .
http {
   ##
   # Basic Settings
   ##
   log_format upstreamlog '[$time_local] $remote_addr passed to: $upstream_addr: $request Upstream Response Time: $upstream_response_time Request time: $request_time';

   sendfile on;
   . . .

完了したら、ファイルを保存して閉じます。

Confdを実行するスクリプトの作成

適切なタイミングでテンプレートリソースファイルとテンプレートファイルで `+ confd +`を呼び出すスクリプトファイルを作成する必要があります。

スクリプトは、サービスが正しく機能するために2つのことを行う必要があります。

  • コンテナの起動時に実行して、バックエンドインフラストラクチャの現在の状態に基づいてNginxの初期設定をセットアップする必要があります。

  • 使用可能なバックエンドサーバーに基づいてNginxを再構成できるように、Apacheサーバーの「+ etcd +」登録の変更を引き続き監視する必要があります。

Marcel de GraafのGitHubページからスクリプトを取得します。 これは、必要なことを「正確に」行う、すてきなシンプルなスクリプトです。 このシナリオでは、いくつかのマイナーな編集のみを行います。

このスクリプトを「+ confd 」実行可能ファイルと一緒に配置しましょう。 これを ` confd-watch +`と呼びます:

vi /usr/local/bin/confd-watch

必要なインタープリターを識別するために、従来の「+ bash 」ヘッダーから始めます。 次に、何か問題が発生した場合にスクリプトがすぐに失敗するように、いくつかの ` bash +`オプションを設定します。 失敗または実行する最後のコマンドの値を返します。

#!/bin/bash

set -eo pipefail

次に、いくつかの変数を設定します。 `+ bash +`パラメータ置換を使用することで、デフォルト値を設定しますが、スクリプトを呼び出すときにハードコーディングされた値をオーバーライドできるように、ある程度の柔軟性を組み込みます。 これは基本的に、接続アドレスの各コンポーネントを個別にセットアップし、それらをグループ化して必要な完全なアドレスを取得します。

パラメータ置換は、次の構文で作成されます: + $ {:-} +。 これには、nullではなく、指定された場合は `+ var_name `の値を使用するプロパティがあり、それ以外の場合は ` default_value +`がデフォルトになります。

デフォルトで `+ etcd +`が期待する値にデフォルト設定しています。 これにより、追加情報なしでスクリプトが正常に機能しますが、スクリプトを呼び出すときに必要に応じてカスタマイズできます。

#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT

このスクリプトが呼び出されたときに利用可能な値を `+ etcd `から読み取ることで、 ` confd `を使用してNginx設定ファイルの初期バージョンをレンダリングします。 ` until +`ループを使用して、初期設定の構築を継続的に試行します。

ループ構造は、 `+ etcd `がすぐに利用できない場合、またはバックエンドサーバーの前にNginxコンテナーがオンラインになった場合に必要になる可能性があります。 これにより、最終的に有効な初期設定を生成できるまで、「 etcd +」を繰り返しポーリングできます。

呼び出している実際の `+ confd `コマンドは1回実行されてから終了します。 これは、バックエンドサーバーに登録の機会を与えるために、次の実行まで5秒待機できるようにするためです。 デフォルトを使用して構築した、またはパラメータで渡した完全な ` ETCD +`変数に接続し、テンプレートリソースファイルを使用して、実行したい動作を定義します。

#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT

echo "[nginx] booting container. ETCD: $ETCD"

# Try to make initial configuration every 5 seconds until successful
until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do
   echo "[nginx] waiting for confd to create initial nginx configuration"
   sleep 5
done

初期構成が設定されたら、スクリプトの次のタスクは、継続的なポーリングのメカニズムを導入することです。 Nginxが更新されるように、将来の変更が検出されるようにします。

これを行うために、 `+ confd `をもう一度呼び出すことができます。 今回は、継続的なポーリング間隔を設定し、プロセスをバックグラウンドに配置して、無期限に実行するようにします。 目標は同じなので、同じ ` etcd +`接続情報と同じテンプレートリソースファイルを渡します。

`+ confd +`プロセスをバックグラウンドに配置した後、作成された設定ファイルを使用してNginxを安全に起動できます。 このスクリプトはDockerの「実行」コマンドとして呼び出されるため、この時点でコンテナーが終了しないように、フォアグラウンドで実行し続ける必要があります。 これを行うには、ログをテーリングするだけで、記録されているすべての情報にアクセスできます。

#!/bin/bash

set -eo pipefail

export ETCD_PORT=${ETCD_PORT:-4001}
export HOST_IP=${HOST_IP:-172.17.42.1}
export ETCD=$HOST_IP:$ETCD_PORT

echo "[nginx] booting container. ETCD: $ETCD."

# Try to make initial configuration every 5 seconds until successful
until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do
   echo "[nginx] waiting for confd to create initial nginx configuration."
   sleep 5
done

# Put a continual polling `confd` process into the background to watch
# for changes every 10 seconds
confd -interval 10 -node $ETCD -config-file /etc/confd/conf.d/nginx.toml &
echo "[nginx] confd is now monitoring etcd for changes..."

# Start the Nginx service using the generated config
echo "[nginx] starting nginx service..."
service nginx start

# Follow the logs to allow the script to continue running
tail -f /var/log/nginx/*.log

これが終了したら、ファイルを保存して閉じます。

最後に行う必要があるのは、スクリプトを実行可能にすることです。

chmod +x /usr/local/bin/confd-watch

ここでコンテナを終了して、ホストシステムに戻ります。

exit

コンテナをコミットしてプッシュする

これで、コンテナをコミットしてDocker Hubにプッシュし、マシンでプルダウンできるようになりました。

コンテナIDを確認します。

docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
       ubuntu:14.04        "/bin/bash"         22 hours ago        Exited (0) About a minute ago                       stupefied_albattani

強調表示された文字列は、必要なコンテナIDです。 Docker Hubのユーザー名とこのイメージに使用する名前とともに、このIDを使用してコンテナーをコミットします。 このガイドでは、「nginx_lb」という名前を使用します。

docker commit  /nginx_lb

必要に応じて、Docker Hubアカウントにログインします。

docker login

ここで、コミットされたイメージをプッシュして、他のホストが必要に応じてプルダウンできるようにする必要があります。

docker push /nginx_lb

Nginx静的ユニットファイルをビルドする

次のステップは、作成したコンテナを起動するユニットファイルを作成することです。 これにより、 `+ fleet +`を使用してプロセスを制御できます。

これはテンプレートにはならないので、このディレクトリの先頭で作成した `+〜/ static +`ディレクトリに配置します。

vim static/nginx_lb.service

標準の `+ [Unit] +`セクションから始めて、サービスを説明し、依存関係と順序を定義します。

[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service

次に、ファイルの `+ [Service] +`部分を定義する必要があります。 Apacheサービスファイルで行ったように、タイムアウトをゼロに設定し、killmodeを再度noneに調整します。 環境ファイルを再度プルして、このコンテナが実行されているホストのパブリックおよびプライベートIPアドレスにアクセスできるようにします。

その後、環境をクリーンアップして、このコンテナの以前のバージョンが強制終了されて削除されるようにします。 作成したばかりのコンテナをプルダウンして、常に最新バージョンを保持するようにします。

最後に、コンテナを起動します。 これには、コンテナを起動し、removeコマンドとkillコマンドで参照した名前を付け、実行中のホストのパブリックIPアドレスをポート80にマップすることを渡します。 runコマンドとして作成した `+ confd-watch +`スクリプトを呼び出します。

[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service

[Service]
# Let the process take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill nginx_lb
ExecStartPre=-/usr/bin/docker rm nginx_lb
ExecStartPre=/usr/bin/docker pull /nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
/nginx_lb /usr/local/bin/confd-watch

今、私たちが整理する必要があるのは、停止コマンドと `+ fleet +`スケジューリング方向だけです。 このコンテナは、他の負荷分散インスタンスまたはバックエンドApacheサーバーを実行していないホストでのみ開始する必要があります。 これにより、サービスは効果的に負荷を分散できます。

[Unit]
Description=Nginx load balancer for web server backends

# Requirements
Requires=etcd.service
Requires=docker.service

# Dependency ordering
After=etcd.service
After=docker.service

[Service]
# Let the process take awhile to start up (for first run Docker containers)
TimeoutStartSec=0

# Change killmode from "control-group" to "none" to let Docker remove
# work correctly.
KillMode=none

# Get CoreOS environmental variables
EnvironmentFile=/etc/environment

# Pre-start and Start
## Directives with "=-" are allowed to fail without consequence
ExecStartPre=-/usr/bin/docker kill nginx_lb
ExecStartPre=-/usr/bin/docker rm nginx_lb
ExecStartPre=/usr/bin/docker pull /nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
/nginx_lb /usr/local/bin/confd-watch

# Stop
ExecStop=/usr/bin/docker stop nginx_lb

[X-Fleet]
Conflicts=nginx.service
[email protected]*.service

完了したら、ファイルを保存して閉じます。

Nginxロードバランサーの実行

チュートリアルの前半ですでに2つのApacheインスタンスが実行されているはずです。 次のように入力して確認できます。

fleetctl list-units
UNIT                MACHINE             ACTIVE  SUB
[email protected]   197a1662.../10.132.249.206  active  running
[email protected]   04856ec4.../10.132.249.212  active  running
[email protected]     197a1662.../10.132.249.206  active  running
[email protected]     04856ec4.../10.132.249.212  active  running

次のように入力して、 `+ etcd +`に正しく登録されていることを再確認することもできます。

etcdctl ls --recursive /services/apache
/services/apache/10.132.249.206
/services/apache/10.132.249.212

Nginxサービスの開始を試みることができます:

fleetctl start ~/static/nginx_lb.service
Unit nginx_lb.service launched on 96ec72cf.../10.132.248.177

画像がプルダウンされるのにかかる時間に応じて、サービスの開始に1分程度かかる場合があります。 起動後、 `+ fleetctl journal `コマンドでログをチェックすると、 ` confd +`からのログ情報が表示されるはずです。 これは次のようになります。

fleetctl journal nginx_lb.service
-- Logs begin at Mon 2014-09-15 14:54:05 UTC, end at Tue 2014-09-16 17:13:58 UTC. --
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated
Sep 16 17:13:48 lala1 docker[15379]: [nginx] confd is monitoring etcd for changes...
Sep 16 17:13:48 lala1 docker[15379]: [nginx] starting nginx service...
Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/access.log <==
Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/error.log <==
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO /etc/nginx/sites-enabled/app.conf has md5sum a8517bfe0348e9215aa694f0b4b36c9b should be 33f42e3b7cc418f504237bea36c8a03e
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync
Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated

ご覧のように、 `+ confd `は初期設定のために ` etcd `を探しました。 そして、 ` nginx`を開始しました。 その後、 `+ etcd `エントリが再評価され、新しい設定ファイルが作成された行が表示されます。 新しく生成されたファイルが所定のファイルの ` md5sum +`と一致しない場合、ファイルは切り替えられ、サービスがリロードされます。

これにより、負荷分散サービスは最終的にApacheバックエンドサーバーを追跡できます。 `+ confd +`が継続的に更新されているように見える場合、ApacheインスタンスがTTLを頻繁に更新していることが原因である可能性があります。 これを回避するために、サイドキックテンプレートのスリープおよびTTL値を増やすことができます。

ロードバランサーの動作を確認するには、Nginxサービスを実行しているホストに `+ / etc / environments `ファイルを要求できます。 これには、ホストのパブリックIPアドレスが含まれます。 この設定を改善したい場合は、Apacheインスタンスの場合と同様に、この情報を ` etcd +`に登録するsidekickサービスを実行することを検討してください。

fleetctl ssh nginx_lb cat /etc/environment
COREOS_PRIVATE_IPV4=10.132.248.177
COREOS_PUBLIC_IPV4=104.131.16.222

ブラウザでパブリックIPv4アドレスにアクセスすると、Apacheインスタンスで構成したページが表示されます。

image:https://assets.digitalocean.com/articles/coreos_confd/apache_index.png [Apache index page]

これで、ログをもう一度見ると、どのバックエンドサーバーが実際にリクエストに合格したかを示す情報を確認できるはずです。

fleetctl journal nginx_lb
. . .
Sep 16 18:04:38 lala1 docker[18079]: 2014-09-16T18:04:38Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 18:04:48 lala1 docker[18079]: 2014-09-16T18:04:48Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync
Sep 16 18:04:48 lala1 docker[18079]: [16/Sep/2014:18:04:48 +0000] 108.29.37.206 passed to: : GET / HTTP/1.1 Upstream Response Time: 0.003 Request time: 0.003

結論

ご覧のとおり、設定の詳細について「+ etcd 」をチェックするようにサービスを設定することができます。 ` confd +`のようなツールは、重要なエントリの継続的なポーリングを許可することにより、このプロセスを比較的単純にすることができます。

このガイドの例では、 `+ etcd +`を使用して初期設定を生成するようにNginxサービスを設定しました。 また、変更を継続的にチェックするためにバックグラウンドで設定します。 これに、テンプレートに基づく動的な構成生成を組み合わせることで、バックエンドサーバーの最新の状況を常に把握することができました。