フリートユニットファイルを使用してCoreOSクラスター用の柔軟なサービスを作成する方法
ステータス:非推奨
理由: 2016年12月22日、CoreOSはフリートを維持しないことを発表しました。 フリートは、CoreOSから削除される2017年2月まで、セキュリティアップデートとバグ修正を受け取ります。 プロジェクトでは、すべてのクラスタリングのニーズにKubernetesを使用することを推奨しています。
代わりに参照してください:フリートなしでCoreOSでKubernetesを使用するガイダンスについては、CoreOSドキュメントのKubernetesを参照してください。
序章
CoreOSのインストールでは、多数のツールを活用して、クラスタリングとDockerに含まれるサービスを管理しやすくします。 その間 etcd
は、個別のノードをリンクし、グローバルデータ用の領域を提供することに関与しています。実際のサービス管理および管理タスクのほとんどは、 fleet
デーモン。
前のガイドでは、 fleetctl
サービスとクラスターメンバーを操作するためのコマンド。 そのガイドでは、フリートがサービスを定義するために使用するユニットファイルについて簡単に触れましたが、これらは、学習するための実用的なサービスを提供するために使用される簡略化された例です。 fleetctl
.
このガイドでは、調査します fleet
ユニットファイルの詳細については、ファイルの作成方法と、サービスを本番環境でより堅牢にするためのいくつかの手法について学習してください。
前提条件
このチュートリアルを完了するために、クラスタリングガイドで説明されているようにCoreOSクラスターが構成されていることを前提としています。 これにより、次のような名前の3つのサーバーが残ります。
- coreos-1
- coreos-2
- coreos-3
このチュートリアルのほとんどはユニットファイルの作成に焦点を当てていますが、これらのマシンは、特定のディレクティブのスケジューリングへの影響を示すために後で使用されます。
また、fleetctlの使用方法に関するガイドを読んだことを前提としています。 あなたはの実用的な知識を持っている必要があります fleetctl
これらのユニットファイルをクラスターで送信して使用できるようにします。
これらの要件を完了したら、ガイドの残りの部分に進みます。
ユニットファイルのセクションとタイプ
のサービス管理の側面のため fleet
主に各ローカルシステムに依存します systemd
initシステム、 systemd
ユニットファイルは、サービスを定義するために使用されます。
サービスはCoreOSで構成された最も一般的なユニットタイプですが、実際には定義できる他のユニットタイプがあります。 これらは、従来の方法で利用できるもののサブセットです。 systemd
ユニットファイル。 これらの各タイプは、ファイル拡張子として使用されているタイプによって識別されます。 example.service
:
- service :これは最も一般的なタイプのユニットファイルです。 これは、クラスター内のマシンの1つで実行できるサービスまたはアプリケーションを定義するために使用されます。
- socket :ソケットまたはソケットのようなファイルに関する詳細を定義します。 これらには、ネットワークソケット、IPCソケット、およびFIFOバッファが含まれます。 これらは、ファイルにトラフィックが見られたときに開始するサービスを呼び出すために使用されます。
- device :udevデバイスツリーで使用可能なデバイスに関する情報を定義します。 Systemdは、udevルールに基づいて、カーネルデバイスの個々のホストで必要に応じてこれらを作成します。 これらは通常、マウントを試みる前にデバイスが使用可能であることを確認するための注文の問題に使用されます。
- mount :デバイスのマウントポイントに関する情報を定義します。 これらは、参照するマウントポイントにちなんで名付けられ、スラッシュがダッシュに置き換えられています。
- automount :自動マウントポイントを定義します。 それらはマウントユニットと同じ命名規則に従い、関連するマウントユニットを伴う必要があります。 これらは、オンデマンドおよび並列マウントを説明するために使用されます。
- timer :別のユニットに関連付けられたタイマーを定義します。 このファイルで定義された時点に達すると、関連するユニットが開始されます。
- path :パスベースのアクティブ化を監視できるパスを定義します。 これは、特定のパスに変更が加えられたときに別のユニットを起動するために使用できます。
これらのオプションはすべて利用可能ですが、サービスユニットが最も頻繁に使用されます。 このガイドでは、サービスユニットの構成についてのみ説明します。
ユニットファイルは、ドットと上記のサフィックスのいずれかで終わる単純なテキストファイルです。 内部では、セクションごとに編成されています。 為に fleet
、ほとんどのユニットファイルは次の一般的な形式になります。
[Unit]
generic_unit_directive_1
generic_unit_directive_2
[Service]
service_specific_directive_1
service_specific_directive_2
service_specific_directive_3
[X-Fleet]
fleet_specific_directive
ユニットファイル内のセクションヘッダーとその他すべては大文字と小文字が区別されます。 The [Unit]
セクションは、ユニットに関する一般的な情報を定義するために使用されます。 すべてのユニットタイプに共通のオプションは、通常、ここに配置されます。
The [Service]
セクションは、サービスユニットに固有のディレクティブを設定するために使用されます。 上記のユニットタイプのほとんど(すべてではありません)には、ユニットタイプ固有の情報に関連するセクションがあります。 詳細については、 generic systemd unit fileのマニュアルページで、さまざまなユニットタイプへのリンクを確認してください。
The [X-Fleet]
セクションは、で使用するユニットのスケジューリング要件を設定するために使用されます fleet
. このセクションを使用すると、ユニットをホストでスケジュールするために、特定の条件が真である必要があります。
メインサービスの構築
このセクションでは、CoreOSでのサービスの実行に関する基本ガイドで説明されているユニットファイルのバリアントから始めます。 ファイルは呼び出されます apache.1.service
次のようになります。
[Unit]
Description=Apache web server service
# Requirements
Requires=etcd.service
Requires=docker.service
Requires=apache-discovery.1.service
# Dependency ordering
After=etcd.service
After=docker.service
Before=apache-discovery.1.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
ExecStartPre=-/usr/bin/docker rm apache
ExecStartPre=/usr/bin/docker pull username/apache
ExecStart=/usr/bin/docker run --name apache -p ${COREOS_PUBLIC_IPV4}:80:80 \
username/apache /usr/sbin/apache2ctl -D FOREGROUND
# Stop
ExecStop=/usr/bin/docker stop apache
[X-Fleet]
# Don't schedule on the same machine as other Apache instances
X-Conflicts=apache.*.service
まずは [Unit]
セクション。 ここでの基本的な考え方は、ユニットを記述し、依存関係情報を配置することです。 まず、一連の要件から始めます。 この例では、厳しい要件を使用しました。 欲しかったら fleet
追加のサービスを開始しようとするが、失敗で停止しないようにするには、 Wants
代わりにディレクティブ。
その後、要件の順序を明示的にリストします。 これは、必要なときに前提条件のサービスを利用できるようにするために重要です。 また、サイドキックなどを自動的に開始して、構築するサービスをアナウンスする方法でもあります。
のために [Service]
セクションでは、サービスの起動タイムアウトをオフにします。 ホストでサービスを初めて実行するときは、コンテナをDockerレジストリからプルダウンする必要があります。これは、起動タイムアウトにカウントされます。 これはデフォルトで90秒に設定されており、通常は十分な時間ですが、より複雑なコンテナーでは、さらに時間がかかる場合があります。
次に、killmodeをnoneに設定します。 これが使用されるのは、通常のキルモード(control-group)により、コンテナー削除コマンドが失敗することがあるためです(特に、Dockerが試行した場合)。 --rm
オプション)。 これにより、次回の再起動時に問題が発生する可能性があります。
環境ファイルを取得して、にアクセスできるようにします。 COREOS_PUBLIC_IPV4
また、作成中にプライベートネットワークが有効になっている場合は、 COREOS_PRIVATE_IPV4
環境変数。 これらは、特定のホストの情報を使用するようにDockerコンテナーを構成する場合に非常に役立ちます。
The ExecStartPre
行は、実行環境がクリーンであることを確認するために、前の実行から残った残骸を破棄するために使用されます。 を使用しております =-
これらの最初の2つは、 systemd
これらのコマンドが失敗した場合は、無視して続行する必要があります。 このため、Dockerは以前のコンテナーを強制終了して削除しようとしますが、コンテナーが見つからなくても心配する必要はありません。 最後の事前開始は、コンテナーの最新バージョンが実行されていることを確認するために使用されます。
実際のstartコマンドは、Dockerコンテナーを起動し、それをホストマシンのパブリックIPv4インターフェイスにバインドします。 これにより、環境ファイルの情報が使用され、インターフェイスとポートを簡単に切り替えることができます。 実行中のプロセスが終了するとコンテナが終了するため、プロセスはフォアグラウンドで実行されます。 stopコマンドは、コンテナーを正常に停止しようとします。
The [X-Fleet]
セクションには、強制する単純な条件が含まれています fleet
別のApacheサービスをまだ実行していないマシンでサービスをスケジュールします。 これは、重複するサービスを別々のマシンで強制的に開始することにより、サービスを高可用性にする簡単な方法です。
メインサービスを構築するための基本的なポイント
上記の例では、かなり基本的な構成を確認しました。 ただし、一般的なサービスの構築を支援するために、これからできることはたくさんあります。
メインサービスを構築する際に留意すべきいくつかの動作:
- 依存関係と順序付けの個別のロジック:依存関係を次のようにレイアウトします
Requires=
またWants=
依存関係を満たせない場合に、構築しているユニットが失敗するかどうかに依存するディレクティブ。 注文を別々に分けますAfter=
とBefore=
要件が変更された場合に簡単に調整できるように線。 依存関係リストを順序付けから分離すると、依存関係の問題が発生した場合のデバッグに役立ちます。 - 別のプロセスでサービス登録を処理する:サービスはで登録する必要があります
etcd
これにより、サービス検出と動的構成機能を利用できます。 ただし、ロジックを分離しておくために、これは別の「サイドキック」コンテナで処理する必要があります。 これにより、他のコンポーネントが必要とする外部の観点から見たサービスの状態をより正確にレポートできます。 - サービスがタイムアウトする可能性に注意してください:調整を検討してください
TimeoutStartSec
より長い開始時間を可能にするためのディレクティブ。 これを「0」に設定すると、起動タイムアウトが無効になります。 Dockerがイメージをプルする必要がある場合があるため(初回実行時または更新が見つかった場合)、これが必要になることがよくあります。これにより、サービスの初期化にかなりの時間がかかる可能性があります。 - サービスが正常に停止しない場合はKillModeを調整します:
KillMode
サービスまたはコンテナが不潔に停止しているように見える場合のオプション。 これを「なし」に設定すると、停止後にコンテナが削除されないという問題を解決できる場合があります。 前回の実行で同じ名前のコンテナーが残されているとDockerが失敗するため、コンテナーに名前を付ける場合は特に重要です。 詳細については、KillModeのドキュメントを確認してください - 起動する前に環境をクリーンアップする:上記の項目に関連して、起動するたびに以前のDockerコンテナーを必ずクリーンアップしてください。 前回のサービスの実行が期待どおりに終了したと想定しないでください。 これらのクリーンアップラインは、
=-
クリーンアップが必要ない場合にサイレントに失敗できるようにする指定子。 コンテナを停止する必要がありますがdocker stop
通常は、おそらく使用する必要がありますdocker kill
クリーンアップ中。 - サービスの移植性のためにホスト固有の情報を取得して使用する:サービスを特定のネットワークインターフェイスにバインドする必要がある場合は、
/etc/environment
アクセスするファイルCOREOS_PUBLIC_IPV4
そして、構成されている場合はCOREOS_PRIVATE_IPV4
. サービスを実行しているマシンのホスト名を知る必要がある場合は、%H
systemd指定子。 可能な指定子の詳細については、systemd指定子のドキュメントをご覧ください。 の中に[X-Fleet]
セクション、のみ%n
,%N
,%i
、 と%p
指定子は機能します。
サイドキックアナウンスサービスの構築
メインサービスを構築する際に留意すべき点についての良いアイデアが得られたので、従来の「サイドキック」サービスの検討を開始できます。 これらのサイドキックサービスはメインサービスに関連付けられており、サービスを登録するための外部ポイントとして使用されます。 etcd
.
このファイルは、本体ファイルで参照されていたため、 apache-discovery.1.service
そしてこのように見えます:
[Unit]
Description=Apache web server etcd registration
# Requirements
Requires=etcd.service
Requires=apache.1.service
# Dependency ordering and binding
After=etcd.service
After=apache.1.service
BindsTo=apache.1.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_PUBLIC_IPV4}:80; \
if [ $? -eq 0 ]; then \
etcdctl set /services/apache/${COREOS_PUBLIC_IPV4} \'{"host": "%H", "ipv4_addr": ${COREOS_PUBLIC_IPV4}, "port": 80}\' --ttl 30; \
else \
etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}; \
fi; \
sleep 20; \
done'
# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}
[X-Fleet]
# Schedule on the same machine as the associated Apache service
X-ConditionMachineOf=apache.1.service
メインサービスとほぼ同じ方法でサイドキックサービスを開始します。 依存関係情報と順序付けロジックに進む前に、ユニットの目的について説明します。
ここでの最初の新しいアイテムは BindsTo=
指令。 このディレクティブにより、このユニットは、リストされたユニットに送信された開始、停止、および再起動コマンドに従います。 基本的に、これは、両方がロードされた後、メインユニットを操作することによって、これらのユニットの両方を管理できることを意味します fleet
. これは一方向のメカニズムであるため、サイドキックを制御しても本体には影響しません。
のために [Service]
セクション、私たちは再び調達します /etc/environment
保持する変数が必要なため、ファイル。 The ExecStart=
この場合のディレクティブは基本的に短いです bash
脚本。 公開されたインターフェイスとポートを使用して、メインサービスに接続しようとします。
接続が成功した場合、 etcdctl
コマンドは、内のホストマシンのパブリックIPアドレスにキーを設定するために使用されます /services/apache
内部 etcd
. この値は、サービスに関する情報を含むJSONオブジェクトです。 キーは30秒で期限切れになるように設定されているため、このユニットが予期せずダウンした場合でも、古いサービス情報が残されることはありません etcd
. 接続に失敗した場合、サービスが利用可能かどうかを確認できないため、キーはすぐに削除されます。
このループには、20秒のスリープコマンドが含まれます。 これは、20秒ごと(30秒前)を意味します etcd
キータイムアウト)、本機は本体が使用可能かどうかを再確認し、キーをリセットします。 これにより、基本的にキーのTTLが更新され、さらに30秒間有効であると見なされます。
この場合のstopコマンドは、キーを手動で削除するだけです。 これにより、本体の停止コマンドが本機にミラーリングされた場合、サービス登録が削除されます。 BindsTo=
指令。
のために [X-Fleet]
セクションでは、このユニットがメインユニットと同じサーバーで起動されていることを確認する必要があります。 これにより、ユニットはリモートマシンへのサービスの可用性についてレポートできなくなりますが、 BindsTo=
正しく機能するためのディレクティブ。
サイドキックサービスを構築するための基本的なポイント
このサイドキックを構築する際に、これらのタイプのユニットの一般的なルールとして覚えておくべきいくつかのことを見ることができます。
- 本体の実際の可用性を確認する:本体の状態を実際に確認することが重要です。 サイドキックが初期化されたからといって、本体が使用可能であると思い込まないでください。 これは、本体の設計と機能に依存しますが、チェックが堅牢であるほど、登録状態の信頼性が高くなります。 チェックは、ユニットのチェックから、ユニットにとって意味のあるものであれば何でもかまいません。
/health
クライアントを使用してデータベースに接続しようとするエンドポイント。 - 登録ロジックをループして定期的に再確認します:開始時にサービスの可用性を確認することは重要ですが、定期的に再確認することも不可欠です。 これにより、予期しないサービス障害のインスタンスをキャッチできます。特に、コンテナが停止しない場合はなおさらです。 サイクル間の一時停止は、メインユニットの追加の負荷に対して迅速な検出の重要性を比較検討することにより、ニーズに応じて微調整する必要があります。
- 障害の自動登録解除のためにetcdに登録するときにTTLフラグを使用します:サイドキックユニットの予期しない障害により、
etcd
. サービスの登録状態と実際の状態の競合を回避するには、キーをタイムアウトさせる必要があります。 上記のループ構造を使用すると、タイムアウト間隔の前に各キーを更新して、サイドキックの実行中にキーが実際に期限切れにならないようにすることができます。 これが正しく機能するようにするには、ループ内のスリープ間隔をタイムアウト間隔よりわずかに短く設定する必要があります。 - 確認だけでなく、etcdに有用な情報を登録する:サイドキックの最初の反復では、正確に登録することだけに関心があるかもしれません。
etcd
ユニットが起動したとき。 しかし、これは他のサービスが利用するために多くの有用な情報を提供する機会を逃しました。 今はこの情報は必要ないかもしれませんが、値を読み取る機能を備えた他のコンポーネントを構築すると、より便利になります。etcd
独自の構成用。 Theetcd
サービスはグローバルなKey-Valueストアであるため、重要な情報を提供することでこれを活用することを忘れないでください。 JSONオブジェクトに詳細を保存することは、複数の情報を渡すための良い方法です。
これらの考慮事項を念頭に置くことで、次のことをインテリジェントに保証できる堅牢な登録ユニットの構築を開始できます。 etcd
正しい情報を持っています。
フリート固有の考慮事項
その間 fleet
ユニットファイルは、ほとんどの場合、従来のものと同じです。 systemd
ユニットファイルには、いくつかの追加機能と落とし穴があります。
最も明らかな違いは、 [X-Fleet]
指示するために使用することができます fleet
スケジューリングの決定を行う方法について。 使用可能なオプションは次のとおりです。
- X-ConditionMachineID :これを使用して、ユニットをロードする正確なマシンを指定できます。 提供される値は完全なマシンIDです。 この値は、クラスターの個々のメンバーから取得できます。
/etc/machine-id
ファイル、またはを介してfleetctl
発行することによりlist-machines -l
指図。 ID文字列全体が必要です。 これは、データディレクトリが特定のマシンに保持されているデータベースを実行している場合に必要になることがあります。 これを使用する特別な理由がない限り、ユニットの柔軟性が低下するため、使用しないようにしてください。 - X-ConditionMachineOf :このディレクティブを使用して、指定されたユニットがロードされているのと同じマシンでこのユニットをスケジュールできます。 これは、サイドキックユニットや関連するユニットをまとめる場合に役立ちます。
- X-Conflicts :これは、このユニットがと一緒にスケジュールできないユニットファイルを指定するという点で、上記の宣言の反対です。 これは、同じサービスの複数のバージョンをそれぞれ異なるマシンで開始することにより、高可用性を簡単に構成するのに役立ちます。
- X-ConditionMachineMetadata :これは、使用可能なマシンのメタデータに基づいてスケジューリング要件を指定するために使用されます。 の「METADATA」列
fleetctl list-machines
出力すると、各ホストに設定されているメタデータを確認できます。 メタデータを設定するには、メタデータをcloud-config
サーバーインスタンスを初期化するときのファイル。 - Global :これは、クラスター内のすべてのマシンでスケジュールする必要があるかどうかを示すブール引数を取る特別なディレクティブです。 このディレクティブと一緒に使用できるのは、メタデータ条件付きのみです。
これらの追加のディレクティブにより、管理者は、使用可能なマシンでサービスを実行する方法を定義する際の柔軟性と能力が向上します。 これらは、特定のマシンに渡す前に評価されます systemd
中のインスタンス fleetctl load
ステージ。
これにより、関連するユニットを操作するときに注意すべき次のことがわかります。 fleet
. The fleetctl
ユーティリティは、外部の依存関係要件を評価しません [X-Fleet]
ユニットファイルのセクション。 これは、コンパニオンユニットを操作するときにいくつかの興味深い問題につながります fleet
.
これは、 fleetctl
ツールは、ターゲットユニットを目的の状態にするために必要な手順を実行し、指定されたコマンドに基づいて必要に応じて送信、ロード、および開始プロセスを実行します。ユニットの依存関係に対してはこれを実行しません。
したがって、メインユニットとサイドキックユニットの両方を送信したが、ロードしていない場合は、 fleet
、入力 fleetctl start main.service
ロードしてから開始を試みます main.service
単位。 ただし、 sidekick.service
ユニットはまだロードされていません。 fleetctl
依存関係情報を評価して、依存関係ユニットをロードおよび開始プロセスに持ち込むことはありません。 main.service
ユニットは故障します。 これは、かつてのマシンが systemd
インスタンスは main.service
ユニット、それは見つけることができなくなります sidekick.service
itが依存関係を評価するとき。 The sidekick.service
ユニットがマシンにロードされたことはありません。
コンパニオンユニットを扱うときにこの状況を回避するために、サービスを同時に開始することができます。 BindsTo=
サイドキックを実行状態にするディレクティブ:
fleetctl start main.service sidekick.service
もう1つのオプションは、メインユニットの実行時にサイドキックユニットが少なくともロードされていることを確認することです。 ロード段階では、マシンが選択され、ユニットファイルがローカルに送信されます systemd
実例。 これにより、依存関係が満たされ、 BindsTo=
ディレクティブは正しく実行され、2番目のユニットを起動できます。
fleetctl load main.service sidekick.service
fleetctl start main.service
あなたの関連するユニットがあなたに正しく反応しない場合には、これを覚えておいてください fleetctl
コマンド。
インスタンスとテンプレート
で作業するときの最も強力な概念の1つ fleet
単位テンプレートです。
ユニットテンプレートは、 systemd
「インスタンス」と呼ばれます。 これらは、テンプレートユニットファイルを処理することによって実行時に作成されるインスタンス化されたユニットです。 テンプレートファイルは、ほとんどの場合、通常のユニットファイルと非常によく似ていますが、いくつかの小さな変更が加えられています。 ただし、これらは正しく使用すると非常に強力です。
テンプレートファイルは、 @
それらのファイル名で。 従来のサービスはこの形式を取りますが:
unit.service
テンプレートファイルは次のようになります。
unit@.service
ユニットがテンプレートからインスタンス化されると、そのインスタンス識別子は @
そしてその .service
サフィックス。 この識別子は、管理者が選択した一意の文字列です。
unit@instance_id.service
基本ユニット名は、ユニットファイル内からアクセスできます。 %p
指定子。 同様に、指定されたインスタンス識別子には、次のコマンドでアクセスできます。 %i
.
テンプレートとしてのメインユニットファイル
これは、と呼ばれるメインユニットファイルを作成する代わりに apache.1.service
前に見たコンテンツを使用して、次のようなテンプレートを作成できます。 [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 username/apache
ExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PUBLIC_IPV4}:%i:80 \
username/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
X-Conflicts=apache@*.service
ご覧のとおり、 apache-discovery.1.service
依存関係 apache-discovery@%i.service
. これは、このユニットファイルのインスタンスが [email protected]
、これにはと呼ばれる相棒が必要になります [email protected]
. The %i
インスタンス識別子に置き換えられました。 この場合、識別子を使用して、サービスの実行方法、特にApacheサーバーが使用可能なポートに関する動的な情報を保持しています。
これを機能させるために、 docker run
コンテナのポートをホスト上のポートに公開するパラメータ。 静的ユニットファイルでは、使用したパラメータは ${COREOS_PUBLIC_IPV4}:80:80
、コンテナのポート80をパブリックIPv4インターフェイス上のホストのポート80にマップしました。 このテンプレートファイルでは、これを次のように置き換えています。 ${COREOS_PUBLIC_IPV4}:%i:80
インスタンス識別子を使用して、使用するポートを指定しているためです。 インスタンス識別子を賢く選択することは、テンプレートファイル内の柔軟性を高めることを意味します。
Docker名自体も変更され、インスタンスIDに基づく一意のコンテナー名も使用されるようになりました。 Dockerコンテナは @
シンボルなので、ユニットファイルから別の名前を選択しました。 Dockerコンテナで動作するすべてのディレクティブを変更します。
の中に [X-Fleet]
セクションでは、以前使用していた静的な種類ではなく、これらのインスタンス化されたユニットを認識するようにスケジューリング情報も変更しました。
テンプレートとしてのサイドキックユニット
同様の手順を実行して、サイドキックユニットをテンプレートに適合させることができます。
私たちの新しいサイドキックユニットは [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_PUBLIC_IPV4}:%i; \
if [ $? -eq 0 ]; then \
etcdctl set /services/apache/${COREOS_PUBLIC_IPV4} \'{"host": "%H", "ipv4_addr": ${COREOS_PUBLIC_IPV4}, "port": %i}\' --ttl 30; \
else \
etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}; \
fi; \
sleep 20; \
done'
# Stop
ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PUBLIC_IPV4}
[X-Fleet]
# Schedule on the same machine as the associated Apache service
X-ConditionMachineOf=apache@%i.service
静的バージョンではなく、インスタンス化されたバージョンのメインユニットプロセスを要求してバインドするのと同じ手順を実行しました。 これにより、インスタンス化されたサイドキックユニットが正しいインスタンス化されたメインユニットと一致します。
間に curl
コマンドを実行すると、サービスの実際の可用性を確認するときに、静的ポート80をインスタントIDに置き換えて、正しい場所に接続できるようにします。 これは、メインユニットのDockerコマンド内でポート公開マッピングを変更したために必要です。
ログに記録される「ポート」も変更します etcd
これと同じインスタンスIDを使用するようにします。 この変更により、JSONデータが設定されます etcd
完全に動的です。 ホスト名、IPアドレス、およびサービスが実行されているポートを取得します。
最後に、条件を変更します [X-Fleet]
再びセクション。 このプロセスがメインユニットインスタンスと同じマシンで開始されていることを確認する必要があります。
テンプレートからのユニットのインスタンス化
テンプレートファイルからユニットを実際にインスタンス化するには、いくつかの異なるオプションがあります。
両方 fleet
と systemd
シンボリックリンクを処理できます。これにより、次のように、完全なインスタンスIDを使用してテンプレートファイルへのリンクを作成するオプションが提供されます。
ln -s [email protected] [email protected]
ln -s [email protected] [email protected]
これにより、2つのリンクが作成されます。 [email protected]
と [email protected]
. これらのそれぞれには、に必要なすべての情報があります fleet
と systemd
これらのユニットを今すぐ実行します。 ただし、必要な変更を1か所で行えるように、テンプレートに戻されています。
その後、これらのサービスを送信、ロード、または開始できます。 fleetctl
このような:
fleetctl start [email protected] [email protected]
インスタンスを定義するためのシンボリックリンクを作成したくない場合は、テンプレート自体をに送信することもできます。 fleetctl
、 このような:
fleetctl submit [email protected] [email protected]
これらのテンプレートからユニットを内部から直接インスタンス化できます fleetctl
実行時にインスタンス識別子を割り当てるだけです。 たとえば、次のように入力すると、同じサービスを実行できます。
fleetctl start [email protected] [email protected]
これにより、シンボリックリンクが不要になります。 一部の管理者は、いつでもインスタンスファイルを利用できることを意味するため、リンクメカニズムを好みます。 また、ディレクトリをに渡すこともできます fleetctl
すべてが一度に開始されるようにします。
たとえば、作業ディレクトリには、というサブディレクトリがあります。 templates
テンプレートファイルとサブディレクトリ instances
インスタンス化されたリンクバージョンの場合。 あなたも static
テンプレート化されていないユニットの場合。 あなたはそのようにこれを行うことができます:
mkdir templates instances static
次に、静的ファイルをに移動できます static
とテンプレートファイルを templates
:
mv apache.1.service apache-discovery.1.service static
mv [email protected] [email protected] templates
ここから、必要なインスタンスリンクを作成できます。 ポートでサービスを実行してみましょう 5555
, 6666
、 と 7777
:
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]
ln -s ../templates/[email protected] [email protected]
ln -s ../templates/[email protected] [email protected]
次に、次のように入力して、すべてのインスタンスを一度に開始できます。
cd ..
fleetctl start instances/*
これは、サービスをすばやく開始するのに非常に役立ちます。
結論
ユニットファイルを作成する方法を十分に理解している必要があります fleet
この時点で。 ユニットファイル内で利用可能な動的機能のいくつかを利用することで、サービスが均等に分散され、依存関係に近くなり、有用な情報をに登録できるようになります。 etcd
.
後のガイドでは、登録している情報を使用するようにコンテナーを構成する方法について説明します。 etcd
. これは、バックエンド内の適切なコンテナーに要求を渡すために、サービスが実際のデプロイメント環境の実用的な知識を構築するのに役立ちます。