Moby: DockerSwarmモードでユーザーのIPアドレスを取得できません

作成日 2016年08月09日  ·  324コメント  ·  ソース: moby/moby

docker version出力:

Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

docker info出力:

Containers: 155
 Running: 65
 Paused: 0
 Stopped: 90
Images: 57
Server Version: 1.12.0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 868
 Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host overlay null bridge
Swarm: active
 NodeID: 0ddz27v59pwh2g5rr1k32d9bv
 Is Manager: true
 ClusterID: 32c5sn0lgxoq9gsl1er0aucsr
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot interval: 10000
  Heartbeat tick: 1
  Election tick: 3
 Dispatcher:
  Heartbeat period: 5 seconds
 CA configuration:
  Expiry duration: 3 months
 Node Address: 172.31.24.209
Runtimes: runc
Default Runtime: runc
Security Options: apparmor
Kernel Version: 3.13.0-92-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.42 GiB
Name: ip-172-31-24-209
ID: 4LDN:RTAI:5KG5:KHR2:RD4D:MV5P:DEXQ:G5RE:AZBQ:OPQJ:N4DK:WCQQ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: panj
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

追加の環境の詳細(AWS、VirtualBox、物理など):

問題を再現する手順:

  1. ポート80を公開する次のサービスを実行します
docker service create \
--name debugging-simple-server \
--publish 80:3000 \
panj/debugging-simple-server
  1. http://<public-ip>/接続してみてください。

受け取った結果を説明してください。
ipheader.x-forwarded-forも正しいユーザーのIPアドレスではありません。

期待した結果を説明してください。
ipまたはheader.x-forwarded-forはユーザーのIPアドレスである必要があります。 期待される結果は、スタンドアロンのDockerコンテナーdocker run -d -p 80:3000 panj/debugging-simple-serverを使用してアーカイブできます。 次のリンクから両方の結果を確認できます。
http://swarm.issue-25526.docker.takemetour.com:81 /
http://container.issue-25526.docker.takemetour.com:82 /

重要と思われる追加情報(たとえば、問題が発生するのはたまにしかありません):
これは、 globalモードとreplicatedモードの両方で発生します。

この問題を簡単に解決できるものを見逃したかどうかはわかりません。

それまでの間、スウォームモードの外でプロキシコンテナを実行し、スウォームモードで公開ポートに転送するという回避策を実行する必要があると思います(SSL終了はこのコンテナでも実行する必要があります)。これにより、スウォームの目的が損なわれます。自己修復とオーケストレーションのためのモード。

arenetworking areswarm kinenhancement statuneeds-attention versio1.12

最も参考になるコメント

logstashをswarmモードで実行しようとしたときにも問題が発生しました(さまざまなホストからsyslogメッセージを収集するため)。 logstashの「host」フィールドは、接続しているホストの実際のIPではなく、常に10.255.0.xとして表示されます。 これにより、ログメッセージの送信元がわからないため、まったく使用できなくなります。 ソースIPの変換を回避する方法はありますか?

全てのコメント324件

/ cc @ aluzzardi @ mrjanaが尋ねた

@ PanJdebugging -simple-serverがip決定する方法の詳細を教えてください。 また、サービスが複数のホスト(またはグローバルモード)にわたって複数のレプリカにスケーリングされる場合、どのような期待がありますか?

@mavenugoこれは、 netモジュールからのノードのremoteAddressを使用するkoaのリクエストオブジェクトです。 結果は、リモートアドレスを取得できる他のライブラリでも同じであるはずです。

ipフィールドは、構成に関係なく常にリモートアドレスである必要があります。

@PanJあなたはまだあなたの回避策を使用していますか、それともいくつかのより良い解決策を見つけましたか?

@PanJアプリをスタンドアロンコンテナとして実行する場合。

docker run -it --rm -p 80:3000 --name test panj/debugging-simple-server

別のホストから公開されたポートにアクセスしますこれを取得します

vagrant@net-1:~$ curl 192.168.33.12
{"method":"GET","url":"/","header":{"user-agent":"curl/7.38.0","host":"192.168.33.12","accept":"*/*"},"ip":"::ffff:192.168.33.11","ips":[]}
vagrant@net-1:~$

192.168.33.11は、curlを実行しているホストのIPです。 これは予想される動作ですか?

@sanimejはい、スウォームモードでも同様に動作するはずです。

@marech回避策としてスタンドアロンコンテナを使用していますが、これは正常に機能します。

私の場合、スタンドアロンインスタンスとスウォームインスタンスの2つのnginxインスタンスがあります。 SSLターミネーションとリバースプロキシはスタンドアロンのnginxで実行されます。 Swarmインスタンスは、リクエストホストに基づいて他のサービスにルーティングするために使用されます。

@PanJコンテナの公開ポートへのアクセス方法は、スウォームモードでは異なります。 スウォームモードでは、クラスター内の任意のノードからサービスにアクセスできます。 これを容易にするために、 ingressネットワークを介してルーティングします。 10.255.0.xは、公開されたポートに到達しようとするクラスター内のホスト上のingressネットワークインターフェイスのアドレスです。

@sanimejこの問題を掘り下げたときに、それがどのように機能するかをちょっと見ました。 ただし、ユースケース(ユーザーのIPを取得する機能)は非常に一般的です。

修正を実装する方法についての知識は限られています。 たぶん、送信元IPアドレスを変更しない特別なタイプのネットワークですか?

RancherはDockerスウォームモードに似ており、期待どおりの動作をしているようです。 多分それは始めるのに良い場所です。

@sanimejは、可能であればすべてのIPをX-Forwarded-Forヘッダーに追加することをお勧めします。可能であれば、すべてのチェーンを確認できます。

@PanJうーん、そしてnignxスタンドアロンコンテナがサービス名またはIPを介してswarmインスタンスとどのように通信するのですか? たぶん、swarmインスタンスに渡すnginx構成部分を共有できます。

@marechスタンドアロンコンテナはポート80をリッスンしてから、 localhost:8181プロキシします

server {
  listen 80 default_server;
  location / {
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_pass          http://localhost:8181;
    proxy_read_timeout  90;
  }
}

SSLターミネーションを行う必要がある場合は、ポート443をリッスンする別のサーバーブロックを追加してから、SSLターミネーションとlocalhost:8181へのプロキシも行います。

Swarmモードのnginxは8181:80を公​​開し、リクエストホストに基づいて別のサービスにルーティングします。

