0

3 台のマシンで 3 つのコンテナーを実行しています。1つはグラファイト、1つはバック、もう1つはフロントと呼ばれます。フロント コンテナーを実行するには、他のコンテナーの両方が必要なので、次のように個別にリンクします。

[Unit]
Description=front hystrix


[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill front
ExecStartPre=-/usr/bin/docker rm -v front
ExecStartPre=/usr/bin/docker pull blurio/hystrixfront
ExecStart=/usr/bin/docker run  --name front --link graphite:graphite --link back:back -p 8080:8080 blurio/hystrixfront
ExecStop=/usr/bin/docker stop front

他の両方のコンテナーを開始し、それらが起動して実行されるまで待ってから、フリートctlでこれを開始すると、次のメッセージで即座に失敗します:

fleetctl status front.service
? front.service - front hystrix
   Loaded: loaded (/run/fleet/units/front.service; linked-runtime; vendor preset: disabled)
   Active: failed (Result: exit-code) since Tue 2015-05-12 13:46:08 UTC; 24s ago
  Process: 922 ExecStop=/usr/bin/docker stop front (code=exited, status=0/SUCCESS)
  Process: 912 ExecStart=/usr/bin/docker run --name front --link graphite:graphite --link back:back -p 8080:8080 blurio/hystrixfront (code=exited, status=1/FAILURE)
  Process: 902 ExecStartPre=/usr/bin/docker pull blurio/hystrixfront (code=exited, status=0/SUCCESS)
  Process: 892 ExecStartPre=/usr/bin/docker rm -v front (code=exited, status=1/FAILURE)
  Process: 885 ExecStartPre=/usr/bin/docker kill front (code=exited, status=1/FAILURE)
 Main PID: 912 (code=exited, status=1/FAILURE)

May 12 13:46:08 core-04 docker[902]: 8b9853c10955: Download complete
May 12 13:46:08 core-04 docker[902]: 0dc7a355f916: Download complete
May 12 13:46:08 core-04 docker[902]: 0dc7a355f916: Download complete
May 12 13:46:08 core-04 docker[902]: Status: Image is up to date for blurio/hystrixfront:latest
May 12 13:46:08 core-04 systemd[1]: Started front hystrix.
May 12 13:46:08 core-04 docker[912]: time="2015-05-12T13:46:08Z" level="fatal" msg="Error response from daemon: Could not get container for graphite"
May 12 13:46:08 core-04 systemd[1]: front.service: main process exited, code=exited, status=1/FAILURE
May 12 13:46:08 core-04 docker[922]: front
May 12 13:46:08 core-04 systemd[1]: Unit front.service entered failed state.
May 12 13:46:08 core-04 systemd[1]: front.service failed.

また、他の 2 つが問題なく実行されていることを確認できる、frotctl list-units の出力も含めたいと思います。

 fleetctl list-units
UNIT                    MACHINE                         ACTIVE  SUB
back.service            0ff08b11.../172.17.8.103        active  running
front.service           69ab2600.../172.17.8.104        failed  failed
graphite.service        2886cedd.../172.17.8.101        active  running
4

1 に答える 1

0

ここにはいくつかの問題があります。まず、docker には --link 引数を使用できません。これは、同じ Docker エンジン上で 1 つのコンテナーを別のコンテナーにリンクするための Docker 固有の手順です。あなたの例では、複数のエンジンがあるため、この手法は機能しません。その手法を使用したい場合は、アンバサダー パターンを採用する必要があります: coreos ambassadorまたは、X-Fleet ディレクティブ MachineOf: を使用して、すべての Docker コンテナーを同じマシン上で実行できますが、それはあなたの目標を打ち負かすと思います。

多くの場合、クラウド サービスでは、あなたの場合のように、あるサービスが別のサービスを必要とします。他のサービスが (まだ) 実行されていない場合、それを必要とするサービスは適切に動作し、終了するか、必要なサービスの準備が整うまで待機する必要があります。したがって、必要なサービスを検出する必要があります。発見フェーズと待機フェーズには多くの手法があります。たとえば、各コンテナに「ラッパー」スクリプトを記述できます。そのラッパーは、これらのタスクを実行できます。あなたの場合、次のように、情報を etcd データベースに書き込む back.service およびgraphite.service にスクリプトを含めることができます。

ExecStartPre=/usr/bin/env etcdctl set /graphite/status ready }'

