ConfdとEtcdを使用してCoreOSでサービスを動的に再構成する方法
序章
CoreOSを使用すると、マシンのクラスター全体でDockerコンテナーでサービスを簡単に実行できます。 そのための手順には、通常、サービスの1つまたは複数のインスタンスを開始してから、各インスタンスをに登録することが含まれます。 etcd
、CoreOSの分散型Key-Valueストア。
このパターンを利用することで、関連サービスはインフラストラクチャの状態に関する貴重な情報を取得し、この知識を使用して自身の動作を通知できます。 これにより、サービスは重要な場合はいつでも動的に構成できます。 etcd
値が変わります。
このガイドでは、 confd
、これは、分散されたKey-Valueストアの変更を監視するために特別に作成されています。 Dockerコンテナー内から実行され、構成の変更とサービスのリロードをトリガーするために使用されます。
前提条件と目標
このガイドを実行するには、CoreOSとそのコンポーネントパーツの基本を理解している必要があります。 以前のガイドでは、CoreOSクラスターをセットアップし、クラスターの管理に使用されるいくつかのツールに精通しました。
以下は、この記事を始める前に読むべきガイドです。 これらのガイドで説明されている一部のサービスの動作を変更するため、資料を理解することは重要ですが、このガイドを使用するときは、最初からやり直す必要があります。
- DigitalOceanでCoreOSクラスターをセットアップする方法
- CoreOSクラスターでサービスを作成して実行する方法
- フリートユニットファイルを使用してCoreOSクラスター用の柔軟なサービスを作成する方法
さらに、使用する管理ツールのいくつかに慣れるために、次のガイドを参照してください。
テンプレート化されたメイン+サイドキックサービスがこのガイドで設定するフロントエンドサービスの基礎として機能するため、「柔軟なサービスを作成する方法」ガイドはこのガイドにとって特に重要です。 前述したように、上記のガイドではApacheおよびサイドキックサービスの作成について説明していますが、このガイドには、最初から簡単に開始できるようにするための構成変更がいくつかあります。 このガイドでは、これらのサービスの変更バージョンを作成します。
このチュートリアルでは、Nginxを使用した新しいアプリケーションコンテナの作成に焦点を当てます。 これは、テンプレートファイルから生成できるさまざまなApacheインスタンスへのリバースプロキシとして機能します。 Nginxコンテナは次のように構成されます confd
私たちのサイドキックサービスが担当するサービス登録を監視します。
このシリーズで使用していたのと同じ3台のマシンクラスターから始めます。
- coreos-1
- coreos-2
- coreos-3
上記のガイドを読み終えて、3台のマシンクラスターを使用できるようになったら、続行します。
バックエンドApacheサービスの構成
まず、バックエンドのApacheサービスを設定します。 これは主に前のガイドの最後の部分を反映していますが、微妙な違いがあるため、ここでは手順全体を実行します。
開始するには、CoreOSマシンの1つにログインします。
ssh -A core@ip_address
Apacheコンテナのセットアップ
基本的なApacheコンテナを作成することから始めます。 これは実際には前回のガイドと同じであるため、Docker Hubアカウントでそのイメージを既に使用できる場合は、これを再度行う必要はありません。 このコンテナは、Ubuntu14.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
次のように入力して、DockerHubにログインまたはアカウントを作成します。
docker login
Docker Hubアカウントのユーザー名、パスワード、メールアドレスを入力する必要があります。
次に、残したインスタンスのコンテナIDを取得します。
docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1db0c9a40c0d ubuntu:14.04 "/bin/bash" 2 minutes ago Exited (0) 4 seconds ago jolly_pare
上の強調表示されたフィールドはコンテナIDです。 自分のコンピューターに表示される出力をコピーします。
次に、そのコンテナID、Docker Hubユーザー名、およびイメージの名前を使用してコミットします。 ここでは「apache」を使用します。
docker commit 1db0c9a40c0d user_name/apache
新しいイメージをDockerHubにプッシュします。
docker push user_name/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
Requires=apache-discovery@%i.service
# Dependency ordering
After=etcd.service
After=docker.service
Before=apache-discovery@%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 user_name/apache
ExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PRIVATE_IPV4}:%i:80 \
user_name/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
Conflicts=apache@*.service
ここで行った変更の1つは、パブリックインターフェイスの代わりにプライベートインターフェイスを使用することです。 すべてのApacheインスタンスは、オープンWebからの接続を処理する代わりに、トラフィックから Nginxリバースプロキシに渡されるため、これは良い考えです。 DigitalOceanでプライベートインターフェイスを使用する場合、スピンアップしたサーバーでは、作成時に「プライベートネットワーク」フラグが選択されている必要があることに注意してください。
また、変更することを忘れないでください user_name
Dockerファイルを正しくプルダウンするためにDockerHubユーザー名を参照します。
サイドキックテンプレートユニットファイルの作成
さて、サイドキックサービスについても同じことをします。 これは、後で必要になる情報を見越して少し変更します。
エディターでテンプレートファイルを開きます。
vim templates/[email protected]
このファイルでは、次の情報を使用します。
[Unit]
Description=Apache web server on port %i etcd registration
# Requirements
Requires=etcd.service
Requires=apache@%i.service
# Dependency ordering and binding
After=etcd.service
After=apache@%i.service
BindsTo=apache@%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
MachineOf=apache@%i.service
上記の構成は、前のガイドの構成とはいくつかの点で異なります。 によって設定された値を調整しました etcdctl set
指図。 JSONオブジェクトを渡す代わりに、単純なIPアドレスとポートの組み合わせを設定しています。 このようにして、この値を直接読み取って、このサービスにアクセスするために必要な接続情報を見つけることができます。
また、他のファイルで行ったように、プライベートインターフェイスを指定するように情報を調整しました。 このオプションを利用できない場合は、これを公開したままにします。
サービスをインスタンス化する
それでは、これらのサービスの2つのインスタンスを作成しましょう。
まず、シンボリックリンクを作成しましょう。 に移動します ~/instances
作成したディレクトリとリンクして、それらが実行されるポートを定義します。 1つのサービスをポート7777で実行し、別のサービスをポート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
/services/apache/10.132.249.206
/services/apache/10.132.249.212
これらのエントリのいずれかの値を要求すると、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
見ることができるように /services/apache
の場所 etcd
変更のために、毎回Nginxを再構成します。
Nginxコンテナの作成
Apacheサービスに使用したのと同じUbuntu14.04ベースからNginxコンテナを起動します。
ソフトウェアのインストール
次のように入力して、新しいコンテナを起動します。
docker run -i -t ubuntu:14.04 /bin/bash
ローカルを更新する apt
キャッシュをパッケージ化し、Nginxをインストールします。 また、インストールする必要があります curl
ベースイメージにはこれが含まれておらず、安定させるために必要です。 confd
一時的にGitHubからのパッケージ:
apt-get update
apt-get install nginx curl -y
これで、リリースページに移動できます。 confd
ブラウザのGitHubで。 最新の安定版リリースへのリンクを見つける必要があります。 この記事の執筆時点では、それは v0.5.0 ですが、これは変更されている可能性があります。 Linuxバージョンのツールのリンクを右クリックし、「リンクアドレスのコピー」または同様のオプションを選択します。
ここで、Dockerコンテナーに戻り、コピーしたURLを使用してアプリケーションをダウンロードします。 これを入れます /usr/local/bin
ディレクトリ。 選択する必要があります confd
出力ファイルとして:
cd /usr/local/bin
curl -L https://github.com/kelseyhightower/confd/releases/download/v0.5.0/confd-0.5.0<^>-linux-amd64 -o confd
次に、ファイルを実行可能にして、コンテナ内で使用できるようにします。
chmod +x confd
また、この機会を利用して、次のような構成構造を作成する必要があります。 confd
期待しています。 これは、 /etc
ディレクトリ:
mkdir -p /etc/confd/{conf.d,templates}
Etcd値を読み取るためのConfd構成ファイルを作成する
アプリケーションがインストールされたので、構成を開始する必要があります confd
. まず、構成ファイルまたはテンプレートリソースファイルを作成します。
の構成ファイル confd
特定をチェックするサービスを設定するために使用されます etcd
値を設定し、変更が検出されたときにアクションを開始します。 これらは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"
上記のファイルには、いくつかの基本的なアイデアを説明するコメントが含まれていますが、以下のオプションを検討することができます。
指令 | 必須? | タイプ | 説明 |
---|---|---|---|
src | はい | 弦 | 情報のレンダリングに使用されるテンプレートの名前。 これが外にある場合 /etc/confd/templates 、パス全体を使用する必要があります。 |
dest | はい | 弦 | レンダリングされた構成ファイルを配置するファイルの場所。 |
キー | はい | 文字列の配列 | The etcd テンプレートを正しくレンダリングするために必要なキー。 テンプレートが子キーを処理するように設定されている場合、これはディレクトリになる可能性があります。 |
オーナー | いいえ | 弦 | レンダリングされた構成ファイルの所有権が付与されるユーザー名。 |
グループ | いいえ | 弦 | レンダリングされた構成ファイルのグループ所有権が付与されるグループ。 |
モード | いいえ | 弦 | レンダリングされたファイルに設定する必要がある8進数のアクセス許可モード。 |
check_cmd | いいえ | 弦 | レンダリングされた構成ファイルの構文をチェックするために使用する必要があるコマンド。 |
reload_cmd | いいえ | 弦 | アプリケーションの構成を再ロードするために使用する必要があるコマンド。 |
プレフィックス | いいえ | 弦 | の一部 etcd のキーの前にある階層 keys 指令。 これを使用して、 .toml より柔軟なファイル。 |
私たちが作成したファイルは、私たちがどのように confd
インスタンスは機能します。 Nginxコンテナは、に保存されているテンプレートを使用します /etc/confd/templates/nginx.conf.tmpl
に配置される構成ファイルをレンダリングします /etc/nginx/sites-enabled/app.conf
. ファイルには、次の権限セットが付与されます。 0644
所有権はrootユーザーに与えられます。
The confd
アプリケーションはで変更を探します /services/apache
ノード。 変化が見られるとき、 confd
そのノードの下で新しい情報を照会します。 次に、Nginxの新しい構成をレンダリングします。 構成ファイルの構文エラーをチェックし、ファイルが配置された後にNginxサービスをリロードします。
これで、テンプレートリソースファイルが作成されました。 Nginx構成ファイルのレンダリングに使用される実際のテンプレートファイルで作業する必要があります。
Confdテンプレートファイルを作成する
テンプレートファイルには、 confd
プロジェクトのGitHubドキュメントを使用して開始します。
上記の構成ファイルで参照したファイルを作成します。 このファイルを templates
ディレクトリ:
vi /etc/confd/templates/nginx.tmpl
このファイルでは、基本的に、標準のNginxリバースプロキシ構成ファイルを再作成するだけです。 ただし、いくつかのGoテンプレート構文を使用して、次のような情報の一部を置き換えます。 confd
から引っ張っている etcd
.
まず、「アップストリーム」サーバーでブロックを構成します。 このセクションは、Nginxがリクエストを送信できるサーバーのプールを定義するために使用されます。 形式は一般的に次のようになります。
upstream pool_name {
server server_1_IP:port_num;
server server_2_IP:port_num;
server server_3_IP:port_num;
}
これにより、リクエストを pool_name
Nginxは、リクエストを渡すために定義されたサーバーの1つを選択します。
テンプレートファイルの背後にある考え方は、解析することです etcd
ApacheWebサーバーのIPアドレスとポート番号。 したがって、アップストリームサーバーを静的に定義するのではなく、ファイルのレンダリング時にこの情報を動的に入力する必要があります。 これを行うには、動的コンテンツにGoテンプレートを使用します。
これを行うには、代わりにこれをブロックとして使用します。
upstream apache_pool {
{{ range getvs "/services/apache/*" }}
server {{ . }};
{{ end }}
}
何が起こっているのか少し説明しましょう。 と呼ばれるサーバーのアップストリームプールを定義するためのブロックを開きました apache_pool
. 内部では、二重角かっこを使用してGo言語コードを開始することを指定します。
これらの括弧内に、 etcd
関心のある値が保持されるエンドポイント。 私たちは使用しています range
リストを反復可能にします。
これを使用して、以下から取得したすべてのエントリを渡します。 /services/apache
の場所 etcd
に 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のすべての接続に応答し、それらを次のサーバーのプールに渡します。 apache_pool
それは etcd
エントリ。
サービスのこの側面を扱っている間、後で競合が発生しないように、デフォルトの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設定をセットアップするには、コンテナーの起動時に実行する必要があります。
- 変更を監視し続ける必要があります
etcd
利用可能なバックエンドサーバーに基づいてNginxを再構成できるように、Apacheサーバーの登録。
スクリプトはMarceldeGraafのGitHubページから取得します。 これは、必要なことを正確に実行する素晴らしくシンプルなスクリプトです。 このシナリオでは、いくつかの小さな編集のみを行います。
このスクリプトを私たちの横に配置しましょう confd
実行可能。 これを呼びます confd-watch
:
vi /usr/local/bin/confd-watch
従来の方法から始めます bash
必要なインタープリターを識別するためのヘッダー。 次に、いくつかを設定します bash
何か問題が発生した場合にスクリプトがすぐに失敗するようにするオプション。 失敗または実行する最後のコマンドの値を返します。
#!/bin/bash
set -eo pipefail
次に、いくつかの変数を設定します。 を使用して bash
パラメータの置換では、デフォルト値を設定しますが、スクリプトを呼び出すときにハードコードされた値をオーバーライドできるように、ある程度の柔軟性を組み込みます。 これは基本的に、接続アドレスの各コンポーネントを個別に設定し、それらをグループ化して必要な完全なアドレスを取得するだけです。
パラメータ置換は、次の構文で作成されます。 ${var_name:-default_value}
. これには、の値を使用するプロパティがあります var_name
それが与えられ、nullでない場合、それ以外の場合はデフォルトで 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
これから使用します confd
から値を読み取ることにより、Nginx構成ファイルの初期バージョンをレンダリングします etcd
このスクリプトが呼び出されたときに使用できます。 を使用します 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
de4f30617499 ubuntu:14.04 "/bin/bash" 22 hours ago Exited (0) About a minute ago stupefied_albattani
強調表示された文字列は、必要なコンテナIDです。 このIDと、DockerHubのユーザー名およびこのイメージに使用する名前を使用してコンテナーをコミットします。 このガイドでは、「nginx_lb」という名前を使用します。
docker commit de4f30617499 user_name/nginx_lb
必要に応じて、DockerHubアカウントにログインします。
docker login
ここで、コミットしたイメージをプッシュアップして、他のホストが必要に応じてイメージをプルダウンできるようにする必要があります。
docker push user_name/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アドレスとプライベートIPアドレスにアクセスできるように、環境ファイルを再度プルします。
次に、環境をクリーンアップして、このコンテナの以前のバージョンがすべて強制終了され、削除されていることを確認します。 作成したばかりのコンテナをプルダウンして、常に最新バージョンであることを確認します。
最後に、コンテナを起動します。 これには、コンテナーを起動し、removeおよびkillコマンドで参照した名前を付け、コンテナーが実行されているホストのパブリックIPアドレスをマップポート80に渡すことが含まれます。 私たちは 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 user_name/nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
user_name/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 user_name/nginx_lb
ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \
user_name/nginx_lb /usr/local/bin/confd-watch
# Stop
ExecStop=/usr/bin/docker stop nginx_lb
[X-Fleet]
Conflicts=nginx.service
Conflicts=apache@*.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値を増やすことができます。
ロードバランサーの動作を確認するには、 /etc/environments
Nginxサービスを実行しているホストからのファイル。 これには、ホストのパブリックIPアドレスが含まれます。 この構成を改善したい場合は、この情報を登録するサイドキックサービスの実行を検討してください。 etcd
、Apacheインスタンスの場合と同じように:
fleetctl ssh nginx_lb cat /etc/environment
COREOS_PRIVATE_IPV4=10.132.248.177
COREOS_PUBLIC_IPV4=104.131.16.222
ここで、ブラウザーでパブリックIPv4アドレスに移動すると、Apacheインスタンスで構成したページが表示されます。
ここで、ログをもう一度見ると、どのバックエンドサーバーが実際にリクエストを渡されたかを示す情報を確認できるはずです。
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: 10.132.249.212:8888: GET / HTTP/1.1 Upstream Response Time: 0.003 Request time: 0.003
結論
ご覧のとおり、サービスを設定して確認することができます etcd
構成の詳細については。 のようなツール confd
重要なエントリの継続的なポーリングを可能にすることで、このプロセスを比較的簡単にすることができます。
このガイドの例では、使用するようにNginxサービスを構成しました etcd
初期構成を生成します。 また、バックグラウンドで設定して、継続的に変更を確認しています。 これをテンプレートに基づく動的構成の生成と組み合わせることで、バックエンドサーバーの最新の状況を一貫して把握することができました。