web-dev-qa-db-ja.com

異なるCoreOSノードで実行されている多くのコンテナへのNginxプロキシ

ネットサーフィンをしていると、Nginx/Confd(またはHaproxy、Vulcand)を使用して、同じホストで実行されているさまざまなDockerコンテナーにプロキシすることに関する多くのチュートリアルを見つけました。しかし、私がそれをする必要があることは異なります。私のインフラストラクチャの概要を以下に示します。

  • 5つのノードを備えたオンラインCoreOSクラスター、すべて実行中etcd
  • クラスターのすべてのノードで、ポートを公開したり、etcdにIP(Docker inspectで取得したDocker IP)を書き込んだりせずに、フリートを使用してさまざまなDockerコンテナー(WordPressアプリを実行しているNginxウェブサーバー))が起動されます。
  • ノードがダウンした場合、私のサービスは自動的に別の利用可能なノードに移動されます

さて、私がする必要があるのは、仮想ホストに応じてさまざまなコンテナにトラフィックをルーティングする1つのNginxプロキシを用意することです。例に従う:

Nginx(pub IPを使用)はリクエストを受信しますxxx.domain.com-> node-1-> container自動割り当てIP(ポート80でリッスン)

Nginx(pub IPを使用)はリクエストを受信しますyyy.domain.com-> node-2-> container自動割り当てIP(ポート80でリッスン)

ここに私の質問があります:

  • 私のシナリオは正しいですか?私は何か間違ったことを考えていますか?
  • NginxプロキシはCoreOSクラスターの外部にある必要がありますか?または、すべてのCoreOSノードで実行する必要がありますか?
  • この構成を実現するにはどうすればよいですか?最善の方法は何ですか?

前もって感謝します!

3
AcidCrash

Nginxがノードで実行されているコンテナーを「検索」できるようにするには、ある種のサービス検出が必要です。コンテナの起動時にetcdにレコードを書き込み、終了時に削除して、nginxにそれらをチェックさせることができます。

サービスを移動する場合は、フリートを見て簡単なスケジューリングを行うことができます。

1
bakins

私はあなたを正しくするかどうかわかりません。しかし、これが私がそれをする方法です:

ロードバランサー(HAProxy、Nginx、Amazon ELB(EC2を使用している場合))をクラスターの外部に配置し、クラスター内のすべてのトラフィックをルーティングします。

その中で、ゴジータを試してみることができます: https://github.com/arkenio/gogeta

これは、グローバルに(すべてのノードで)実行され、etcdのドメインエントリに基づいてトラフィックを特定のコンテナにルーティングするリバースプロキシです。次に、gogetaが監視するetcdにサービスファイルを追加および削除するようにサービスファイルを設定できます。

ExecStart=<do something>    
ExecStartPost=/usr/bin/etcdctl set /services/<your_service>/%i/location '{\"Host\": "%H", \"port\": <your containers exposed port>}'

ExecStop=/usr/bin/docker stop <your service>
ExecStopPost=/usr/bin/etcdctl rm --recursive /services/<your_service>/%i

それは機能し、ラウンドロビン戦略で要求の負荷を分散します。私が提出した問題があるようですが https://github.com/arkenio/gogeta/issues/1

それはあなたを助けますか?

1
Julian Kaffke

これを行うには、nginx、etcd、confdのトリオを使用できます。 「 CoreOS、confd、nginxによる負荷分散 」というタイトルのすばらしいブログ投稿があり、3つのコンテナーの実行について説明しています。

  1. 動的に生成されたnginx構成を保存できる共有「データ」コンテナーが必要です
  2. confdを実行しているコンテナが必要です。これは、etcdから値を読み取ります。 nginx構成を動的に生成します(これは共有「データ」コンテナーからボリュームに保存されます)
  3. 最後に、その構成にその共有「データ」ボリュームを使用するだけのnginxが必要になります。

重要なのは、各HTTPバックエンドがetcdを介してそれ自体をアナウンスすることです。その後、confdが変更を取得し、その場でnginxを再構成します。このプロセスは、@ Julianが前の回答で述べたものに非常に近いものです。

ExecStart=<do something>    
ExecStartPost=/usr/bin/etcdctl set /services/<your_service>/%i/location '{\"Host\": "%H", \"port\": <your containers exposed port>}'

ExecStop=/usr/bin/docker stop <your service>
ExecStopPost=/usr/bin/etcdctl rm --recursive /services/<your_service>/%i

その他の例については、 confd template docs を確認してください。ただし、大まかに次のようなものがあります。

{{range $dir := lsdir "/services/web"}}
upstream {{base $dir}} {
    {{$custdir := printf "/services/web/%s/*" $dir}}{{range gets $custdir}}
    server {{$data := json .Value}}{{$data.IP}}:80;
    {{end}}
}

server {
    server_name {{base $dir}}.example.com;
    location / {
        proxy_pass {{base $dir}};
    }
}
{{end}}

より高い可用性のセットアップが必要な場合を除いて、これらの「トリオ」の1つだけを実行する必要があることに注意してください。その場合、2つ以上が必要になります。 HAに移行するときは、おそらくELBインスタンスを前面に配置する必要があります。

1
Kenneth Kalmer