server {
  listen 80;
  server_name your.domain.com;
  location / {
    proxy_pass          http://your-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

server {
  listen 80;
  server_name another.domain.com;
  location / {
    proxy_pass          http://another-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

この場合、APIRateLimitおよびその他の関数はユーザーのIPアドレスに依存します。 スウォームモードで問題をスキップする方法はありますか?

logstashをswarmモードで実行しようとしたときにも問題が発生しました(さまざまなホストからsyslogメッセージを収集するため)。 logstashの「host」フィールドは、接続しているホストの実際のIPではなく、常に10.255.0.xとして表示されます。 これにより、ログメッセージの送信元がわからないため、まったく使用できなくなります。 ソースIPの変換を回避する方法はありますか?

この問題の解決策については+1。

ユーザーのIPを取得する機能がないと、Prometheusなどの監視ソリューションを使用できなくなります。

おそらく、ここではLinuxカーネルのIPVS機能が役立つでしょう。 接続がユーザースペースでプロキシされているため、IPの変更が行われていると思います。 一方、IPVSは、送信元IPアドレスを変更せずに、カーネル空間で要求をリダイレクトして負荷分散できます。 IPVSは、さまざまな負荷分散アルゴリズム、フローティングIPアドレス、直接ルーティングなど、より高度な機能を組み込むのにも適しています。

私にとっては、仮想IPとエンドポイントが属するサーバーのIPとの関係をなんとかして知ることができれば十分でしょう。 そうすれば、Prometheusが仮想IPに関連するアラートを送信するときに、影響を受けるサーバーを見つけることができます。 それは良い解決策ではありませんが、何もないよりはましです。

@vfarcic今のやり方ではそれが可能だとは思いません。 すべてのクライアント接続は同じIPからのものであるため、それを元に戻すことはできません。 動作する唯一の方法は、接続のプロキシ/ NATを実行しているものが、タイムスタンプ、送信元IP、および送信元ポートを含む接続ログを保存した場合です。 それでも、ソースIPが必要なほとんどのユースケースではあまり役に立ちません。

私はおそらくユースケースをうまく説明していませんでした。

Swarmグローバルサービスとして実行されているエクスポーターを廃棄するように構成されたPrometheusを使用しています。 タスクを使用します。すべてのレプリカのIPを取得します。 そのため、サービスではなくレプリカエンドポイントを使用しています(負荷分散なし)。 私が必要としているのは、それらのレプリカIPのそれぞれが由来するノードのIPをどうにかして把握することです。

「dockernetworkinspect」に気づきました"は、単一ノードのコンテナーとIPv4アドレスに関する情報を提供します。これを拡張して、ノードとともにネットワークのクラスター全体の情報を取得できますか?

何かのようなもの:

       "Containers": {
            "57bc4f3d826d4955deb32c3b71550473e55139a86bef7d5e584786a3a5fa6f37": {
                "Name": "cadvisor.0.8d1s6qb63xdir22xyhrcjhgsa",
                "EndpointID": "084a032fcd404ae1b51f33f07ffb2df9c1f9ec18276d2f414c2b453fc8e85576",
                "MacAddress": "02:42:0a:00:00:1e",
                "IPv4Address": "10.0.0.30/24",
                "IPv6Address": "",
                "Node": "swarm-4"
            },
...

「ノード」の追加に注意してください。

--filter引数が追加された単一のノードだけでなく、クラスター全体でそのような情報を利用できる場合は、コンテナーのIPv4アドレスとノード。 それは素晴らしい解決策ではありませんが、それでも何もないよりはましです。 現在、Prometheusが問題を検出したら、アドレスの場所が見つかるまで、各ノードで「dockernetworkinspect」を実行する必要があります。

@dackに同意し

このソリューションはIPレベルで機能する必要があります。これにより、HTTPに基づかないサービスも適切に機能します(httpヘッダーに依存できません...)。

そして、これがいかに重要であるかを強調することはできません。それがなければ、スウォームモードではまったく動作できないサービスがたくさんあります。

これがHaProxyがこの問題を解決している方法です: http ://blog.haproxy.com/2012/06/05/preserve-source-ip-address-despite-reverse-proxies/

@kobologは、DockerConでのIPVSに関する講演を踏まえて、この問題に光を

リストに自分を追加するだけです。 logstashを使用してsyslogメッセージを受け入れていますが、ホストIPが10.255.0.4に設定されているとすべてelasticsearchにプッシュされるため、使用できなくなり、コンテナー化されていないlogstashデプロイメントに戻す必要があります。これに対する修正がない場合。

@mrjanaは、この問題を回避するために必要な提案を追加できますか?

IPVSは、HTTPレイヤーの問題を修正できるユーザースペースリバースプロキシではありません。 これが、HAProxyのようなユーザースペースプロキシとこれの違いです。 HAProxyを使用する場合は、HAProxyをクラスターに配置し、すべてのサービスインスタンスとHAProxyを同じネットワークに参加させることでそれを行うことができます。 そうすれば、HAProxyはHTTP header.x-forwarded-forを修正できます。 または、L7ロードバランサーがクラスターの外部にある場合は、サービスの個々のインスタンスのそれぞれを公開するHost PublishModeと呼ばれる新しいPublishModeの今後の(1.13での)機能を使用できます。独自の個別のポートで、外部ロードバランサーをそのポートに向けることができます。

@mrjana (現在スウォームモードで

@dack私の理解では、Docker入力ネットワークはすでにIPVSを使用しています。

HAProxyを使用する場合は、HAProxyをクラスターに配置し、すべてのサービスインスタンスとHAProxyを同じネットワークに参加させることでそれを行うことができます。 そうすれば、HAProxyはHTTPヘッダーを修正できます。x-forwarded-for

@mrjanaでも。HAProxyがクライアントIPを取得する唯一の方法は、

簡単に言えば、Dockerサービスとスウォームモードを使用するとすぐにこれに対処する方法は私が知る限り絶対にありません。

Docker入力ネットワークの作成者がディスカッションに参加できれば興味深いでしょう。IPVSが内部でどのように構成/運用されているか(IPVSには多くのモードがあります)、およびどのように修正できるかについての洞察が得られる可能性があります。問題。

@tlvennこれがソースコードのどこにあるか知っていますか? 私は間違っている可能性がありますが、私が観察したいくつかのことに基づいて、IPVSを使用しているとは思いません。

  • ソースポートが変換されます(この問題の全体的な理由)。 IPVSはこれを行いません。 NATモードでも、宛先アドレスのみを変換します。 リターンパケットをIPVSホストに送り返すには、デフォルトルートまたはポリシールーティングを使用する必要があります。
  • ポートがスウォームモードで公開されると、スウォーム内のすべてのdockerdインスタンスが公開されたポートでリッスンします。 IPVSが使用された場合、それはカーネルスペースで発生し、dockerdはポートでリッスンしません。

こんにちは@dack

彼らのブログから:

内部的には、Linuxカーネルに15年以上使用されているカーネル内のレイヤー4マルチプロトコルロードバランサーであるLinuxIPVSを使用してこれを機能させます。 カーネル内にIPVSルーティングパケットを使用すると、swarmのルーティングメッシュは、コンテナを意識した高性能の負荷分散を実現します。

私が間違っていなければ、コードソースはswarmkitプロジェクトに存在するはずです。

@stevvooeは、ここで根本的な問題が何であるかを理解するのに役立つのではないかと思います。

OK、コードを簡単に見てきましたが、今では少しよく理解できたと思います。 ブログに記載されているように、実際にIPVSを使用しているように見えます。 SNATは、service_linux.goで設定されたiptablesルールを介して実行されます。 私が正しく理解していれば、その背後にあるロジックは次のようになります(ノードAがノードBで実行されているサービスのクライアントパケットを受信すると仮定します)。

  • スウォームノードAはクライアントパケットを受信します。 IPVS / iptablesは、(src ip)->(node a ip)および(dst ip)->(node B ip)を変換します
  • パケットはノードBに転送されます
  • ノードBは、その応答をノードAに送信します(これは、src ipと見なされます)。
  • ノードAは、srcとdstを元の値に変換し直し、応答をクライアントに転送します

SNATの背後にある理由は、応答が元の要求が通過したのと同じノードを通過する必要があるためだと思います(NAT / IPVS状態が格納される場所であるため)。 リクエストは任意のノードを経由する可能性があるため、SNATを使用して、サービスノードがリクエストをルーティングするノードを認識します。 単一の負荷分散ノードを使用するIPVSセットアップでは、それは問題にはなりません。

したがって、問題は、すべてのノードが着信クライアント要求を処理できるようにしながら、SNATを回避する方法です。 最善のアプローチが何であるか完全にはわかりません。 SNATに依存する代わりに、ポリシールーティングを使用して応答を送信できるように、サービスノードに状態テーブルを設定する方法があるかもしれません。 あるいは、ある種のカプセル化が役立つかもしれません(VXLAN?)。 または、IPVSの直接ルーティング方式を使用することもできます。 これにより、サービスノードは(元の要求を受信したノードを介してではなく)クライアントに直接応答できるようになり、サービスに新しいフローティングIPを追加できるようになります。 ただし、サービスにはフローティングIP経由でのみ接続でき、個々のノードIP経由では接続できないことも意味します(これがどのユースケースでも問題になるかどうかはわかりません)。

かなり興味深い発見@dack

うまくいけば、そのSNATをすべて一緒にスキップする解決策が見つかるでしょう。

それまでの間、 PublishModeを使用してホストレベルのポート公開を導入し、入力ネットワークを効果的にバイパスする、少し前にコミットされた回避策がある可能性があります。

https://github.com/docker/swarmkit/pull/1645

たくさんのフィードバックに感謝します。週末の後でこの問題を詳しく見ていきます。

それまでの間、いくつかの情報:

@tlvenn@mrjanaは、入力ネットワーク機能の背後にある主要な作成者です。 ソースは主にdocker / libnetworkにあり、一部はSwarmKitにあります

@dack :それは確かにIPVSによって支えられています

@tlvenn私が知る限り、Docker Swarmはマスカレードを使用します。これは、最も簡単な方法であり、ほとんどの構成で機能することが保証されているためです。 さらに、これは実際にポートをマスカレードできる唯一のモードです[re:@dack]。これは便利です。 理論的には、この問題はIPIPカプセル化モードを使用することで解決できます。パケットフローは次のようになります。

  • パケットはゲートウェイサーバー(この場合は群れの任意のノード)に到着し、そのノードのIPVSは、宛先IPアドレスとポートに基づいて、実際には仮想サービスのパケットであると判断します。
  • パケットは別のIPパケットにカプセル化され、負荷分散アルゴリズムに基づいて選択された実サーバーに送信されます。
  • 実サーバーは、囲んでいるパケットを受信して​​カプセル化を解除し、実際のクライアントIPを送信元として、仮想サービスIPを宛先として認識します。 すべての実サーバーは、仮想サービスIPとのARP不可能なインターフェイスエイリアスを持っているはずなので、このパケットは実際に自分宛てであると想定されます。
  • 実サーバーはパケットを処理し、応答をクライアントに直接送り返します。 この場合のソースIPは仮想サービスIPになるため、火星の応答は含まれません。これは良いことです。

もちろん、多くの警告や間違っている可能性のあることがありますが、一般的にこれは可能であり、IPIPモードは本番環境で広く使用されています。

IP固定やその他のセキュリティチェックで正しい外部IPを受信できるようにする必要があるため、これに対する解決策がすぐに見つかることを期待しています。

見て。 当社の製品は、セキュリティと分析のためにソースIP情報を活用しています。

@aluzzardi更新はありますか?

バンプ、来年初めに開始する非常に大規模なプロジェクトでこれを機能させる必要があります。

フローを調べると、現在は次のように機能しているようです(この例では、ノードAが着信トラフィックを受信し、ノードBがサービスコンテナーを実行しています)。

  • ノードAはDNATを実行して、パケットをingress_sboxネットワーク名前空間(/ var / run / docker / netns / ingress_sbox)に送信します。
  • ノードAのingress_sboxはNATモードでIPVSを実行します。これは、DNATを実行してパケットをノードBのコンテナに(入力オーバーレイネットワーク経由で)送信し、SNATを実行してソースIPをノードAの入力オーバーレイネットワークIPに変更します。
  • パケットはオーバーレイを介して実サーバーにルーティングされます
  • リターンパケットは同じパスを逆にたどり、送信元/宛先アドレスを元の値に書き換えます。

SNATは次のような方法で回避できると思います。

  • ノードAは、NATなしでパケットをingress_sboxに渡します(iptables /ポリシールーティング?)
  • ノードAのingress_sboxは、直接ルーティングモードでIPVSを実行します。これにより、入力オーバーレイネットワークを介してノードBにパケットが送信されます。
  • ノードBのコンテナは変更されていないパケットを受信します(コンテナはすべてのパブリックIPのパケットを受け入れる必要がありますが、ARPを送信することはできません。これを行うにはいくつかの方法があります。IPVSドキュメントを参照してください)。
  • リターンパケットはノードBからクライアントに直接送信されます(オーバーレイネットワークまたはノードAを経由して戻る必要はありません)

追加のボーナスとして、NAT状態を保存する必要がなく、オーバーレイネットワークトラフィックが削減されます。

@aluzzardi @mrjanaこれに関する更新はありますか? Dockerからの少しのフィードバックをいただければ幸いです。

見て。 ソースIP情報がないと、ほとんどのサービスが期待どおりに機能しません

どうしてこうなりました ?
unassign_bug

@tlvennはGithubのバグのようですか?

@PanJ @tlvenn @vfarcic @dackなど、PTAL#27917。 サービス公開モード= hostを有効にする機能を導入しました。これにより、サービスがIPVSをバイパスし、 docker run -pような動作を取り戻す方法が提供され、次のような場合にソースIPが保持されます。それが必要。

plsは1.13.0-rc2を試し、フィードバックを提供します。

やっぱり変な

公開モードに関しては、上記のスウォームキットからすでにリンクしています。これは回避策になる可能性がありますが、この問題に完全に対処するための適切なソリューションがDocker1.13に付属していることを心から願っています。

ソースIPを保持することはユーザーが期待する動作であり、現在のDockerサービスの非常に深刻な制限であるため、この問題はバグとして分類される可能性があります。

@kobolog@dackの両方が、これを解決する方法についていくつかの潜在的なリードを考え出した思います

Dockerでこの問題を調査しているのは誰か、ステータスの更新について、ある程度の可視性を教えてください。 前もって感謝します。

#27917以外に、1.13の解決策はありません。 ダイレクトリターン機能は、さまざまなユースケースについて分析する必要があり、バグ修正と見なされるために軽視されるべきではありません。 これを1.14で調べることができます。 ただし、これは、アルゴリズム(rr対他の10のメソッド)、データパス(LVS-DR、LVS-NAT、およびLVS-TUN)を含む構成可能なLB動作のカテゴリにも分類されます。 誰かがこれに貢献することをいとわないなら、plsはPRをプッシュし、私たちはそれを動かすことができます。

十分に公平なことですが、現在代替手段があることを考えると、 @ mavenugoだと思います。

少なくとも、1.13のドキュメントを修正して、デフォルトの入力公開モードでDockerサービスを使用する場合、ソースIPが保持されないことを明確に示し、これがサービスを実行するための要件である場合はホストモードを使用することを示唆できますか? ?

これは、サービスに移行している人々が、この予期しない動作によって火傷を負わないようにするのに役立つと思います。

確かにそうです、この動作を示すドキュメントの更新と、公開mode=hostを使用する回避策は、LVS-NATモードで失敗するようなユースケースに役立ちます。

もう一度チェックインして、この本当のことを理解するのに新しい進展がなかったかどうかを確認しますか? それは確かに私たちにとっても大きな制限です

Docker 1.14のロードマップに解決策はありますか? この問題の一部が原因で、dockerを使用したソリューションの展開が遅れています。

client-ipを保持するカスタムヘッダーがhttp / httpsリクエストに追加されるのを楽しみにしています。 これは可能であるはずですよね? X_Forwarded_forがいつ上書きされるかは気にしないので、リクエストが群れに入った最初のときにのみ設定されるカスタムフィールドが必要です。

client-ipを保持するカスタムヘッダーがhttp / httpsリクエストに追加されるのを楽しみにしています。 これは可能であるはずですよね? X_Forwarded_forがいつ上書きされるかは気にしないので、リクエストが群れに入った最初のときにのみ設定されるカスタムフィールドが必要です。

負荷分散はL3 / 4で行われます。 httpヘッダーを追加することはできません。

修正には、送信元アドレスの書き換えを削除することが含まれます。

@mavenugo今日mode=hostを使用しました。 現在は機能しており、クライアントIPは保持されていますが、より良い解決策を期待しています:)お疲れ様でした!

二重投稿でごめんなさい...
スタックファイル(yml v3)を使用して、docker service createを介して--publish mode=host,target=80,published=80を使用する場合と同じ動作を得るにはどうすればよいですか?

私は試した

...
services:
  proxy:
    image: vfarcic/docker-flow-proxy:1.166
    ports:
      - "80:80/host"
      - "443:443/host" 
...

しかし、それは機能していません(https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#/portsと同じパターンを使用)

スタックファイル(yml v3)を使用して、docker servicecreateを介して--publishmode = host、target = 80、published = 80を使用する場合と同じ動作を得るにはどうすればよいですか?

@ hamburml - https://github.com/docker/docker/issues/30447の未解決の問題/機能に注目して

残念ながら、 mode=hostを回避策として使用することはできません。これは、サービスがスウォームネットワークと通信し、ホストインターフェイスだけでなくすべてのノードでリッスンする必要があるためです...

@ tkeeler33サービスをglobalサービス(スウォーム内の各ノードにインスタンスをデプロイする)としてデプロイし、スウォームネットワークに接続してスウォーム内の他のサービスと通信できるようにする必要があると思います。

@ thaJeztah-はい。ただし、コンテナをオーバーレイ/スウォームネットワークとホストmode=host両方に同時に接続することはできません。 それが現時点での私の最大の制限です。

@ tkeeler33は私のために働くようです。

$ docker network create -d overlay swarm-net

$ docker service create \
  --name web \
  --publish mode=host,published=80,target=80 \
  --network swarm-net \
  --mode=global \
  nginx:alpine

$ docker service create --name something --network swarm-net nginx:alpine

webサービスが同じネットワーク上のsomethingサービスに接続できるかどうかをテストします。

docker exec -it web.xczrerg6yca1f8ruext0br2ow.kv8iqp0wdzj3bw7325j9lw8qe sh -c 'ping -c3 -w1 something'
PING something (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.251 ms

--- something ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.251/0.251/0.251 ms

@ thaJeztah-ありがとう! 深く掘り下げた後、問題は--opt encryptedオプションを使用してDockerネットワークを作成したことであり、これによりコンテナーがホストからの接続に失敗することに気付きました。 手順を試してみると、根本的な原因をすばやく絞り込むことができました。 このオプションは、適切な暫定的な回避策である可能性があります。セキュリティへの影響に頭を悩ませる必要があります。

情報に大いに感謝します!

@ tkeeler33 --opt encryptedはホストポートマッピングに影響を与えないはずです。 暗号化オプションの唯一の目的は、ノード間のvxlanトンネルトラフィックを暗号化することです。 ドキュメントから:「暗号化(--opt暗号化)を使用してオーバーレイネットワークを作成することを計画している場合は、プロトコル50(ESP)トラフィックが許可されていることも確認する必要があります。」 設定をチェックして、ESPが許可されていることを確認できますか?
また、 --opt encryptedオプションは、純粋にデータプレーン暗号化です。 すべてのコントロールプレーントラフィック(ルーティング交換、サービスディスカバリ配布など)は、オプションがなくてもデフォルトですべて暗号化されます。

@mavenugoその通りです。 --opt encryptedで新しいネットワークを作成したとき、それはうまくいきました。 新しく作成したネットワークを既存のネットワークと比較すると、 "Internal": trueが設定されていることに気付きました。 それはおそらく問題であり、最初のネットワーク作成時の間違いでした...あなたの助けと説明に感謝します、それは長い一日でした...

@dack @kobolog LVS-TunnelおよびLVS-DRモードの一般的な展開では、着信パケットの宛先IPは、実サーバーで非ARPIPとしてもプログラムされているサービスVIPになります。 ルーティングメッシュは根本的に異なる方法で機能し、着信要求は任意のホストに送信される可能性があります。 実サーバーがパケットを受け入れるには(任意のLVSモードで)、宛先IPをローカルIPに変更する必要があります。 バックエンドコンテナからの応答パケットが正しい送信元アドレスで戻る方法はありません。 直接返す代わりに、応答パケットを入力ホストに戻そうとすることができます。 しかし、ソースIPを変更して正方形に戻す以外に、それを行うためのクリーンな方法はありません。

@thaJeztahドキュメントでこれを明確にし、クライアントIPを保持する必要がある場合は、ホストmodを使用することを提案し、この問題を解決する必要があると思います。

@sanimejNATなしでこれを行うことが不可能な理由はまだわかりません。 たとえば、通常のLVS-DRフローを使用するオプションだけがありませんか? Dockerは非arpvipを適切なノードに追加し、LVSは着信パケットをノードに転送し、発信パケットは直接戻ります。 着信パケットが任意のホストにヒットする可能性があることが重要なのはなぜですか? これは、複数のフロントエンドサーバーと複数のバックエンドサーバーを備えた標準のLVSと同じです。

@thaJeztah回避策をありがとう:)
プロキシをcomposeバージョン3でデプロイしている場合、新しい公開構文はサポートされていないため、このコマンドを使用してデプロイされたサービスにパッチを適用できます( nginx_proxyをサービス名に置き換えます)

docker service update nginx_proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443"

@dack通常のLVS-DRフローでは、宛先IPはサービスVIPになります。 したがって、LBは、宛先IPを変更せずに、パケットをバックエンドに送信できます。 着信パケットの宛先IPはホストのIPの1つになるため、これはルーティングメッシュには当てはまりません。

@sanimejこの問題を解決するために上記の提案に関するフィードバックはありますか?

@tlvenn LVS-IPトンネルはLVS-DRと非常によく似ていますが、バックエンドがmac-rewriteではなくIPトンネル内のIPを介してパケットを取得する点が異なります。 したがって、ルーティングメッシュのユースケースでも同じ問題が発生します。

あなたが参照した提案から..
The real server receives the enclosing packet, decapsulates it and sees real client IP as source and virtual service IP as destination.

パケットの宛先IPは、VIPではなく、クライアントがパケットを送信したホストのIPになります。 書き換えられない場合、実サーバーは外部IPヘッダーを削除した後にドロップします。 宛先IPが書き換えられると、クライアントへの実サーバーの応答の送信元IPが正しくなくなり、接続に失敗します。

明確化@sanimejをありがとう。 おそらくPROXYプロトコルを実装できますか? シームレスなソリューションは提供されませんが、少なくともユーザーIPを解決するソリューションをサービスに提供します。

送信元ポートの範囲をブロックに分割し、クラスター内の各ホストにブロックを割り当てることで、送信元IPの保持を実現するための厄介な方法があります。 次に、ハイブリッドNAT + DRアプローチを実行できます。このアプローチでは、入力ホストが通常のSNATを実行し、パケットを実サーバーに送信します。 実サーバーが実行されているホストで、送信元IPに基づいてSNATを実行し、送信元ポートを入力ホストに割り当てられた範囲のポートに変更します。 次に、コンテナからのリターンパケットで、送信元ポート範囲(およびターゲットポート)と照合し、送信元IPを入力ホストのIPに変更します。

技術的にはこれで問題ありませんが、クラスターメンバーがすばやく追加および削除される実際の展開では、実用的でなく脆弱です。 これにより、ポートスペースも大幅に削減されます。

入力ホストでソースIPを変更できないため、前述のNAT + DRアプローチは機能しません。 送信元ポートのみをその特定のホストの範囲内のポートに変更し、バックエンドホストからのルーティングポリシーを使用してパケットを入力ホストに戻すことは、オプションの場合があります。 これには、前に述べた他の問題がまだあります。

@thaJeztah
NginxコンテナからWebコンテナに実際のIPアドレスを転送するための回避策はありますか?
私はで動作しているnginxのコンテナ持ってglobalモードとに公開host 、そうnginxのコンテナは、正しいIPアドレスを取得します。 両方のコンテナはお互いを正常に認識しますが、WebコンテナはクライアントアドレスではなくNginxコンテナのIPアドレスを取得します。
NginxはWebのリバースプロキシであり、Webはポート8000​​でuwsgiを実行します。

server {
    resolver 127.0.0.11;
    set $web_upstream http://web:8000;

    listen 80;
    server_name domain.com;
    location / {
        proxy_pass $web_upstream;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering 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;
    }
}

@lpakula上記の私の答えとこの動作するnginx構成を確認してください

@ pi0返信ありがとうございます

リンクからnginx構成を使用していますが、IPアドレスがまだ間違っているため、構成に何かが不足している必要があります

オーバーレイネットワークと2つのサービスを備えたDocker

    docker service create --name nginx --network overlay_network --mode=global \
        --publish mode=host,published=80,target=80 \
        --publish mode=host,published=443,target=443 \
        nginx:1.11.10

    docker service create --name web --network overlay_network \
        --replicas 1 \
        web:newest

Nginxコンテナーは、最新の公式コンテナーhttps://hub.docker.com/_/nginx/を使用し
Webコンテナはポート8000​​でuwsgiサーバーを実行します

リンクからグローバルnginx.confしていますが、 conf.d/default.confは次のようになります。

   server {
       resolver 127.0.0.11;
       set $web_upstream http://web:8000;

       listen 80;
       server_name domain.com;
       location / {
        proxy_pass $web_upstream;
      }
  }

そして、nginxコンテナログ:

  194.168.X.X - - [17/Mar/2017:12:25:08 +0000] "GET / HTTP/1.1" 200

Webコンテナログ:

  10.0.0.47 - - [17/Mar/2017 12:25:08] "GET / HTTP/1.1" 200 -

そこに何が欠けていますか?

IPアドレスはまだ間違っています。 ただし、HTTPヘッダーが追加されます。
実際のIPアドレスが含まれています。 選択したWebサーバーを構成する必要があります
プロキシを信頼する(ソースIPの代わりにヘッダーを使用する)
19:36ルカシュPakulaで金、2560年3月17日には[email protected]
書きました:

@ pi0https ://github.com/pi0返信ありがとうござい

リンクからnginx構成を使用していますが、IPアドレスはまだです
間違っています、構成に何かが欠けている必要があります

オーバーレイネットワークと2つのDocker
サービス

docker service create --name nginx --network overlay_network --mode=global \
    --publish mode=host,published=80,target=80 \
    --publish mode=host,published=443,target=443 \
    nginx:1.11.10

docker service create --name web --network overlay_network \
    --replicas 1 \
    web:newest

Nginxコンテナは最新の公式コンテナを使用しています
https://hub.docker.com/_/nginx/ http:// url
Webコンテナはポート8000​​でuwsgiサーバーを実行します

リンクからグローバルnginx.confを使用していて、conf.d /default.confの外観
次のように:

サーバー{
リゾルバ127.0.0.11;
$ web_upstream http:// web :8000;を設定します。

   listen 80;
   server_name domain.com;
   location / {
    proxy_pass $web_upstream;
  }

}

そして、nginxコンテナログ:

194.168.XX --- [2017年3月17日:12:25:08 +0000] "GET / HTTP / 1.1" 200

Webコンテナログ:

10.0.0.47 ---- [2017年3月17日12:25:08] "GET / HTTP / 1.1" 200-

そこに何が欠けていますか?


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/docker/docker/issues/25526#issuecomment-287342795
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/ABtu97EFaCmLwAZiOrYT4nXi4oXPCbLQks5rmn43gaJpZM4Jf2WK

>>

PanJ、
Panjamapong Sermsawatsri
電話。 (+66)869761168

@lpakulaああ、 web:newest画像がX-Real-IPヘッダーも尊重する必要がある別のことがあります。 nginxは送信者のIPを自動的に変更せず、ヒントヘッダーを送信するだけです。

@ pi0 @PanJ
それは理にかなっています、みんなありがとう!

ホストモードを使用してポートをバインドします。

nginxは、 TPROXYカーネルモジュールを使用してIP透過性をサポートします

@stevvooe Dockerもそのようなことをすることができますか?

nginxは、TPROXYカーネルモジュールを使用してIP透過性をサポートします。
@stevvooe Dockerもそのようなことをすることができますか?

可能性は低いですが、エントリはノード間で追跡する必要があるためです。 @sanimejまたは@mavenugoにします。

swarmはクライアントIPアドレスを取得するためのRESTAPIを提供できますか?

この問題に関係のない@tonysongtl

他に考慮すべき点は、可用性の高いセットアップでトラフィックがノードに配信される方法です。 ノードは、クライアントにエラーを発生させることなくダウンできる必要があります。 現在の推奨事項は、外部ロードバランサー(ELB、F5など)を使用し、レイヤー4で各Swarmノードへの負荷分散を簡単なレイヤー4ヘルスチェックで行うことです。 F5はSNATを使用していると思います。したがって、この構成の最良のケースは、実際のクライアントIPではなく、F5の単一のIPをキャプチャすることです。

参照:
https://docs.docker.com/engine/swarm/ingress/#configure -an-external-load-balancer
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Docker_EE_Best_Practices_and_Design_Considerations
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Universal_Control_Plane_2.0_Service_Discovery_and_Load_Balancing

やあ。

理解と完全性のために、要約させてください。間違っている場合は訂正してください。

主な問題は、コンテナが元のsrc-IPを受信して​​いないが、VIPを群がっているということです。 次のシナリオでこの問題を再現しました。

create docker swarm
docker service create --name web --publish 80:80 nginx
access.log source IP is 10.255.0.7 instead of client's browser IP

そうみたいです:

swarm内のサービスが(デフォルトの)メッシュを使用している場合、swarmはNATを実行して、同じ発信元からのトラフィックが常に同じhost-running-serviceに送信されるようにしますか?
したがって、元のsrc-IPが失われ、swarmのサービスVIPに置き換えられます。

@kobolog https://github.com/moby/moby/issues/25526#issuecomment-258660348および@dackhttps //github.com/moby/moby/issues/25526#issuecomment-260813865の提案は@sanimejによって反論されたようhttps://github.com/moby/moby/issues/25526#issuecomment -280722179 https://github.com/moby/moby/issues/25526#issuecomment -281289906しかし、TBH、彼の議論は完全に明確ではありません私はまだ、これが決定的に不可能なのになぜスレッドが閉じられなかったのか理解できません。

@sanimejはこれで

  1. Swarmは、src-IP = Aおよびdestination = "my-service-virtual-address"のメッセージを受信します
  2. パッケージは、そのサービスを実行しているスウォームノードに送信され、元のメッセージがカプセル化されます。
  3. ノードは、宛先をcontainer-running-that-service-IPに変更するタスクに転送します
    スウォームとノードは、可能な場合はいつでも、同じ発信元からのトラフィックが同じノードに転送されるようにテーブルを維持できます。

特定のサービスに対して「NATの代わりにリバースプロキシ」を有効にするオプションは、すべての人を満足させるこのすべての問題を解決しませんか?

一方、IIUCの場合、残っている唯一のオプションはhttps://docs.docker.com/engine/swarm/services/#publish -a-services-ports-directly-on-the-swarm-nodeを使用することです。これは、 -繰り返しますが、IIUC-はメッシュをまったく使用していないように見えるため、スウォームモードを使用する利点がわかりません(composeと比較して)。 実際、1.12以前の群れのように見え、_Consul_などが必要です。

あなたの助けと忍耐に感謝します。
よろしく

@sanimej
さらに... DockerがポートフォワーディングNATを実行していない(宛先IP /ポートのみを変更している)のはなぜですか?

  1. Swarmは「Aからmyserviceへ」というメッセージを受信します
  2. Swarmは、dest = node1を設定して、そのサービスを実行しているホストにメッセージを転送します
  3. Node1は、「from A to node1」というメッセージを受信し、設定dest = container1を転送します。
  4. Container1は「Aからcontainer1へ」というメッセージを受信します
  5. 返信するには、コンテナはデフォルトゲートウェイルートを使用します

チャイムを鳴らしたいだけです。 これを行う簡単な方法はないことは理解していますが、発信元IPアドレスを何らかの方法で保存しないと、多くのアプリケーションの使用例が大幅に妨げられます。 これが私の頭のてっぺんから考えることができるいくつかです:

  • ネットワーク/サービスエンジニアリングには、ユーザーの出所を詳細に示すメトリックを設定できることが不可欠です。

  • 多くのセキュリティアプリケーションでは、サービスの悪用に基づく動的なブラックリストを許可するために、発信元のIPアドレスにアクセスする必要があります。

  • 多くの場合、位置認識サービスは、他の方法が失敗したときにユーザーの一般的な位置を特定するために、IPアドレスにアクセスできる必要があります。

この問題のスレッドを読んだところ、Docker Swarm内にスケーラブルなサービスが必要な場合、特定の回避策がうまく機能していないようです。 ワーカーノードごとに1つのインスタンスに制限すると、オファリングの柔軟性が大幅に低下します。 また、Swarmオーケストレーションコンテナにフィードする前に、エッジでLB / Proxyを非Swarmオーケストレーションコンテナとして実行するというハイブリッドアプローチを維持することは、過去にさかのぼるようです。 ユーザーがサービスオーケストレーションのために2つの異なるパラダイムを維持する必要があるのはなぜですか? エッジでLB /プロキシを動的にスケーリングできるのはどうですか? それは手動で行う必要がありますよね?

Dockerチームはおそらくこれらのコメントを検討し、Dockerエコシステムに存在する品質と柔軟性を維持しながら、この機能を導入する方法があるかどうかを確認できますか?

さらに余談ですが、私は現在これに見舞われています。 承認/認証されたリクエストをダウンストリームのWebサーバーに転送するWebアプリケーションがあります。 当社のサービス技術者は、Webアクセスログを使用するダウンストリームサーバーにユーザーが到達したかどうかを確認できる必要があります。 現在のシナリオでは、プロキシサーバーが発信元IPアドレスを認識しないため、その機能を提供する方法はありません。 アプリケーションを簡単にスケーラブルにしたいと思っていますが、少なくともスケーリングされたインスタンスごとに新しいVMをスローしない限り、提示された回避策ではこれを実行できないようです。

@JitsusamaはKubernetesで問題を解決できますか?

@thaJeztah docker -composeを使用して

私は試した

`services:
  math:
    build: ./math
    restart: always
    ports:
    - target: 12555
      published: 12555
      mode: host

しかし、ソースIPとして172.xx1を使用しているようです

@trajano 、私には手がかりがありません。 Kubernetesはどういうわけかこの問題を回避できますか?

@実様
はい、ソースIPをどのように保持するかについてのドキュメントがあります。 これは機能しますが、ロードバランサーを使用しない場合は、エンドポイントのないノードでパケットがドロップされるため、それほどきれいではありません。 セルフホストのロードバランサーとしてRancherを使用する予定の場合、残念ながら現在はまだサポートされていません

@trajano

しかし、ソースIPとして172.xx1を使用しているようです

アプリケーションにローカルでアクセスしている場合、 docker_gwbridgeはプロキシコンテナと対話するインターフェイスであるため、そのIPは正しいはずです(swarmを使用している場合)。 IPネットワーク内の別のマシンからアプリにアクセスして、正しいアドレスを取得できるかどうかを確認できます。

作成の回避策については、可能です。 ここでは、イメージjwilder/nginx-proxyをフロントエンドリバースプロキシとして(概念を単純化するために)使用し、公式ビルドイメージnginxをバックエンドサービスとして使用します。 DockerSwarmモードでスタックをデプロイします。

version: '3.3'

services:

  nginx-proxy:
    image: 'jwilder/nginx-proxy:alpine'
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  nginx:
    image: 'nginx:1.13.5-alpine'
    deploy:
      replicas: 3
    ports:
      - 80
      - 443
    environment:
      - VIRTUAL_HOST=website.local
$ echo '127.0.0.1 website.local' | sudo tee -a /etc/hosts
$ docker stack deploy --compose-file docker-compose.yml website

これにより、スタック用のwebsite_defaultネットワークが作成されます。 私のエンドポイントは環境変数VIRTUAL_HOSTで定義されており、 http://website.localアクセスすると次のようになります。

website_nginx-proxy.0.ny152x5l9sh7<strong i="30">@Sherry</strong>    | nginx.1    | website.local 172.18.0.1 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
website_nginx.1.vskh5941kgkb<strong i="33">@Sherry</strong>    | 10.0.1.3 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36" "172.18.0.1"

website_nginx.1.vskh5941kgkbのヘッダーの終わりには、元のIP( 172.18.0.1 )のヒントがあることに注意してください。 X-Forwarded-ForとX-Real-IPは、デフォルトでjwilder/nginx-proxynginx.tmplに設定されています。

ポート443場合、docker-composeファイルに両方のポートを追加できなかったため、次を使用します。

docker service update website_nginx-proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443" \
    --network-add "<network>"

また、環境変数VIRTUAL_HOSTを含むアプリでリバースプロキシしたいネットワークを追加します。 jwilder/nginx-proxyのドキュメントでは、より詳細なオプションを使用できます。または、独自の設定を作成することもできます。

Kubernetesのイングレスコントローラーは基本的に同じことを行います。イングレスチャートは(通常) X-Forwarded-ForX-Real-IPをサポートしており、イングレスの選択とタイプ、およびそれらのデプロイメントレプリカを少し柔軟にサポートしています。

そのため、kubernetesのドキュメントは完全ではありません。 されている別の方法
かなり一般的には、実際には入力+プロキシプロトコルです。

https://www.haproxy.com/blog/haproxy/proxy-protocol/

プロキシプロトコルは、ソースを保持する広く受け入れられているプロトコルです
情報。 Haproxyには、プロキシプロトコルのサポートが組み込まれています。 Nginx
プロキシプロトコルを読み取ることはできますが、挿入することはできません。

プロキシプロトコルが設定されると、どこからでもその情報にアクセスできます
のようなダウンストリームサービス
https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/proxy-protocol/README.md

openshiftでさえ、ソースIP情報にこれを活用します
https://docs.openshift.org/latest/install_config/router/proxy_protocol.html

これは、プロキシプロトコルを挿入するk8sの最新のhaproxy入力です。

群れでこれを行う方法は、入力がプロキシを読み取れるようにすることです。
プロトコル(次のようなアップストリームLBからトラフィックを受信して​​いる場合
すでに注入されたプロキシプロトコル)および注入されたプロキシプロトコル
情報(すべてのトラフィックが実際に最初に入力にヒットした場合)。

特にある場合、私は他の方法でそれを行うことに賛成していません
これを行うための一般的に受け入れられている標準。

Traefikは数週間前にproxy_protocolサポートを追加し、v1.4.0-rc1以降で利用可能です。

これは、dockerswarmの入力レベルで実行する必要があります。 入力の場合
プロキシプロトコルデータを注入せず、ダウンストリームサービスも注入しません
(traefix、nginxなどを含む)はそれを読み取ることができます。

2017年9月10日21:42に、「monotykamary」 [email protected]は次のように書いています。

Traefikはproxy_protocolサポートを追加しました
https://github.com/containous/traefik/pull/2004数週間前であり、
v1.4.0-rc1以降で利用できます。


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-328352805 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU3jj5dJcpMDysjIyGQK7SGx8GwWbks5shApqgaJpZM4Jf2WK

imは、このバグとインフラキットの関係についても混乱しています。 例: https

ロールアップをインフラキットに群がらせますか? 私は特にその入口側に熱心です。

この問題も発生しています。 インバウンド接続のクライアントIPと要求されたIPを知りたい。 たとえば、ユーザーがサーバーへの生のTCP接続を実行する場合、ユーザーのIPが何であるか、およびユーザーが接続したマシンのIPを知りたいとします。

@blazedd以前および他のスレッドでコメントしたように、これは実際にはpublishModeを使用して可能です。 すなわち:サービスはメッシュネットワークによって処理されません。

IIUC、イングレスがこれを処理する方法を改善するためにいくつかの進歩が進んでいますが、それが実際には唯一の解決策です。

外部LB構成を回避するために、publishmodeとmode:globalを使用してnginxサービスをデプロイしました

@mostologお返事ありがとうございます。 ほんの少しのメモ:

  1. publishModeは問題をまったく解決しません。 インバウンドソケット接続は、スウォームがセットアップしたローカルネットワークに引き続き解決されます。 少なくともポートリストを使用する場合mode: host
  2. nginxは本当に良い解決策ではありません。 私たちのアプリケーションはTCPベースですが、Webサーバーではありません。 手動でコーディングせずに使用できるヘッダーはありません。
  3. docker run --net=host ...を使用すると、すべて正常に機能します。
  4. これまでに機能することがわかった唯一の解決策は、 https

@blazeddスタックには次のものがあります。

    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host

したがって、ログに実際のIPが記録されるに違いありません。

@mostolog少なくともWindowsでは動作しません。 まだ172.0.0.xアドレスをソースとして取得しています。

@mostolog mode: hostは、コンテナをホストネットワークに公開しません。 コンテナを入力ネットワークから削除します。これは、コンテナを実行するときにDockerが通常動作する方法です。 dockerrunコマンドで使用される--publish 8080:8080を複製します。 nginxが実際のIPを取得している場合、それはソケットがそれらのIPに直接接続されている結果ではありません。 これをテストするには、フレームワークなしで生のTCP実装またはHTTPサーバーの使用を真剣に検討し、報告されたアドレスを確認する必要があります。

IPVSルートネットワークをコンテナに直接使用してみませんか? すべてのスウォームノードのオーバーレイインターフェイスのIPを仮想IPとしてバインドし、 ip rule from xxx table xxxを使用してマルチゲートウェイを作成すると、スウォームノードはユーザースペースネットワークプロキシデーモン(dockerd)なしで、クライアントをコンテナーに直接ルーティングできます(DNAT)。

@blazedd試してみましたか? @mostologの例に従うと、外部IPアドレスを取得しています。

私は再びこの問題に直面しています。

私の設定は次のとおりです。

  • DRモードのipvsロードバランサー(docker swarmの外部)
  • 3つのDockerノード。宛先IPがすべてのノードに追加され、arpがIPVSDRルーティング用に適切に構成されています。

スタックをスウォームにデプロイし、アドレスを操作せずに仮想IPのポート80でリッスンさせたいと思います。

私はこれを行うことでほとんどそこに着くことができます:
ポート:
-ターゲット:80
公開:80
プロトコル:tcp
モード:ホスト

ここでの問題は、バインドするIPアドレスを指定できないことです。すべてにバインドするだけです。 そのポートを使用して複数のサービスを実行する場合、これにより問題が発生します。 1つのIPにのみバインドする必要があります。 異なるポートを使用することは、DRロードバランシングのオプションではありません。 開発者は、同じIPが複数のノードに存在することは決してないと想定していたようです。これは、DRロードバランサーを使用する場合には当てはまりません。

さらに、短い構文を使用すると、バインドIPは無視され、すべてのアドレスにバインドされます。 単一のIPにバインドする唯一の方法は、クラスター化されていないコンテナー(サービスやスタックではない)を実行することです。

そのため、サービス/スタック機能に依存するのではなく、スタンドアロンコンテナを使用して、自分で管理する必要があります。

同じ問題があります。
すべてのアプリケーション(特にHTTPではなく生のUDP / TCPを使用するものもあります)が期待どおりに機能することを可能にするdockeringres内の透過的なソリューションに投票します。

サービスがグローバルに展開されているため、「mode = hostportpublishing」回避策を使用できます。
ただし、これはmacvlanネットワークドライバーの使用と互換性がないようです。これは他の理由で必要です。
「macvlanドライバはポートマッピングをサポートしていません」のようなログを取得します。
複数のネットワークを使用してみましたが、役に立ちません。

ここで特定のチケットを作成しました: https
それは今のところ私に解決策を残しません: '(

こんにちは、みんな
今のところ回避策はありますか? ホストポートとして公開せずに
港 ?

2018年1月11日00:03に、「OlivierVoortman」 [email protected]は次のように書いています。

同じ問題があります。
Docker Ingress内で、すべてを許可する透過的なソリューションに投票します
アプリケーション(特にHTTPではなく生のUDP / TCPを使用するものもあります)は次のように機能します
期待される。

私のサービスは「mode = hostportpublishing」の回避策を使用できます
グローバルに展開。
ただし、これはmacvlanの使用と互換性がないようです
ネットワークドライバ。他の理由で必要です。
「macvlanドライバはポートマッピングをサポートしていません」のようなログを取得します。
複数のネットワークを使用してみましたが、役に立ちません。

ここで特定のチケットを作成しました:docker / libnetwork#2050
https://github.com/docker/libnetwork/issues/2050
それは今のところ私に解決策を残しません: '(


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-356693751 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUzlM-BMbEsDYAiYH6hKLha-aRqerks5tJQJngaJpZM4Jf2WK

クライアントのIPを取得できないのは本当に残念です。 これにより、ほとんどのdockerswarmの優れた機能が使用できなくなります。

私のセットアップでは、クライアントのIPを取得する唯一の方法は、 network_mode:hostを使用し、swarmをまったく使用しないことです。

mode=host port publishingまたは従来のdocker run -p "80:80" ...しても機能しませんでした

いくつかの解決策がhttps://github.com/moby/moby/issues/15086で提案されましたが、私のために働いた唯一の解決策は「ホスト」ネットワーキングでした...

適切なIPがない場合の別の問題は、nginxのレート制限が正しく機能せず、docker swarmロードバランサーで使用できないことです。これは、nginxが単一のユーザー/ IPからのリクエストをすべてカウントするため、リクエストがレート制限されて拒否されるためです。 したがって、回避策はmode = hostを使用することだけですが、この方法では負荷分散機能が失われ、DNSが特定のインスタンスを指すようにする必要があります。

おそらくdockerはこの仕事に理想的なツールではありません。私は、前面に面したHTTPサーバーをセットアップし、クライアントIPをHTTPリクエストヘッダーの一部として配置するためにvagrantを調べていました。

Dockerがオーバーレイネットワークを介してクライアント情報を渡すことができるようになるまで、Docker Flow ProxyやTraefikなどのプロキシを使用し、そのサービスでホストモードで目的のポートを公開し、アプリケーションサービスをそれに接続することができます。 完全なソリューションではありませんが、非常にうまく機能し、アプリケーションサービスの負荷分散/クライアントIPの取得が可能です。

@ deeeky666 Traefikおよび同様の機能は、ドッキングされていない場合にのみ機能します

traefikでudoサポートが表示されません

私のiPhoneから送信された

最後に、Dockerコンテナをあきらめました。 生産準備ができていません!

5:43の水、2018年1月24日には、Efrain [email protected]書きました:

traefikでudoサポートが表示されません

私のiPhoneから送信された

>>


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-360091189 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AHf7rvMcH2iFBxcExfO_Ol0UttCspuTnks5tNwlkgaJpZM4Jf2WK

問題は、部分的に解決するようだ17.12.0-ce使用してmode=host

docker service create --publish mode=host,target=80,published=80 --name=nginx nginx

いくつかの制限があります(ルーティングメッシュなし)が、機能します!

@goetas mode=hostは回避策としてしばらくの間機能したので、問題が何らかの形で解決されたとは言えません。 mode = hostの使用には多くの制限があり、ポートが公開されている、群れの負荷分散を使用できないなどです。

@darklow私は制限を知っていますが、私のユースケースでは問題ありません(それ以上ではないにしても!)。 17.09.1-ceではまったく機能していなかったので、私にとってはすでに改善されています!

この回避策の大きな欠点は、更新中のダウンタイムを回避できないことです。
現在、安定性か送信元IPアドレスかをあきらめることを選択する必要があります。

同意します。 Swarmには、ソースIPを保持するための高可用性の方法が必要です。

おそらくプロキシプロトコルを使用しています。 追加するのは大きな努力ではないと思います
DockerSwarmへのプロキシプロトコルのサポート。

これを調べている人はいますか?

2018年1月28日22:39、「元気滝内」 [email protected]は次のように書いています。

その回避策の大きな欠点は、ダウンを回避することができないことです
更新中の時間。
現在、安定性とソースIPのどちらを放棄するかを選択する必要があります
住所。


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-361078416 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU-or7fnhKTg7fhjtZYjGYHBFRE7Dks5tPKnYgaJpZM4Jf2WK

@sandys同意します。 プロキシプロトコルは素晴らしいアイデアです。
@thaJeztah @aluzzardi @mrjanaこの問題に注意を向けてください。 しばらくの間、チームからの応答はありませんでした。 ありがとうございました。

プロキシプロトコルは私にとって最良の解決策のように思えます。 うまくいけば、チームはそれを検討するでしょう。

@goetas少なくともある時点では機能していましたが、docker1.12.6では再び172.xxxの動作に戻ったようです。

これは非常に悪いことであり、レート制限、不正防止、ロギング、安全なログイン、セッション監視などを軽減します。
mode:hostでリッスンすることは

これは私たちにとって非常に重要で重要なバグであり、Swarmでの稼働を妨げています。 また、プロキシプロトコルがこのための適切なソリューションであると信じています。 Docker入力は、プロキシプロトコルでソースIPを渡す必要があります。

Twitterで提案されている解決策の1つは、 Swarmの外部で管理されるイングレスとしてTraefikを使用することです。 これは私たちにとって非常に最適ではなく、管理したいオーバーヘッドではありません。

Swarm開発者がSwarm-ingressにプロキシプロトコルを実装する方法を確認したい場合は、Traefikで説明されているすべてのバグを確認する必要があります(例:https://github.com/containous/traefik/issues/2619)

スウォームモードではなく「作成」を使用して、これを一貫して機能させました。 多分何か考えること。

プロキシプロトコルに関するいくつかの懸念事項:

Docker自体によってデコードされますか、それともアプリケーションによってデコードされますか? プロキシプロトコルの実装をアプリケーションに依存している場合、これはすべてのアプリケーションの一般的なソリューションではなく、プロキシプロトコルを実装するWebサーバーまたはその他のアプリケーションでのみ機能します。 Dockerがプロキシプロトコルをアンラップしてアドレスを変換する場合、接続状態を追跡し、発信パケットに対して逆変換を実行する必要もあります。 dockerは多くの非Webアプリケーションにも役立つため、私はWeb固有のソリューション(アプリケーションのプロキシプロトコルに依存)には賛成していません。 この問題は、TCP / UDPアプリケーションの一般的なケースで対処する必要があります。Dockerには、Web固有のものは他にありません。

他のカプセル化方法と同様に、パケットサイズ/ MTUの問題も懸念されます。 ただし、これはおそらく、この問題のほぼすべての解決策で懸念されることになると思います。 その答えは、スウォームネットワークがオーバーヘッドを許容するのに十分な大きさのMTUをサポートしていることを確認することでしょう。 ほとんどの群れはローカルネットワーク上で実行されていると思うので、それはおそらく大きな問題ではありません。

@ trajano-ホストネットワークで動作することはわかっています(これはおそらく、作成ソリューションが実行していることです)。 ただし、これにより、swarmのクラスターネットワークの利点(負荷分散など)がすべて失われます。

@dackバックエンドはプロキシプロトコルを知っている必要があります。
私はそれがほとんどの場合を解決すると思います、そして少なくともあなたはコンテナ内のあなたのバックエンドの前にプロトコルヘッダーを処理する薄いパススルーのようなプロキシを置くことができます。
情報不足は致命的な問題ですので、他のきちんとした解決策に先立って、できるだけ早く解決する必要があると思います。

プロキシプロトコルは広く受け入れられています。 サポートされているツールの数を確認してください-https://www.haproxy.com/blog/haproxy/proxy-protocol/
クラウドロードバランサー(ELB、Google LB)やTraefikなどの新しいツールもカバーしていません。

また、これはkubernetesのほぼ標準です: https

現時点では、プロキシプロトコルは、この問題を解決する上で最も広く受け入れられている標準です。 私はこれを再発明し、世界のnginxesとの互換性を壊すことに大きな価値を見ていません。

これらはL7プロトコルです。 群れの侵入はL4です。 ここで再発明されているものは何もありません。それはすべてDNATを使用するIPVSです。

@ cpuguy83はあなたが今何を意味しているのか理解できませんでした。

プロキシプロトコルはレイヤー4です。
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

PROXYプロトコルの目標は、サーバーの内部構造を
サーバーが取得できたはずのプロキシによって収集された情報
クライアントがサーバー経由ではなくサーバーに直接接続している場合は、それ自体で
プロキシー。 プロトコルによって運ばれる情報は、サーバーが運ぶ情報です。
getockname()とgetpeername()を使用して取得します。

  • アドレスファミリ(IPv4の場合はAF_INET、IPv6の場合はAF_INET6、AF_UNIX)
  • ソケットプロトコル(TCPの場合はSOCK_STREAM、UDPの場合はSOCK_DGRAM)
  • レイヤ3の送信元アドレスと宛先アドレス
  • レイヤー4の送信元ポートと宛先ポート(ある場合)

http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1 -accept-proxy

accept-proxy

のいずれかによって受け入れられた接続を介してPROXYプロトコルの使用を強制します
同じ行で宣言されたソケット。 PROXYプロトコルのバージョン1および2
サポートされ、正しく検出されます。 PROXYプロトコルがレイヤーを決定します
アドレスがどこにでも使用される着信接続の3/4アドレス
「tcp-requestconnection」ルールを除いて使用されます。
実際の接続アドレスのみが表示されます。 ログには住所が反映されます
違反していない限り、プロトコルに示されています。違反している場合は、実際の
アドレスは引き続き使用されます。 このキーワードと外部からのサポートの組み合わせ
コンポーネントは、効率的で信頼性の高い代替手段として使用できます。
X-Forwarded-常に信頼できるとは限らず、常にでもないメカニズムの場合
使用可能。 より詳細な情報については、「tcp-requestconnectionexpect-proxy」も参照してください。
プロトコルの使用を許可するクライアントの設定。

プロキシプロトコルよりも良い方法があったということですか? それは完全に可能であり、dockerswarmでのソースIP保存のコンテキストでもっと知りたいと思います。 ただし、プロキシプロトコルは、swarm-ingressのダウンストリームになる他のツール(nginxなど)や、swarm-ingressのアップストリームになるAWSELBなどのツールによってより広くサポートされています。 それは私の唯一の0.02ドルでした

@sandysプロキシプロトコルはカプセル化のように見えます(少なくとも接続の開始時)。これには、スタックのずっと下のレシーバーからのカプセル化の知識が必要です。 このアプローチには多くのトレードオフがあります。

私はこれをコアでサポートしたくありませんが、おそらく入力をプラグ可能にすることは価値のあるアプローチでしょう。

@sandyshttps ://github.com/sandysプロキシプロトコルは次のようになります
知識を必要とするカプセル化(少なくとも接続開始時)
スタックのずっと下の受信機からのカプセル化の。 三
このアプローチには多くのトレードオフがあります。

それは本当です。 それがRFCの標準である理由です。 あります
しかし、この背後にある勢い-ほぼすべてのコンポーネントの重要性
それをサポートします。 私見それをサポートすることは悪い決断ではありません。

私はこれをコアでサポートしたくありませんが、おそらくイングレスを作ります
プラグ可能なアプローチは価値のあるアプローチです。

これはより大きな議論です-しかし、私はそれを単一の最大のものに追加するかもしれません
Docker Swarmが他の製品よりも優れている点は、すべてのバッテリーを搭載していることです。
ビルトイン。

それでも、プロキシプロトコルを
業界の支持を得ているこの問題。

LinuxおよびLxC(特にdockerではない)でL3ルーターをシミュレートすることはできませんか?

@trajanoシミュレーションは必要ありませんが、この問題を解決するためのカプセル化が必要です。
たとえば、オプション(例: --use-proxy-protocol )は、クライアントIPアドレスを必要とし、nginxなどのカプセル化されたパケットの処理方法を知っているサービスに提供できます。

現在機能しているように、パケットを受信するDockerノードはSNATを実行し、アプリケーションコンテナを含むノードにパケットを転送します。 SNATの代わりに何らかの形式のトンネリング/カプセル化が使用された場合、元の変更されていないパケットをアプリケーションに渡すことができるはずです。

これは他のプロジェクトで解決された問題です。 たとえば、OpenStackでは、GREやVXLANなどのトンネルを使用できます。

このスレッドの最近の部分で、Dockerチームを代表し、少なくとも「聞こえます」と言っている人はいますか? 約18か月前の2016年8月9日に最初に報告された後、「すぐに使える」と期待され、コミュニティにとってそのような関心のある機能がまだ解決されていないようです。

このスレッドの最近の部分で、Dockerチームを代表し、少なくとも「聞こえます」と言っている人はいますか?

/ cc @GordonTheTurtle @thaJeztah @riyazdf @aluzzardi

@ bluejaguar @ ruudboon私はDockerの一部です。 これはよく知られている問題です。 現在、ネットワークチームは、オーバーレイネットワークの安定性に関する長年のバグに焦点を当てています。 これが、過去数回のリリースで実際に新しいネットワーク機能がなかった理由です。

私の提案は、問題を解決するために進んで取り組む具体的な提案、または少なくとも誰もがそれを受け入れて実行できる十分な提案を考え出すことです。

@ cpuguy83私はhttps

さらに、ELBは2017年11月にプロキシプロトコルv2のサポートを追加しました(https://docs.aws.amazon.com/elasticloadbalancing/latest/network/doc-history.html)

OpenStackのオクタビアLB-サービスとしての(私たちの進入に類似)は、昨年4月のプロキシプロトコルを合併- http://git.openstack.org/cgit/openstack/octavia/commit/?id=bf7693dfd884329f7d1169eec33eb03d2ae81ace

openstackのプロキシプロトコルに関するドキュメントの一部を次に示します-https //docs.openshift.com/container-platform/3.5/install_config/router/proxy_protocol.html
微妙な違いのいくつかは、httpsのプロキシプロトコルに関するものです(入力で証明書を終了する場合とそうでない場合の両方)。

この問題に関する更新/回避策はありますか? DockerSwarmモードのクライアントIPを本当に知る必要があります。
どんな助けでも大歓迎です。

私のバージョン:

クライアント:
バージョン:18.02.0-ce
APIバージョン:1.36
Goバージョン:go1.9.3
Gitコミット:fc4de44
構築:2018年2月7日水曜日21:16:33
OS / Arch:linux / amd64
実験的:誤り
オーケストレーター:群れ

サーバ:
エンジン:
バージョン:18.02.0-ce
APIバージョン:1.36(最小バージョン1.12)
Goバージョン:go1.9.3
Gitコミット:fc4de44
構築:2018年2月7日水曜日21:15:05
OS / Arch:linux / amd64
実験的:誤り

@adijes 、およびこの問題に直面している他のユーザー。 コンテナをbridgeネットワークにバインドできます(このスレッドの誰かが言及しているように)。

version: "3.4"

services:
  frontend:
    image: nginx
    deploy:
      placement:
        constraints:
          - node.hostname == "prod1"
    networks:
      - default
      - bridge
  # backed services...
  # ...

networks:
  bridge:
    external:
      name: bridge

frontendbridgeバインドされており、常に正確なホストにとどまり、そのIPはパブリックドメインにバインドされています。 これにより、実際のユーザーIPを受信できるようになります。 また、 defaultネットワークにもバインドされているため、バックアップされたサービスに接続できます。

frontendをその唯一のホストでライブに保つ限り、スケーリングすることもできます。 これにより、ホストは単一障害点になりますが、(私は)小さなサイトでも問題ありません。

より多くの情報を追加するために編集:

私のnginxコンテナはhttps://github.com/jwilder/nginx-proxyの背後にあり、SSLを有効にするためにhttps://github.com/JrCs/docker-letsencrypt-nginx-proxy-companionも使用していdocker runコマンドを介して実行されます。 おそらく、それが私がクライアントから実際のIPを取得した理由です。 bridgeネットワークは、nginxコンテナがnginx-proxyと通信できるようにするために必要です。

FWIW、私が使用しているもの:

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

上記のセットアップは、実行中の別のセットアップでも機能します。

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

@ letientai299それは私のために動作しません

ネットワーク「ブリッジ」は外部として宣言されていますが、適切なスコープではありません。「スウォーム」ではなく「ローカル」です。

マスターノードと3つのワーカーノードがあります

@trajano 、私のアップデートを参照してください。

@ letientai299実は、どうやってbridgeスウォームモードで動作させるのだろうと思っていました。 つまり、私が持っているエラーは発生しませんでした。

@dackあなたがホストネットワーキングと言うとき、私はあなたが持っていることを意味すると思います

ports:
- target: 12555
  published: 12555
  protocol: tcp
  mode: host

残念ながら、 docker stack deployモードで実行すると、機能せず、ソースIPが失われますが、docker-composeupは正しく機能します。

@goetasに基づいて次のことも試しました

docker service create --constraint node.hostname==exposedhost \
  --publish published=12555,target=12555,mode=host \
  trajano.net/myimage

それでもソースIPを取得する運はありませんこれはServer Version: 17.12.0-ce

ある時点で誰もが欲しがるようなもののようで、オーバーレイネットワークをブリッジ/ホストネットワークと一緒に使用することは実際には不可能であるため、さまざまな理由でクライアントIPが本当に必要な場合のブロッカーです。

クライアント:
バージョン:17.12.0-ce
APIバージョン:1.35
Goバージョン:go1.9.2
Gitコミット:c97c6d6
構築:2017年12月27日水曜日20:03:51
OS / Arch:darwin / amd64

サーバ:
エンジン:
バージョン:17.12.1-ce
APIバージョン:1.35(最小バージョン1.12)
Goバージョン:go1.9.4
Gitコミット:7390fc6
構築:2018年2月27日火曜日22:17:54
OS / Arch:linux / amd64
実験的:真

2018年です。この問題について何か新しいことはありますか?
スウォームモードでは、nginx reqlimitを使用できません。 $ remote_addrは常に10.255.0.2をキャッチしました。
これは、DockerSwarmに関する非常に深刻な問題です。
たぶん、今日からkubernetesを試してみる必要があります。

@Maslow私は上記のいくつかのコメントがあるところに投稿しました。

チェックをリラックスできますか

networks:
  bridge:
    external:
      name: bridge

または次のように拡張します

networks:
  bridge:
    external:
      name: bridge
      scope: local

およびscope: localネットワークは、ネットワークモードがhost場合にのみ許可されます

ネットワーク「ブリッジ」は外部として宣言されていますが、適切なスコープではありません。「スウォーム」ではなく「ローカル」です。

または許可する

networks:
  bridge:
    driver: bridge

失敗しないために

サービスtrajano_servの作成に失敗しました:デーモンからのエラー応答:ネットワークtrajano_bridgeをサービスで使用できません。 オーバーレイドライバーで作成されたネットワークなど、スウォームを対象とするネットワークのみを使用できます。

公開されたポートにmode: hostがある場合。

ports:
- target: 32555
  published: 32555
  protocol: tcp
  mode: host

@trajanoすでに群れがある非群れスコープのネットワークを使用できます...例:これは機能します:

version: '3.4'

services:
  test:
    image: alpine
    command: top
    ports:
      - target: 32555
        published: 32555
        protocol: tcp
        mode: host
    networks:
      - bridge

networks:
  bridge:
    external:
      name: bridge

Dockerスタックをデプロイした複数のワーカーを含む群れでこれをテストしましたか? 私はそれがcomposeで動作することを知っています。

2018年3月18日には、8:55 PMで、ブライアン・ゴフの[email protected]書きました:

@trajanoすでに群れがある非群れスコープのネットワークを使用できます...例:これは機能します:

バージョン:「3.4」

サービス:
テスト:
画像:高山
コマンド:トップ
ポート:
-ターゲット:32555
公開日:32555
プロトコル:tcp
モード:ホスト
ネットワーク:
- 橋

ネットワーク:
橋:
外部の:
名前:橋

あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

はい、私は群れを通してこれをやっています...

2018年3月19日月曜日午前9時12分、Archimedes Trajano <
[email protected]>は次のように書いています:

Dockerスタックを持つ複数のワーカーがいる群れでこれをテストしましたか
配備。 私はそれがcomposeで動作することを知っています。

2018年3月18日には、午前8時55分PMで、ブライアン・ゴフ[email protected]
書きました:

@trajanoすでに群れがある非群れスコープのネットワークを使用できます...
例:これは機能します:

バージョン:「3.4」

サービス:
テスト:
画像:高山
コマンド:トップ
ポート:

  • ターゲット:32555
    公開日:32555
    プロトコル:tcp
    モード:ホスト
    ネットワーク:

ネットワーク:
橋:
外部の:
名前:橋

あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-374206587 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAwxZsm3OohKL0sqUWhlgUNjCrqR0OaVks5tf67YgaJpZM4Jf2WK

-

  • ブライアンゴフ

+1

3つのノードを使用した次のDockerSwarmロードバランシングでこの問題が発生します。

オーバーレイネットワーク<-> nginxプロキシjwilderdocker <-> nginxwebヘッドdocker

提案に従いましたが、ログはReal ClientIPではなくdockernetwork ip10.255.0.3を返し続けます。

+1

@ cpuguy83これは、私たちのより大きな群れのセットアップのブロッカーになり始めています。 クラウド(プロキシプロトコルがロードバランサーによって事実上使用されている)をさらに活用し始めると、この情報が失われます。これは私たちにとって非常に重要です。

ETAについて何か考えがありますか? これは私たちに大いに役立つでしょう。

@sandys正確には何のためのETA?

@ cpuguy83こんにちは、お返事ありがとう
この問題が取り上げられるのはいつだと思いますか(あるとしても)?

この問題は、グローバルサービスを実行し、PublishMode = hostを使用してポートを公開することで解決できることに注意してください。 人々が接続するノードがわかっている場合は、それも必要ありません。制約を使用して、そのノードに固定します。

@kleptog部分的にはできません。 サービスの更新中のダウンタイムを回避することはできません。

テストシナリオ-lvs / ipvsを詳しく調べます。

  • 非表示の入力コンテナにアクセスし、snatルールを削除します
  • 公開されたポートを使用してサービスにnsenterし、デフォルトgwを削除し、デフォルトルートを入力コンテナipに追加します。

これで、ソースIPが保持されます。

私はまだオーバーヘッドの影響を理解しようとしています。入力コンテナにsnatルールだけを含めるのではなく、各サービスコンテナ内でポリシーベースのルーティングを維持しています。
しかし、これが機能することは本当に安心です。

私の素朴ないじりで申し訳ありませんが、誰か( @dack ?)が私に

ああ、わかった。 マルチノードスウォームでは、IPはlvsディレクターである必要があり、リクエストが入った正しいノードに戻る方法を見つけるために...

とにかくコードを見るのは面白いでしょう。 誰かがすでに知っていれば、それは私にいくらかの時間を節約することができます。 ありがとうございました

これに関する更新は、さまざまな国に3つのクラスターがあり、Azure Traffic Managerでさえ実際のユーザーIPが必要です。そうでない場合、ユーザーを適切なクラスターなどにリダイレクトしません。誰か、すぐに、またはこれからチェックしますか? ありがとう

また、これに関する更新が必要です-これは大きな落とし穴です-これを回避する唯一の方法は、前に別のプロキシを追加し、x-forwarded-forをスタックに送信することです。これは、Swarmがパブリックのオプションではないことを意味します多くのシナリオでトラフィックに直面しています。

@ cpuguy83 @trajano
以下が動作しないことを確認できます

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80
      - mode: host
        protocol: tcp
        published: 443
        target: 81
networks:
  bridge:
    external:
      name: bridge

network "bridge" is declared as external, but it is not in the right scope: "local" instead of "swarm"で失敗します。

Dockerバージョン

Client:
 Version:       18.03.0-ce-rc4
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    fbedb97
 Built: Thu Mar 15 07:33:59 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:      18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:        Wed Mar 21 23:08:31 2018
  OS/Arch:      linux/amd64
  Experimental: false

@ Mobe91
群れを再現してみてください。 私もエラーがありました。 再初期化の群れの後、すべてが私のために働いた。
私のdocker-compose.ymlファイル:

version: "3.6"

services:
    nginx:
        image: nginx:latest
        depends_on:
            - my-app
            - my-admin
        ports: 
            - target: 80
              published: 80
              protocol: tcp
              mode: host
            - target: 443
              published: 443
              protocol: tcp
              mode: host
            - target: 9080
              published: 9080
              protocol: tcp
              mode: host
        volumes:
            - /etc/letsencrypt:/etc/letsencrypt:ro
            - /home/project/data/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
            - /home/project/data/nginx/conf.d:/etc/nginx/conf.d
            - /home/project/public:/var/public
        networks:
            - my-network
            - bridge
        deploy:
            placement:
                constraints: [node.role == manager]

    my-app:
        image: my-app
        ports:
            - 8080:8080
        volumes:
            - /usr/src/app/node_modules
            - /home/project/public:/usr/src/app/public
        networks:
            - my-network

    my-admin:
        image: my-admin
        ports:
            - 9000:9000
        networks:
            - my-network

networks:
    my-network:
    bridge:
        external: true
        name: bridge

私のdocker version

Client:
 Version:   18.03.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0520e24
 Built: Wed Mar 21 23:10:01 2018
 OS/Arch:   linux/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:    Wed Mar 21 23:08:31 2018
  OS/Arch:  linux/amd64
  Experimental: false

私の英語でごめんなさい。

@ Mobe91これは私が使用したものですが、「portainer」またはLinuxマシンからデプロイします。 Windowsから正しく展開できません。

version: '3.4'
services:
  hath:
    image: trajano.net/hath
    deploy:
      placement:
        constraints:
        - node.hostname==docker-engine
    networks:
    - host
    ports:
    - target: 12555
      published: 12555
      protocol: tcp
      mode: host
    secrets:
    - hath_client_login
    volumes:
    - hath:/var/lib/hath
volumes:
  hath:
    name: 'noriko/s/hath'
    driver: cifs
networks:
  host:
    external:
      name: host
secrets:
  hath_client_login:
    external:
      name: hath_client_login

主な違いは、 bridge hostではなく

もちろん、負荷分散機能はありません。負荷分散が必要な場合は、負荷分散を行うL3ルーターのようなものを前面に配置する必要が

@trajanoは正しいです、Windowsクライアントが問題でした、Linuxクライアントでの展開は

しかし、なぜhostまたはbridgeネットワークが必要なのかわかりません。
以下は私にとっては問題なく機能します。つまり、nginxで実際のクライアントIPアドレスを取得します。

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80

@ Mobe91ありがとう私はそのための問題を開くhttps://github.com/moby/moby/issues/32957と連携し

繊毛を使った人はいますか? http://cilium.readthedocs.io/en/latest/gettingstarted/docker/

サービスをホストに結び付けなくても、これを修正できる可能性があるようです。

@sandys良い発見-私はそれをテストし始めようとしています、それはあなたのために働きましたか? これを修正できない場合は、nginxを群れから引き出そうとしています.....

プロキシを個々のホストに固定しないように展開を再設計する際にこれにぶつかりました(本番環境では、他の理由でインターフェイスにバインドするため、クライアントIPを副産物として「ピックアップ」します)。

私たちのテスト環境では、制約によってマネージャーにデプロイし、各マネージャーが実行中のインスタンスを取得するようにmode = globalを設定することによってのみ改善できます。 特にマネージャーノードを失い、何かがトラフィックをそのノードに誘導している場合は、注意する必要があるのは依然として余分なオーバーヘッドです。 ただし、単一のホストに固定するよりはましです。

@sandys繊毛を試しましたか? 少なくともk8sで同じ問題が発生しているように見えるWeaveに似ています: https

Ciliumを使用できませんでしたが、Ciliumに連絡しました
swarmconfigを支援する開発者。 しかし、私は繊毛に非常に興奮しています
イングレスは解決したい問題であるため(織りとは異なり)

2018年5月10日木曜日、17:24 James Green、 notifications @ github.comは次のように書いています。

プロキシをに固定しないようにデプロイメントを再設計する際にこれにぶつかりました
個々のホスト(本番環境では、他のインターフェイスにバインドします)
理由により、クライアントIPを副産物として「ピックアップ」します)。

私たちのテスト環境では、マネージャーに展開することによってのみ改善することができます
制約と設定モード=グローバルで、各マネージャーが
実行中のインスタンス。 注意しなければならないのはまだ余分なオーバーヘッドです、
特に、マネージャーノードを失い、何かが私たちを指示している場合
それへのトラフィック。 ただし、単一のホストに固定するよりはましです。

@sandys https://github.com/sandys Ciliumを試しましたか? に似ています
少なくともk8sで同じ問題が発生するように見えるWeave:
kubernetes / kubernetes#51014
https://github.com/kubernetes/kubernetes/issues/51014


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-388032011 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK

2018年5月10日17:24に、「JamesGreen」 [email protected]は次のように書いています。

プロキシをに固定しないようにデプロイメントを再設計する際にこれにぶつかりました
個々のホスト(本番環境では、他のインターフェイスにバインドします)
理由により、クライアントIPを副産物として「ピックアップ」します)。

私たちのテスト環境では、マネージャーに展開することによってのみ改善することができます
制約と設定モード=グローバルで、各マネージャーが確実に実行されるようにします
実例。 特に次の場合は、注意する必要があるのはまだ余分なオーバーヘッドです。
マネージャーノードを失い、何かがトラフィックをそこに向けています。
ただし、単一のホストに固定するよりはましです。

@sandys https://github.com/sandys Ciliumを試しましたか? に似ています
少なくともk8sで同じ問題が発生するように見えるWeave:
kubernetes / kubernetes#51014
https://github.com/kubernetes/kubernetes/issues/51014


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-388032011 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK

  • 1

こんにちは、みんな、
CiliumでDockerSwarmをサポートしたい場合(特に入力と
この特定の問題の周り)、このバグについてコメント/いいねしてください-
https://github.com/cilium/cilium/issues/4159

金、12:59 AMで2018年5月11日、上McBacker [email protected]書きました:

>>

  • 1


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-388159466 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU_18F_cNttRUaAwaRF3gVpMZ-3qSks5txJUfgaJpZM4Jf2WK

現在のバージョンでは、次のように機能します。
その後、「デフォルト」ネットワークにもあるので、群れの他のノードにアクセスできます。

  web-server:
    image: blabla:7000/something/nginx:latest
    #ports:
    #  - "80:80"
    #  - "443:443"
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host        
    deploy:
      mode: global
      restart_policy:
        condition: any
      update_config:
        parallelism: 1
        delay: 30s

鍵はports.mode: hostを使用することであることが確認できます。 ドキュメント(https://docs.docker.com/compose/compose-file/#long-syntax-1)から:

モード:各ノードでホストポートを公開するためのホスト、または負荷分散されるスウォームモードポートの入力。

次に、 mode: host使用すると、入力による負荷分散が停止し、実際のIPが表示されます。 例として、これが私のnginxログです:

  • mode: host
    metrics-agents_nginx.1.pip12ztq3y1h<strong i="14">@xxxxxxxx</strong> | 62.4.X.X - - [12/Jun/2018:08:46:04 +0000] "GET /metrics HTTP/1.1" 200 173979 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.227" remote_addr: 62.4.X.X proxy_add_x_forwarded_for: 62.4.X.X
  • mode: host
    metrics-agents_nginx.1.q1eosiklkgac<strong i="20">@xxxxxxxx</strong> | 10.255.0.2 - - [12/Jun/2018:08:50:04 +0000] "GET /metrics HTTP/1.1" 403 162 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.000" remote_addr: 10.255.0.2 proxy_add_x_forwarded_for: 10.255.0.2

そして、最後のログが403 Forbidden応答である理由がわからない場合、これはnginxでホワイトリスト( allow 62.4.X.Xおよびdeny all )を使用しているためです。

環境:
Description: Debian GNU/Linux 9.4 (stretch)
Docker version 18.03.0-ce, build 0520e24

@nperronが言ったことを確認します。
ホストモードを使用すると、クライアントIPを取得できます。

Dockerバージョン18.03.1-ce、ビルド9ee9f40
Ubuntu 16.04.4 LTS

動作していることを確認できます。

Dockerバージョン18.03.1-ce、ビルド9ee9f40
Ubuntu 16.04.4 LTS

警告:IPTABLES = FALSEを設定した場合、これは機能しません!
UFWを使用してポートを保護していて、Dockerの群れがそれらのUFW設定を上書きしていることがわかった場合は、これを行った可能性があります(または少なくとも私は行いました)。

コマンドまたは/etc/docker/daemon.jsonでiptables = falseを設定することを提案するチュートリアルがいくつかあります。

うまくいけば、これは私がちょうど経験した欲求不満を誰かに救うでしょう!

Ingressを使用していないため、「モード:ホスト」=動作していると言うのはやめるべきです。 そのため、スウォームでサービスを実行しているコンテナを1つだけ持つことは不可能ですが、それでも任意のホストを介してそのコンテナにアクセスできます。 サービスを「グローバル」にする必要があるか、サービスが実行されているホストでのみアクセスできるため、Swarmの目的が少し損なわれます。

TLDR:「モード:ホスト」は回避策であり、解決策ではありません

@ r3pekこの苦境を解決するためにホストモードを使用すると、イングレスが失われることに同意しますが、スウォームの目的全体を損なうことはほとんどないと思います。 私たちの使用シナリオでは、同じオーバーレイスウォームにあります:
イントラネット経由でのみアクセスする必要がある管理複製コンテナ->呼び出し元のIPを必要としないため、「通常」に構成され、入力を利用します。
公開されていないコンテナ->これらについては何も言うことはありません(ただし、サービス名を介してそれらにアクセスできることの力を過小評価していると思います)。
公開サービス->これはhttpsおよびURLベースのルーティングを行うnginxプロキシです。 これは、x-forwardが必要になる前でもグローバルに定義されていました-クライアントの実際のIPに対して、実際の問題はありません。

nginxがグローバルであり、入力がないということは、クラスターの任意のIPを介して到達できることを意味しますが、負荷分散やフォールトトレラントではないため、nginxの前に非常に安価で簡単にセットアップできるL4Azureロードバランサーを追加しましたサービス。

あなたが言うように、Hostは回避策ですが、それを有効にするとDocker Swarmの目的が完全に無効になると言うのは、少し誇張されたimoです。

こんにちはロベルト
誇張されているとは思いません-ホストモードは単一のポイントを公開するためです
失敗の。 さらに、負荷の管理の追加レイヤーが必要です
群れの生態系の外でバランスを取ります。

自分で紺碧のlbを使用したと言うことで、
口論。

「クライアントIP伝播で群れを実行するには、
セットアップした外部ロードバランサーを使用していることを確認してください...または
クラウドサービスの1つ」。

一時的な回避策ではないと言っているのではありません...しかし、
私たち全員が断固として認識していない場合、Swarmの約束を無視します
欠点。

2018年7月5日木曜日、14:16 Roberto Fabrizi、 notifications @ github.com
書きました:

@ r3pek https://github.com/r3pek私はあなたが失うことに同意しますが、
この窮状を解決するためにホストモードを使用する場合の入力、私はそれを言うだろう
Swarmの目的全体を損なうことはほとんどありません。
パブリックに面した入力ネットワーク。 私たちの使用シナリオでは、同じ
オーバーレイスウォーム:
管理複製コンテナは、
イントラネット->発信者のIPを必要としないため、構成されています
「通常」、入力を利用します。
露出されていないコンテナ->これらについては何も言うことはありません(私はあなたがいると信じています
彼らのサービスを介してそれらにアクセスできることの力を過小評価している
名前ですが)。
公開コンテナ->これはhttpsとURLを実行するnginxプロキシです
ベースのルーティング。 x-forward-forが必要になる前でもグローバルに定義されていました
クライアントの実際のIPなので、実際の問題はありません。

nginxがグローバルであり、入力がないということは、
クラスターの任意のIPですが、負荷分散されていないため、非常に非常に多くのIPを追加しました
nginxの前にL4Azure LoadBalancerを安価で簡単にセットアップできます
サービス。

あなたが言うように、ホストは回避策ですが、それを完全に有効にすることを言っています
DockerSwarmの目的を打ち破るのは少し誇張されたimoです。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-402650066 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU_ogRzwM6X0PMknXxsxmZLLTtfraks5uDdJlgaJpZM4Jf2WK

Docker Swarmの入力に、貧弱なロードバランサー(IPVS)が選択されたことは明らかです。 少なくともL4プロキシプロトコルをサポートしていれば、これは問題にはなりません。 それがL7ポンドが与えることができるすべての追加機能なしでまだL4(TCP)ロードバランサーであることを除いて。

Kubernetesには、 nginx入力haproxy入力などのL4(TCP)-L7(HTTP)ロードバランサーがあり、どちらもL4プロキシプロトコルまたはL7 HTTPヘッダーの使用を許可して、ユーザーの実際のパスにX-Forwarded-Forが利用されるようにしますバックエンドへのIP。

DockerSwarmイングレスの開発者は何と言うだろうかと思います。 おそらく誰かがこのケースをhttps://github.com/docker/swarmkit/issuesに移動する必要があり

Kubernetesには、nginx入力やhaproxy入力などのL4(TCP)-L7(HTTP)ロードバランサーがあり、どちらもL4プロキシプロトコルまたはL7 HTTPヘッダーを使用して、X-Forwarded-Forを使用してユーザーの実際のIPを渡すことができます。バックエンドに。

AFAICS、これらのLBサービスはK8に組み込まれていませんが、明示的にデプロイする必要があるサービスです。 Dockerswarmでも同じことができます。 ここでは違いはわかりません。 (それを除けば、nginx入力コントローラーは「公式」のようです。)

私の知る限り、違いは、そのような負荷分散サービスをデプロイした場合でも、swarmkitロードバランサーから「呼び出される」ため、ユーザーのIPが失われることです。 したがって、ホストモードを使用していない場合、swarmkitロードバランサーを無効にすることはできません。

公平を期すために-k8sでは、カスタム入力を行うことができます。 群がってそれ
ではありません。

群れは、すべてが「組み込み」であるという立場を取ります。 同じことが
ネットワーク-k8sでは、組み込みのswarmにweaveなどを設定する必要があります。

アンドレイが言っていること(そして私は一種の同意です)はそれです-
swarmは、ユーザーが持っているので、入力の一部としてこの機能を作成する必要があります
それを制御することはできません。

17:07セティので土、2018年7月28日に[email protected]書きました:

私の知る限り、違いは、そのような
負荷分散サービスは、swarmkitロードバランサーから「呼び出されます」
そのため、ユーザーのIPを失います。 したがって、swarmkitを無効にすることはできません
ホストモードを使用していない場合はロードバランサー。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-408601274 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU1-Ism_S1Awml8lO8N0Aq6rtrLH4ks5uLEzugaJpZM4Jf2WK

群れのしわを取り除き終えたと思いましたが、ステージに上がると、Webサーバーコンテナへのすべての外部アクセスが入力ネットワークIPとして表示されていることに気付きました。

私はスタックを単一ノードの群れで実行しており、少なくとも今後数か月は実行する予定です。 現在の(単一ノードの群れ)ユースケースで最も悪い回避策をお勧めできますか? 私はクライアントIPなしではできません-あまりにも多くのクライアントIPに依存しています。

一時的なアプローチは、単純なプロキシコンテナを「グローバル」モード(IIRCが実際のNICのIPを取得できる)で実行し、プロキシヘッダーを追加してスウォームオーバーレイネットワークで実行されている内部サービスにすべての接続を転送することでした。

x-forwarded-forヘッダーを取得するだけで十分な場合は、そのセットアップがAFAICTで機能するはずです。

ありがとう、@ maximelb。 最終的に何を使用しましたか(nginx、haproxyなど)?

@jamiejacksonそれは物事が少し異なるところです。 私たちの場合、長時間実行されるSSL接続とその下のカスタムバイナリプロトコルをホストするサーバーを実行しているため、HTTPプロキシは使用できませんでした。 そこで、単純なTCPフォワーダーを作成し、内部サーバーで手動で解凍できる「msgpack」ヘッダーを使用しました。

私はHTTPプロキシにあまり精通していませんが、それらのほとんどがあなたのためにトリックを行うと思います。 :-/

こんにちはマキシム、
これは私たちにとって非常に興味深いものです。 Dockerを共有できますか?
チャンス ?

私はこれがどのように機能するかを理解しようとしています。 今日は逆にnginxがあります
プロキシ(サービスとして)とその背後にある複数のDockerサービス。

あなたの場合-nginxは「グローバルモード」プロキシになりますか? またはそれは
特別なTCPフォワーダー。 したがって、ノード数をスケーリングすると、プロキシフォワーダーが
各ノードに行きます。 私はどういうわけかこの状況でx-forwarded
入力ネットワークが外部IPを強制終了するため、ヘッダーが失われます。
(プロキシプロトコルがないため)。

詳細を教えていただければ幸いです。

よろしく
サンディープ

2018年8月8日水曜日午前7時18分MaximeLamothe-Brassard <
[email protected]>は次のように書いています:

私たちの一時的なアプローチは、で単純なプロキシコンテナを実行することでした
「グローバル」モード(IIRCが実際のNICのIPを取得できる)そしてそれを使用する
群れで実行されている内部サービスにすべての接続を転送します
プロキシヘッダーが追加されたオーバーレイネットワーク。

x-forwarded-forヘッダーを取得するだけで十分な場合は、そのセットアップを行う必要があります
仕事AFAICT。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-411257087 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUx3DOjXb79FNjsuZ-RZVqkkhHAbYks5uOkOHgaJpZM4Jf2WK

@sandys確かに、これは

これはリバースプロキシdocker-composeエントリです。

reverseproxy:
    image: yourorg/repo-proxy:latest
    networks:
      - network_with_backend_service
    deploy:
      mode: global
    ports:
      - target: 443
        published: 443
        protocol: tcp
        mode: host

これはバックエンドサービスエントリです。

backendservice:
    image: yourorg/repo-backend:latest
    networks:
      - network_with_backend_service
    deploy:
      replicas: 2

リバースプロキシ(バックエンド側)のターゲットはtasks.backendservice (すべてのレプリカのAレコードがあります)になります。 バックエンドサービスがデフォルトのスウォームオーバーレイネットワーク上にある場合は、 networks部分をスキップできます。

globalビットは、「このコンテナーを正確にデプロイします。すべてのDockerスウォームノードに1回だけです。ポートmode: hostは、「ノードのネイティブNICにバインドする」というものです。

それが役に立てば幸い。

ホストモードを使用しています。 ほぼあなたは外部ロードバランサーを持っています
全体の前で。
ホストモードになっているため、Swarmに依存することはできなくなりました。

それは実際に私たちがしばらく話していた問題です:(

2018年8月8日水曜日、20:47 Maxime Lamothe-Brassard、<
[email protected]>は次のように書いています:

@sandys https://github.com/sandys確かに、ここに私たちからの抜粋があります
docker-関連するコンテナーで作成します。

これはリバースプロキシdocker-composeエントリです。

リバースプロキシ:
画像:yourorg / repo- proxy:latest
ネットワーク:
--network_with_backend_service
配備:
モード:グローバル
ポート:
-ターゲット:443
公開:443
プロトコル:tcp
モード:ホスト

これはバックエンドサービスエントリです。

バックエンドサービス:
画像:yourorg / repo- backend:latest
ネットワーク:
--network_with_backend_service
配備:
レプリカ:2

リバースプロキシ(バックエンド側)のターゲットは次のようになります
tasks.backendservice(すべてのレプリカのAレコードがあります)。 あなたはできる
バックエンドサービスがデフォルトの群れにある場合は、ネットワークの部分をスキップします
オーバーレイネットワーク。

グローバルビットは、「このコンテナを正確にデプロイします-すべてのDockerに1回」と言います
群れノード。 ポートモード:ホストは「ネイティブにバインド」と言っているものです
ノードのNIC」。

それが役に立てば幸い。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-411442155 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU8N7KAFtOp_cPO8wpbBQqzDfpBWOks5uOwEkgaJpZM4Jf2WK

意味が100%確実ではありませんが、外部では、クラスターノードごとにAレコードを持つDNSを使用しています。 これにより、外部可動部品がなくても安価な「バランス調整」が可能になります。 クライアントがリクエストを行うと、ランダムなAレコードを選択し、クラスターノードの1つで443に接続します。

そこで、その特定のノードで実行され、443でリッスンしているリバースプロキシは、実際のクライアントIPを含むネイティブ接続を取得します。 次に、そのリバースプロキシコンテナはヘッダーを追加し、スウォームオーバーレイネットワーク(tasks.backend)を使用して接続を別の内部コンテナに転送します。 これはtasks.backendターゲットを使用するため、内部サービスのランダムなAレコードも取得します。

したがって、厳密な意味では、接続をリダイレクトするのはオーバーレイネットワークの魔法をバイパスしています。 代わりに、リバースプロキシを使用してこの動作を複製し、ヘッダーを追加します。 最終的な効果は、オーバーレイネットワークの魔法と同じです(大まかな意味で)。 また、スウォームの実行と並行して実行します。つまり、同じクラスター上でクライアントIPを必要としない他のすべてのサービスを、他に何もせずに実行できます。

決して完璧な解決策ではありませんが、修正が行われるまで(もしあれば)、外部コンポーネントや主要なDocker構成なしで解決できます。

@jamiejacksonが見つけた「最も悪い」回避策は、ホストモードのグローバルサービスとしてTraefikを使用することです。 彼らは彼らのドキュメントに良い
https://github.com/containous/traefik/issues/1880

お役に立てれば。 また、実際のリクエスターIPを確認できないソリューションを使用することはできないため、何かが変更されるまで、この問題の修正に固執します。 少なくともセキュリティ上の理由から、これはかなり一般的なニーズのようです。

理解しました(そしてこれの緩いバージョンが私たちが使用するものです)。

ただし、この特定のバグのアジェンダは、開発者に要求することでした。
それを魔法のオーバーレイネットワークに組み込むために(おそらくプロキシを使用して)
プロトコルまたは他のメカニズム)

2018年8月8日水曜日、21:22 Maxime Lamothe-Brassard、<
[email protected]>は次のように書いています:

意味が100%わからないが、外部ではA付きのDNSを使用している
クラスタノードごとのレコード。 これにより、安価な「バランシング」が提供されます。
外部可動部品。 クライアントがリクエストを行うとき、彼らはランダムなAを選択しました
記録し、クラスターノードの1つで443に接続します。

そこで、その特定のノードで実行されているリバースプロキシと
443でリッスンすると、実際のクライアントIPを含むネイティブ接続が取得されます。
次に、そのリバースプロキシコンテナはヘッダーを追加し、接続を転送します
スウォームオーバーレイネットワークを使用して別の内部コンテナに
(tasks.backend)。 これはtasks.backendターゲットを使用するため、
ランダム内部サービスのレコード。

したがって、厳密な意味では、オーバーレイネットワークの魔法をバイパスしています。
接続をリダイレクトします。 代わりに、この動作を次のように複製します。
リバースプロキシとヘッダーを追加します。 最終的な効果は同じです(
オーバーレイネットワークの魔法としてのルーズセンス)。 それはまたそれをします
群れの実行と並行して、他のすべてのサービスを実行できることを意味します。
何もせずに同じクラスター上のクライアントIPを必要としない
他のそれらのため。

決して完璧な解決策ではありませんが、修正が行われるまで(もしあれば)それは得られます
外部コンポーネントや主要なDocker構成なしであなたを。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-411455384 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU5RKjGc3hEk6bk-doicDa1MbYGAyks5uOwlIgaJpZM4Jf2WK

TBH入力ネットワークにIPを追加するためのパッチが適用されていない理由がわかりません
プロキシプロトコルのデータ。

それはインクリメンタルであり、既存のスタックを壊すことはなく、明確に定義されています
標準、それは大きなクラウドベンダーでさえ広くサポートされています、それは広く
アプリケーションフレームワークによってサポートされます。

それは重要な開発努力ですか?

2018年8月8日水曜日、21:30 Matt Glaser、 notifications @ github.comは次のように書いています。

@jamiejacksonhttps ://github.com/jamiejackson 「最も悪い」
私たちが見つけた回避策は、ホストモードでグローバルサービスとしてTraefikを使用することです。
彼らは彼らのドキュメントに良い一般的な例を持っています
https://docs.traefik.io/user-guide/cluster-docker-consul/#full-docker-compose-file_1
この設定に関連する場合と関連しない場合があるバグがいくつか見られましたが、
Traefikは素晴らしいプロジェクトであり、Swarmではかなり安定しているようです。 あります
その問題ページのスレッド全体(ここにループバックします:))、
同様の回避策:
含む/ traefik#1880
https://github.com/containous/traefik/issues/1880

お役に立てれば。 また、私たちができないソリューションを使用することはできません
実際のリクエスターIPを確認して、このクラッジ修正が行われるまで続けます。
何かが変わる。 セキュリティ上の理由から、かなり一般的なニーズのようです。
少なくとも。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-411458326 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU7NNbsW44L95VYCvlyL_Bje-h6L9ks5uOwsUgaJpZM4Jf2WK

ええと、Dockerは現在入力トラフィックに触れていないので、少なくとも追加することは重要ではありません。
また、これはオープンソースプロジェクトであることに注意してください。本当に何かが必要な場合は、通常、それを実装するのはあなた次第です。

+1、これは本当にショートッパーです。
私は、アプリケーションの大部分が実際のクライアントIPを必要としていると思います。 メールサーバースタックについて考えてみてください。任意のホストからのメールを受け入れる余裕はありません。

proxy_protocol nginxグローバルストリームインスタンスホストモードに切り替えました。これは、レプリケートされたアプリケーションproxy_nginxに転送されます。 これは今のところ十分に機能します。

サービスグローバルnginx_stream

stream {
    resolver_timeout 5s;
    # 127.0.0.11 is docker swarms dns server
    resolver 127.0.0.11 valid=30s;
    # set does not work in stream module, using map here
    map '' $upstream_endpoint {
        default proxy_nginx:443;
    }

    server {
        listen 443;
        proxy_pass $upstream_endpoint;
        proxy_protocol on;
    }
}

サービス複製nginx_proxy

server {
    listen 443 ssl http2 proxy_protocol;
    include /ssl.conf.include;

    ssl_certificate /etc/nginx/certs/main.crt;
    ssl_certificate_key /etc/nginx/certs/main.key;

    server_name example.org;

    auth_basic           "closed site";
    auth_basic_user_file /run/secrets/default.htpasswd;

    # resolver info in nginx.conf
    set $upstream_endpoint app;
    location / {
        # relevant proxy_set_header in nginx.conf
        proxy_pass http://$upstream_endpoint;
    }
}

nginx_streamのnginx設定全体を貼り付けることは可能でしょうか?
nginx_proxyとそのSwarm構成?

それが機能する場合、これは素晴らしいです!

2018年9月11日火曜日、17:14 rubot、 notifications @ github.comは次のように書いています。

proxy_protocolnginxグローバルストリームインスタンスに切り替えました。
複製されたアプリケーションproxy_nginxに転送します。 これは十分に機能します
今のところは。

サービスグローバルnginx_stream

ストリーム {
resolver_timeout 5s;
#127.0.0.11はdocker swarmsdnsサーバーです
リゾルバ127.0.0.11valid = 30s;
#セットはストリームモジュールでは機能しません、ここでマップを使用します
マップ '' $ upload_endpoint {
デフォルトのproxy_nginx :443;
}

server {
    listen 443;
    proxy_pass $upstream_endpoint;
    proxy_protocol on;
}

}

サービス複製nginx_proxy

サーバー{
443 ssl http2proxy_protocolをリッスンします。
インクルード/ssl.conf.include;

ssl_certificate /etc/nginx/certs/main.crt;
ssl_certificate_key /etc/nginx/certs/main.key;

server_name example.org;

auth_basic           "closed site";
auth_basic_user_file /run/secrets/default.htpasswd;

# resolver info in nginx.conf
set $upstream_endpoint app;
location / {
    # relevant proxy_set_header in nginx.conf
    proxy_pass http://$upstream_endpoint;
}

}


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-420244262 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU5K-gK09XdI9NxLlT36IrJP7U7_cks5uZ6IrgaJpZM4Jf2WK

nginx_streamとnginx_proxyのnginx設定全体をSwarm設定で貼り付けることは可能でしょうか? それが機能する場合、これは素晴らしいです!

@sandysこのようなもの:
https://gist.github.com/rubot/10c79ee0086a8a246eb43ab631f3581f

同じ問題が発生しました、これは対処される予定ですか? リリースが予定されている基本的な機能のようです。

配備:
モード:グローバル
ポート:

  • ターゲット:443公開:443プロトコル:tcpモード:ホスト

このアドバイスに従うと、docker swarmバランサーが方程式から外れるため、問題が修正されます。
それはまだHAであり、すでにhaproxy(docker flowプロキシコンテナ内)を持っていたので、私にとっては有効なソリューションです。
唯一の問題は、haproxy統計がすべてのレプリカに分散されているため、クラスター全体のトラフィックを監視するときに、何らかの方法でその情報を集約する必要があることです。 以前は、DockerSwarmバランサーの背後にあるhaproxyインスタンスが1つだけありました。
乾杯、
ジャック

OPのリクエスト( @PanJ )を読むと、

  1. これで、入力ルーティングレイヤーをスキップして、ポートをホストIPに「公開」するSwarmサービスを作成できます。
  2. その同じサービスは、オーバーレイなどの他のネットワークに同時に接続できるため、オーバーレイのメリットで他のサービスにアクセスできます

18.09エンジンを使用している私にとって、テストでは両方の長所を活用できます。 単一のサービスがバックエンドオーバーレイネットワークに接続し、ホストNICにポートを公開して、ホストIPに着信する実際のクライアントIPを確認することもできます。 これをtraefikリバースプロキシで使用して

@PanJこれはあなたのためにそれを解決しますか?

重要なのは、ポートをmode: ingress (デフォルト)ではなくmode: hostで公開することです。

このモードの利点は、実際のクライアントIPとネイティブホストNICのパフォーマンスが得られることです(IPVSカプセル化AFAIKの外部にあるため)。 短所は、レプリカを実行しているノードでのみリッスンすることです。

私にとって、「入力IPVSルーティングを使用し、クライアントIPも表示したい」という要求は、libnetworkの別の機能要求です。

ここで何が変わったのですか? これを行うためにホストモードを使用しているため
久しぶりです。 実際、これはこのスレッドで提案されている回避策です。
良い。

問題はもちろん、このサービスを特定のものにロックする必要があるということです
Swarmが他の場所でスケジュールできないようにホストします。 問題は何でしたか
完全に-そのプロキシプロトコル/ IPVSなどがこの問題を解決します。

2019年1月4日金曜日、09:34 Bret Fisher < [email protected]は次のように書いています。

OPのリクエスト( @PanJ https://github.com/PanJ )を読むと、
提案されているように、現在の機能がこの問題を解決しているようです
月。 OPは入力ルーティング+クライアントIPAFAIKを要求しませんでした、彼らは尋ねました
レプリカ/グローバルのスウォームサービスでクライアントIPを取得する方法については、
これは現在実行可能です。 改善の2つの主要な領域はこれが起こることを可能にします:

  1. これで、ポートをに「公開」するSwarmサービスを作成できます。
    ホストIP、入力ルーティングレイヤーをスキップ
  2. その同じサービスは、オーバーレイのような他のネットワークに接続できます。
    同時に、オーバーレイのメリットで他のサービスにアクセスできるようになります

18.09エンジンを使用している私にとって、テストでは両方の長所を活用できます。 NS
単一のサービスがバックエンドオーバーレイネットワークに接続し、公開することもできます
ホストNICのポートを確認し、実際のクライアントIPがホストIPに着信するのを確認します。 私
これをtraefikリバースプロキシで使用して、traefikでクライアントIPトラフィックをログに記録します
それはバックエンドサービスに向けられています
https://github.com/BretFisher/dogvscat/blob/7e9fe5b998f2cf86951df3f443714beb413d63fb/stack-proxy-global.yml#L75-L83
これで、「本物のログを記録する」という私が見たほとんどのリクエストを解決できると思います。
IP」。

@PanJ https://github.com/PanJこれはあなたのためにそれを解決しますか?

重要なのは、ポートをモード:入力ではなくモード:ホストで公開することです(
ディフォルト)。

このモードの長所は、実際のクライアントIPとネイティブホストNICを取得することです。
パフォーマンス(IPVSカプセル化AFAIKの外部にあるため)。 短所はそれです
レプリカを実行しているノードでのみリッスンします。

私にとって、「入力IPVSルーティングを使用したいのですが、
クライアントIP」は、libnetworkの別の機能要求です。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451348906 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUzs15UVWOVl54FLwBJSZJKX-9D0jks5u_tLPgaJpZM4Jf2WK

@BretFisher mode: hostは回避策にすぎず、解決策ではありません。 @sandysによると、回避策には注意点がほとんどないため、この問題は修正されたと見なすべきではありません。

回避策が見つかったため、改善があるかどうかはわかりません。 私はかなり長い間Kubernetesに移動しましたが、この問題が2年以上続いていることにまだ驚いています。

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 私から
kubernetesに移行するステートメントでさえ適切ではありません
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。 あなたも
外部LBを持っているか、nginx入力プロキシのようなものを使用する必要があります
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは同じです
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰かができた
上記の提案されたtcpストリームソリューションを確認してパックし、
nginxプロキシの動作のようなもの。 ただ受け入れてください、その群れは
自分でカスタマイズ

PanJ [email protected] schrieb神父、4。2019年1月、9:28午前:

@BretFisher https://github.com/BretFisherモード:ホストは
回避策ですが、解決策ではありません。 @sandysとしてhttps://github.com/sandys
回避策にはいくつかの注意点があると述べたので、この問題を考慮すべきではありません
修正されたとおり。

回避策が行われているため、改善があるかどうかはわかりません
発見した。 私はかなり長い間Kubernetesに引っ越してきましたが、今でも
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451382365 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

dockerflowプロジェクトを拡張し、nginxバリアントを追加して開始することもできます
kubernetes-swarnのingressproxy。 間違いなくこれはすべて群れでいっぱいです
たくさんあることを知っているので、追加のシステムコンテナを調達します
kubernetesでそれらを。 スリムな資源のための群れの強さではありませんか
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、4。2019年1月、

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 私から
kubernetesに移行するステートメントでさえ適切ではありません
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。 あなたも
外部LBを持っているか、nginx入力プロキシのようなものを使用する必要があります
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは同じです
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰かができた
上記の提案されたtcpストリームソリューションを確認してパックし、
nginxプロキシの動作のようなもの。 ただ受け入れてください、その群れは
自分でカスタマイズ

PanJ [email protected] schrieb神父、4。2019年1月、9:28午前:

@BretFisher https://github.com/BretFisherモード:ホストは
回避策ですが、解決策ではありません。 @sandysとしてhttps://github.com/sandys
回避策にはいくつかの注意点があると述べたので、この問題を考慮すべきではありません
修正されたとおり。

回避策が行われているため、改善があるかどうかはわかりません
発見した。 私はかなり長い間Kubernetesに引っ越してきましたが、今でも
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451382365 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

これらは複雑なソリューションです-プロキシプロトコルはヘッダーを追加するだけです
情報であり、非常によく知られている標準です-haproxy、nginx、AWS elb、
などすべてがそれに続きます。 https://www.haproxy.com/blog/haproxy/proxy-protocol/

変更の表面積は、組み込みのSwarmに制限されます。
イングレス(このサポートが追加される場所)。 そして、すべてのサービスがそれを持っています
利用可能。

2019年1月4日金曜日、14:36 rubot < [email protected]は次のように書いています:

dockerflowプロジェクトを拡張し、nginxバリアントを追加して開始することもできます
kubernetes-swarnのingressproxy。 間違いなくこれはすべて群れでいっぱいです
たくさんあることを知っているので、追加のシステムコンテナを調達します
kubernetesでそれらを。 スリムな資源のための群れの強さではありませんか
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、4。2019年1月、

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 私から
kubernetesに移行するステートメントでさえ適切ではありません
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。 君は
また
外部LBを持っているか、nginx入力プロキシのようなものを使用する必要があります
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは同じです
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰かができた
上記の提案されたtcpストリームソリューションを確認してパックし、
nginxプロキシの動作のようなもの。 ただ受け入れてください、その群れは
自分でカスタマイズ

PanJ [email protected] schrieb神父、4。2019年1月、9:28午前:

@BretFisher https://github.com/BretFisherモード:ホストは
回避策ですが、解決策ではありません。 @sandysとしてhttps://github.com/sandys
回避策にはいくつかの注意点があると述べたので、これを考慮すべきではありません
問題
修正されたとおり。

回避策が行われているため、改善があるかどうかはわかりません
発見した。 私はかなり長い間Kubernetesに引っ越してきましたが、それでも
なれ
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451382365 、または
ミュート
スレッド
<
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451389574 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

私が言ったように、すでにプロキシを利用している上記のtcpストリームソリューションを確認してください
プロトコル。
プロキシプロトコルを追加するには、コンテナ内の構成も必要になります。
上流の群れに追加されました。 クリーナーと多分もっと良い以外に価値はありません
リクエストに文書化された目標

サンディープスリニヴァサ[email protected] schriebは神父、4 2019年1月です、
11:37:

これらは複雑なソリューションです-プロキシプロトコルはヘッダーを追加するだけです
情報であり、非常によく知られている標準です-haproxy、nginx、AWS elb、
などすべてがそれに続きます。 https://www.haproxy.com/blog/haproxy/proxy-protocol/

変更の表面積は、組み込みのSwarmに制限されます。
イングレス(このサポートが追加される場所)。 そして、すべてのサービスがそれを持っています
利用可能。

2019年1月4日金曜日、14:36 rubot < [email protected]は次のように書いています:

dockerflowプロジェクトを拡張し、nginxバリアントをに追加することもできます
始める
kubernetes-swarnのingressproxy。 間違いなくこれはすべて群れでいっぱいです
たくさんあることを知っているので、追加のシステムコンテナを調達します
kubernetesでそれらを。 スリムな資源のための群れの強さではありませんか
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、4。2019年1月、

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 私から
kubernetesに移行するステートメントでさえ適切ではありません
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。 君は
また
外部LBを持っているか、nginx入力プロキシのようなものを使用します。
しなければならない
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは同じです
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰かができた
上記の提案されたtcpストリームソリューションを確認してパックし、
nginxプロキシの動作のようなもの。 ただ受け入れる、その群れはする必要があります
なれ
自分でカスタマイズ

PanJ [email protected] schrieb神父、4。2019年1月、9:28午前:

@BretFisher https://github.com/BretFisherモード:ホストは
回避策ですが、解決策ではありません。 @sandysとして<
https://github.com/sandys>
回避策にはいくつかの注意点があると述べたので、これを考慮すべきではありません
問題
修正されたとおり。

回避策が行われているため、改善があるかどうかはわかりません
発見した。 私はかなり長い間Kubernetesに引っ越してきましたが、それでも
なれ
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451382365
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451389574 、または
ミュート
スレッド
<
https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451409453 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK

上記の解決策には、ホストモードバインディングが必要です。 それが大きな問題です。 それ
Dockerスケジューラーを使用してコンテナーを割り当てる可能性を排除します
別のホストへ-私はもはやメッシュネットワークの一部ではありません。

2019年1月4日金曜日、17:28 rubot < [email protected]は次のように書いています:

私が言ったように、すでにプロキシを利用している上記のtcpストリームソリューションを確認してください
プロトコル。
プロキシプロトコルを追加するには、コンテナ内の構成も必要になります。
上流の群れに追加されました。 クリーナーと多分もっと良い以外に価値はありません
リクエストに文書化された目標

サンディープスリニヴァサ[email protected] schriebは神父、4 2019年1月です、
11:37:

これらは複雑なソリューションです-プロキシプロトコルはヘッダーを追加するだけです
情報であり、非常によく知られている標準です-haproxy、nginx、AWS elb、
などすべてがそれに続きます。 https://www.haproxy.com/blog/haproxy/proxy-protocol/

変更の表面積は、組み込みのSwarmに制限されます。
イングレス(このサポートが追加される場所)。 そして、すべてのサービスが
それ
利用可能。

2019年1月4日金曜日、14:36 rubot < [email protected]は次のように書いています:

dockerflowプロジェクトを拡張し、nginxバリアントをに追加することもできます
始める
kubernetes-swarnのingressproxy。 間違いなくこれはすべて詰まっています
群れ
あなたがたくさんあることを知っているので、追加のシステムコンテナを上げるでしょう

kubernetesでそれらを。 スリムな資源のための群れの強さではありませんか
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、4。2019年1月、

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 私から
視点でさえ、kubernetesに移行するステートメントは
適切
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。 君は
また
外部LBを持っているか、nginx入力プロキシのようなものを使用します。
しなければならない
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは持っています
同じ
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰か
たぶん......だろう
上記の提案されたtcpストリームソリューションを確認してパックし、
nginxプロキシの動作のようなもの。 ただ受け入れる、その群れはする必要があります
なれ
自分でカスタマイズ

PanJ [email protected] schrieb神父、4。2019年1月、9:28午前:

@BretFisher https://github.com/BretFisherモード:ホストはのみ
NS
回避策ですが、解決策ではありません。 @sandysとして<
https://github.com/sandys>
回避策にはいくつかの注意点があると述べたので、考慮すべきではありません
これ
問題
修正されたとおり。

回避策があったので、改善があるかどうかはわかりません
その間
発見した。 私はかなり長い間Kubernetesに引っ越してきました
まだ
なれ
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451382365
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451389574 、または
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
>>


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451409453 、または
ミュート
スレッド
<
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451424992 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

私が言ったように、kubernetes nginxingressにはホストモードのバインディングも必要です。
デーモンセット。 外部LBはノードポートに接続します。ノードポートにはホストモードも必要です
稼働中、または稼働中のプロキシプロトコルを手動で構成します。 Kubernetes
それでも、同じ問題を扱います。
群れのための私の観点からの1つの可能な機能要求は
ネットワークプロバイダーをプラグ可能にします。 これにより、使用が可能になります
lvs / iptables以外のテクニック

サンディープスリニヴァサ[email protected] schriebは神父、4 2019年1月です、
13:05:

上記の解決策には、ホストモードバインディングが必要です。 それが大きな問題です。 それ
Dockerスケジューラーを使用してコンテナーを割り当てる可能性を排除します
別のホストへ-私はもはやメッシュネットワークの一部ではありません。

2019年1月4日金曜日、17:28 rubot < [email protected]は次のように書いています:

私が言ったように、すでにプロキシを利用している上記のtcpストリームソリューションを確認してください
プロトコル。
プロキシプロトコルを追加するには、コンテナ内の構成も必要になります
もしも
上流の群れに追加されました。 クリーナーと多分以外に価値はありません
より良い
リクエストに文書化された目標

サンディープスリニヴァサ[email protected] schrieb午前神父、4。1月
2019、
11:37:

これらは複雑なソリューションです-プロキシプロトコルは追加するだけです
ヘッダ
情報であり、非常によく知られている標準です-haproxy、nginx、AWS
エルブ、
などすべてがそれに続きます。
https://www.haproxy.com/blog/haproxy/proxy-protocol/

変更の表面積は、組み込みのSwarmに制限されます。
イングレス(このサポートが追加される場所)。 そして、すべてのサービスが
それ
利用可能。

2019年1月4日金曜日、14:36 rubot < [email protected]は次のように書いています:

dockerflowプロジェクトを拡張し、nginxバリアントをに追加することもできます
始める
kubernetes-swarnのingressproxy。 間違いなくこれはすべて詰まっています
群れ
あなたがたくさんあることを知っているので、追加のシステムコンテナを上げるでしょう

kubernetesでそれらを。 スリムな群れの強さではないですか
資源
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、2019年1月4日、
09:48:

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 から
僕の
視点でさえ、kubernetesに移行するステートメントは
適切
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。
君は
また
外部LBを使用するか、nginx入力プロキシなどを使用します
どれの
しなければならない
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは持っています
同じ
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰か
たぶん......だろう
上記の提案されたtcpストリームソリューションをチェックしてパックします
得る
nginxプロキシの動作のようなもの。 ただ受け入れる、その群れの必要性

なれ
自分でカスタマイズ

PanJ [email protected] schriebは神父、4 2019年1月です、
09:28:

@BretFisher https://github.com/BretFisherモード:ホストは
それだけ
NS
回避策ですが、解決策ではありません。 @sandysとして<
https://github.com/sandys>
回避策にはいくつかの注意点があると述べたので、考慮すべきではありません
これ
問題
修正されたとおり。

回避策があったので、改善があるかどうかはわかりません
その間
発見した。 私はかなり長い間Kubernetesに引っ越してきました
まだ
なれ
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
< https://github.com/moby/moby/issues/25526#issuecomment -451382365

また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451389574
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>>


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451409453 、または
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451424992 、または
ミュート
スレッド
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451426276 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK

そして明確にするために、上記のソリューションにはサービスの前にtcpストリームがあります
プロキシー。 したがって、あなたのリクエストは間違いなくバグではなく、機能のリクエストです。 と
この機能は、ネットワークモードで実装される場合、群れでのみ実装できます。
主な問題はNAT /ホストレベルでIPを失うことにあるため、変更します

Ruben Nicolaides [email protected] schrieb am Fr.、4。2019年1月、13:11:

私が言ったように、kubernetes nginxingressにはホストモードのバインディングも必要です。
デーモンセット。 外部LBはノードポートに接続します。ノードポートにはホストモードも必要です
稼働中、または稼働中のプロキシプロトコルを手動で構成します。 Kubernetes
それでも、同じ問題を扱います。
群れのための私の観点からの1つの可能な機能要求は
ネットワークプロバイダーをプラグ可能にします。 これにより、使用が可能になります
lvs / iptables以外のテクニック

サンディープスリニヴァサ[email protected] schrieb午前神父、4。1月
2019、13:05:

上記の解決策には、ホストモードバインディングが必要です。 それが大きな問題です。 それ
Dockerスケジューラを使用して割り当てる可能性を排除します
コンテナ
別のホストへ-私はもはやメッシュネットワークの一部ではありません。

2019年1月4日金曜日、17:28 rubot < [email protected]は次のように書いています:

私が言ったように、すでにプロキシを利用している上記のtcpストリームソリューションを確認してください
プロトコル。
プロキシプロトコルを追加するには、コンテナ内の構成も必要になります
もしも
上流の群れに追加されました。 クリーナーと多分以外に価値はありません
より良い
リクエストに文書化された目標

サンディープスリニヴァサ[email protected] schrieb午前神父、4。1月
2019、
11:37:

これらは複雑なソリューションです-プロキシプロトコルは追加するだけです
ヘッダ
情報であり、非常によく知られている標準です-haproxy、nginx、AWS
エルブ、
などすべてがそれに続きます。
https://www.haproxy.com/blog/haproxy/proxy-protocol/

変更の表面積は、組み込みのSwarmに制限されます。
イングレス(このサポートが追加される場所)。 そして、すべてのサービスは
持ってる
それ
利用可能。

2019年1月4日金曜日、14:36 rubot < [email protected]は次のように書いています:

dockerflowプロジェクトを拡張し、nginxバリアントをに追加することもできます
始める
kubernetes-swarnのingressproxy。 間違いなくこれはすべて詰まっています
群れ
あなたが知っているように、追加のシステムコンテナを調達します


kubernetesでそれらを。 スリムな群れの強さではないですか
資源
無駄のないプロジェクト?

Ruben Nicolaides [email protected] schrieb am Fr.、2019年1月4日、
09:48:

なぜこれがバグだと人々が考えるのか、私はまだちょっと驚いています。 から
僕の
視点でさえ、kubernetesに移行するステートメントは
適切
答え。 私が見るように、kubernetesにはまったく同じ問題/動作があります。
君は
また
外部LBを使用するか、nginx入力プロキシなどを使用します
どれの
しなければならない
デーモンセットとして実行します。 私が間違っている場合は私を訂正してください、しかし私たちは持っています
同じ
ここでは正確な状況ですが、ここでは準備された自動解決策はありません。 誰か
たぶん......だろう
上記の提案されたtcpストリームソリューションをチェックしてパックします
得る
nginxプロキシの動作のようなもの。 ただ受け入れる、その群れ
する必要があります
なれ
自分でカスタマイズ

PanJ [email protected] schriebは神父、4 2019年1月です、
09:28:

@BretFisher https://github.com/BretFisherモード:ホストは
それだけ
NS
回避策ですが、解決策ではありません。 @sandysとして<
https://github.com/sandys>
回避策にはいくつかの注意点があると述べたので、考慮すべきではありません
これ
問題
修正されたとおり。

回避策があったので、改善があるかどうかはわかりません
その間
発見した。 私はかなり長い間Kubernetesに引っ越してきました
まだ
なれ
この問題が2年以上も続いていることに驚いた。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
<
https://github.com/moby/moby/issues/25526#issuecomment-451382365>、
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451389574
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAEsU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>>


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451409453
また
ミュート
スレッド
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>>


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451424992 、または
ミュート
スレッド
<
https://github.com/notifications/unsubscribe-auth/AAEsU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-451426276 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK

  1. そのような長いスレッドの後、私は完全な例で現在の機能セットを文書化しようとしていました。
  2. OPのリクエストにあなたの特定のニーズは見当たりません。 @PanJは、クライアントIPをどうかを確認するように依頼しました。これは、2018年半ばの時点で実行できます。 入力ルーティングメッシュも使用する必要があるとは思いません。

それをバグと呼んでも機能要求と呼んでも、ソースNATのない入力メッシュは(私の意見では)不可欠です。 本当のソースIPを見ることができないと壊れてしまうアプリケーションはたくさんあります。 もちろん、Webサーバーの場合は、ホストノードを使用してリバースプロキシを実行し、クライアントIPヘッダーを追加できます。 ただし、これによりオーバーヘッドが追加され、Webベース以外のアプリケーションのオプションではない可能性があります。 パケットの実際の送信元IPが正しいことを実際に必要とするアプリケーションでは、唯一のオプションは入力メッシュを使用しないことです。 それは、そもそも群れを使用することの利点の大部分を捨てます。

この問題が修正されたかどうかをお知らせください。
代わりにkubernetiesを使用する必要がありますか?

同じ問題が発生しました...現時点では修正が見つかりません。

誰かがこの行動の解決策を見つけたら、ここに報告してください。

ありがとう!

同じ問題があります。 Apache httpdサーバーがあり、リクエストを受信して​​いる国に関する統計を後で抽出するために、すべてのアクセスをログに記録したいと思います。

php:apacheがホストヘッダーフィールドを正しくログに記録しなかった理由を理解しようとしたときに、私はこの問題に自分で遭遇しました。 私はショックを受け、これが何年も経ってもまだ機能していないことに失望しています。 ホストフィールドがユーザーランドプロキシIPをログに記録し続ける場合、WebホスティングにSwarmモードをどのように使用する必要がありますか? スウォームモードでこれを回避する方法を見つけることができませんでした。 Classic Swarm(コンテナベース)やConsulのようなものを使用できると思いますが、それは逆行しているように感じます。

私は自分のシナリオに受け入れられる解決策を見つけました:

services:
  server:
    image: httpd:2
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    networks:
      - my_second_service
      - another_great_software

これにより、apacheはオーバーレイネットワークの背後ではなくホストコンピューターでリッスンします(適切なリモートIPアドレスを読み取ります)が、 networksオプションを介して他のサービスにリクエストをプロキシし、それを使用することで「高可用性」を実現します。どこでも実行

@ rafaelsierra-これが私が抱えている問題です(そして私が間違っている場合は修正してください)が、この構成では1つのApache / PHPコンテナーのみが実行され、ホストノードのポート80にバインドできます。 Nginxコンテナをポート80/443にバインドして、たくさんのApacheコンテナを実行し、それらを仮想ホストする必要があります。

@SysEngDanはい、確かに80/443ポートにバインドできるコンテナは1つだけですが、このポートにバインドするコンテナは他のコンテナへのすべてのリクエストのプロキシのみを担当するため、私の場合は問題ありません。オーバーレイネットワークの背後で実行されています。

単一のnginx / Apacheコンテナがすべてのリクエストを受信し、vhostに基づいて適切なコンテナにプロキシすることで、おそらく同じソリューションを使用できます。これらのコンテナはホストにバインドする必要はありません。

@ rafaelsierra-よろしくお願いします。このチケットに記載されている問題を理解しているかどうかはわかりません。 前の段落で述べたようにサービスを構成すると、問題は、クライアントIPがオーバーレイネットワークでのみリッスンしているコンテナーに渡されないことです。 ホストに直接バインドする場合、問題ではありません。 外部(ホスト)から内部(オーバーレイ)へのドッカーネットワークプロキシに依存している場合、宛先Apacheコンテナは元のクライアントIPアドレスではなく、プロキシのIP(ドッカーネットワークから)を受け取ります。

@SysEngDan私はこの問題を理解していますが、過去2年間は解決策がないため(正直なところ、これが「修正可能」かどうかはわかりません)、自分のニーズに合った別の解決策を考え出す必要がありました(アクセスを制限する)リモートIPアドレスに基づく)。

単一のコンテナーがホストのポート80/443でリッスンし、他のコンテナーにプロキシする(この問題の範囲外であるため、言及しなかった適切なHTTPヘッダーを使用する)ことで問題が解決し、このソリューションを共有したいと思いました。オーバーレイされたネットワークがリモートIPアドレスを渡すことができないために同様の問題に直面している人々のために

ああ、あなたがそこで何をしたかわかります.....すみません、私はそれを逃しました。 オーバーレイネットワークを切り取り、代わりに外部向けコンテナをサービスネットワーク(ネットワークを指定せずに新しいサービスを開始すると自動的に作成されるもの)に直接接続します。 わかりました、それはうまくいくと思います。 追加されたオーバーヘッドは、docker-composeファイルにサービスネットワークを追加するタスクです。 ホストコンテナが起動し、それらのサービスの1つが利用できない場合はどうなるのでしょうか?

その場合、502を取得します。

docker-compose.ymlが1つもありません。オーバーレイされたネットワークを介して相互に通信する複数のサービスを備えた複数のスタックがあり、ホストサーバーにバインドしているが、引き続きアクセスできる公開サービスがあります。他のすべてのオーバーレイネットワーク。すべてのリクエストをプロキシできます。

ホストモードの回避策は、この問題についてすでに何度も議論されています。 一部の限られたシナリオ(特定のリバースプロキシWebトラフィックの設定など)では問題ない場合がありますが、この問題の一般的な解決策ではありません。 同じ「ソリューション」をもう一度ハッシュするのではなく、以前の投稿を読んでください。

@darrellennsここには200以上のコメントがあります。公式の解決策が提供されていない場合でも、基本的な「適用される場合はホストバインドを使用する」ソリューションを提供して、この問題をロックしてクリーンアップする方がよいと思います。そうしないと、私のような多くの人が見逃してしまいます。それと同じものを何度もコメントし続ける

したがって、このバグは、ipsをホワイトリストに登録するtraefiksの機能に影響を与えると思います。 あれは正しいですか?

とにかく、スウォームモードを実行しようとしている人にとって、これはホストモードを使用してポートを公開する例です。

docker service create \
--name traefik \
--constraint=node.role==manager \
--publish mode=host,target=80,published=80 \
--publish mode=host,target=443,published=443 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/home/$USER/dev-ops/logs,target=/dev-ops/logs \
--mount type=bind,source=/opt/data/traefik/traefik.toml,target=/traefik.toml \
--mount type=bind,source=/opt/data/traefik/acme.json,target=/acme.json \
--network traefik \
--label traefik.frontend.rule=Host:traefik.example.com \
--label traefik.port=8080 \
traefik \
--docker \
--docker.swarmMode \
--docker.watch \
--docker.exposedByDefault

@coltenkrauterそれが何に影響するか正確にはわかりませんが、ホストモードではtraefikサービスのレプリカを1つしか実行できず、それが私だけではないと思います。 このように、サービスのスウォームモード機能を中継せずに、traefikの安定性を完全に信頼する必要があります。

また、最初に報告されたように、traefikの特別なニーズとはあまり関係がなく、元のIPを受け取らない汎用httpサービスでテストされました。つまり、docker swarmモードが壊れています(この重要な機能がありません)。誰も気にしないようです。

そして、私はこのことについてコメントし続けたいと思います。なぜなら、noisがそれを修正したい誰かを邪魔していることを願っています:)(申し訳ありませんが、それは私のユーザーからの私にも同じです)

ホストモードでは、traefikサービスのレプリカを1つしか実行できず、それが私だけではないと思います。 このように、サービスのスウォームモード機能を中継せずに、traefikの安定性を完全に信頼する必要があります。

ホストごとに1つのインスタンスを実行できます

ホストモードでは、traefikサービスのレプリカを1つしか実行できず、それが私だけではないと思います。 このように、サービスのスウォームモード機能を中継せずに、traefikの安定性を完全に信頼する必要があります。

ホストごとに1つのインスタンスを実行できます

ya、しかし、traefikは正しく動作するためにこれを必要とするので、マネージャノードで動作することを余儀なくされます。 つまり、1つのマネージャーノード、1つのホスト、1つのインスタンス

traefikは、
dockerソケットプロキシ、リモートソケット、またはtraefikエンタープライズ。 これが
その方法のスタックファイルの例:
https://github.com/BretFisher/dogvscat/blob/master/stack-proxy-global.yml

17:25ダニエルCrucianiで土、2019年3月16日には[email protected]
書きました:

ホストモードでは、traefikサービスのレプリカを1つしか実行できませんが、実行できません。
それは私だけだと思います。 このように私はtraefikの安定性を完全に信頼しなければなりません
サービスのスウォームモード機能を中継せずに。

ホストごとに1つのインスタンスを実行できます

ya、しかしtraefikはこれを必要とするのでマネージャーノードで動作することを余儀なくされます
正しく動作します。 つまり、1つのマネージャーノード、1つのホスト、1つのインスタンス


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-473593956 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAwW31DHIwEJE1EqN3-8qj44WopocuQTks5vXWE_gaJpZM4Jf2WK

それを知るのは興味深いですが、この機能はkubernetesで利用できますが、docker swarmモードでは利用できません。また、traefikの複数のインスタンスを実行するオプションがあると主張していますが、複数のインスタンスを実行する場合は、複数のノードで実行します。単一ノードの場合、これはサポートされていないため、不可能です。
また、リクエストをプロキシするだけでなく、他のサービスはポートをマップできません。これは、すべてのホストをポートにマップする必要がある特別な種類の構成が必要であり、とにかく、インスタンスごとに少なくとも1つの複数のノードが必要だからです。 。

などなど。 このディスカッションを上にスクロールして、それに関する他のディスカッションを見つけることができます。 回避策を維持するのが難しく、従うのが難しいので、回避策を作成するのがどれだけ良いかというデモストレーションに還元できるとは思いません。 そして、特別な場合の回避策を維持するために費やされるすべての時間は、問題を修正するためによりよく費やされます。

一方、この種の機能がdocker swarmのモデルのセキュリティ問題である場合は、wontfixとしてマークするだけで、kubernetesに切り替える予定です。その場合は、プロジェクト間で競合はないと思います。明示的には決して起こらないと言っているだけなので、可能であれば、あらゆる種類のノードスウォームにドッカースウォームモードを選択する前に、誰でもアクションを実行できます。

kubernetesには、群がっていない機能がたくさんあります。その逆も同様です。 私たちは皆、機能を含む多くの要因に基づいて、特定のソリューションにどのオーケストレーターを使用するかを決定します。 すべての問題/ニーズを解決するツールはありません。

私はただ助けようとしているコミュニティメンバーです。 この問題の現在の解決策が気に入らない場合は、おそらくkubernetesなどを使用して、他の方法で解決する必要があるようです。 kubernetesで解決する方法が自分の好みに合っていると思う場合は、これが1つのオーケストレーターを別のオーケストレーターよりも選択する合理的な理由です。

歴史的に、mobyとswarmのメンテナは、このような問題をwontfixとしてクローズしません。これは、明日、コミュニティの誰かがこの問題の解決策を含むPRをドロップする可能性があるためです。 また、それまでそれを回避する方法を議論することは、この問題スレッドの有効な使用法だと思います。 :)

群れのメンテナではありませんが、歴史的に、チームは、リポジトリでコミットを取得している現在のPRを超えて、将来の機能計画を開示していないと言えます。

もちろんあなたのコメントは歓迎されると言うのを忘れました(または私はそれをあいまいな方法で言いました、ごめんなさい)。 しかし、私は元の@PanJレポートを補強し

それまでの間、スウォームモードの外でプロキシコンテナを実行し、スウォームモードで公開ポートに転送するという回避策を実行する必要があると思います(SSL終了はこのコンテナでも実行する必要があります)。これにより、スウォームの目的が損なわれます。自己修復とオーケストレーションのためのモード。

これは、もちろんこの特定のトピックについてのみ、「スウォームモードの目的を破る」ことを意味しますが、もっと注意を払う価値があります。

チームにプロキシプロトコルを追加するPRを構築させようとしています
入力ネットワーク。 私たちはGolangプログラマーではないので、少しわかります
トリッキー。

しかし、私はDockerチームが最高かつ最も
互換性のある(エコシステム全体の)ソリューションは、プロキシプロトコルを階層化することです
入力ネットワークのサポート。

複雑さは、入力ネットワークが必要なだけではないという事実にあります
独自のヘッダーを挿入しますが、存在する可能性があるという事実をサポートする必要があります
すでに挿入されているアップストリームプロキシプロトコルヘッダー(たとえば、GoogleLBまたは
AWS ELB)。

2019年3月17日、日曜日、12:17 Daniele Cruciani、 notifications @ github.com
書きました:

もちろんあなたのコメントは歓迎されると言うのを忘れました(または私はそれを
あいまいな方法、申し訳ありません)。 しかし、私は元の@PanJを強化するのが好きです
https://github.com/PanJレポート:

その間、私は実行している回避策を実行する必要があると思います
スウォームモード外のプロキシコンテナを公開ポートに転送します
スウォームモード(SSLターミネーションもこのコンテナで実行する必要があります)では、
自己回復とオーケストレーションのためのスウォームモードの目的を破ります。

これは「スウォームモードの目的を破る」という意味です。もちろんこれだけです。
特定のトピックは、もっと注意を払うに値するのに十分です。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-473621667 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUwNWJsGKlLejcNzS2pR0awBB4OVlks5vXeTugaJpZM4Jf2WK

https://stackoverflow.com/questions/50585616/kubernetes-metallb-traefik-how-to-get-real-client-ip
階層化され、完全に構成可能なk8sを求められたように

docker swarmを使用してdigitaloceanでnginxを実行し、nginxログ内で10.255.0.2だけでなく実際の$remote_addrを取得しようとしている人のために。 @coltenkrauterのソリューションを使用できます。 キャッチは、あなただけのほとんどの人々のために[OK]をする必要があり、この溶液でホスト上の1個のnginxのコンテナを実行することができるということです。

docker-compose.ymlファイルを変更するだけです。

正しくない

services:
  nginx:
    ports:
      - "80:80"
      - "443:443"

正しい

services:
  nginx:
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

_編集:今、私たちは皆、正しい答えを得ることが保証されています_

問題がイングレスネットワークで発生すると問題が述べている場合、イングレス( mode: host )を使用しないことは回避策ではあり
リバースプロキシとして単一のホストだけを使用する人は誰もいません。 フローティングIPを持つ複数のホストが必要であり、この設定を実現するにはswarm-meshが必須です。

不可能かもしれませんが、 INGRESSチェーンのある段階でMASQUERADEを実行するようにiptablesルールを変更すると、実際のソースIPが保持されるように回避策になると思いました。 iptables / netfilterの専門家はいないのですか?

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-INGRESS  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         

Chain DOCKER-INGRESS (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

別の方法として、元のソースIPを取得してX-Forwarded-Forヘッダーを作成するだけで群がることはできませんか?

リバースプロキシとして単一のホストだけを使用する人は誰もいません。 フローティングIPを持つ複数のホストが必要であり、この設定を実現するにはswarm-meshが必須です。

群れの各ノードは、リバースプロキシのインスタンスを実行し、オーバーレイネットワークを介して基盤となるサービスにトラフィックをルーティングできます(ただし、プロキシのみが元のIPアドレスを認識します)。

スレッド全体を必ず読んでください(GitHubはかなりの有用なコメントを隠しているので、それらを展開する必要があります:dispointed :);

別の方法として、元のソースIPを取得してX-Forwarded-Forヘッダーを作成するだけで群がることはできませんか?

https://github.com/moby/moby/issues/25526#issuecomment-367642600を参照してX-Forwarded-ForはL7プロトコルです。 群れの侵入はL4であり、DNATでIPVSを使用します

@ port22は、一般的に、我々はこの問題を回避するには解決策ではないことに同意し、解決策は、それがlayerable作る@sandysが上で提案を確認することです#25526コメント

別の方法として、元のソースIPを取得して作成するだけで群がることはできません

X-Forwarded-Forヘッダー?
#25526(コメント)を参照
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-ForはL7プロトコルです。 群れの侵入はL4であり、DNATでIPVSを使用します

ここでの正しい解決策は、L4で注入されたプロキシプロトコルです。 幾つかある
同じユースケースについてのEnvoyでの関連する賛否両論の議論
https://github.com/envoyproxy/envoy/issues/4128および
https://github.com/envoyproxy/envoy/issues/1031

2019年4月10日水曜日午前1時40分Sebastiaanvan Stijn <
[email protected]>は次のように書いています:

リバースプロキシとして単一のホストだけを使用する人は誰もいません。 複数欲しい
フローティングIPを持つホストであり、これを実現するにはswarm-meshが必須です。
設定。

群れの各ノードは、リバースプロキシのインスタンスを実行し、ルーティングできます
オーバーレイネットワークを介した基盤となるサービスへのトラフィック(ただし、
プロキシは元のIPアドレスを知っています)。

スレッド全体を必ず読んでください(GitHubはかなり便利なものを隠しているようです
コメントなので、それらを拡張する必要があります😞);

別の方法として、元のソースIPを取得して作成するだけで群がることはできません
X-Forwarded-Forヘッダー?

#25526(コメント)を参照
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-ForはL7プロトコルです。 群れの侵入はL4であり、DNATでIPVSを使用します


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-481415217 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsU5KdnWQ21hJx_xzc-QROJiWbAlulks5vfPOigaJpZM4Jf2WK

群れの各ノードは、リバースプロキシのインスタンスを実行できます

これにより、スウォームロードバランサーの機能が排除されます。これは、実際にはその問題のすべてです。
そして、具体的に言うと、traefikはクラスターアジャイルではないというのが私の問題です。 構成バックエンドとしてconsulを使用している場合を除き、スタンドアロンで実行する必要があります。これにより、最大証明書が最大100に制限されますが、これは私には適用されません。 確かに、これは群れの問題ではなく、traefikの問題であると言うことができます。 おもしろい事実:traefikは、これは領事の問題であると述べています。 領事はこう述べています:traefikはそれを間違っています。

@ port22一般的に、回避策は解決策ではないことに同意します

私のポイントは、イングレスが必要な場合、イングレスを使用しないことは回避策ではないということです。 回避策は、ハッキングが必要な場合でも、ソースIPを保持しながらswarmロードバランサーを使用できるようにするものです。

DNATでIPVSを使用する

したがって、私はそれがDNATルール/チェーン内のMASQUERADEで実行できると考えていました。 ?

@ port22わかりましたが、
ブリッジネットワークhttps://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interfaceのようなオプションがあるはずです
したがって、これを簡単にセットアップできるようにするためですが、それでも主な問題は、オーバーレイネットワークでのサポートの欠如です。 したがって、オプションは無視されるため、オプションはありません。dockerdは、外部から変更された場合にルールを書き換えます。

を解決するためにプロキシプロトコルサポートの機能リクエストを提出しました
このバグの問題。

誰かがコメントを追加したい場合に備えて。

https://github.com/moby/moby/issues/39465

2019年4月10日水曜日、21:37 Daniele Cruciani、 notifications @ github.com
書きました:

@ port22 https://github.com/port22私はあなたの主張を理解しましたが、
そのネットワーク自体で、私はそれを海岸壁で動作させるように試みましたが、
唯一の方法は、Dockerルール/チェーンの例外を作成することであり、私にはありませんでした
Dockerスウォームモードでの成功(ただし、スウォームモードのDockerでは問題ありません。
これまでのところ、群れにぶつかっているサービス以外のすべてのサービスを無効にしています)
たぶん、ブリッジネットワークのようなオプションがあるはずです
https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
したがって、これを簡単にセットアップできるようにするためですが、それでも主な問題は
オーバーレイネットワークのサポートがありません。 したがって、オプションはありません。
それらは無視され、dockerdはから変更された場合にルールを書き換えます
外。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526#issuecomment-481754635 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAEsUxsVQ7m9uiYbHhNKMMtkhTZV6iTNks5vfgwygaJpZM4Jf2WK

3年後、修正はありませんか?

私も同じ問題を抱えていますが、haproxyに問題があります。 プロキシサーバーをホストモードにし、HAでキープアライブを使用することは問題ありませんが、欠落している部分は負荷分散だけであり、単純なWebプロキシではそれほど問題にはならないと思います。 複雑なスクリプトが含まれているか、プロキシとバックエンドが同じ物理マシン上になく、ネットワークトラフィックが1つのNICに対して高すぎる場合を除き、...

では、内部オーバーレイネットワークのプライベートアドレスではなく、Docker Swarmの外部からのリクエストの送信元IPアドレスを確認することは本当に不可能ですか? まだ?

@thaJeztah Docker Incチームの誰かが、この問題のステータスについて更新してくれますか? それはまだ検討および/または取り組んでいますか? ETAはありますか? または、DockerがKubernetesと統合されているため、これは完全に無視されますか? それはほぼ3年前に報告されています:/

@thaJeztah https://github.com/thaJeztah DockerIncの誰かができますか
チームは、この問題のステータスについて更新します。 まだ検討中ですか
および/または取り組んだ? ETAはありますか? または、Docker以降、これは完全に無視されますか?
Kubernetesとの統合? それはほぼ3年前に報告されています:/

私が完全にできるように、このステートメント(「修正されない」)を取得するのは本当に良いことです
kubernetesへの移行を正当化します。 残念だ。

ありがとう。

>>

たぶん彼らはツイッターで返信するだろうか?

https://twitter.com/suretec/status/1160496779386904576?s=19

これを修正する必要がある拡張リクエストが提案されています-https://github.com/moby/moby/issues/39465

そこにあなたの考えやコメントを追加してください

私はすでにその問題についてコメントしています:-)

これは私にとってしばらくの間ブロッカーでした。 私はIPアドレスを通過する必要があり、多くの検索(このスレッドで他の人と一緒に検索してほぼ3年になります...)の後、swarmで実行可能なソリューションはまだ見つかりませんでした。

この問題のため、本番環境でswarmを使用できませんでした。これを追加できるかどうかについては、正式な回答を待っています。 これが追加されていない場合は、代替の提案されたソリューションを歓迎します。

haproxyの背後にあるtraefikを使用して同じ問題が発生しています。 2016年以来、これには254件のコメントがあるのを見て驚いた。

@Betriebsrat traefikがリクエストをすぐに処理できないようにするのはなぜですか? haproxyは本当に必要ですか、それとも単なる習慣ですか? traefikをホストモードで公開すると、クライアントのIPアドレスが表示され、すべてが正常になります:)

この「解決策」は何度か言及されたと思いますが、人々はそれを見逃し続けています。

私はそれが時々オプションではないことも知っています、しかし私はほとんどの場合これが可能であるはずだと信じています。

@ajardan私が試した解決策は、フロントエンドで応答するホストが1つ以上あるため、実行できません。 理想的には、群れ全体がリクエストをルーティングできるようにしたいです。 小規模な操作の場合、1つのサービスをhostモードに切り替えて、それを取り込みサーバーとして使用するだけで問題なく機能することに同意します。

traefikのようなものをホストモードに配置すると、ほとんどの場合、群れを使用することで利用しようとしている利点が無効になります:(

@pattonwebzホストモードは、複数のホストで複数のコンテナーを実行するサービスに対して有効にできます

このセットアップをグローバルモードのサービスで使用しましたが、マネージャーノードに限定されており、数万のリクエストに対して完全に正常に機能していました。

詳細が必要な場合は、詳しく説明させていただきます。

@ pattonwebz @ ajardanこれらすべての場合に構成可能なhaproxyサービスを使用してい

@pattonwebz上記の@ajardanのソリューションに加えて、ホストネットワークを使用してグローバルモードでhttps://hub.docker.com/r/decentralize/swarm-tcp-proxyを実行し、インバウンドトラフィックにPROXYプロトコルサポートを追加できます。次に、プロキシプロトコルヘッダーをデコードするように構成されたTraefikに転送します。

これは、Docker Swarmの一部としてのフラグであり、これらすべてではありません。
複雑なソリューション私見。

haproxyを使用して、証明書を管理し、SSLをオフロードします。
「実行はホストモード」という解決策は解決策ではないということを人々は見逃し続けています。
Dockerの負荷分散を活用するために、入力ネットワークと連携することを望んでいます。
スレッド全体は基本的に「ホストモードを使用する」->「3年間続く「理由」サークルのために不可能です。

ここでも実行可能な代替手段としてswarm-tcp-proxyを検討しますが、過去に同様のことを検討すると、そのようなアイデアを持った私にとっては常に何かが取引のビーカーになってしまいます。

完璧な世界では、私の既存の(そして実際のクライアントIPを取得する機能がないことを除いてうまく機能している)群れは、追加のサービスレイヤーやプロキシを超えるプロキシを必要とせずに、IPデータを処理して通過するだけです。

「実行はホストモード」という解決策は解決策ではないということを人々は見逃し続けています。

それ自体は解決策ではありませんが、回避策として非常にうまく使用できます(そして使用されています)。 Dockerのネイティブロードバランサーは引き続き使用できます。Dockerのサービスメッシュにアクセスする前に、ホストネットワークスタックにレイヤーを追加するだけです。

@Betriebsrat traefikは証明書とSSLを非常にうまく実行できるので、なぜそれが必要なのかまだわかりません。

また、前に@matthanleyが述べたように、

これはサービスごとに構成可能であるため、非常に柔軟です。

Dockerスウォームクラスターの外部に別のNginxサーバーを設定し、リクエストをスウォームサービスに転送することができます。 このNiginxconfには、フォワードヘッダーを追加するだけです。 例えば。
位置 / {
proxy_pass http:// phpestate;

    #Proxy Settings
    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;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

DockerSwarmモードで実際のクライアントIPを取得するソリューションはないようです。

同じ問題を確認し、次の実装によって回避しました。
https://github.com/moby/moby/issues/25526#issuecomment -475083415

単一のノードで複数の入力コンテナを実行することはできないため、これは理想的ではないソリューションです(現在はグローバルであると推測されます)

難しいのは、DockerがTCP / UDPを処理することですが、これはHTTPプロトコルの問題です。 少なくとも、DockerがソースIPをリモートホストとして「偽造」するのではなく、Swarm Meshから独自の内部IPを提供することを望みます...しかし、リターントラフィックが間違った場所に送られるため、問題が発生する可能性があります。

最も簡単な方法は、すべてのhttpリクエストに対して元のIPのヘッダーを追加することです。

正しい。 具体的には、l4で機能するプロキシプロトコルヘッダーとして
およびl7であり、ほとんどの既知のアプリケーションソフトウェア(および
ビッグクラウドプロバイダー)。

私はそのために別のバグを提出しました、それはいくつかのコメントにリンクされています
その上。 興味があれば、そのバグに追加してください

2019年9月5日木曜日、18:56 Vladimir、 notifications @ github.comは次のように書いています。

最も簡単な方法は、すべての元のIPのヘッダーを追加することです。
httpリクエスト。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/moby/moby/issues/25526?email_source=notifications&email_token=AAASYU7APUNJPLZ6AJ6XXMDQIECIJA5CNFSM4CL7MWFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAASYU4VZGKUFLL5STZ44GDQIECIJANCNFSM4CL7MWFA

その2019とこれはまだ問題ですか? それはtraefikのipホワイトリストを苦痛にします。 すべてのノードにホストポートが必要なわけではありません。

@kaysond私たちの立場はSwarmをあきらめることでした。 AWSとECSに移行しています。 申し訳ありませんが、これ以上建設的なものを投稿することはできませんが、最終的には機能するものが必要です。 これは、私たちに影響を与える唯一の主要なSwarmバグ(または機能の欠如)ではなく、他の人はここ数年で明らかな修正/フィードバックを受けていません。 最も残念ですが、そこにあります。

@jmkgreen私たちは同じ立場にあり、この問題がまだ続いているため、過去6か月以上にわたって

回避策の問題は何ですか? ホストモード+グローバルでサービスを宣言し、すべてのノードにヒットするようにLBを設定します。これは機能します。 プロキシは軽量であるため(httpsオフロードなどを行うためnginxを使用します)、すべてのサーバーにデプロイされているという事実は、サーバーリソースの1%未満しか使用しないという問題ではありません。 プロセス中にエラーが発生した場合は、私がお手伝いします([email protected])。

回避策の問題は何ですか? ホストモード+グローバルでサービスを宣言し、すべてのノードにヒットするようにLBを設定します。これは機能します。

@RemiBouプロキシ自体を更新/再起動する必要がある場合、外部ロードバランサーは停止をすぐには検出せず、プロキシがまだ再起動しているノードにリクエストを送信し続けます。 したがって、外部LB構成に応じて、最大30秒の停止が発生します。

また、Swarmには、サービス更新プロセスにフックを入れて外部ロードバランサーを呼び出し、更新中にノードをサービス停止にする方法はありません。 また、更新される前にスクリプトをトリガーしてコンテナー内で実行することもできません(たとえば、「 i_am_healthy 」フラグを削除し、外部LBにポーリングによってサービスが停止していることを検出させる)。

回避策の問題は何ですか?

私の問題は、その回避策では、ホスト上で同じサービスのいくつか(または同じポートを必要とするいくつかのサービス)を実行することが不可能であるということです。 それは私が取り組んでいるプロジェクトの必要性です。

確かに、しかし、これだけを実行し、IPが群れの中にあるときにプロキシサービスをデプロイすることはできません。httpヘッダーとして他のサービスに転送できますか?

確かに、しかし、これだけを実行し、IPが群れの中にあるときにプロキシサービスをデプロイすることはできません。httpヘッダーとして他のサービスに転送できますか?

はい...そして、そのシンプロキシサービスを再構成または更新する必要がない限り、ダウンタイムを回避するために、SwarmLBを使用してその背後にあるコンポーネントを更新することができます。

誰かがhttps://hub.docker.com/r/decentralize/swarm-tcp-proxyを指しており、haproxyを使用してそれを実行しています。

でもちょっと苦痛。 また、プロキシを更新する必要がある場合でも、ダウンタイムが発生します。

@ ms1111 Nginx

回避策の問題は何ですか?

この場合、この回避策と、ホストに公開されているポートを特定のIPアドレスにバインドできないことの組み合わせです。 代わりに、実際の訪問者のIPを必要とし、PROXYプロトコルをサポートするすべての内部サービスでは、ホストの0.0.0.0にポートが公開されていますが、これは最適とは言えません。

もう1つは、1秒あたり数百の新しい接続がある場合の無視できないパフォーマンスヒットです-公開されているすべてのポートは、実際にはconntrackを必要とするiptablesのDNATルールであり、他の問題があります(k8sもヒットしますが、Swarmにはこれがあります)それを悪化させるNATの追加レベル)。

Dockerに、

起きろ! この問題に関与している人の数を考えると、明らかな問題があります(同じ原因を持つ他の人がいます)。 私たちが得ているのは、回避策が解決策ではない理由が何度も説明されているにもかかわらず、回避策があることを何度も繰り返す人々だけです。 「回避策」という言葉は、それが一時的なものであり、後で解決されることを示しています。 問題が作成されてから3年以上が経過し、その間ずっと「回避策があります」という応答が返されます。

すべてのSwarmユーザーに、

現実的にしましょう。 悲しい真実は、Dockerを含め、誰もSwarmを本当に気にかけていないということです。 誰もがk8sに移行し、Swarmへの「実際の」投資はありません。 プロジェクトは生命維持のために死ぬのを待っているので、この問題が修正されることを期待しないでください。 スマートになり、k8sに移行します。

この問題はあまりにも長い間無視されているようです。 実装されることはないようです。 追いかけっこをしてk8sを使用するだけです。

@leojonathanoh k8sがこの特定の問題をどのように正確に解決するかを詳しく説明していただけますか:)?

シンプル:プロキシプロトコル

@ajatkj言ったように。 または、それが不可能な場合は、外部ロードバランサーとServiceリソースのexternalTrafficPolicy: Local 。 ここで言うのはそれだけです。 そして、私はスレッドから退会しています。

なぜ人々は他の人々が彼らのために仕事をすることを期待するのですか?

私はヒーローになりたいと思っていますが、実際には他の多くのことに取り組んでおり、これは私の日々には影響しません。 これはあなたの日々に影響を与えますか? これを解決するためのサポートが必要です。

私もこれを何度も見てきましたが、魔法の群れルーティングが使用しているIPVSNATでこれを機能させる方法は実際にはないようです。

ここでは、k8sの方がはるかに柔軟であることに同意します。 それがあなたのニーズによりよく合うならば、それを使ってください。
修正されていないことを訴え、k8sに切り替えると脅迫することは、問題追跡システムにはまったく意味がなく、一般的に役に立たないだけです。

人々は彼らが持っている知識を手伝います。 すべての人がコード自体を変更するスキルを持っているわけではないため、必要な変更についてコンセンサスを得るのに役立つこのような問題を作成します。

ここでは、特に変更を加える必要があると主張する人は誰もいませんが、 @ sandysがプロキシプロトコルに関して開いた問題についても、コアチームが変更に同意しました。 では、変更が受け入れられるかどうかわからない場合、誰かがこれにどのように取り組むことができますか?

最良の方法は、提案を考え出すことです。 作業が完了した後、アーキテクチャはどのようになると思いますか。 それは何をもたらしますか? 私たちは何を失いますか?

最良の方法は、提案を考え出すことです。 作業が完了した後、アーキテクチャはどのようになると思いますか。 それは何をもたらしますか? 私たちは何を失いますか?

すでにここで行われています:#39465

host-mode-networkingを試してください

コメントする前にスレッド全体をお読みください

「プロキシプロトコルを使用する」、確かに興味深いものは何をレイアウトしていませんが
コードベースに変更を加える必要があります。

これは単純な質問かもしれませんが、最初にソースIPを書き直す必要があるのはなぜですか? とにかく、トラフィックはインターフェイスのデフォルトゲートウェイを介して返されませんか? スウォームロードバランサーを介して送信された場合でも、ゲートウェイは、トラフィックの送信元を既に認識しているロードバランサーを介してそれを返すことができます...

これは単純な質問かもしれませんが、最初にソースIPを書き直す必要があるのはなぜですか? とにかく、トラフィックはインターフェイスのデフォルトゲートウェイを介して返されませんか? スウォームロードバランサーを介して送信された場合でも、ゲートウェイは、トラフィックの送信元を既に認識しているロードバランサーを介してそれを返すことができます...

どのIPからリクエストが来ているかを知る必要があります。 たぶん、特定のユーザーがIPを制限したいと思っていて、実行中のサービスの外部でそれを行うことはできません。つまり、traefikは、どのユーザーがIPを作成しているかを指定するリクエストの内容を知らないため、一部のユーザーを除外して受け入れることはできません。その他はipのみに基づいています(この例のポリシーはip + request-content => allow / disallowであるため)。

または、多くの場合、接続をログに記録するためだけに使用します。 サービスの使用量を顧客に請求する必要があります。また、リクエストの時間、リソースの量、リクエストのソースIPを表形式で提供する必要があります。 請求されるほとんどすべてのサービスがこの種のレポートを提供します。

あなたは私の質問を誤解したと思います。 サービスが真のソースIPを確認したい理由を理解しています。 Dockerがコンテナに到達する前に変更する理由を知りたい

2019年11月1日、1:47には、1:47 AMで、ダニエルCruciani [email protected]書きました:

たぶんこれは素朴な質問ですが、なぜ書き直す必要があるのですか?
そもそもソースIP? トラフィックは経由で返されませんか
とにかくインターフェースのデフォルトゲートウェイ? 群れの負荷を介して来たとしても
バランサー、ゲートウェイはロードバランサーを介してそれを返すことができます
トラフィックがどこから来たのかはすでにわかっています...

どのIPからリクエストが来ているかを知る必要があります。 多分
特定のユーザーがIPを制限したいのですが、外部でそれを行うことはできません
実行中のサービス、つまりtraefikはリクエストの内容を知りません
それはどのユーザーがそれを作っているかを指定するかもしれないので、それはいくつかを除外することはできません
ユーザーとIPのみに基づいて他を受け入れます(これのポリシーのため
例はip + request-content => allow / disallow)です。

または、多くの場合、接続をログに記録するためだけに使用します。 顧客に請求する必要があります
私のサービスの使用のために、そして私は表形式で提供する必要があります:時間
リクエスト、リソースの量、リクエストのソースIP。 ほぼすべてのサービス
請求済みは、この種のレポートを提供します。

-
あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示してください。
https://github.com/moby/moby/issues/25526#issuecomment -548711563

@kaysond質問するのは良い場所ではありません。

あなたは本質的に2つの質問をしています、

  1. IPVSが技術的にどのように機能するか、および
  2. libnetworkが最初にIPVSを選択する理由

どちらも異なる方法で答えるのは難しいです。

これらの質問をするのに最適な場所はどこにあるのだろうか。私は今、これらの選択の履歴とそのすべてがどのように機能するかを読むことに非常に興味を持っているので、ここでもう少しコンテキストを得ることができます。

@kaysond質問するのは良い場所ではありません。

あなたは本質的に2つの質問をしています、

  1. IPVSが技術的にどのように機能するか、および
  2. libnetworkが最初にIPVSを選択する理由

どちらも異なる方法で答えるのは難しいです。

すべてのアップデート?

同じ問題に遭遇したので、しばらくこのスレッドをフォローしていますが、 traefikの背後にある群れの中でいくつかのわかりました。 問題は、私たちがcloudflareの背後にいて、CF転送ヘッダーを取得する必要があったことでした。 (はい、私たちはipvsを使用し、私たちのサービスは群れで複製されます)。

でこれをもう一度試してみました:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:22 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

および次のDockerが構成します。

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

whoamiの出力は次のとおりです。

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

だからいいえ。 それでも機能しません

好奇心から....一部の開発者は、群れのネットワークを管理するコードを私に指摘できますか?

でこれをもう一度試してみました:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:22 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

および次のDockerが構成します。

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

whoamiの出力は次のとおりです。

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

だからいいえ。 それでも機能しません

ホストモードごとにtraefikを使用して、実際のIPを取得できます

ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

まだ開いていますか?
2020-05-08

まだ開いていますか?
2020-05-08

うん、まだ開いている。 スレッドには、表面上にあるはずのように簡単に解決できない理由を強調するアーキテクチャ上の問題があります。 この時点で、これらの問題はおそらく克服できない可能性があります。

実際のユーザーIPを取得する必要がある場合は、ここのスレッドにいくつかの代替案が掲載されています。 サービスのHOSTモードは最も単純なアプローチのように見えますが、個々のノードでスケーラビリティを必要とするものには適していません。

DigitalOcean LB-> Traefik-> ApacheコンテナでPROXYプロトコルを使用することに成功しました。 Apacheコンテナは、サービスにアクセスしたユーザーの実際のIPをログに記録することができました。 理論的には、すべてのプロキシレイヤーがPROXYプロトコルをサポートしている限り機能するはずです。

https://docs.traefik.io/v1.7/configuration/entrypoints/#proxyprotocol

Traefikサービスは「ingress」という名前の1つのDockerネットワーク上にあり、Apacheサービスには独自のスタックネットワークがありますが、外部として「ingress」ネットワークの一部でもあります。

https://autoize.com/logging-client-ip-addresses-behind-a-proxy-with-docker/

2020年、まだ修正されていません。 非常に重要な機能のようです

これは非常に必要です。 いくつかのホストモードを置くことは単なるパッチであり、ネットワークの背後でNGINXを実行する必要がある場合があります(使用法と設定によって異なります)。 これを修正してください。

これの回避策と、ホストを設定せずにdocker swarmを実行することは、クライアント側でIPを取得することだと思います。 元。 Webおよびモバイルクライアントにjsを使用し、信頼できるソースからのみ受け入れます。 元。 js-> get ip、バックエンドはユーザートークンなどを含むIPのみを受け入れます。ipはヘッダーに設定し、httpsを介して暗号化できます。 しかし、私はパフォーマンスについて知りません

@ Damidara16それはまさに私たちがやりたくないことです。 それをするのは本当に安全ではありません。 必要に応じてバイパスできます。

悪いことに、これはまだ未解決の問題です、悲しいことに...それはすぐに修正されるようには見えません

悪いことに、これはまだ未解決の問題です、悲しいことに...それはすぐに修正されるようには見えません

ボットによってまもなく閉鎖されると思います。 githubがこの機能を開始して以来、多くのバグは無視できます。

悪いことに、これはまだ未解決の問題です、悲しいことに...それはすぐに修正されるようには見えません

ボットによってまもなく閉鎖されると思います。 githubがこの機能を開始して以来、多くのバグは無視できます。

これは、企業の肥大化したチームがコミュニティを管理するための最良の機能です。

これが修正される可能性はほとんどありません。 誰もがk8sが「レース」に勝ったと考えており、群れは必要ありませんが、これらを使用するチームの必要性とスキルに応じて、両方が共存し、適切に使用できると思います。 RIPスウォーム:)

私はマネージドHAIPを使用していますが、群れの前に何か他のものを使用することもできます。これは、群れのIPを指すスタンドアロンのnginxロードバランサーです。
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

あなたの群れでは、リバースプロキシはこれを必要とします:

server {
        listen 443 ssl proxy_protocol;
        location / {
        proxy_set_header   X-Real-IP $proxy_protocol_addr;  # this is the real IP address 

スウォームを実行している場合は、スウォーム(またはスティッキーなど)へのリクエストをラウンドロビンするためのロードバランサーが必要になります。

これまでのところ、このアーキテクチャ上の決定は「欠けている部分」のように見えるかもしれませんが、オプションを提供し、組み込み機能を無効にしてアプリケーションのニーズにより適したものに置き換える必要をなくすことにより、柔軟性が追加されます。

この問題の回避策を見つけた可能性があると思います。たとえば、-constraint-add = 'node.hostname == mynode'を使用するか、またはそれぞれが単一のノードで構成される群れのセット。

問題

根本的な問題は、ingress_sbox名前空間のiptables natテーブルのSNATルールが原因で発生します。これにより、すべての着信リクエストがコンテナに表示され、入力ネットワークにノードのIPアドレスが割り当てられます(例:10.0.0.2、10.0.0.3、。 ..、デフォルトの入力ネットワーク構成)、例:

iptables -t nat -A POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j SNAT --to-source 10.0.0.2

ただし、このSNATルールを削除すると、コンテナは受信パケットを受信しますが(現在は元の送信元IPから発信されています)、元の送信元IPに返送された送信パケットは、同じ入力ネットワーク上ではなく、上にあるコンテナのデフォルトゲートウェイを介して送信されます。 docker_gwbridgeネットワーク(例:172.31.0.1)、およびそれらのパケットは失われます。

回避策

したがって、回避策は次のとおりです。1。ingress_sbox名前空間でこのSNATルールを削除(実際には禁止)します。 2.スウォームサービスコンテナのポリシールーティングルールを作成します。これにより、これらの発信パケットは、ノードの入力ネットワークIPアドレス(例:10.0.0.2)に強制的に戻されます。 3.ポリシールーティングルールの追加を自動化して、すべての新しいサービスコンテナに作成時にすぐにインストールされるようにします。

  1. SNATルールを禁止するために、通常のSNATに到達しないようにするルールを表の前半に作成します。
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

(dockerはサービスの作成中にSNATルールを数回再作成するように見えるため、既存のSNATルールを単に削除するのではなく、この方法で行います。このアプローチはそのルールに取って代わり、より回復力があります)。

  1. コンテナポリシールーティングルールを作成するには:
docker inspect -f '{{.State.Pid}}' <container-id>
nsenter -n -t $NID bash -c "ip route add table 1 default via 10.0.0.2 && ip rule add from 10.0.0.0/24 lookup 1 priority 32761"
  1. 最後に、上記をdocker eventと組み合わせると、次のingress-routing-daemonスクリプトを使用して、SNATルールの変更、新しく開始されたコンテナーの監視、およびポリシールーティングルールの追加のプロセスが自動化されます。
#!/bin/bash

# Ingress Routing Daemon
# Copyright © 2020 Struan Bartlett
# --------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# --------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

echo "Ingress Routing Daemon starting ..."

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo INGRESS_SUBNET=$INGRESS_SUBNET
echo INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic from incoming connections is routed back via the correct interface.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy route."
      nsenter -n -t $NID bash -c "ip route add table 1 default via $INGRESS_DEFAULT_GATEWAY && ip rule add from $INGRESS_SUBNET lookup 1 priority 32761"
    fi
  done

これで、リクエストが単一ノードの公開ポートに到着すると、そのコンテナには、リクエストを行っているマシンの元のIPアドレスが表示されます。

使用法

上記のingress-routing-daemonを、サービスを作成するに、スウォームノードのすべてのノードでルートとして

テスト、ユースケース、および制限

上記は、マルチノードスウォームで実行されているサービスの単一ノードに制約された複数のレプリカを使用してテストされています。

また、複数のノードを使用してテストされており、各ノードにはそのノードに制約された個別のノードごとのサービスがありますが、これには、ノードごとのサービスごとに異なる公開ポートを使用する必要があるという制限があります。 それでも、それはいくつかのユースケースで機能する可能性があります。

それぞれが独自のスウォーム内の単一ノードとして構成されている場合、このメソッドは複数のノードを使用しても機能するはずです。 これには、Dockerスウォームを使用してノード間でコンテナーを分散することができなくなるという制限がありますが、コンテナーレプリカやライフサイクル管理など、Dockerサービスを使用することによる他の管理上の利点があります。

さらなるユースケースに対処するための回避策の改善

今後の開発により、このメソッドは、ノードごとの個別のサービスやスウォームの分割を必要とせずに、複数のノードにスケーリングできるようになるはずです。 私は2つの可能なアプローチを考えることができます:1。各ノードのipvsadmテーブルからすべての非ローカルIPを削除するためにDockerまたは特注デーモンを手配します。 2.ポリシールーティングルールを拡張して、出力パッケージを正しいノードにルーティングするように調整します。

1の場合、ipvsadm -S -nをポーリングして、サービスに追加された新しいIPを探し、それぞれがローカルであるかどうかを確認し、そうでないものを削除します。 これにより、各ノードがサービス全体内で独自のコンテナーのロードバランサーとして機能できるようになりますが、あるノードに到達するリクエストを別のノードに転送することはできません。 これは確かに私自身のユースケースを満たします。サーバーのセットの前に独自のIPVSロードバランサーがあり、それぞれがWebアプリケーションを実行しており、同じアプリケーションの複数の負荷分散されたコンテナー化されたインスタンスに置き換えたいと考えています。 、サーバー全体を失うことなく更新をロールアウトできるようにします。

2の場合、iptablesを使用して、各ノードのingress_sbox iptableにノードごとのTOSを割り当てることができます(たとえば、ノードの入力ネットワークIPの最後のバイトに)。 次に、コンテナで、TOS値を接続マークにマップし、次に接続マークから送信パケットのファイアウォールマークにマップするように調整し、ファイアウォールマークごとに、パケットを発信元ノードにルーティングする異なるルーティングテーブルを選択します。 このためのルールは少し不格好ですが、2〜16ノードに細かくスケーリングする必要があると思います。

上記がお役に立てば幸いです。 私も(2)に行きます、そして私が進歩するならば、さらなるアップデートを投稿します。

以下は、入力ルーティングデーモンの改良版であるingress-routing-daemon-v2 。これは、ポリシールーティングルールモデルを拡張して、SNATを必要とせずに各コンテナが出力パケットを正しいノードにルーティングできるようにします。

改良モデル

以前のモデルに従ってSNATルールを禁止することに加えて、新しいモデルでは、IPVSロードバランサーエンドポイントとして使用する予定の各ノード(通常はマネージャーノード、またはそれらのサブセット)のingress_sbox名前空間にiptablesルールが必要です。マネージャーノード)、入力ネットワーク内の任意のノード宛てのすべてのパケットにノードごとのTOS値を割り当てます。 (ノードの入力ネットワークIPの最後のバイトを使用します。)

TOS値はパケット内に格納されているため、着信要求が送信され、パケットが送信された宛先ノードで読み取ることができます。

次に、宛先ノードのコンテナーで、同じ値を使用して、着信パケットのTOS値を接続マークにマップするように調整します。

これで、同じ接続上の発信パケットには同じ接続マークが付けられるため、同じ値を使用して、発信パケットの接続マークをファイアウォールマークにマッピングします。

最後に、一連のポリシールーティングルールは、ファイアウォールマーク値に従って、発信パケットを必要なロードバランサーエンドポイントノードにルーティングするように設計された別のルーティングテーブルを選択します。

これで、クライアントリクエストがスウォーム内の任意のノードの公開ポートに到着すると、リクエストの送信先のコンテナ(同じノードまたは他のノード、あるいはその両方)に、リクエストを行ったクライアントの元のIPアドレスが表示されます。応答を元のロードバランサーノードにルーティングして戻すことができます。 これにより、応答をクライアントにルーティングできるようになります。

使用法

セットアップ

ロードバランサーエンドポイントとして使用するすべてのスウォームのノードでルートとしてingress-routing-daemon-v2を実行することにより、スウォームに固有のINGRESS_NODE_GATEWAY_IPS値を生成します(通常はマネージャーのみ)ノード、またはマネージャーノードのサブセット)、 INGRESS_DEFAULT_GATEWAY表示される値に注意してください。 これを行う必要があるのは1回だけ、またはノードを追加または削除するたびです。 INGRESS_NODE_GATEWAY_IPS10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5ようになります(入力ネットワーク用に定義されたサブネットとノードの数による)。

デーモンの実行

サービスを作成するに、スウォームのノード(マネージャーとワーカー)のすべてのノードでルートとしてINGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 --install実行します。 (サービスがすでに作成されている場合は、正の数のレプリカにスケールバックする前に、必ず0にスケールバックしてください。)デーモンはiptablesを初期化し、dockerが新しいコンテナーを作成するタイミングを検出し、新しいコンテナーごとに新しいルーティングルールを適用します。

デーモンのアクティビティを特定のサービスに制限する必要がある場合は、 [ -n "$SERVICE" ][ "$SERVICE" = "myservice" ]ます。

iptablesルールのアンインストール

各ノードでingress-routing-daemon-v2 --uninstallを実行します。

テスト

ingress-routing-daemon-v2スクリプトは、4ノードの群れにデプロイされたWebサービスの8つのレプリカでテストされています。

指定された負荷分散されたエンドポイントノードIPのいずれかに向けられたサービスのCurl要求は成功した応答を返し、コンテナーログの検査は、アプリケーションが着信要求をCurlクライアントのIPから発信されたものとして認識したことを示しました。

制限事項

TOS値は8ビットの数値を格納できるため、このモデルは原則として最大256のロードバランサーエンドポイントノードをサポートできます。

ただし、このモデルでは、すべてのコンテナーに1つのiptablesマングルルール+1つのポリシールーティングルール+1つのポリシールーティングテーブルをマネージャーエンドポイントノードごとにインストールする必要があるため、このようなエンドポイントノードの数が増えると、パフォーマンスが低下する可能性があります(ただし、経験上、これは最新のハードウェア上の16未満のロードバランサーエンドポイントノードでは目立たない可能性があります)。

ロードバランサーエンドポイントノードをスウォームに追加する場合、または既存のマネージャーノードをロードバランサーエンドポイントとして使用し始めたい場合は、既存のコンテナーがトラフィックを新しいエンドポイントノードにルーティングできないため、慎重に踏み込む必要があります。 新しいロードバランサーエンドポイントを使用する前に、 INGRESS_NODE_GATEWAY_IPSの更新値を使用してINGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2を再起動し、すべてのコンテナーのローリング更新を実行してみてください。

ネイティブDocker統合の範囲

私はDockerコードベースに精通していませんが、 ingress-routing-daemon-v2が行うことで、原則としてDockerがネイティブに実装できないものは見当たりませんが、Dockerチームに任せます。検討するか、Dockerコードに精通している人のための演習として。

入力ルーティングデーモンv2スクリプト

これが新しいingress-routing-daemon-v2スクリプトです。

#!/bin/bash

# Ingress Routing Daemon v2
# Copyright © 2020 Struan Bartlett
# ----------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# ----------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

if [ "$1" = "--install" ]; then
  INSTALL=1
elif [ "$1" = "--uninstall" ]; then
  INSTALL=0
else
  echo "Usage: $0 [--install|--uninstall]"
fi

echo
echo "  Dumping key variables..."

if [ "$INSTALL" = "1" ] && [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  echo "!!! ----------------------------------------------------------------------"
  echo "!!! WARNING: Using default INGRESS_NODE_GATEWAY_IPS"
  echo "!!! Please generate a list by noting the values shown"
  echo "!!! for INGRESS_DEFAULT_GATEWAY on each of your swarm nodes."
  echo "!!!"
  echo "!!! You only have to do this once, or whenever you add or remove nodes."
  echo "!!!"
  echo "!!! Then relaunch using:"
  echo "!!! INGRESS_NODE_GATEWAY_IPS=\"<Node Ingress IP List>\" $0 -x"
  echo "!!! ----------------------------------------------------------------------"
fi

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo "  - INGRESS_SUBNET=$INGRESS_SUBNET"
echo "  - INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY"

# We need the final bytes of the IP addresses on the ingress network of every node
# i.e. We need the final byte of $INGRESS_DEFAULT_GATEWAY for every node in the swarm
# This shouldn't change except when nodes are added or removed from the swarm, so should be reasonably stable.
# You should configure this yourself, but for now let's assume we have 8 nodes with IPs in the INGRESS_SUBNET numbered x.x.x.2 ... x.x.x.9
if [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  INGRESS_NET=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f1,2,3)
  INGRESS_NODE_GATEWAY_IPS="$INGRESS_NET.2 $INGRESS_NET.3 $INGRESS_NET.4 $INGRESS_NET.5 $INGRESS_NET.6 $INGRESS_NET.7 $INGRESS_NET.8 $INGRESS_NET.9"
fi

echo "  - INGRESS_NODE_GATEWAY_IPS=\"$INGRESS_NODE_GATEWAY_IPS\""

# Create node ID from INGRESS_DEFAULT_GATEWAY final byte
NODE_ID=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f4)
echo "  - NODE_ID=$NODE_ID"

if [ -z "$INSTALL" ]; then
  echo
  echo "Ingress Routing Daemon v2 exiting."
  exit 0
fi

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# 1. Set TOS to NODE_ID in all outgoing packets to INGRESS_SUBNET
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables mangle rule: iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -D POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff

if [ "$INSTALL" = "0" ]; then
  echo
  echo "Ingress Routing Daemon v2 iptables rules uninstalled, exiting."
  exit 0
fi

echo "Ingress Routing Daemon v2 starting ..."

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic for incoming connections is routed back via the correct interface
# and to the correct node from which the incoming connection was received.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy routes."

      # 3. Map any connection mark on outgoing traffic to a firewall mark on the individual packets.
      nsenter -n -t $NID iptables -t mangle -A OUTPUT -p tcp -j CONNMARK --restore-mark

      for NODE_IP in $INGRESS_NODE_GATEWAY_IPS
      do
        NODE_ID=$(echo $NODE_IP | cut -d'.' -f4)

    # 2. Map the TOS value on any incoming packets to a connection mark, using the same value.
        nsenter -n -t $NID iptables -t mangle -A PREROUTING -m tos --tos $NODE_ID/0xff -j CONNMARK --set-xmark $NODE_ID/0xffffffff

    # 4. Select the correct routing table to use, according to the firewall mark on the outgoing packet.
        nsenter -n -t $NID ip rule add from $INGRESS_SUBNET fwmark $NODE_ID lookup $NODE_ID prio 32700

    # 5. Route outgoing traffic to the correct node's ingress network IP, according to its firewall mark
    #    (which in turn came from its connection mark, its TOS value, and ultimately its IP).
        nsenter -n -t $NID ip route add table $NODE_ID default via $NODE_IP dev eth0

      done

    fi
  done

こんにちは@ struanb 、v2スクリプトでアンインストールセクションがどのように機能するのかわかりません。何か足りないものがありますか?

こんにちは@jrbecart。 私はそうしないことを望みます。 iptablesルールをインストールする前に、 iptables -Dを使用して既存のルールを削除するwhileループが2つあることがわかります。 これは、スクリプトが--install連続して複数回実行され、 --uninstall呼び出しが介在しない場合の、安全対策です。

そのため、スクリプトが--uninstallで呼び出されると、スクリプトが終了するまでにそれらのルールは削除され、新しいルールはまだ追加されていません。

これがあなたの質問に答えることを願っています。

みなさん、こんにちは。NGINX構成を適切に定義する以外に何もインストールおよび構成せずに、この問題の修正を発見したことをお伝えしたいと思います。 私たちは皆、さまざまなアプローチを試みてきたことを知っています。 これは誤って発見されました。 正直、ずっと前に諦めました。 さて、今日まで。 監視システムを実装しているときに、NGINXログを使用して実際のソースIPであるソースIPを取得できたので、それがどのように可能であるかをデバッグし始めました。

これがその種のログの例です

10.0.0.2 - - [19/Nov/2020:04:56:31 +0000] "GET / HTTP/1.1" 200 58 "-" req_t=0.003 upstream_t=0.004 "<browser-info>" "<source-ip-1,source-ip2,....>"

注:プロキシ(Cloudfareなど)を使用している場合は、複数のソースIPがあります。

情報はそこにあり、私の本当のIPはそこにありました。 次に、ロギングNGINX形式を確認して、魔法がどのように可能であるかを確認しました。これを見つけました。

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      'req_t=$request_time upstream_t=$upstream_response_time '
                      '"$http_user_agent" "$http_x_forwarded_for"';

つまり、魔法はここにあります-> $http_x_forwarded_for

この後、 proxy_set_header X-Real-IP $http_x_forwarded_for;ようなプロキシヘッダーを変更しました。

そして最後に、NodeJSプロジェクトでその情報を使用し、本番環境のようなシステム内で、オーバーレイネットワークと約4つのVMを備えたDocker Swarmを使用した最後のテストで、何が機能したかを推測します。 ようやく実際のIPアドレスを取得できました。

この号は長い間開かれているのでとても嬉しいですが、これが答えだと思います。 私が使用したバージョンは次のとおりです。

Docker version: 19.03.8
NGINX version: nginx/1.14.2

フィードバックをお待ちしております。 私と同じ結果が得られることを願っています。

乾杯!
セバスチャン。

PS:実際のIPアドレスの代わりに「-」がログに表示されるため、別のネットワークインターフェイス、つまりローカルホストの外部を使用してこれを試してください。 完全にホームネットワークの外で、インターネットに沿ってテストしてみてください。

ボーナス:ルックアップテーブルを使用してIPアドレスをジオロケーションにマッピングし、それらをカウントしてマップに配置することもできるので、答えは「はい」です。これが私たちが探していたものです:)

@sebastianfelipeこれは何年に

@sebastianfelipeこれは何年に

私は確信しています。 接続されているすべてのサービスでネットワークホストを使用しているわけではありません。 Digital Oceanロードバランサーを含む本番環境のような環境にオーバーレイネットワークを備えたスタックをデプロイしたところ、機能しました。 つまり、これ以上テストすることはできません。 100%本物です。

@sebastianfelipe DigitalOceanロードバランサーがユーザーのIPアドレスをX-Forwarded-Forヘッダーに追加していると思います。 これは既知の回避策であり、スタンドアロンのDockerSwarmモードでユーザーのIPを取得する問題を解決しません。

@beornf私は$http_x_forwarded_for変数に起こります。 Digital Oceanロードバランサーは、DockerSwarmによって直接追加されない情報を別のNGINX変数に追加します。 おそらくこれは、あらゆるケースに真の解決策をもたらす「ダミーのような」アプローチにつながる可能性があります。 少なくともDigitalOceanのお客様は、現時点でこれに対処する方法を喜んで知っているはずです。

@beornf @sebastianfelipeコンテキストに加えて、CloudFlareはX-Forwarded-Forも追加し、ほとんど無料です。

@beornf @sebastianfelipeコンテキストに加えて、CloudFlareはX-Forwarded-Forも追加し、ほとんど無料です。

これは、実際のIPを取得する方法を必要とする多くの人にとってはうまくいくと思います。 Cloudfareは、プロキシとして、またはDNSのみとして調整できます。 DigitalOceanのお客様には最適ではありません。 これは、これまでのよりクリーンな回避策です。 しかし、私は@beornfに同意します。これを実現するために、Digital OceanやCloudfareに依存することなく、実際のソリューションが必要です。

ありがとう!

このページは役に立ちましたか?
0 / 5 - 0 評価