次に、前の起動スクリプトで etcdctl get /graphite/status を実行して、コンテナーの準備が整ったときを確認します (準備が整うまで続行しないでください)。必要に応じて、グラファイト スクリプトに IP アドレスとポートを保存して、フロント スクリプトが接続先を取得できるようにすることができます。

発見のためのもう 1 つの手法は、登録者を使用することです。これは、コンテナが出入りするたびに etcd のディレクトリ構造を更新する、非常に便利な docker コンテナです。これにより、各コンテナーがそれ自体をアナウンスする必要がなく、自動化されるため、上に挙げたような検出手法を簡単に使用できます。サービスが etcd データベースに表示されるのを待機する起動スクリプトを含めるには、「front」コンテナーが引き続き必要です。私は通常、coreos の起動時にレジストレータを起動します。実際、私は 2 つのコピーを開始します。1 つは内部アドレス (フランネル アドレス) を検出するため、もう 1 つは外部 (コンテナー外で利用可能なサービス) を検出するためです。これは、私のマシンで管理するデータベース登録者の例です。

core@fo1 ~/prs $ etcdctl ls --recursive /skydns /skydns/net /skydns/net/tacodata /skydns/net/tacodata/services /skydns/net/tacodata/services/cadvisor-4194 /skydns/net/tacodata /services/cadvisor-4194/fo2:cadvisor:4194 /skydns/net/tacodata/services/cadvisor-4194/fo1:cadvisor:4194 /skydns/net/tacodata/services/cadvisor-4194/fo3:cadvisor:4194 /skydns /net/tacodata/services/internal /skydns/net/tacodata/services/internal/cadvisor-4194 /skydns/net/tacodata/services/internal/cadvisor-4194/fo2:cadvisor:4194 /skydns/net/tacodata/services /internal/cadvisor-4194/fo1:cadvisor:4194 /skydns/net/tacodata/services/internal/cadvisor-4194/fo3:cadvisor:4194 /skydns/net/tacodata/services/internal/cadvisor-8080 /skydns/net /tacodata/services/internal/cadvisor-8080/fo2:cadvisor:8080 /skydns/net/tacodata/services/internal/cadvisor-8080/fo1:cadvisor:8080 /skydns/net/tacodata/services/internal/cadvisor-8080/fo3:cadvisor:8080

cadvisor で使用可能な内部および外部ポートを確認できます。レコードの 1 つを取得した場合:

etcdctl get /skydns/net/tacodata/services/internal/cadvisor-4194/fo2:cadvisor:4194
{"host":"10.1.88.3","port":4194}

そのコンテナに内部的に接続するために必要なすべてを取得します。このテクニックは、skydnsと組み合わせると真価を発揮します。Skydnsは、登録者から提示された情報を使用してdnsサービスを提示します。つまり、簡単に言うと、アプリケーションでホスト名を使用するようにするだけです (ホスト名はデフォルトで Docker イメージの名前になりますが、変更することもできます)。したがって、この例では、私のアプリケーションは cadvisor-8080 に接続でき、dns は cadvisor-8080 が持っている 3 つの IP アドレスの 1 つを与えます (3 台のマシン上にあります)。DNS は srv レコードもサポートしているため、既知のポートを使用していない場合は、srv レコードからポート番号を取得できます。

Coreos とフリートを使用すると、コンテナー自体を発行/検出/待機ゲームに関与させないことは困難です。少なくともそれは私の経験です。

-g

于 2015-05-12T15:29:25.987 に答える