Kubernetes: ユーザースペースの代わりにiptablesをプロキシに使用する

作成日 2015年01月23日  ·  187コメント  ·  ソース: kubernetes/kubernetes

私は昨日iptablesで遊んでいましたが、ユーザースペースの助けを借りずに基本的にすべてのプロキシを実行する一連のiptablesルールをプロトタイプ化しました(まあ、Googleのヒットからコピーして変更しました)。 緊急ではありませんが、紛失する前にメモを提出したいと思います。

これには、ソースIPを保持し、ネットを大幅に簡素化するという追加の優れた副作用があります(私が知る限り)。 これで、kube-proxyはServices-> iptablesを同期する必要があります。 これには、古いiptablesやカーネルと互換性がないという欠点があります。 以前はこれに問題がありました。ある時点で、気になる時間をどれだけさかのぼって決定する必要があります。

これはおそらくさらに最適化できますが、基本的なテストでは、スティッキーセッションが機能していることがわかり、その部分をコメントアウトすると、各バックエンドにヒットする確率がほぼ等しくなります。 決定論的なラウンドロビンを正しく機能させることができませんでした(--probabilityの代わりに--nthを使用)が、必要に応じてそれに戻ることができました。

これにより、以下にリストされているバックエンドでサービスポータルがセットアップされます

iptables -t nat -N TESTSVC
iptables -t nat -F TESTSVC
iptables -t nat -N TESTSVC_A
iptables -t nat -F TESTSVC_A
iptables -t nat -N TESTSVC_B
iptables -t nat -F TESTSVC_B
iptables -t nat -N TESTSVC_C
iptables -t nat -F TESTSVC_C
iptables -t nat -A TESTSVC -m recent --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m recent --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m recent --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.500 -j TESTSVC_B
iptables -t nat -A TESTSVC -m statistic --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m recent --name hostA --set -j DNAT -p tcp --to-destination 10.244.4.6:9376
iptables -t nat -A TESTSVC_B -m recent --name hostB --set -j DNAT -p tcp --to-destination 10.244.1.15:9376
iptables -t nat -A TESTSVC_C -m recent --name hostC --set -j DNAT -p tcp --to-destination 10.244.4.7:9376

iptables -t nat -F KUBE-PORTALS-HOST
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
iptables -t nat -F KUBE-PORTALS-CONTAINER
iptables -t nat -A KUBE-PORTALS-CONTAINER -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
prioritawaiting-more-evidence release-note sinetwork siscalability

全てのコメント187件

いいね! 間違いなくこれを統合する必要があると思います。別のメモとして、プロキシが高負荷でコアの約30%を消費するのを見ていましたが、iptablesはそれよりも優れたパフォーマンスを提供すると信じなければなりません。

これを優先する必要があります-これは、kube-proxyと
そのすべてのテスト。 また、バックコンパットの問題もあります(
古いカーネルまたは古いiptablesバイナリ)。

11:06 AMで月、2015年1月26日には、ブレンダン・バーンズ[email protected]
書きました:

いいね! 私たちは間違いなくこれを統合する必要があると思います。別のメモで、
プロキシが重い負荷の下でコアの約30%を食べるのを見ていました、私はしなければなりません
iptablesはそれよりも優れたパフォーマンスを提供すると信じています。

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

おそらくそれを並列オプションとして実装し、ゆっくりと移行することは理にかなっていますか?

12:01時月、2015年1月26日には、ティムHockin [email protected]
書きました:

これを優先する必要があります-これは、kube-proxyと
そのすべてのテスト。 また、バックコンパットの問題もあります(
古いカーネルまたは古いiptablesバイナリ)。

11:06 AMで月、2015年1月26日には、ブレンダン・バーンズ[email protected]
書きました:

いいね! 私たちは間違いなくこれを統合する必要があると思います。別の
ノート、
プロキシが重い負荷の下でコアの約30%を食べるのを見ていました、私はしなければなりません
iptablesはそれよりも優れたパフォーマンスを提供すると信じています。

このメールに直接返信するか、GitHubで表示してください
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71527216

私はそれを学ぶためにこのコードをよく知らない他の誰かをだまそうとしています
そしてそれを引き受けます。 私は本当にそれに取り組みたいのですが、
他の誰かがこのスペースを学びました(あなたではありません!:)

そうは言っても、あなたは膨大なP1リストについての(良い)電子メールも送信しました-そして私は
これはまだそのリストにあるとは思わないでください。

13:06時月、2015年1月26日には、ブレンダン・バーンズ[email protected]
書きました:

たぶんそれを並列オプションとして実装し、ゆっくりと移行することで
検出?

12:01時月、2015年1月26日には、ティムHockin [email protected]
書きました:

これを優先する必要があります-これはkube-proxyのほぼ完全な書き直しです

そのすべてのテスト。 また、バックコンパットの問題があります(機能しません
オン
古いカーネルまたは古いiptablesバイナリ)。

2015年1月26日月曜日午前11:06、ブレンダンバーンズ<
[email protected]>
書きました:

いいね! 私たちは間違いなくこれを統合する必要があると思います。別の
ノート、
プロキシが重い負荷の下でコアの約30%を食べるのを見ていました、私はしなければなりません
iptablesはそれよりも優れたパフォーマンスを提供すると信じています。

このメールに直接返信するか、GitHubで表示してください
<

https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

このメールに直接返信するか、GitHubで表示してください
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment-71527216>

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71538256

これはP2ですか? 今のところP3にする価値はありますか?

私はそれを機能させることを望んでいますが、私たちはまだそれを降格するかもしれません

14:49の水曜日、2015年2月11日には、Satnamシン[email protected]
書きました:

これはP2ですか? 今のところP3にする価値はありますか?

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -73982161

「希望」は、可能であれば到達するP3と同じではありませんか?

@thockinとの話し合いから:これは、1.0では必須ではないサービスポート範囲をサポートするための要件ですが、最終的にはサポートしたいと考えています。

@thockin 「これには、古いiptablesやカーネルと互換性がないという欠点があります。」 カーネルはどのくらい「新しい」必要がありますか?

それほど新しいものではありませんが、2012年から
仕事。

2015年2月23日月曜日午後2時44分、Sidharta Seethana < [email protected]

書きました:

@thockin https://github.com/thockin "これには、存在しないという欠点があります
古いiptablesおよびカーネルと互換性があります。
する必要がありますか?

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75654187

@thockinありがとう。 たとえば、RHEL / CentOS 6を使用/テストしているので、最近の3.xカーネルに強く依存していないと便利です。

@ pweil-先日これについて話し合っていました
23:40 Sidharta Seethanaで月、2015年2月23日には[email protected]
書きました:

@thockinhttps ://github.com/thockinありがとう。 私たちは使用/テストしています
たとえば、RHEL / CentOS 6-ハードがない場合は便利です
最近の3.xカーネルへの依存。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480

そうですね、Dockerを実行するには必要ですが、ある時点でそれを切断する必要があります。
back-rev iptablesのサポートは、私が(最終的に)作成するのを妨げることはありません
この変化、そしてそれは何人かの人々に刺すでしょう。

2015年2月23日月曜日午後8時40分、Sidharta Seethana < [email protected]

書きました:

@thockinhttps ://github.com/thockinありがとう。 私たちは使用/テストしています
たとえば、RHEL / CentOS 6-ハードがない場合は便利です
最近の3.xカーネルへの依存。

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480

@thockinの助けを借りて、udpでも同じことを試しました。

3つのsky-dnsレプリケーションコントローラーを使用してGCEKubernetesクラスターを作成しました。
kubernetes-masterで、iptablesに以下を設定します。
DNSサービスIPは10.0.0.10であり、DNSを実行しているポッドエンドポイントは10.244.0.5:53、10.244.3.6:53、10.244.0.6:53でした。

iptables -t nat -N TESTSVC
iptables -t nat -F TESTSVC
iptables -t nat -N TESTSVC_A
iptables -t nat -F TESTSVC_A
iptables -t nat -N TESTSVC_B
iptables -t nat -F TESTSVC_B
iptables -t nat -N TESTSVC_C
iptables -t nat -F TESTSVC_C
iptables -t nat -N KUBE-PORTALS-HOST
iptables -t nat -F KUBE-PORTALS-HOST

iptables -t nat -A TESTSVC -m latest --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m latest --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m latest --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C

iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.5 -j TESTSVC_B
iptables -t nat -A TESTSVC -m statistic --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m latest --name hostA --set -j DNAT -p udp --to-destination 10.244.0.5:53
iptables -t nat -A TESTSVC_B -m latest --name hostB --set -j DNAT -p udp --to-destination 10.244.3.6:53
iptables -t nat -A TESTSVC_C -m latest --name hostC --set -j DNAT -p udp --to-destination 10.244.0.6:53
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.10/32 -p udp -m udp --dport 53 -j TESTSVC
iptables -t nat -A OUTPUT -j KUBE-PORTALS-HOST


kubernetes-master> nslookup kubernetes.default.kuberenetes.local 10.0.0.10

返信があります!

素晴らしいもの! 参考までに(対面での会話から確認)、一般に複数のiptablesコマンドを同時に実行することは安全ではありません(チェーンが異なれば問題ないように思えます)。 iptablesはlibiptcのラッパーであり、iptc_commitのコメントを参照してください

これは明らかに2013年に修正されましたが、おそらく--wait(?)を渡した場合のみです: http ://git.netfilter.org/iptables/commit/?id = 93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

これの根本的な原因は、iptablesがiptables-save / iptables-restoreを効果的に呼び出すことです(少なくともチェーンごとに)。 そのため、追加や削除ではなく、iptables-save&iptables-restoreを呼び出すコードをたくさん見てきました。 それが役に立ったら掘り下げることができるコードを持っているかもしれません。

CASやLL / SCのような操作を行う方法がないことに気が遠くなります。

--waitのサポートを追加する必要がありますが、GCEの
debian-backportsにはありません。

少なくとも私たちを防ぐために、コード内で独自のロックを行う必要があるかもしれません
自分を踏むことから。

2015年2月26日木曜日午後1時56分、ジャスティンサンタバーバラ<
[email protected]>は次のように書いています:

素晴らしいもの! 参考までに(対面での会話から確認)、
一般に、複数のiptablesコマンドを同時に実行することは安全ではありません
(異なるチェーンはそれが大丈夫かもしれないように聞こえます)。 iptablesはラッパーです
libiptc、およびiptc_commitのコメントを参照してください。
http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html

これは明らかに2013年に修正されましたが、おそらく--wait(?)を渡した場合のみです。
http://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

これの根本的な原因は、iptablesが効果的にiptablesを呼び出すことです-save /
iptables-復元(少なくともチェーンごと); 私はちょうど多くのコードを見てきました
したがって、何かをするのではなく、iptables-save&iptables-restoreを呼び出します
追加と削除を介して。 私は掘ることができるいくつかのコードを持っているかもしれません
それが役に立ったらアップ。

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76282629

一連のルールを作成している途中で失敗した場合はどうなりますか?

公正な質問-私たちはおそらくそれが何を意味するのかについて本当に真剣に考える必要があります
この途中でエラーが発生します

20:47の木、2015年2月26日には、ブライアン・グラント[email protected]
書きました:

の束を作成している途中で失敗した場合はどうなりますか
ルール?

このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76331174

@thockin今日のircから:

net.ipv4.conf.all.route_localnetは、127.0.0.1がDNATルールのターゲットになることを許可します。 ドキュメントから:

route_localnet -ブール値

ループバックアドレスを火星の送信元または宛先と見なさないでください
ルーティング中。 これにより、ローカルルーティングの目的で127/8を使用できるようになります。
デフォルトはFALSE

これをkubeletに統合しますか、それとも別のデーモンに保持しますか? Kubeletは、env変数を設定するためにすでにサービスを監視しています。

別のバイナリとして保持したいと思います。 あなたが
k8s以外の他のマシン(ペットVMなど)でこれを実行したい場合があります
k8sサービスにアクセスするためのクラスター。

--brendan

11:37時金、2015年3月13日には、ブライアン・グラント[email protected]
書きました:

これをkubeletに統合しますか、それとも別のデーモンに保持しますか?
Kubeletは、env変数を設定するためにすでにサービスを監視しています。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747

追いつく。 失敗した場合に何が起こるか(多くありますが、私を信じてください)に関して、私はアンチエントロピーアプローチの大ファンです-望ましい状態をどこかに保存し、定期的に望ましい状態と実際の状態を調整します(実際の状態を変更することによって) )。 この場合、おそらく次のように簡単です。

while(true){
actualState = iptablesSave()
if actualState!= desiredState {iptablesRestore(desiredState))
sleep_a_while()
}

iptablesの作成の失敗に対処する正しい方法である100%に同意します
ルール。

13:16時金、2015年3月13日には、クイントンフール[email protected]
書きました:

追いつく。 故障の場合に何が起こるかについて(うち
多くの人がいるでしょう、私を信じてください)、私は反エントロピーアプローチの大ファンです

  • 必要な状態をどこかに保存し、定期的に必要な状態を調整して
    実際の状態(実際の状態を変更することによる)。 この場合、おそらく次のように簡単です。

while(true){
actualState = iptablesSave()
if actualState!= desiredState {iptablesRestore(desiredState))
sleep_a_while()
}


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296

それは多かれ少なかれ今起こっていることですよね? 予想されるルールごとに、
存在するかどうかを確認し、存在しない場合は作成します。

14:02時金、2015年3月13日には、ブレンダン・バーンズ[email protected]
書きました:

iptablesの作成の失敗に対処する正しい方法である100%に同意します
ルール。

13:16時金、2015年3月13日には、クイントンフール[email protected]
書きました:

追いつく。 故障の場合に何が起こるかについて(うち
多くの人がいるでしょう、私を信じてください)、私は反エントロピーの大ファンです
アプローチ

  • 必要な状態をどこかに保存し、定期的に必要な状態を調整して
    実際の状態(実際の状態を変更することによる)。 この場合、おそらく同じくらい簡単です
    なので:

while(true){
actualState = iptablesSave()
if actualState!= desiredState {iptablesRestore(desiredState))
sleep_a_while()
}


このメールに直接返信するか、GitHubで表示してください
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79392626

別のバイナリにユーティリティがあることに同意しますが、多分それをリンクします
kubelet(cAdvisorが行っているのと同じ方法)で、
同時。

12:03時金、2015年3月13日には、ブレンダン・バーンズ[email protected]
書きました:

別のバイナリとして保持したいと思います。 あなたが
k8s以外の他のマシン(ペットVMなど)でこれを実行したい場合があります
k8sサービスにアクセスするためのクラスター。

--brendan

11:37時金、2015年3月13日には、ブライアン・グラント[email protected]
書きました:

これをkubeletに統合しますか、それとも別のデーモンに保持しますか?
Kubeletは、env変数を設定するためにすでにサービスを監視しています。


このメールに直接返信するか、GitHubで表示してください
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79257059

ノードコンポーネントをより統合するかモジュール化するかについて、Kubernetes-Mesosの人々が何を言わなければならないかを知りたいと思います。 @jdef?

[[編集済み]] k8sコンポーネントのモジュール性が本当に気に入っています。たとえば、kubeletプロセスとは別のプロキシプロセスを実行しています。 何らかの理由でプロキシが失敗しても、kubeletは削除されません。 Mesosエグゼキューターには現在非常に適切なフェイルオーバーモデルがないため、これは非常に優れています。kubernetes-mesosフレームワークのエグゼキューターはkubelet / executorハイブリッドです。 このモデルでは、mesosマスターでプロキシサービスを実行し、外部クライアントのラウンドロビンバランサーとして使用することもできます(提出した入門ガイドのように)。

バイナリの梱包/出荷に関しては、hyperkubeのように機能をまとめておくと非常に便利だと思います。 また、kubernetes-mesosフレームワークコンポーネントを最小限のDockerコンテナにパッケージ化する方法についても考えました。 Iptablesには外部ライブラリの依存関係があり、それが事態を複雑にします。 したがって、k8smフレームワークを単一のhyperkubeイメージを含むDockerとして出荷するのが良い妥協案かもしれませんが、そのフレームワークが実行され、クラスター全体にkubelet-executorの分散が開始されると、基本的に、いずれかのkubeletに変形できるhyperkubeイメージが出荷されます-エグゼキュータまたはプロキシ-各プロセスはホスト上で直接実行できます。 これは基本的に、iptables- {binaries、libraries} -in-Dockerの依存関係の問題を回避するためのエンドランを実行します。

モジュラー機能の場合は+1、シングルバイナリイメージの場合は+1

@thockin re:アンチエントロピー:ああ、そうです。 proxier.SyncLoop()がそれを行っているのがわかります。 2月26日の@ bgrant0607の質問に対する答えは、エラーは無視でき、SyncLoop()の次の反復(現在は1分)で修復されるというものではありませんか? それとも私は何かが足りないのですか?

@thockin

  1. ネットワークトラフィックのブラックホールが心配ですか、それともサービス/ポッドの作成者が処理する必要があるものですか?

ユーザースペースプロキシを使用
仮想IP10.0.0.11には、10.240.1.1、10.240.1.2、10.240.1.3の3つのエンドポイントがあると想定します。
ユーザースペースプロキシでは、1つのエンドポイントが10.240.1.1が機能しなかった場合、プロキシはtcp接続が10.240.1.1で確立されていないことを認識し、他の2つのエンドポイントの1つにフォールバックする可能性があります。

iptablesを使用
iptablesを使用する場合、kubernetesはエンドポイントが機能したかどうかを認識しないため、フォールバックメカニズムはありません。
エンドポイントに何らかのヘルスチェックがあれば、これを軽減できます。これにより、応答しないエンドポイントが削除されます。

または、応答しないエンドポイントについて心配することは、kubernetesシステムの責任ではなく、ポッド作成者の責任ですか?

ユーザーは、Kubeletによって実行される準備プローブを設定できます。 プローブに障害が発生すると、エンドポイントコントローラによってエンドポイントがエンドポイントリストから削除されます。 次に、サービスプロキシはエンドポイントをターゲットセットから削除する必要があります。

私はGSoCのためにこれを調べてきました、そして私は疑問に思っています:

したがって、理想的には、iptablesが使用するのに十分新しいかどうかを検出し、それ以外の場合はkube-proxyを引き続き使用しますか?

https://github.com/GoogleCloudPlatform/kubernetes/issues/5419から、これが理想的なアプローチのようです。 kubeletがip-tablesを使用するか、kube-proxyを開始するかを決定します。

私もGSoCに少し遅れています(春休みでした...)ので、明日/今日(もちろん27番目の締め切りを除いて)にGSoCの提案を提出できるかどうかも疑問に思っています。これはまだ開いています)?

@BenTheElderはい、金曜日までに提案を提出する必要があります。 このトピックに潜在的に興味を持っている人がもう1人いますが、具体的な提案はまだありません。

完全にiptablesのないOSについては、2012年より古いカーネルについてはそれほど心配していませんが、それらはすでにある程度壊れています。

@ bgrant0607ありがとう!
私はこの問題を選択するかもしれないと思います。 面白そうですね。

準備プローブはアプリケーションの起動にはうまく機能しますが、準備がアプリケーションの障害を軽減するのに適しているかどうかはわかりません。 ポッドに障害が発生すると、シグナルはアプリケーション-> kubelet-> apiserver-> endpoints_controller-> apiserver-> kube-proxyから渡される必要があります。 アプリケーションの障害からエンドポイントがkube-proxyローテーションから削除されるまでの待ち時間を理解したいと思います。 この期間中、リクエストは応答しないエンドポイントにプロキシされます。

接続障害時の再試行は一般的な戦略であり、多くの一般的なロードバランサー(haproxy、AWS ELBなど)のかなり便利な機能であり、kube-proxyの現在の実装によって処理されます。 この責任を外部LBに移行する必要がありますか? クラスタ内トラフィックはどうですか?

別の考えとして、iptablesを使用すると、実際のLBと比較して、再構成時に接続のドレインが正常に行われるという問題が発生する可能性があります。

マイクは良い点を上げます。

午後11時で月、2015年3月23日には、マイクDanese [email protected]
書きました:

別の考えとして、私たちは優雅に接続の問題に遭遇する可能性があります
再構成時の排出と実際のLBの比較。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -85354865

私はkube-proxyとproxypkgのソースを読んでいます。 iptablesは現在のリビジョンでまだ使用されていませんか?

これに対して正確に何をする必要がありますか? 現在のマスターソースからは、iptablesがすでにプロキシでかなり広範囲に使用されているように見えます。

@mikedanese @thockin準備は、計画停止に最も役立ちます。 計画外の停止は、常にいくつかの観察可能なエラーを引き起こします。 ポーリング間隔は通常、更新の待ち時間に比べて長くする必要がありますが、apiserverなどを介した待ち時間が長すぎる場合やKube-proxy間の直接通信を介して、宛先ノードに再転送ルールを設定することもできます。パスは十分に信頼できません。

@BenTheElder既存のルールは、プロキシを介してトラフィックをルーティングします。 ここでの考え方は、ルールを使用してプロキシをバイパスすることです。

@ bgrant0607ありがとう、それは今完全に理にかなっています。 別のソースと設計ドキュメントを読んで、ドラフト提案の作成はほぼ完了しました。

ドラフトGSoC提案: https

スケジュールセクションに関するフィードバックを特にいただければ幸いです。 よくわかりません。
早く終了する必要があります。次のような他の(小さい?)未解決のGSoCの問題に取り組みたいと思います。
https://github.com/GoogleCloudPlatform/kubernetes/issues/1651。

もう一度ありがとう、Kubernetesは最も友好的なグループのためにケーキを取ります。

私の提案が受け入れられ、夏の間これに取り組んでいくことをとてもうれしく思います。 :スマイリー:

私は非常に興奮しています。 残念ながら、私は現在決勝戦の真っ最中ですが、今週末のいつかから、もっと多くのことに取り組み、それに取り組む必要があります。おそらくます。終了した。

@thockin @brendanburnsユーザースペースプロキシと並行してこれを実行したいのか、それとも再実装への移行がどのように機能するのかを誰かが

すでにiptables> = 1.4.11(2011年5月26日リリース)を好んでいるようです。

// Executes the rule check without using the "-C" flag, instead parsing iptables-save.
// Present for compatibility with <1.4.11 versions of iptables.  This is full
// of hack and half-measures.  We should nix this ASAP.
func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...string) (bool, error) {

ソース: https

実際にそれより古いホストが表示されますか?

1つのアプローチは、実行時に実行しているiptablesのバージョンを検出し、そのバージョンに指定できる「最善のこと」を実行することです。たとえば、次のようになります。

if(oldversion){
ユーザースペースプロキシモジュールをロードする
}
そうしないと {
iptablesプロキシモジュールをロードする
}

上記のifステートメントにブランチが多すぎないように注意し(理想的には2つだけ)、コード内の複数の場所にこの種のifステートメントを含めることはできるだけ避けてください。

上記のアプローチがどれほど実行可能であるかを理解するために、コードを詳細に調べていません。

また、すべてのノードが同じ戦略(ユーザースペースとiptablesプロキシ)を実装する必要がありますか、それとも各ノードが個別に決定できますか?

各ノードが独立して決定する場合、上記のifステートメント(つまり、source_mode x dest_mode)のブランチ数の2乗に比例してテスト表面積を増やす可能性がありますが、モード数を2に保つことができれば、それで問題ないと思います。 。

NS

ああ、残念ながら、古いノードが表示されるかどうかという質問に対する答えは「はい」です。

上記については別号で多くの議論がありますので、掘り下げてみます。

@ quinton-hooleありがとう!

また、あるノードでユーザースペースを実行し、別のノードでiptablesを実行できると確信しています。

-Cがない場合のハックを除いて、モードの数は2にする必要がありますが、-Cがあるノードは純粋なiptablesバージョンを実行できるはずです(私は思います)。

はい、#7528ではカーネルバージョンなどについて説明しています。

ありがとう。
kubernetesの要件を探したとき、それはわかりませんでした。 私が見つけた唯一の要件は、一意のIPをどのように想定するかを説明しているネットワークドキュメントにありました。

要件が何であるかがよくわかったら、要件について書かれたドキュメントを入手する必要があります。

私はここでこれをハッキングし始めました: https

具体的には、ユーザースペースの実装をインターフェイスの背後に移動しました。
https://github.com/BenTheElder/kubernetes/commit/4e5d24bb74aca43b0dd37cf5cfee8a34f8eff2bf

実装の選択をcmd / kube-proxyとpkg / proxyのどちらにするかは今のところわかりません。そのため、これを削除して、代わりにkube-proxyで実装を選択することができます。

編集:振り返ってみると、kube-proxyから実装を選択する方がおそらく理にかなっていると思います。

@BenTheElder私はCalicoでTimのルールをテストしましたが、それらは正常に機能します。 すべての作業はフィルターテーブルで行うため、ここでのDNATルールはその時点で適切なsrcIPを設定しています。

より一般的には、Kubernetesもルールを挿入する場合、ネットワークプラグインがiptablesを安全に変更する方法を定義するためのディスカッションを行うとよいでしょう。 Kubernetesのルールが将来変更された場合、それらのルールを踏みにじる(または踏みにじられる)ことは避けてください。

@Symmetricはい。 プラグインの部分についてはまだまったくわかりませんが、それはかなり重要なようです。

私はおそらく今週末は少し忙しくなるでしょうが、月曜日は最初のイテレーションを実装するGSoCのためにこのフルタイムで作業を開始する必要があります。
そうしている間、私はこれを心に留めておきたいのですが、ネットワークプラグインAPIを調べた後、これを処理するための最もクリーンな方法が何であるかは本当にわかりません。

これをどのように見せたいか/どのように機能させるべきかについて何か考えがありますか?

FWIW、kube-proxyがほとんど応答しなくなっていたので、私は私たちのために働く何かをしました。 ここにあります: https

私は以前にこのスレッドを見たことがありませんでしたが、ランダムな統計の一致の重みを間違えたことを除いて、何か近いものになってしまいました:-)

また、nf_conntrack_maxにすばやく到達したことも共有したいと思います。 おそらく増やす必要があります。

# cat /etc/sysctl.d/nf_conntrack.conf 
net.netfilter.nf_conntrack_max = 1000000
net.nf_conntrack_max           = 1000000

iptablesすべての必要性を理解していないかもしれませんが、代わりにIPVSを使用しないのはなぜですか?
iptablesよりもプロキシに関連しているようです...
簡単なgoの実装は次のとおりです: https
そして、#561を完了するために、 ktcpvsプロジェクトもあります。

IPVSは、netfilter(iptablesなど)の抽象化でもあるようです。 iptablesを使用することで、既存のコードといくつかの機能を共有することができます。 そしてiptablesは、netfilterを管理するためのより柔軟で一般的なソリューションのようです。

#561とktcpvsについて:ktcpvsは、2004年以降開発されていないようであり、ユーザーがURLの書き換えを希望する機能を備えていないようです。 とにかく#561は、プラグ可能なバラナサーで使用できる一般的なソリューションを探しています。

補足:goプロジェクトにはライセンスがないようです。

iptablesは、nftables( nft cli)を優先して、「1日」非推奨になります。
また、iptables CLIを使用してルールを作成することは、それほど堅牢ではないようです...

クイック検索で、この他のMITプロジェクトを見つけてください//github.com/vieux/go-libipvs
しかし、すべての複雑さはカーネルコード内ですでに防弾されているため、単純に機能するものを作成するのは非常に簡単なようです。

iptablesがすぐに主要なディストリビューションから削除されるとは思えません。iptablesCLIは、netfilterのルールを作成および管理するためのものです...?

リンクされているような不完全なcgoラッパーは、 iptablesiptables-restoreシェルアウトするよりもはるかに安全性が低いようです。また、他のルール(ノードポートなど)とiptables-restore iptablesがすでに必要です。ある程度のアトミック性で一括更新を行うことができます。

IPVSはさらに、「実際の」サーバーとは別に、負荷分散ホストマシンで使用するように設計されているようです。
これは、サポートされている唯一の使用法であることを示唆しています。

2.2。 落とし穴:外部クライアントが必要です(ディレクターと実サーバーは仮想サービスにアクセスできません)

LVSをセットアップしてテスト/実行するには、クライアント、ディレクター、実サーバーの3台以上のマシンが必要です。

外部からは、LVSは1台のマシンとして機能します。 クライアントをLVS内のマシン(ディレクターまたは実サーバー)の1つにすることはできません。 外部クライアントが必要です。 LVS内の任意のマシンからLVS制御サービス(http、smtp、telnetなど)にアクセスしようとした場合。 ディレクターからのアクセスはハングし、実サーバーからのアクセスはLVSをバイパスしてローカルでサービスに接続します。

また IPVS / LVSは、ハートビートデーモンや追加の監視プロセスなどのいくつかの追加要件を追加している

iptablesアプローチの場合は+1。 Calicoではiptablesを幅広く使用しており、堅牢であり、パフォーマンスと拡張性に優れていることが証明されています(ルールを適切に設計していることを前提としています)。 @ BenTheElder 、iptablesの動作についてサポートが必要な場合は、

iptablesとiptablesの+ 1-復元、それははるかに手間のかからないアプローチです
IPVS / LVSよりも少なく、システム要件が少なくて済みます(ハートビートデーモン、
NS。)

11:27時土、2015年6月13日には、アレックスPollitt [email protected]
書きました:

iptablesアプローチの場合は+1。 Calicoではiptablesを幅広く使用しています。
それらは堅牢であることが証明されており、パフォーマンスと拡張性に優れています(
ルールをうまく設計する)。 @BenTheElder https://github.com/BenTheElder
iptablesの動作についてサポートが必要な場合は、
私たちは喜んでチップインするので、私たちは知っています。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -111719474

アレックスに感謝します、もしそうなら私はあなたに知らせます。

時間があれば、現在の実装(https://github.com/GoogleCloudPlatform/kubernetes/pull/9210)に関するフィードバック/入力を使用できます。

これはほぼ完了しており、現在アップストリームマスターで完全に更新されています。生成されたルールをiptables-saveと比較し、カウンターなどを復元するコードの記述を完了する必要がありますが、ルールは生成され、(ほとんど)機能します。ここでOPに概説されているルールにほぼ従っていますが、最大の変更点はチェーン名だけです。これは、iptablesが受け入れる名前の自動生成に必要でした。

https://github.com/BenTheElder/kubernetes/issues/3で報告されているエッジケースがあり、ポッド自体に接続するポッドを処理するために変更が必要になる場合があります。

@MikaelCluseau@Symmetricと、特にこれや他のことを処理するための再設計を行うことについて、いくつかの優れたフィードバックと議論をしました(ありがとう!)。 ただし、特にルールの設計については、さらにいくつかの入力を使用できます。 他の誰かが見てみる時間があれば、私は最善のルートが何であるかわからないので大いに感謝されます、そして私はそれ以上の入力なしに大きな変更を加えないようにしたいです。

PR自体はかなり大きいですが、関連するルール生成はすべてpkg/proxy/proxieriptables.go syncProxyRules()にあります: https

既存のディスカッションは、(もちろんここで)PRコメント、 https://github.com/BenTheElder/kubernetes/issues/3 、およびます。 BenTheElder / kubernetes / issues / 4。

入力が必要なもう1つの問題:

現在のコードでは、nodePortの場合のみを処理するために、kube-proxyが引き続き含まれています。 この場合もkube-proxyを廃止できると思います。そして、 BenのPRでそうするためのいくつかの簡単なiptablesルールを提案しました。

ただし、これらのルールは外部LBのソースIPを覆い隠すため、理想的ではありません。 問題は、ノードに到達したときにLBからのDNATトラフィックだけの場合、応答パケットが別のノードから送信される可能性があるため、LBが応答を元のTCPセッションと相関させることができないと思われることです。 。 この懸念は有効ですか? これについて心配する必要がなければ、実装はより簡単になります。

HTTPプロキシを幸せに保つためにできる魔法があると思いますが、L4でこれを一般化する方法がわかりません。

私はあなたのPRから黒魔術を試していますが、それは私にとって何も生成しません。ルールがiptablesの呼び出しで生成され始めたようで、その後iptables-restoreファイルが生成されます。

生成されたファイルのヘッダー部分、通常はiptables呼び出しが入力された部分に欠落があります。ログの関連部分があります:

I0807 11:41:24.560063 8369 iptables.go:327] iptables -N [KUBE-PORTALS-CONTAINER -tnat]を実行しています
I0807 11:41:24.562361 8369 iptables.go:327] iptables -C [PREROUTING -t nat -m comment --comment handleClusterIPs;を実行しています。 注:これは、NodePortルールの前にある必要があります-j KUBE-PORTALS-CONTAINER]
I0807 11:41:24.563469 8369 iptables.go:327] iptables -N [KUBE-PORTALS-HOST -tnat]を実行しています
I0807 11:41:24.565452 8369 iptables.go:327] iptables -C [OUTPUT -t nat -m comment --comment handleClusterIPs;を実行しています。 注:これは、NodePortルールの前にある必要があります-j KUBE-PORTALS-HOST]
I0807 11:41:24.566552 8369 iptables.go:327] iptables -N [KUBE-NODEPORT-CONTAINER -tnat]を実行しています
I0807 11:41:24.568363 8369 iptables.go:327] iptables -C [PREROUTING -t nat -m addrtype --dst-type LOCAL -m comment --comment handle service NodePorts; 注:これはチェーンの最後のルールである必要があります-j KUBE-NODEPORT-CONTAINER]
I0807 11:41:24.569564 8369 iptables.go:327] iptables -N [KUBE-NODEPORT-HOST -tnat]を実行しています
I0807 11:41:24.571458 8369 iptables.go:327] iptables -C [OUTPUT -t nat -m addrtype --dst-type LOCAL -m comment --comment handle service NodePorts; 注:これはチェーンの最後のルールである必要があります-j KUBE-NODEPORT-HOST]
I0807 11:41:24.573392 8369 iptables.go:327] iptables -C [POSTROUTING -t nat -m comment--comment handle pod connect to self -s 10.240.240.78 / 32 -d 10.240.240.78 / 32 -jMASQUERADEを実行しています]
I0807 11:41:24.574447 8369 proxier.go:349] iptablesルールの同期。
I0807 11:41:24.575592 8369 proxier.go:399]チェーン:PREROUTING、ルール:: PREROUTING ACCEPT [0:0]
I0807 11:41:24.575615 8369 proxier.go:401]ルール:-A PREROUTING -m comment --comment "handle ClusterIPs;注:これはNodePortルールの前にある必要があります" -j KUBE-PORTALS-CONTAINER
I0807 11:41:24.575625 8369 proxier.go:401]ルール:-A PREROUTING -m addrtype --dst-type LOCAL -m comment --comment "handle service NodePorts;注:これはチェーンの最後のルールである必要があります" -j KUBE-NODEPORT-CONTAINER
I0807 11:41:24.575633 8369 proxier.go:399]チェーン:INPUT、ルール:: INPUT ACCEPT [0:0]
I0807 11:41:24.575646 8369 proxier.go:399]チェーン:出力、ルール::出力受け入れ[0:0]
I0807 11:41:24.575658 8369 proxier.go:401]ルール:-A OUTPUT -m comment --comment "handle ClusterIPs;注:これはNodePortルールの前にある必要があります" -j KUBE-PORTALS-HOST
I0807 11:41:24.575670 8369 proxier.go:401]ルール:-A OUTPUT -m addrtype --dst-type LOCAL -m comment --comment "handle service NodePorts;注:これはチェーンの最後のルールである必要があります" -jKUBE-ノードポート-ホスト
I0807 11:41:24.575683 8369 proxier.go:399]チェーン:POSTROUTING、ルール:: POSTROOUTING ACCEPT [0:0]
I0807 11:41:24.575691 8369 proxier.go:401]ルール:-ポストルーティング! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
I0807 11:41:24.575699 8369 proxier.go:401]ルール:-A POSTROUTING -s 10.240.240.78/32 -d 10.240.240.78/32 -m comment --comment "handle pod connecting to self" -j MASQUERADE
I0807 11:41:24.575709 8369 proxier.go:399]チェーン:KUBE-NODEPORT-CONTAINER、ルール:: KUBE-NODEPORT-CONTAINER- [0:0]
I0807 11:41:24.575720 8369 proxier.go:399]チェーン:KUBE-NODEPORT-HOST、ルール:: KUBE-NODEPORT-HOST- [0:0]
I0807 11:41:24.575729 8369 proxier.go:399]チェーン:KUBE-PORTALS-CONTAINER、ルール:: KUBE-PORTALS-CONTAINER- [0:0]
I0807 11:41:24.575740 8369 proxier.go:399]チェーン:KUBE-PORTALS-HOST、ルール:: KUBE-PORTALS-HOST- [0:0]
I0807 11:41:24.581897 8369 proxier.go:603]同期ルール:: KUBE-PORTALS-HOST- [0:0]
:KUBE-PORTALS-CONTAINER- [0:0]
:KUBE-NODEPORT-HOST- [0:0]
:KUBE-NODEPORT-CONTAINER- [0:0]
:KUBE-SVC-VO8JL93ZeRSf8cnsLpl- [0:0]
:KUBE-SVC-L26cB3JYuxdW5TF84ct- [0:0]
:KUBE-SVC-j2SF8q3nUajS8vOx2qL- [0:0]
:KUBE-SVC-shln2urO8W1aBiB2bWJ- [0:0]
:KUBE-SVC-8jQ3IvijvhJ4ppFj3Ui- [0:0]
[... をちょきちょきと切る ...]

iptable-saveをverboseモードで生成された結果とマージすると、インポートして適切な処理を実行できます。

@bnprssレポートに感謝します。最近、一時ファイルの使用や、レビュープロセスの一部の書き換え中に、 iptables-restoreの「-Tテーブル」フラグを使用するなど、テストされていない変更が多数ありました。 リグレッションの原因がわかったら、修正を加えます。

@bnprssテーブルヘッダーがない(「* nat」が最初の行である必要がある)と言ったように、誤って削除され、それを元に戻した後、他のバグはないように見えます(https:/を除く)。 /github.com/BenTheElder/kubernetes/issues/3)。 再度ありがとう、それについて申し訳ありません。 修正をプッシュしました。

よくできました。ルールが読み込まれ、内部から機能しているように見えますが、外部ロードバランサーでは運がなく、外部からの通信がありません。

は。 PRに移って、詳細を教えていただけますか? ここのところ
それはうまく機能していますが、私はローカルテストを超えて自分自身を展開していません。
他のテスターが外部ロードバランサーを使用していたとは思わないでください。
2015年8月7日午後1時29分、「bnprss」 [email protected]は次のように書いています。

よくできました。ルールが読み込まれ、内部からは機能しているようですが、運がありません。
外部ロードバランサーを使用すると、外部からの通信が応答しません。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128772763

はい、詳細については、さらに問い合わせを行い、PRに関するログまたはリードを作成しますが、明日までに、何かを壊す可能性がある前に実行するための適切なバックアップジョブが必要です。

区切り文字「-_」なしでルールのトークンを計算できますか?

@bnprss 、すばらしい。
サービス用に生成されたルールチェーンは、サービスポート/エンドポイントのハッシュであり、base64urlがエンコードされて切り捨てられます。 KUBE-SVC-。 コードは次のとおりです: https
これは、決定論的でありながらiptablesの文字数制限を満たす有効なチェーン名を生成する方法として選択しました。
したがって、外部で複製できるはずです。
つまり、区切り文字の使用をやめることはできますか。ただし、「_」はエンコードされたハッシュに由来し、「-」はすべて既存のユーザースペースプロキシのルール名のパターンに従っているだけです。
必要に応じて、他の何かを問題なく使用できる可能性があります。

私はそれで大丈夫です、そしてこれは本当に化粧品です! :)
しかし、これは私が以前に見たものとは異なります:
gce lbルール:a07f76b3b2ec311e59e2642010af0479
gce fwルール:k8s-fw-a7ecad94f3ba511e59e2642010af0479
gceルーティングルール:default-route-6973e029b504a0e8
ノードへのgceルーティング:obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

これはいいです:
KUBE-SVC-6ADi2TVfn7mFPvBjC56
それらのものは面白いです:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y--z1xTUpHPT6sgAUCC

ええ、私も彼らのファンではありません、おそらくハッシュを変更することができます
エンコーディング。

14:16時金、2015年8月7日には、bnprss [email protected]書きました:

私はそれで大丈夫です、そしてこれは本当に化粧品です! :)
しかし、これは私が以前に見たものとは異なります:
gce lbルール:a07f76b3b2ec311e59e2642010af0479
gce fwルール:k8s-fw-a7ecad94f3ba511e59e2642010af0479
gceルーティングルール:default-route-6973e029b504a0e8
ノードへのgceルーティング:
obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

これはいいです:
KUBE-SVC-6ADi2TVfn7mFPvBjC56
それらのものは面白いです:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y--z1xTUpHPT6sgAUCC


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128785914

はい、SHAの切り捨てられた部分のみを使用することが可能です。gitはそれで問題ありません。dockerも同様であり、kubeエンティティへの他の参照が行われる方法のようです。 生成されたハッシュで衝突が発生した場合、base64は役に立ちません。 ;)
@thockinがその点についてアドバイスできると思います。

私はiptablesの有効な文字にもっと関心があり、適切なリファレンスを見つけるのに苦労しました。 これについては、後ほど詳しく説明します。

2時29分PMで金、2015年8月7日には、bnprss [email protected]書きました:

はい、SHAの切り捨てられた部分のみを使用することが可能です。gitは問題ありません。
それ、dockerも、そしてkubeへの他の参照の方法のようです
エンティティが作成されます。 生成されたハッシュbase64で衝突が発生した場合、
ヘルプ。 ;)
@thockinhttps ://github.com/thockinがその点についてアドバイスできると思い


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128788454

@bnprss fyi PRはかなり不安定で、やり直されています。thockinごとに、今のところNodePortなどを削除し、ポータルをサポートするよりシンプルでクリーンなバージョンを取得してから、完全なパリティに戻すことに重点を置いています。

今はこれを実行しようとはしませんが、うまくいけばすぐに戻ってきます。 PRをいくつかの小さな関連するものに分割し、今すぐiptables-proxyのものでクリーンなものをプッシュします。

家で遊んでいる人たちのために、私たちはそれをいっぱいにすることができると確信しています
同等ですが、段階的に確認する方がはるかに簡単です:)

2015年8月7日金曜日午後9時35分、ベンジャミンエルダー[email protected]
書きました:

上記のコメントへの私の返信、またすぐに押しつぶされます:

IRCで議論:

  • それでもカウンターを処理する必要がありますが、解析を続けたい
    util / iptablesパッケージの状態。
  • チェーンの長さの制限を処理するには、ハッシュなどが必要です

そうでなければ、非常にクリーンな単純化のように見え、後に実装されます
もう少し議論。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128912169

ステータス:「メイン」ロジックがチェックインされ、フラグゲートされます。

現在、ノードポートに取り組んでいます。 特別な処理が必要な奇妙なケースがたくさんあります。 これまでの私のメモ:

# Basic node ports:
iptables -t nat -N KUBE-NODEPORTS
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A OUTPUT -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m comment --comment "TEST: default/nodeport:p" -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

# To get traffic from node to localhost:nodeport to the service:
echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet
# Mark packets that are destined for services from localhost, then masquerade those
iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

# To get traffic from a pod to itself via a service:
for intf in $(ip link list | grep veth | cut -f2 -d:); do brctl hairpin cbr0 $intf on; done
# Mark packets that are destined for each endpoint from the same endpoint, then masquerade those.
# This is hacky, but I don't really know which pods are "local" and I don't really want to right now. (but I will eventually)
iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001

テスト用の寄稿ツールに取り組んでいます。
これまでのところ、ノード上でサーバーを起動すると考えています。
それへのリクエスト、kube-proxyリソースのロードとダンプの取得について見てください
グラフ化などのためにデータをCSVに変換します。
うまくいけば、金曜日の前に行われ、今すぐkubectlに慣れてきます。

20:48の水曜日、2015年8月12日には、ティムHockin [email protected]
書きました:

ステータス:「メイン」ロジックがチェックインされ、フラグゲートされます。

現在、ノードポートに取り組んでいます。 必要な奇妙なケースがたくさんあります
特殊な取り扱い。 これまでの私のメモ:

基本的なノードポート:

iptables -t nat -N KUBE-NODEPORTS
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A OUTPUT -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m comment --comment "TEST:default / nodeport:p " -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

ノードからlocalhost:nodeportからサービスへのトラフィックを取得するには:

エコー1> / proc / sys / net / ipv4 / conf / all / route_localnet

ローカルホストからのサービス宛てのパケットにマークを付け、それらをマスカレードします

iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

サービスを介してポッドからそれ自体にトラフィックを取得するには:

$のintfの場合(ipリンクリスト| grep veth | cut -f2 -d :); brctl hairpin cbr0 $ intfをオンにします。 終わり

同じエンドポイントからの各エンドポイント宛てのパケットにマークを付けてから、それらをマスカレードします。

これはハッキーですが、どのポッドが「ローカル」であるかはよくわかりません。今はあまり知りたくありません。 (しかし、私は最終的に)

iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130492394

@BenTheElder GCEでかなり詳細なネットワークパフォーマンス測定を行ったところです。netperfを確認することをお勧めします(qperfは遅延測定も提供します)。

netperfはクライアント/サーバーパフォーマンスツールです。クライアントとサーバーの両方をDockerコンテナーpaultiplady / netserver:ubuntu.2にパッケージ化しました。 netperfにはたくさんのオプションがありますが、2つのnetserverポッドを起動して実行するようなものです

kubectl exec  -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j -H $netserver-pod-2-ip -t OMNI --  -T tcp -D -O THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

レイテンシーとスループットを含む統計のまともな広がりを与えるはずです。 docker run --net=hostを使用してnetserverコンテナーを実行し、ノード->ポッドテストを実行することもできます。

このコンテナのdockerfileは非常に単純です。よりスリムなものに拡張したい場合は、それを起動できます(たとえば、より高速にプルするためのalpinelinuxベースのコンテナ)。

おかげで私はそれを調べます。

このコメントから

ただし、netperf / qperfについて見ていきますが、常に複数のテストを行うことができます。
@thockinとの以前の議論によると、最初にそのグラフを完成させたいと思います。

12時02 AMに木、2015年8月13日には、ポール・Tiplady [email protected]
書きました:

@BenTheElderhttps ://github.com/BenTheElder私は合理的にやっただけです
GCEでの詳細なネットワークパフォーマンス測定-ご覧になることをお勧めします
netperf(qperfはレイテンシーの測定値も提供します)。

netperfはクライアント/サーバーパフォーマンスツールです。クライアントとサーバーの両方をパッケージ化しました。
Dockerコンテナ内のサーバーpaultiplady / netserver:ubuntu.2。
netperfにはたくさんのオプションがありますが、2つスピンアップするようなものです
ネットサーバーポッドと実行中

kubectl exec -t $ netserver-pod-1 --netperf –l 30 -i 10 -I 99,1 -c -j -H $ netserver-pod-2-ip -t OMNI --- T tcp -D -O THROUGHPUT、THROUGHPUT_UNITS、MEAN_LATENCY、MIN_LATENCY、MAX_LATENCY、P50_LATENCY、P90_LATENCY、P99_LATENCY、STDDEV_LATENCY、LOCAL_CPU_UTIL

レイテンシーとスループットを含む統計のまともな広がりを与えるはずです。
docker run --net = hostを使用してnetserverコンテナを実行できます。
ノード->ポッドテストも。

このコンテナのdockerfileは非常に単純です。
あなたはそれをよりスリムなものに拡張したい(例えば、alpinelinuxベース
より速く引っ張るための容器)。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576

ノードポートに関して:#9210で@Symmetricはこのケースをもたらしました:

トラフィックが流れる場合:
LB -> node1:nodePort
また、サービスポッドがnode2にある場合、完全なフローは次のようになります。
LB -> node1:nodePort -> node2 -> pod:svcPort
srcIPは引き続きLBであるため、応答は次のようになります。
pod -> node2 -> LB
node2はLBに直接ルーティングできるため。

これで、DNATを解除して、リターンパケットの正しい送信元IPを復元する機会が失われます(これは、ノード1でのみ発生する可能性があります)。

問題を再現しました。 それが本当の問題であることを確認してください。 tcpdumpは、(オフマシンの)ポッドIP:portにDNATされているパケットを、srcをそのままにして表示しますが、宛先マシンのtcpdumpは何も表示しません。 パケットが届いたとしても、どうなるかわかりません。

唯一の解決策はSNATだと思います。 最も影響の少ない解決策は、オフノード宛てのLBからのSNATパケットのみを_のみ_することですが、a)kube-proxyにその情報がありません(コードを犠牲にして取得できます)。ポリシーはとにかくSNATの場合を考慮する必要がありますが、外部LBパケットを常にSNATすることで単純化できます。 それは政策エンジンにとってどれほど悪いのでしょうか?

最終的に、LBはポッドを持つホストのみをターゲットにするのに十分スマートになり、トラフィックはローカルのままになり、これは意味がなくなります。

しかし、それはもっと複雑になります。 deprecatedPublicIPsフィールドがありますが、動作を微調整することで、おそらく非推奨ではなくなります。 私たちはそれらのために同じことをする必要があると思います。 しかし、それはさらに複雑になります-私は実際にすべてのパブリックIPを知っているわけではありません(たとえば、VMには1対1のNAT外部IPがあります)。 簡単な答え-常にSNATノードポートパケット。 どう思いますか?

明日もっとテストします。

@BenTheElderネットサーバーポッドをサービスにして、パフォーマンスからのトラフィックを<->
サーバーはサービスVIPを経由しています。 そうすれば、あなたはする必要はありません
サンプリング/レイテンシの計算を自分で...

2015年8月12日水曜日午後9時20分、ベンジャミンエルダー[email protected]
書きました:

おかげで私はそれを調べます。

このコメントから
ある種のサービスリクエストのレイテンシーを実行したいと思いますが。 右
今私はノードXとして標準のnginxコンテナを使用して作業しようとしています
グラフを作成できるように、テストポッドの時間を繰り返しヒットする
ノードY。

ただし、netperf / qperfについて見ていきますが、常に複数のテストを行うことができます。
以前の議論によると、最初にそのグラフを完成させたいと思います
@thockin

12時02 AMに木、2015年8月13日には、ポール・Tiplady [email protected]
書きました:

@BenTheElderhttps ://github.com/BenTheElder私は合理的にやっただけです
GCEでの詳細なネットワークパフォーマンス測定-ご覧になることをお勧めします
netperf(qperfはレイテンシーの測定値も提供します)。

netperfはクライアント/サーバーパフォーマンスツールです。クライアントとサーバーの両方をパッケージ化しました。
Dockerコンテナ内のサーバーpaultiplady / netserver:ubuntu.2。
netperfにはたくさんのオプションがありますが、2つスピンアップするようなものです
ネットサーバーポッドと実行中

kubectl exec -t $ netserver-pod-1 --netperf –l 30 -i 10 -I 99,1 -c -j -H
$ netserver-pod-2-ip -t OMNI --- T tcp -D -O
THROUGHPUT、THROUGHPUT_UNITS、MEAN_LATENCY、MIN_LATENCY、MAX_LATENCY、P50_LATENCY、P90_LATENCY、P99_LATENCY、STDDEV_LATENCY、LOCAL_CPU_UTIL

レイテンシーや
スループット。
docker run --net = hostを使用してnetserverコンテナを実行できます。
ノード->ポッドテストも。

このコンテナのdockerfileは非常に単純です。
あなたはそれをよりスリムなものに拡張したい(例えば、alpinelinuxベース
より速く引っ張るための容器)。


このメールに直接返信するか、GitHubで表示してください
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558

NS。 @thockinは、最終的にe2eレイテンシテストが
良い。 時間の許す限り、さまざまなテストが行​​われ、
おそらくgceとAWSなどを考慮する必要があります。
2015年8月13日午後1時47分、「PaulTiplady」 [email protected]は次のように書いています。

ネットサーバーポッドをサービスにして、パフォーマンスからのトラフィックを<->
サーバーはサービスVIPを経由しています。 そうすれば、あなたはする必要はありません
サンプリング/レイテンシの計算を自分で...

2015年8月12日水曜日午後9時20分、ベンジャミンエルダー[email protected]
書きました:

おかげで私はそれを調べます。

[このコメント]から(

https://github.com/kubernetes/kubernetes/pull/9210#issuecomment-130154261)
ある種のサービスリクエストのレイテンシーを実行したいと思いますが。 右
今私はノードXとして標準のnginxコンテナを使用して動作しようとしています
オン
グラフを作成できるように、テストポッドの時間を繰り返しヒットする
ノードY。

ただし、netperf / qperfについて見ていきますが、常に複数のテストを行うことができます。
以前の議論によると、最初にそのグラフを完成させたいと思います
@thockin

2015年8月13日木曜日午前0時2分、Paul Tiplady < [email protected]

書きました:

@BenTheElderhttps ://github.com/BenTheElder私はちょうどいくつかをしました
合理的に
GCEでの詳細なネットワークパフォーマンス測定-ご覧になることをお勧めします

netperf(qperfはレイテンシーの測定値も提供します)。

netperfはクライアント/サーバーパフォーマンスツールです、私は両方のクライアントをパッケージ化しました

Dockerコンテナ内のサーバーpaultiplady / netserver:ubuntu.2。

netperfにはたくさんのオプションがありますが、2つスピンアップするようなものです
ネットサーバーポッドと実行中

kubectl exec -t $ netserver-pod-1 --netperf –l 30 -i 10 -I 99,1 -c -j
-NS
$ netserver-pod-2-ip -t OMNI --- T tcp -D -O

THROUGHPUT、THROUGHPUT_UNITS、MEAN_LATENCY、MIN_LATENCY、MAX_LATENCY、P50_LATENCY、P90_LATENCY、P99_LATENCY、STDDEV_LATENCY、LOCAL_CPU_UTIL

レイテンシーや
スループット。
docker run --net = hostを使用してnetserverコンテナを実行できます。
ノード->ポッドテストも。

このコンテナのdockerfileは非常に単純で、起動できます
もしも
あなたはそれをよりスリムなものに拡張したい(例えば、alpinelinuxベース
より速く引っ張るための容器)。


このメールに直接返信するか、GitHubで表示してください
<

https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576


このメールに直接返信するか、GitHubで表示してください
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130776866

@Symmetricnetperfテストはうまく機能しています。 提案をありがとう:-)

後でWebサービスのような「実際の」負荷のテストを修正したいのですが、引数を正しく取得した後、これまでのところ非常に優れたデータが得られています。 後片付けが終わったら結果を投稿します。

それがあなたのために働いていると聞いてうれしいです-途方もない数があります
そのツールのオプションですが、私のプロファイリング作業に非常に役立つことが証明されています。
iperfよりも間違いなく優れています...

2015年8月13日木曜日午後2時32分、ベンジャミンエルダー[email protected]
書きました:

@Symmetric https://github.com/Symmetricnetperfテストが機能しています
うまく。 提案をありがとう:-)

後でWebサービスのような「実際の」負荷のテストを改訂したい
おそらく、しかし引数を正しく取得した後、それは非常に素晴らしいデータを提供しているので
遠い。 後片付けが終わったら結果を投稿します。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130850398

@thockin私たちはLBトラフィックのためにSNATと一緒に暮らすことができると思います。 私の現在の考えでは、ポッドのアクセスポリシーを次のいずれかとして指定する必要があります。

  • デフォルトは「[mynamespace]から許可」です。この場合、LBパケットはドロップされます。
  • 'allow from [名前空間]'または 'allow from [クラスター内のすべての名前空間]'、ここでもLBパケットは常にドロップされます
  • 「すべてから許可」。この場合、それがLB、他のノード、またはどこからのものであるかは関係ありません。

したがって、LBのソースIPを失っても、実際にはそれほどコストはかかりません。

LBがサービスポッドの適切なノードに到達していることを保証できれば、それは素晴らしいことです。その場合、SNATは必要ありません。また、LB IPがプロビジョニングされているときに、それらをホワイトリストに登録することで、よりタイトな船を実行できます。サービス、およびそれ以外の場合はトラフィックをドロップします。

publicIPに関しては、nodePortと同じ考慮事項があると思います。したがって、LBが適切なホストにヒットするまで、それらをSNATする必要があります。 nodePortよりも邪悪であるという何らかの方法を見逃していない限り、上記のどれが問題ありません...

安全対策として、すべてをMASQUERADEにプロキシするフラグを実際に含めると非常に便利です(ユーザースペースプロキシに非常に近い動作をします)。 私はそれを行うのはそれほど難しいことではなく、問題が発生した場合に診断またはフォールバックするための非常に良い方法だと思います(私はvxlanのケースについて考えています)。

--------メッセージd'origine --------
デ:ポール・Tiplady [email protected]
日付:2015年8月14日12:50(GMT + 11:00)
À:kubernetes / kubernetes [email protected]
Cc: Mikaë[email protected]
Objet:Re:[kubernetes]プロキシの代わりにiptablesを使用する
(#3760)

@thockin私たちはLBトラフィックのためにSNATと一緒に暮らすことができると思います。 私の現在の考えでは、ポッドのアクセスポリシーを次のいずれかとして指定する必要があります。

デフォルトは「[mynamespace]から許可」です。この場合、LBパケットはドロップされます。
'allow from [名前空間]'または 'allow from [クラスター内のすべての名前空間]'、ここでもLBパケットは常にドロップされます
「すべてから許可」。この場合、それがLB、他のノード、またはどこからのものであるかは関係ありません。

したがって、LBのソースIPを失っても、実際にはそれほどコストはかかりません。

LBがサービスポッドの適切なノードに到達していることを保証できれば、それは素晴らしいことです。その場合、SNATは必要ありません。また、LB IPがプロビジョニングされているときに、それらをホワイトリストに登録することで、よりタイトな船を実行できます。サービス、およびそれ以外の場合はトラフィックをドロップします。

publicIPに関しては、nodePortと同じ考慮事項があると思います。したがって、LBが適切なホストにヒットするまで、それらをSNATする必要があります。 nodePortよりも邪悪であるという何らかの方法を見逃していない限り、上記のどれが問題ありません...


このメールに直接返信するか、GitHubで表示してください。

@MikaelCluseauそれは悪い考えではありません-それについて具体的に新しい問題を開いていただけませんか?そうすれば私はそれを

それでもTODO:ヘアピンe2eを修正し、デフォルトで有効にする

こんにちはティム、あなたに戻ってこないことをお詫びします、しかし私達はここで処理するためにいくつかの混乱を持っていました...私は次の土曜日に修正ヘアピンを選ぶと思います。

これは私自身へのメモでした-あなたはこれのいくつかに取り組むことを計画していましたか? :)

はい、確かに、e2eテストについて話していたときに言ったように。 私がお手伝いします。Kubernetesは私にとって非常に役立つので、可能な限り習得したほうがいいです。バグを取るよりも何が最善ですか? :-)優先度の高いものを自由に提案してください。ただし、ヘアピンは最初はかなり良いと思います。 これはkubeletで行われ、有効にするフラグが必要です(最初はデフォルトで無効になっています)。 私は週に0.5から1日働くようにします。

AFAIKは、これをデフォルトにすることだけを残しました。これは、v1.1の後で発生する可能性があり(ブローアップがないと仮定)、これには数マイルの余裕があります。

おっと!

11:21の木、2015年9月24日には、ティムHockin [email protected]
書きました:

この残りの部分は、デフォルトにすることだけです。
v1.1の後で(爆発がないと仮定して)発生し、これには数マイルあります
その上に。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142960614

v1.1の後しばらくして、これには数マイルあります。

痛い。 私たちは本当に1.1のためにそれを頼りにしていました...。
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md

@bgriederは、パラメーターを使用して有効にすることができます。

INですが、デフォルトではオンではありません。 ごとに1つのアノテーションでオプトインできます
ノード(およびkube-proxyの再起動)

8:27の木、2015年9月24日には、ブルーノ・G.の[email protected]書きました:

v1.1の後しばらくして、これには数マイルあります。

痛い。 私たちは本当に1.1のためにそれを頼りにしていました...。
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142962932

@thockin @bnprssわかりましたが、リリース後にバージョン1.1がGoogle ContainerEngineで実行されることを期待しています。 「ノードごとに1つの注釈でオプトインする」にはどのような柔軟性が必要になるのだろうか。 プロセスの詳細を教えてください。または、ドキュメントを教えてください。

1.1にアップグレードしたら:

$ for node in $(kubectl get nodes -o name); do kubectl annotate $node net.beta.kubernetes.io/proxy-mode=iptables; done

次に、各ノードにSSHで接続し、kube-proxyを再起動します(または各ノードを再起動します)。

もっと慎重になりたい場合は、1つまたは2つのノードを実行してから、試してみてください:)

この問題を「リリースノート」としてマークしたので、1.1のドキュメントにその魔法のループを含めることを忘れないでください。

@RichieEscarez

(立ち寄って、iptablesプロキシを1週間使用していると言いたかったのですが、すべて問題ないようです!)

@thockinこれを閉じるか、1.1マイルストーンから削除する必要がありますか?

デフォルトの有効化のためだけに1.2に移動します。

馬鹿げた質問の可能性があることをお詫びしますが、クライアントIPの保存に関して:

@thockin 9月2日の別の問題で、「クラスター内トラフィックのみがクライアントIPを保持する」と

新しい1.2クラスターを起動し、ノードアノテーションを適用して再起動しましたが、HAProxyを実行しているポッドに対して行われたすべてのリクエストの送信元アドレスとして10.244.0.1が表示されます。

この時点で、設定を見逃したかどうか、またはまだ不可能なことを達成しようとしているかどうかを把握しようとしています。つまり、実際のクライアントのパブリックIPアドレスがクラスターの外部。

デフォルトでは、引き続きユーザースペースモードが使用されます。 に注釈を設定する必要があります
ノード(net.beta.kubernetes。io/ proxy-mode = iptables)を再起動し、
プロキシー。 ただし、外部クライアントIPは公開されず、クラスター内のみが公開されます。
IP。
2015年10月23日17:09、「BenHundley」 [email protected]は次のように書いています。

馬鹿げた質問の可能性があることをお詫びしますが、保存について
クライアントIPの数:

@thockinhttps ://github.com/thockin9月2日の別の号で見ました
「クラスター内トラフィックのみがクライアントIPを保持する」ということ-これはまだですか
1.2アルファに当てはまりますか?

新しい1.2クラスターを起動し、ノードアノテーションを適用し、再起動し、
それでも、に対して行われたすべてのリクエストの送信元アドレスとして10.244.0.1が表示されます。
HAProxyを実行しているポッド。

この時点で、私は私たちが逃したかどうかを理解しようとしています
設定するか、まだ不可能なことを達成しようとしています-それ
リクエストを行っている実際のクライアントのパブリックIPアドレスを確認しています
クラスターの外部から。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150725513

外部トラフィックをDNATし、kube-proxyを介してルーティングすることで、外部クライアントのIPを維持できます。 たとえば、サービスネットワークが10.42.0.0/16で、IP 10.10.1.1に高可用性kubeプロキシがある場合、次のiptableルールを設定できます。

-A PREROUTING -i public -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

および次のルート:

10.42.0.0/16 via 10.10.1.1 dev edge 

背後のポッドは、実際のIPを確認します。

Oct 24 02:41:39 email-0yr7n mail.info postfix/smtpd[469]: connect from zed.yyy.ru.[94.102.51.96]

もちろん、パケットのリターンパスを正しく設定する必要があります。

ええ、このDNATがオフマシンのバックエンドに接続されている場合、
SNAT。 これが根本的な問題です。

20:12時金、2015年10月23日には、ミカエルCluseau [email protected]
書きました:

外部トラフィックをDNATすることで、外部クライアントのIPを維持できます+
kubeプロキシを介したルーティング。 たとえば、サービスネットワークが
10.42.0.0/16で、IP上に可用性の高いkubeプロキシがあります
10.10.1.1では、次のiptableルールを設定できます。

-事前設定-ipublic -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

および次のルート:

10.10.1.1開発エッジ経由の10.42.0.0/16

背後のポッドは、実際のIPを確認します。

10月24日02:41:39email-0yr7n mail.info postfix / smtpd [469]:zed.yyy.ruから接続します。[94.102.51.96]

もちろん、パケットのリターンパスを正しく設定する必要があります。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150747217

面白そうですね、リンクはありますか? :-)パケットが正しいconntrackルールを通過することを確認する方法を見つけようとしています。 クラスターを介してconntrackの状態を複製することを考えていました。

私はあなたが達成しようとしていることに少し迷っています。

現在のiptablesプロキシが機能することになっている方法は、パケット
ノードに到着すると、ローカルで生成されていないことが検出され、フラグが立てられます。
SNAT、バックエンドを選択し、SNATを使用してバックエンドに転送し、バックエンドが応答します
私たちにとって、私たちはSNATやDNATを解除し、外部ユーザーに対応します。

21:32時金、2015年10月23日には、ミカエルCluseau [email protected]
書きました:

面白そうですね、リンクはありますか? :-)私は確実にする方法を見つけようとしています
パケットは正しいconntrackルールを通過します。 考えていた
クラスターを介してconntrack状態を複製します。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150753147

わからない場合は申し訳ありません。 私はSNATのないケースについて話していました。 すべてのkube-proxyが同じconntrackリストを持っている場合、コンテナが顧客に応答するときに、それらのいずれかが正しくDNATを解除できるはずです。

次のような線状の構造を維持するためにHAを使用しないレプリケーションがない場合はわかりませんでした。

[client] ----- [proxy in HA] ------ [node1]
                           `------- [node2]

しかし、三角形のものが機能することができれば、それはより多くの可能性を開くはずです。

[client] ----- [proxy1] ------ [node1]
       `------ [proxy2] ------ [node2]

それはかわいいでしょうが、クレイジーで複雑に見えます

23:20の日、2015年10月25日には、ミカエルCluseau [email protected]
書きました:

わからない場合は申し訳ありません。 私はSNATのないケースについて話していました。 もしも
すべてのkube-proxyには同じconntrackリストがあり、それらのいずれもができるはずです
コンテナが顧客に返信するときに、DNATを正しく解除します。

を維持するためにHAを必要としないレプリケーションなしのwasを見ることができませんでした
このような線状の構造:

[クライアント] ----- [HAのプロキシ] ------ [node1]
`------- [node2]

しかし、三角形のものが機能することができれば、それはより多くの可能性を開くはずです。

[クライアント] ----- [proxy1] ------ [node1]
`------ [proxy2] ------ [node2]


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151037663

私が探求しなければならない方法(私は適切な調査の前に尋ねたくありませんが、サブジェットが開いているので...)はここで見ることができる「非対称マルチパスルーティング」です:http:// conntrack-tools.netfilter.org/manual.html#sync-aa。 そして、はい、それは本当に本当に素晴らしいでしょう:-)

おそらく機能する可能性のある最も単純なもの...

  1. proxy1はiptablesフックを介して新しい接続を受信し(どこかで見たことがあると思います)、そのLBがそれをproxy2のノードに割り当てます。
  2. proxy1は、「{src-ip}:{src-port}-> {pod-ip}:{pod-port}のconntrackエントリを設定する」のようなリクエストを送信します。
  3. proxy2はリクエストを受信し、conntrackエントリを設定して、proxy1にACKします。
  4. proxy1は、パケットにDNATルールを通過させます(これにより、conntrackエントリもproxy1に配置されます)。
  5. ポッドが応答すると、proxy2のホストはそれに応じてDNATをunDNATします。
  6. クライアントがproxy1を介してこのフローで別のパケットを送信すると、conntrackエントリも適切なDNATを実行します。

このように、オーバーヘッドは新しい接続ごとに2パケットであり、非SNAT +余分なルーティングを回避することで迅速に返済されます(そうでない場合、パケットはproxy1を経由して戻る必要があるため)。

私はネットワークの人ではないので、思い込みすぎるかもしれませんが、それは理にかなっているようです。

私の場合、NodePortサービスごとにファイアウォールルールを確立することを目指していました。

次のように、INPUTチェーンに他のすべてのルールを単純なALLOW IP / DROPで追加できるようです。

iptables -A INPUT -s $WHITELISTED_IP -p tcp --dport $CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $CONTAINER_PORT -j DROP

これらのルールを適用するために、私が想定していたのは、NodePortサービスで注釈を使用することでした。 注釈はホワイトリストに登録されたIPを保持します。

これらのルールが適用されるのを少し待つことができるので、各ミニオンで細かくcronタスクが実行され、すべてのサービスアノテーションからミニオンのINPUTチェーンが更新されることを想像しました。

ここで問題を引き起こす可能性のあるものはありますか? 私は気が狂っていますか?

@thockinは私よりも優れたビューを持っていますが、これには注釈を使用しません。 セキュリティは直交しているので、システムとは別に、またはネットワーク/プロキシプラグインに配置する必要があると思います。 Kubernetesを使用している場合は、etcdを使用しているため、ルールセットをキーに保存し、etcdctl watch / execで更新するだけです。

# while true; do etcdctl watch "/iptables/$(hostname)" && etcdctl get /iptables/$(hostname) |iptables-restore --noflush; done &
# iptables -F my-filter
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination      
# ~nwrk/go/bin/etcdctl set /iptables/$(hostname) >/dev/null <<EOF
*filter
:my-filter -
-A my-filter -j ACCEPT -s 1.2.3.4 -p tcp --dport 80
-A my-filter -j DROP -p tcp --dport 80
COMMIT
EOF
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      *       1.2.3.4              0.0.0.0/0            tcp dpt:80
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80

欲しいと思います#14505

8:53で月、2015年10月26日には、ベンHundley [email protected]
書きました:

私の場合、NodePortサービスごとにファイアウォールルールを確立することを目指していました。

単純なALLOWIP / DROP他のすべてのルールを追加できるようです
INPUTチェーンは次のようになります。

iptables -A INPUT -s $ WHITELISTED_IP -p tcp --dport $ CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $ CONTAINER_PORT -j DROP

これらのルールを適用するために、私が想像していたのは、
NodePortサービス。 注釈はホワイトリストに登録されたIPを保持します。

これらのルールが適用されるのを少し待つことができるので、私は細かく想像しました
ミニオンのINPUTを通過して更新する各ミニオンのcronタスク
すべてのサービスアノテーションからのチェーン。

ここで問題を引き起こす可能性のあるものはありますか? 私は気が狂っていますか?


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151181267

これが最初のアプローチであり、セキュリティグループがロードバランサーに接続されていました。 AWSでネットワークインターフェースあたりのリスナーの制限に非常に速く到達し、ファイアウォールルールを単一のkubeクラスターの複数のSGと複数のELBに分散させようとするいくつかの厄介なロジックに遭遇しました。

幸いなことに、iptablesをいじくり回すことを伴わないより良いソリューションに取り組んでいます。

参加したばかりの場合は、要約させてください。 クライアントIPを取得できないことに関するすべての問題がこの問題に統合されましたが、提案された(および実装された)ソリューションでは解決されません。 現在、クライアントのIPにアクセスする方法はありません。 ハ。

@ shaylevi2現在、クラウドLBを介してnodePortにバウンスしているときにクライアントIPを取得する良い方法はありません。 クラウドLBが追いついたら、すぐにジャンプします。 しかし、これはクラスター内のクライアントIPを保持します

しかし、これはクラスター内のクライアントIPを保持します

これは、クラスターネットワークがどのように設定されているかによって異なります。 たとえば、iptablesルールはOVS内部トラフィックで実行されないため、現時点ではOpenShiftでは正しく機能しません。 したがって、パケットはサービスエンドポイントに入るDNATを取得しますが、ソースIPはクラスター内部であるため、応答はOVS内にとどまり、iptablesに再度ヒットすることはなく、DNATが逆になることはありません。そのため、クライアントポッドはパケットを認識しません。 現時点では、これに対する最も簡単な回避策は、エンドポイントに入るパケットを完全にマスカレードし、途中でOVSから再びバウンスするように強制することです。 (私はこれを回避する方法を考え出すことに取り組んでいます。)

OVSには内部的にVIPの概念がありますか? あなたはただ取り除くことができます
kube-proxy(cf opencontrail)

7:09で金、2015年11月20日には、ダン・ウィンシップ[email protected]
書きました:

しかし、これはクラスター内のクライアントIPを保持します

これは、クラスターネットワークがどのように設定されているかによって異なります。 たとえば、そうではありません
iptablesルールが実行されないため、現時点ではOpenShiftで正しく機能します
OVS-内部トラフィック。 したがって、パケットはDNATされてサービスに入ります
エンドポイントですが、送信元IPはクラスター内部であるため、応答は
OVS内にとどまるので、iptablesに再びヒットしないので、DNATはヒットしません
逆になり、クライアントポッドはパケットを認識しません。 で
このための最も簡単な回避策は、パケットを完全にマスカレードすることです。
エンドポイントに入り、OVSから再びバウンスするように強制します
逃げ道。 (私はこれを回避する方法を考え出すことに取り組んでいます。)


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158426296

完全にOVS内でpure-iptables-proxyingと本質的に同等のことを行うことについて話しましたが、それにはOVS conntrackサポートが必要であり、これにはまだ依存したくないごく最近のカーネルが必要です。 それはおそらく長期計画です。

(今のところ、コンテナインターフェイスからの既知のサービスエンドポイントに一致する送信元IP +ポートを持つパケットに対して、OVSから無償の追加ホップを追加することで機能させることができるようです。ノードはおそらくそれを非DNATします、次にそれをOVSにバウンスして戻し、そこでクライアントポッドに正しく配信します。)

Service VIPの抽象化に関するドキュメントを作成して、作成したいと思っています。
それは置き換えることができる抽象化であることを明確にします(そしていくつかの中にあるべきです
ケース)。

6:54で月、2015年11月23日には、ダン・ウィンシップ[email protected]
書きました:

私たちは本質的に同等のことをすることについて話しました
pure-iptables-完全にOVS内でプロキシしますが、OVSconntrackが必要です
サポート。これには、依存したくない最新のカーネルが必要です。
まだ。 それはおそらく長期計画です。

(今のところ、無償の追加機能を追加することで機能させることができるようです
既知のサービスと一致する送信元IP +ポートを持つパケットのOVSからホップアウトします
コンテナインターフェイスからのエンドポイント。 その後、ノードは
おそらくそれをDNAT解除してから、OVSにバウンスして戻します。
クライアントポッドに正しく返送されました。)


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158959014

iptables / nftablesはTCPとUDPの両方の負荷分散のユースケースを解決しますが、個人的にはIPVS https://github.com/kubernetes/kubernetes/issues/17470が負荷分散専用に構築されているため、はるかに適していると思います。 (読み取り:k8sチームの継続的な変更/メンテナンスが少ない)、より豊富な負荷分散アルゴリズムのセットを提供し、ほぼラインレートの速度で安定性が証明されており、amdにはルールを操作する準備ができているgolangライブラリもあります。

@thockin 、その他、 https: //github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158に従って、アノテーションを作成しましたが、正しく言及されているように、外部クライアントIPはまだコンテナ内にあるアプリでは表示されません。

これを実現する方法、つまり外部クライアントIPを取得する方法は? 私のセットアップでは、外部LBはなく、サービスはノードポートとして公開され、クライアントはコンテナ化されたアプリケーションへのプレーンTCP(http / Websocketではない)接続を確立しています。

@ashishvyasどのバージョンの

v1.1.3を実行しています

https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584およびhttps://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158の指示に従いnet.beta.kubernetes.io/proxy-modenet.experimental.kubernetes.io/proxy-modeという名前のアノテーションを使用します。

for node in $(kubectl get nodes -o name); do
  kubectl annotate $node net.experimental.kubernetes.io/proxy-mode=iptables;
done

kube-proxyの起動の最初に、「Foundexperimentalannotation」や「Annotationallowsiptablesproxy」などのログステートメントが表示されます。

https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16が組み込まれた最初のリリースは1.1.4であったため、 net.beta.kubernetes.io/proxy-modeは多くの人にとって機能していません。 あなたはこれに遭遇した最初の人ではありません。

プロキシの動作方法が原因で、クライアントIPが通過すると失われます
ノードポート。 私はこれが素晴らしいことではないことを知っています。 どのようにするかは私の心に非常にあります
これを適切に修正しますが、ほとんどの場合、
ロードバランサー(またはトラフィックがノードに到達する他の方法など)
DNS-RRとして)

10:25の水曜日、2016年1月13日には、マイクDanese [email protected]
書きました:

#3760(コメント)の指示に従ってください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584
および#3760(コメント)
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158
ただし、という名前の注釈を使用する代わりに
net.beta.kubernetes.io/proxy-mode、という名前の注釈を使用します
net.experimental.kubernetes.io/proxy-mode。

$(kubectl get nodes -o name);のノードの場合 NS
kubectlは$ nodenet.experimental.kubernetes.io / proxy-mode = iptablesに注釈を付けます。
終わり

kube-proxyの起動の開始時にログステートメントが表示されるはずです
「実験的な注釈が見つかりました」や「注釈によりiptablesプロキシが許可されます」など

da9a9a9の最初のリリース
https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16
1.1.4になりました。 あなたはこれに遭遇した最初の人ではありません。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171387997

@thockin 、これに一時的に対処するための回避策は今すぐ可能ですか? はいの場合は、このスレッドで私と他の人に詳細な手順を提供することをお勧めします。

いいえ、現在、実際の回避策はありません。 問題は
各kubeプロキシが異なるノード上のバックエンドを選択する可能性があるという事実。
元のクライアントIPでトラフィックを転送すると、他のノードが使用されます
明らかに機能しない直接応答します。

「修正」は、サービスSのトラフィックを次のノードに送信することです。
S_および_がトラフィックを送信するための少なくとも1つのバックエンド
各ノードが持つバックエンド。 その後、Kubeプロキシはローカルバックエンドを選択できます
排他的に。

2つのノードと3つのバックエンドについて考えてみます。 1つのノードは必然的に2で終わります
バックエンド。 どのルートのトラフィックでも、1つのノードに2倍の量を送信する必要があります
別のノードに対して行います。 私たちはまだその問題に取り組んでいません-どれも
クラウドロードバランサーはこれをサポートしているので、一種の投機的であり、
したがって、作業を開始するのは非常に危険です。

12:17の水曜日、2016年1月13日には、アシシュVyasさん[email protected]
書きました:

@thockin https://github.com/thockin 、一時的に回避策
これは今可能ですか? はいの場合、提供することをお勧めします
このスレッドに関する私や他の人のための詳細な手順が役立ちます。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171420567

@ mikedanese

$ sudo docker pull gcr.io/google_containers/
リポジトリgcr.io/google_containers/hyperkubeをプルする
タグv1.1.4がリポジトリgcr.io/google_containers/hyperkubeに見つかりません
$ sudo docker pull gcr.io/google_containers/
v1.1.3:google_containers / hyperkubeからプル
ダイジェスト:sha256:004dde049951a4004d99e12846e1fc7274fdc5855752d50288e3be4748778ca2
ステータス:gcr.io/google_containers/ hyperkube:v1.1.3の画像は最新です

@thockin長い回答をお詫びします。これを解決しようとした両方の方法について説明し、他の人が両方で直面した課題を理解できるようにしたいと思いました。

少し背景として、私たちのメインアプリケーションは非常に高性能なスマートDNSプラットフォーム(つまり、UDPが必要で、ポッドごとに少なくとも10万以上のリクエスト/秒を実行する必要があります)と、クライアントを実際に確認する必要があるSNIプロキシでのサポートアプリケーションです。 IPアドレス(これは私たちのショーストッパーです)。 アプリケーションごとに異なるネットワークアプローチを使用したくなかったため、すべてを単一のネットワーク方式で標準化することにし、上記の理由(パフォーマンス/安定性/柔軟性/目的ビルドSLB)からIPVSを使用することにしました。 、しかし、これらの同じ行に沿ってiptablesだけを使用して、何かを一緒にハックすることもできます。 vxlan(高速、簡単、サイト間で機能)を使用しますが、これらの方法は両方とも、OVSを備えたGRE / VXLANまたは標準のレイヤー2ホストネットワークでも機能するはずです(ホストがすべて同じL2ネットワーク上にあると仮定)。

フェイルオーバー速度の要件や特定のタイプのサービスに最適なものに応じて、エニーキャストとDNSを組み合わせて着信エンドユーザートラフィックを分散するため、ノードに着信するエンドユーザートラフィックはかなり均等に分散されますが、ご指摘のとおり、問題は、ポッドの場所に関係なく、ポッド間でトラフィックが均等に分散されることです。 もう1つの問題は、他のサービスと通信するサービスの負荷が効果的に分散されていることを確認することです。

これに対処するために、2つのモデルを試みました。

私たちが試した最初の方法は、2層のVIPでした。 ノード間でトラフィックを分散する外部VIP(サービスごとに1つ)(ノード上のそのサービスのポッド数に基づく)、次にノード内で負荷を分散する内部VIP(ポッドを備えたノードで実行)(通常は)ポッド間で均等に)。 このモデルの制限は、外部VIPを実行しているノードが、2つの異なるネットワーク名前空間を実行するか、独自の物理ノードを実行する必要があることでした。 DSRモード(直接サーバーリターン)モードのIPVSの優れた点は、リターントラフィックを確認する必要がないことです。トラフィックは次のようになります。

Consumer >> (over L3) >> External VIP node >> (1) >> Internal VIP node >> (2) >> Container >> (any which way you want) >> Consumer

(1)外部VIPを持つホスト上のIPVS(DSRモード)は、トラフィックを送信する_node_(IPVS用語では「実サーバー」)を選択し、パケットのDST MACアドレスのみを変更します(つまり、IPパケットは変更されずに到着します。 k8sノード)。 ノード上でそのサービスを実行しているポッドの数に基づいて、ノード間で負荷分散します。
(2)k8sノードのIPVS(DSRモードでも)は、ポッド間でトラフィックを負荷分散します(ノードへのvethを介して)。 コンテナー(TCPおよびUDP)からの応答は、サービスのコンシューマーに直接返されます。

このモデルの利点は、開始が非常に簡単で、ルールセットの管理が非常に簡単だったことです。 このモデルの欠点は、外部VIPを実行している多数のノードを介して、すべてのサービス要求(応答ではない)が集中することです。 「シェアードナッシング」が好きなので、バージョン2に入ります。

現在おもしろい2番目のモデルは、よりスマートなIPVSおよびiptables構成を備えたVIPの単一レイヤーです。

Consumer >> Any node/local node >> (1) >> Container >> (any which way you want) >> Consumer
または、別のノードに移動する可能性があります。
Consumer >> Any node/local node >> (1) >> Remote Node >> (2) >> Container >> (any which way you want) >> Consumer

(1)トラフィックがプライマリVIPにヒットし、トラフィックはクラスター内のすべてのポッド間で負荷分散されます。
(2)トラフィックがセカンダリVIPにヒットし、トラフィックはすべてのローカルポッド間でのみ負荷分散されます。 このセカンダリVIPは、ネットワーク上の他のホスト(FWMARK VIP)から着信するトラフィックにのみ使用されます。 外部インターフェースに着信するトラフィックをFWMARK = 1234でマークします。これにより、トラフィックは別のルールセットに移動し、ノード間のループが防止されます。

プライマリVIPには、ローカルポッドとポッドを備えたリモートホストのリストがあります(各ローカルポッドの重みは100、リモートノードのポッド数は100 *)。 したがって、たとえば、3つのポッドがnodeAでローカルに実行されており、nodeBで2つのポッドが実行されている場合、nodeAのルールセットは次のようになります。

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> interfaceip.of.nodeB:80 Route 200 0 0
FWM 1234 rr
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod3.on.nodeA.ip:80 Route 100 0 0

ただし、nodeBでは、IPVS構成は2つのローカルポッドと3つのリモートポッドしかないため、少し異なって見えます。

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0
-> interfaceip.of.nodeA:80 Route 300 0 0
FWM 1234 rr
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0

もう1つの方法は、FWMARKを切り替え、iptablesを使用してveth +インターフェイス内のすべてのものをFWMARKし(ワイルドカード一致)、FWMARK一致をローカルロードバランシングにのみ使用することです。

ここにはNATが含まれていないため、各ポッドを起動するときに、環境内のSVC_XXX_YYY IPをループバックまたはダミーインターフェイスに追加する必要がありますが、IPVSVIPを変更してDNATを実行することもできます。なぜそれがうまくいかないのか。

その結果、最も直接的なネットワーキングが実現し、リクエストの処理/ルーティングを一元化する必要がなくなるため、拡張性が大幅に向上します。 欠点は、IPVSルールを作成する際のいくつかの追加の賢さです。 これらすべてを行うために小さな(golang)デーモンを使用しますが、時間があり、十分な関心があれば、このためのk8sモジュールを作成することを検討します。

私はこの問題に遅れをとっており、おそらく完全なトレイルを十分に詳しく読んでいませんが、それが役立つ場合に備えて:上記の@qokeの投稿を理解している場合、彼らはノードポートではなくVIPを使用したいと考えています。 スレッドの前半で提起された懸念の1つは、iptableskubeproxyを使用するときにソースIPが維持されないことでした。 ただし、私が信じているノードポート機能ではなく、サービスVIPを使用している場合は維持されます。 (とにかく、私が言っているように、私は実際に完全な証跡を読んでいないので、これらのコメントが明白であるか役に立たない場合は無視してください!来週戻ってきたときにそれを深く読む時間を作るようにします休暇から。)

@lxpollitt正解

私の側では、フランネル(vxlanモード)がコンテナーネットワークを管理しているので、ルーティングノードの名前空間でkube-proxy(iptablesモードでマスカレードではない)+フランネルを使用します。 外部要求は、サービスIPにDNATされてから、kube-proxyを使用して名前空間を介して転送されます。 アクティブ/アクティブルータークラスターのテストは行っていませんが、この設定により、外部IPを維持できます。 私はそれをFWIWと言いますが、それが「最も直接的なネットワーキング」ではないことを理解しています。

kube-proxyがそれを管理できればいいのですが、特定のニーズ、特に負荷分散がすでにkube-proxyの外にあるという事実を考えると、顧客のiptables-rulesmanagerをコーディングするのは意味がありません。 kubernetesクラスターの状態を監視し、実行中のホストのポッドに対してのみDNAT VIPにルールを設定しますか? これは、kube-proxyのモードでもありますが、たとえば...まあ..名前が苦手です... --proxy-mode = iptables-to-node-pods-only。

詳細な記事をありがとう。 あなたの解決策は面白いです、そして私は過ごしました
今日それについて考えるのにかなりの時間。 残念ながら、あなたは
一般的な意味で機能しない非常に特定の領域に渡った。
GCEのようなクラウドは、ルーティングされているため、IPVSゲートウェイモードを使用できません
通信網。 ゲートウェイが機能したとしても、ポートの再マッピングはサポートされていません。
これはKubernetesが行うため、サービスポート==ターゲットの場合にのみ適用されます
港。

kubernetesのコアでの課題は、
ある種の状況を一般的に、または邪魔にならないようにして、
自分で設定します。 たぶん、ipvsencapモードで何かを行うことができます。
しかし、私はそれのパフォーマンスへの影響を知りません。

3:37の木、2016年1月14日には、qoke [email protected]書きました:

@thockin https://github.com/thockin長い応答をお詫びし
他の人ができるように私たちがこれを解決しようとした両方の方法をカバーしたかった
私たちが両方で直面した課題を理解してください。

少し背景として、私たちの主なアプリケーションは非常に高性能です
スマートDNSプラットフォーム(つまり、UDPが必要で、少なくとも100k以上を実行する必要があります
ポッドあたりのリクエスト/秒)、およびSNIプロキシでのそのサポートアプリケーション
クライアントの実際のIPアドレスを確認する必要があります(これは
我ら)。 異なるネットワークアプローチを異なるものに使用したくありませんでした
アプリケーションのため、単一のネットワーク方式で標準化することにしました。
すべて、そして私たちは上記の理由でIPVSを使用することを選択しました
(パフォーマンス/安定性/柔軟性/目的ビルドSLB)、しかしあなたはできます
おそらく、これらの同じ行に沿ってiptablesだけを使用して何かを一緒にハックします
それも。 私たちはvxlan(高速、簡単、サイト間で動作)を使用していますが、これらは両方とも
メソッドは、OVSまたは標準のレイヤー2を備えたGRE / VXLANでも機能する必要があります
ホストネットワークも(ホストがすべて同じL2ネットワーク上にあると仮定)。

エニーキャストと
DNS、フェイルオーバー速度の要件または最適に機能するものに応じて
特定の種類のサービスであるため、
私たちのノードに入るエンドユーザートラフィック、しかしあなたが指摘したように問題は、
に関係なく、ポッド間でトラフィックが均等に分散されます。
ポッドの場所。 他の問題は、サービスが他の人と通信していることを確認することです
サービスは効果的に負荷分散されます。

これに対処するために、2つのモデルを試みました。

私たちが試した最初の方法は、2層のVIPでした。 外部VIP(1つにつき1つ
サービス)、ノード間でトラフィックを分散します(のポッド数に基づく)
ノード上のそのサービス)、次に内部VIP(ノード上で実行される)
ポッドを使用)、ノード内で負荷を分散します(通常は均等に)
ポッド間)。 このモデルの制限は、外部で実行されているノードでした
VIPは、2つの異なるネットワーク名前空間を実行するか、独自の名前空間を実行する必要がありました
物理ノード。 DSRモードのIPVSの良い点(直接サーバーリターン)
モードは、リターントラフィックを確認する必要がないことです。トラフィックは次のようになります。

コンシューマー>>(L3経由)>>外部VIPノード>>(1)>>内部VIPノード>>
(2)>>コンテナ>>(好きなように)>>消費者

(1)外部VIPを備えたホスト上のIPVS(DSRモード)は、_node_を選択します
トラフィックを(IPVS用語では「実サーバー」)に送信し、DSTMACのみを変更します
パケットのアドレス(つまり、IPパケットは変更されずにk8sノードに到着します)。 ロードします
そのサービスを実行しているポッドの数に基づいて、ノード間でバランスを取ります
ノード。
(2)k8sノードのIPVS(DSRモードでも)は、トラフィック全体の負荷を分散します
ポッド(ノードへのvethを介して)。 コンテナ(TCPおよびUDP)からの応答は
サービスの利用者に直接戻ります。

このモデルの利点は、始めるのが本当に簡単だったことです。
ルールセットの管理は非常に簡単でした。 このモデルの欠点は、
すべてのサービスリクエスト(返信ではない)を
外部VIPを実行しているノードの数。 私たちは「シェアードナッシング」が好きなので、
バージョン2を入力してください。

現在おもしろい2番目のモデルはVIPの単層です
よりスマートなIPVSおよびiptables構成。

コンシューマー>>任意のノード/ローカルノード>>(1)>>コンテナー>>(どの方法でも
欲しい)>>消費者
または、別のノードに移動する可能性があります。
コンシューマー>>任意のノード/ローカルノード>>(1)>>リモートノード>>(2)>>コンテナー

(あなたが望む任意の方法)>>消費者

(1)トラフィックがプライマリVIPにヒットし、トラフィックはのすべてのポッド間で負荷分散されます
クラスター。
(2)トラフィックがセカンダリVIPにヒットし、トラフィックはすべてのユーザー間でのみ負荷分散されます
ローカルポッド。 このセカンダリVIPは、から着信するトラフィックにのみ使用されます
ネットワーク上の他のホスト(FWMARK VIP)。 入ってくるトラフィックをマークします
FWMARK = 1234の外部インターフェイス。これにより、トラフィックが強制的に送信されます。
ノード間のループを防ぐ別のルールセットに。

プライマリVIPには、ローカルポッドとポッドを備えたリモートホストのリストがあります(
ローカルポッドごとに100の重み、および100 *ポッドの数
リモートノード)。 たとえば、3つのポッドがnodeAでローカルに実行されている場合、
nodeBで実行されている2つのポッドがあり、nodeAのルールセットは次のようになります。
これ:

Prot LocalAddress:Portスケジューラフラグ
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0rr永続的360
-> pod1.on.nodeA.ip:80ルート1000 0
-> pod2.on.nodeA.ip:80ルート1000 0
-> pod2.on.nodeA.ip:80ルート1000 0
-> interfaceip.of.nodeB:80ルート200 0 0
FWM 1234 rr
-> pod1.on.nodeA.ip:80ルート1000 0
-> pod2.on.nodeA.ip:80ルート1000 0
-> pod3.on.nodeA.ip:80ルート1000 0

ただし、nodeBでは、IPVS構成は少し異なるように見えます。
nodeAには2つのローカルポッドと3つのリモートポッドしかありません。

Prot LocalAddress:Portスケジューラフラグ
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0rr永続的360
-> pod1.on.nodeB.ip:80ルート1000 0
-> pod2.on.nodeB.ip:80ルート1000 0
-> interfaceip.of.nodeA:80ルート300 0 0
FWM 1234 rr
-> pod1.on.nodeB.ip:80ルート1000 0
-> pod2.on.nodeB.ip:80ルート1000 0

別の方法は、FWMARKを切り替えて、iptablesを使用して
veth +インターフェイス(ワイルドカード一致)のすべてをFWMARKし、FWMARKを使用する
一致はローカル負荷分散にのみ使用されます。

最終結果は、一元化する必要のない、最も直接的なネットワーキングです。
リクエストの処理/ルーティングにより、スケーリングが大幅に向上します。 欠点はいくつかあります
IPVSルールを作成するときの追加の賢さ。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171619663

iptables-to-node-pods-onlyモードを試してみると面白いと思いますが、
しかし、それは多くの波紋を持っています。 不均衡の可能性は非常に現実的であり、
少なくともサービスコントローラーは、プログラムする方法を知っている必要があります
外部ロードバランサー。

木では、2016年1月14日15:59で、ミカエルCluseau [email protected]
書きました:

私の側では、フランネル(vxlanモード)でコンテナネットワークを管理しているので、
kube-proxy(iptablesモードで、マスカレードではない)+フランネルを
ルーティングノードの名前空間。 外部リクエストはサービスのためにDNATされます
IPは、kube-proxyを使用して名前空間を介して転送されます。 私はしていません
アクティブ/アクティブルータークラスターのテストを実行しましたが、この設定により、
外部IP。 私はそれをFWIWと言いますが、それが「ほとんど」ではないことを理解しています
直接ネットワーキング」。

kube-proxyがそれを管理できればいいのですが、
特定のニーズ、特に負荷分散という事実を考えると
すでにkube-proxyの外にありますが、顧客をコーディングするのは意味がありませんか
iptables-kubernetesクラスターの状態を監視してセットアップするルールマネージャー
実行中のホストのポッドのみに対するDNATVIPへのルール? これは可能性があります
kube-proxyのモードでもありますが...まあ..私は得意ではありません
名前...-- proxy-mode = iptables-to-node-pods-only。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171821603

@thockinたとえば、2つのレプリカが同じノード上にある場合はどうでしょうか。 「外部ロードバランサーをプログラムする」ケースは、複数のインスタンスがあり、外部LBプログラマーはおそらく「シングルマスター」モードである必要があるため、kube-proxyの範囲外に置くことができると思います。 したがって、kube-proxyモード「iptables-to-node-pods-only」を許可することは、2ステップのプロセスの最初の1つにすぎません。

明日は、kube-proxyの「iptables-to-node-pods-only」モードに加えて、サービスごとに1つのルートを持つLinuxルーティングテーブルを維持するcontrib / ip-route-elbのようなものを実装しようと試みることができると思います。 、特定のサービスに対してノードが持つエンドポイントの数に基づいて、各ノードに適切な重みを付けます。

@thockinたとえば、2つのレプリカが同じノード上にあるということですか? 私たちはケースを置くことができると思います「プログラム
複数のインスタンスと外部LBがあるため、kube-proxyの範囲外の「外部ロードバランサー」
プログラマーはおそらく「シングルマスター」モードになっているはずです。 したがって、kube-proxyモード「iptables-to-node-
ポッドのみ」は、2ステップのプロセスの最初の1つにすぎません。

「ローカルポッドへのプロキシのみ」は、プロセスのステップ2である必要があります。 ステップ1
ロードバランサーのみを送信するようにサービスコントローラーを変更する必要があります
特定のサービスに対して1つ以上のバックエンドを持つノードへ。 そのステップ
単独でおそらく合理的ですが、
私たちがそれを正しく理解していることを確認してください。 最終的にはこれをやりたいと思いますが、
とりあえず。

それが完了したら、ノードポートをローカルに優先させることについて話し合うことができます
可能であればバックエンドですが、この手順にはもっと注意が必要です
考えた..それは_常に_を意味しますか(つまり、リモコンを決して選択しないでください)
ローカルのものが利用可能な場合はバックエンド)または確率的ですか? やるべきか
同じノードポートを介してそれを取得します(異なるノードは非常に取得します
異なる動作)または使用される別のポートを割り当てますか
このノードに1つ以上のバックエンドがある場合に限りますか? どのように処理しますか
不均衡の問題?

明日、kube-proxyの「iptables-to-node-pods-only」モードのようなものを実装してみることができると思います。
さらに、適切な重みで、サービスごとに1つのルートを持つLinuxルーティングテーブルを維持するcontrib / ip-route-elb
特定のサービスに対してノードが持つエンドポイントの数に基づいて、ノードごとに。

ELBがウェイトをサポートしている場合は、いくつかの点でより適切に機能します。
GCE、そうではありません。 それは結構です、私はそれがサポートされているとは思いませんでした
重み。 私はそれが貢献することはできないと思います-それはかなりです
システムの基本的な部分。

2016年1月16日午前5時19分、TimHockinは次のように書いています。

「ローカルポッドへのプロキシのみ」は、プロセスのステップ2である必要があります。 ステップ1
ロードバランサーのみを送信するようにサービスコントローラーを変更する必要があります
特定のサービスに対して1つ以上のバックエンドを持つノードへ。 そのステップ
単独でおそらく合理的ですが、
私たちがそれを正しく理解していることを確認してください。 最終的にはこれをやりたいと思いますが、
とりあえず。

それは理にかなっている。

それが行われると、[...]

それが終わったら見てみましょう:-)

ELBがウェイトをサポートしている場合は、いくつかの点でより適切に機能します。
GCE、そうではありません。 それは結構です、私はそれがサポートされているとは思いませんでした
重み。

それはマニュアルからであり、あなたはおそらく私の10倍以上を持っているので
この種のネットワーキングの経験から、私はキャッチを完全に無視しなければなりません。
男ip-routeはこれを言います:

           nexthop NEXTHOP
                  the nexthop of a multipath route.  NEXTHOP is a 

トップレベルの引数リストに似た独自の構文を持つ複雑な値:

                          via [ FAMILY ] ADDRESS - is the nexthop 

ルーター。

                          dev NAME - is the output device.

                          weight NUMBER - is a weight for this 

相対的な帯域幅または品質を反映するマルチパスルートの要素。

私はそれが貢献することはできないと思います-それはかなりです
システムの基本的な部分。

「E」は「external」の略なので、そこから始められる気がしましたが、
少なくともアイデアをサポートするためのコードを取得するために。

2016年1月15日金曜日午後2時55分、MikaëlCluseau
[email protected]は次のように書いています:

2016年1月16日午前5時19分、TimHockinは次のように書いています。

「ローカルポッドへのプロキシのみ」は、プロセスのステップ2である必要があります。 ステップ1
ロードバランサーのみを送信するようにサービスコントローラーを変更する必要があります
特定のサービスに対して1つ以上のバックエンドを持つノードへ。 そのステップ
単独でおそらく合理的ですが、
私たちがそれを正しく理解していることを確認してください。 最終的にはこれをやりたいと思いますが、
とりあえず。

それは理にかなっている。

今日はこれについてもっと考えましたが、それほど難しいことではないと思います。
ミディアムハード。

それが行われると、[...]

それが終わったら見てみましょう:-)

十分に公平なことですが、私は一連の変更がどこに向かっているのかを知りたいだけです:)

ELBがウェイトをサポートしている場合は、いくつかの点でより適切に機能します。
GCE、そうではありません。 それは結構です、私はそれがサポートされているとは思いませんでした
重み。

それはマニュアルからであり、あなたはおそらく私の10倍以上を持っているので
この種のネットワーキングの経験から、私はキャッチを完全に無視しなければなりません。
男ip-routeはこれを言います:

nexthop NEXTHOP
マルチパスルートのネクストホップ。 NEXTHOPは
トップレベルの引数リストに似た独自の構文を持つ複雑な値:

[FAMILY] ADDRESS経由-ネクストホップ
ルーター。

devNAME-は出力デバイスです。

ウェイトNUMBER-これのウェイトです
相対的な帯域幅または品質を反映するマルチパスルートの要素。

ただし、LinuxのIPルーティングの概念は実際には使用していません。 のどれも
とにかく、私が知っているLB実装はそれを使用します。 GCEはGoogleのクラウドを使用しています
ウェイトがないバランサー。 アマゾンELBかわからない
NS。

私はそれが貢献することはできないと思います-それはかなりです
システムの基本的な部分。

「E」は「external」の略なので、そこから始められる気がしましたが、
少なくともアイデアをサポートするためのコードを取得するために。

確かに、私たちは貢献で始めることができます:)

また、これを追求したい場合は、次のような2つのバグを開く必要があります。

1)サービスのロードバランサーは、実際に
そのサービスのバックエンドを持っている

2)ロードバランサー間でクライアントIPを保持するには、kube-proxyは
存在する場合は常にローカルバックエンドを優先します(外部参照#1)

その後、意図と方向性を説明します

2016年1月15日金曜日午後5時11分、Tim [email protected]次のように書いています。

2016年1月15日金曜日午後2時55分、MikaëlCluseau
[email protected]は次のように書いています:

2016年1月16日午前5時19分、TimHockinは次のように書いています。

「ローカルポッドへのプロキシのみ」は、プロセスのステップ2である必要があります。 ステップ1
ロードバランサーのみを送信するようにサービスコントローラーを変更する必要があります
特定のサービスに対して1つ以上のバックエンドを持つノードへ。 そのステップ
単独でおそらく合理的ですが、
私たちがそれを正しく理解していることを確認してください。 最終的にはこれをやりたいと思いますが、
とりあえず。

それは理にかなっている。

今日はこれについてもっと考えましたが、それほど難しいことではないと思います。
ミディアムハード。

それが行われると、[...]

それが終わったら見てみましょう:-)

十分に公平なことですが、私は一連の変更がどこに向かっているのかを知りたいだけです:)

ELBがウェイトをサポートしている場合は、いくつかの点でより適切に機能します。
GCE、そうではありません。 それは結構です、私はそれがサポートされているとは思いませんでした
重み。

それはマニュアルからであり、あなたはおそらく私の10倍以上を持っているので
この種のネットワーキングの経験から、私はキャッチを完全に無視しなければなりません。
男ip-routeはこれを言います:

nexthop NEXTHOP
マルチパスルートのネクストホップ。 NEXTHOPは
トップレベルの引数リストに似た独自の構文を持つ複雑な値:

[FAMILY] ADDRESS経由-ネクストホップ
ルーター。

devNAME-は出力デバイスです。

ウェイトNUMBER-これのウェイトです
相対的な帯域幅または品質を反映するマルチパスルートの要素。

ただし、LinuxのIPルーティングの概念は実際には使用していません。 のどれも
とにかく、私が知っているLB実装はそれを使用します。 GCEはGoogleのクラウドを使用しています
ウェイトがないバランサー。 アマゾンELBかわからない
NS。

私はそれが貢献することはできないと思います-それはかなりです
システムの基本的な部分。

「E」は「external」の略なので、そこから始められる気がしましたが、
少なくともアイデアをサポートするためのコードを取得するために。

確かに、私たちは貢献で始めることができます:)

ドキュメントなしのPRのリスクは、それが間違った方向にあることです。 です
提案として何かをレビューする方がはるかに簡単です。 私はあなたを見ていきます
機会があればPR、早く願っています。
2016年1月15日19:02、「MikaëlCluseau」 [email protected]は次のように書いています。

この名前といくつかの名前で直接(1)のプルリクエストを開いても大丈夫ですか?
説明?


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172149777

残念ながら、あなたは一般的な意味で機能しない非常に特定の領域に渡りました。
GCEのようなクラウドは、ルーティングされたネットワークのため、IPVSゲートウェイモードを使用できません。 ゲートウェイが機能した場合でも、Kubernetesがサポートするポートの再マッピングはサポートされていないため、サービスポート==ターゲットポートの場合にのみ適用されます。

ゲートウェイ側では、これはレイヤー3ネットワーク(オーバーレイを使用)で正常に機能します。オーバーレイネットワークがなくても問題は解決できましたが、使用するアプローチを移植可能で機能させる必要があるため、この方法で構築しました。サードパーティのクラウド(GCEなど)。

DSRモードの制限を修正すると、サービスポート==ターゲットポートになりますが、同じポートで実行する必要のある2つのアプリケーションが_同じコンテナ内に_ない限り、これは実際には問題ではありません(これと、「コンテナごとに1つのアプリケーション」のガイドラインを想定すると、これの単一のユースケースは見つかりませんでした)。 多くのコンテナがすべて同じノードで実行されており、その中のサービスはすべて同じポートで実行されており、すべてが正常に負荷分散されています。 ポートを再マップする必要がある場合(理由の背後にある本当の理由を理解したいのですが)、「ROUTE」モードの代わりにIPVSNATモードを使用できます。

kubernetesのコアでの課題は、ある種の状況を一般的に処理する方法、または邪魔にならないようにして自分で設定できるようにする方法を見つけることです。 ipvs encapモードで何かできるかもしれませんが、パフォーマンスへの影響はわかりません。

私たちが行ったことは、可能な限り一般的なものです(ここで機能し、Amazonで機能し、拡張する必要がある場合はGCEで機能すると確信しています)。DSRの唯一の制限はアプリケーションです。ポッド/コンテナで実行する場合は、サービスと同じポートで実行する必要があります。内部で多くの議論を重ねた結果、E2Eアプリケーションスタックの観点からこれが制限されるシナリオを見つけることができませんでした。

とはいえ、方程式からDSR(IPVSルートモード)を削除し、代わりにIPVSの「NATモード」を使用すると、ポートを再マップでき、IPVS機能/パフォーマンスなどを取得できるという利点があります。 唯一の欠点は、NATがパフォーマンスに負担をかけることですが、(a)UDPをサポートし、(b)ユーザースペースソリューションと比較して非常に高速です。

@brendandburns @thockinスレッドの前半で、いくつかのパフォーマンス数値を要求しました。 これを最も包括的なテストのセットとは言いませんが、HTTPはコンテナーで最も一般的なワークロードの1つであると思います。そのため、出発点としていくつかのapache-bench番号を示します。

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

DNATは、他の2つのソリューションとの公正な比較のためにIPVSで有効にされました(これは、サービスポートがターゲットサービスポートと異なる可能性があることも意味します)。 私たちのワークロードは一部の人にとっては少し変わっているように見えるかもしれませんが、私たちのパフォーマンス目標はおそらく他の人と同じです(つまり、ハードウェアをすべて絞り込んでください)。

ありがとう!

kube-proxyがUDPを実行しないという考えがどこから来ているのかわかりません-それ
完全ではないかもしれませんが、絶対にそうです(接続がなければ、それは起こります
タイムアウトまで)。

iptables(新しい)kube-proxyとユーザースペースを明確にすることも価値があります
(レガシーモード。

午後9時45分(土)、2016年1月16日には、qoke [email protected]書きました:

@thockinhttps ://github.com/thockinあなたが要求したスレッドの前半
いくつかのパフォーマンス数値。 私はこれを最も包括的なセットとは呼びません
テストの数ですが、HTTPはで最も一般的なワークロードの1つだと思います
コンテナなので、ここに出発点としていくつかのApacheベンチ番号があります。

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

DNATは、他の2つのソリューションとの公正な比較のために、IPVSで有効にされました
(これは、サービスポートがターゲットサービスポートと異なる可能性があることも意味します)。 私たちの
ワークロードは一部の人にとっては少し変わっているように見えるかもしれませんが、私たちのパフォーマンス目標
おそらく他の人と異ならないでしょう(つまり、すべての人のためにハードウェアを絞る)
得られる)。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172293881

新しいモードとレガシーモードの良い呼びかけ-注目され、更新されました。

また、UDP側についても、説明していただきありがとうございます。 これまで、kube-proxyでUDPが完全にサポートされていることを知りませんでした。 最初にUDPでkube-proxyを試したとき、たくさんのハングが発生しました。 理由はわかりませんが、タイムアウトを増やしても問題が発生しました。 解決策をすばやく見つける必要があったため、デバッグするのではなく、IPVSを使用して解決策を回避することになりました。 当時は、非常に低い1秒あたりのパケット数(1k pps未満)でしか機能しませんでしたが、最近再テストは行っていません。

iptablesと高速UDPサービスの主な問題は、netfilterconntrackテーブルがいっぱいになることです。 conntrackのサイズを100万に増やしても、マルウェアに感染したエンドユーザーのDDoSがあなたを攻撃したり、DNS増幅攻撃に使用しようとしたりすると、conntrackテーブルが再びいっぱいになります。 一般的に、DNSサーバー(または任意の高レートUDPサービス)のベストプラクティスは、conntrackを無効にすることです(rawテーブルで-j NOTRACKを使用)。conntrackを無効にすると、iptables NATとステートフルなもの(-m状態)が壊れます。

GITリポジトリとは別に、「k8s.io/kubernetes/pkg/proxy/ipvs」モジュール/パッケージを作成する前に調べるのに最適な場所はどこですか? それとも、これはコードベースをよく知っている人に任せるのが最善ですか?

また、特定のベンチマークの実行をご希望の場合はお知らせください。何がで​​きるかを確認します。

2016年1月17日午後8時50分、qokeは次のように書いています。

GITリポジトリとは別に、前に見るのに最適な場所はどこですか
「k8s.io/kubernetes/pkg/proxy/ipvs」モジュール/パッケージを作成しようとしていますか?

私はあなたも貢献から始めることができると信じています。

FWIW ...リストウォッチとアンデルタストアを使用して独立した
クラスターの状態に反応するbinay
https://github.com/kubernetes/kubernetes/pull/19755。 情報があれば

https://github.com/kubernetes/kubernetes/pull/19755/files#diff -0becc97ac222c3f2838fbfe8446d5375R26
十分です、あなたはほんの数行下の呼び出しを変更する必要があるはずです
(https://github.com/kubernetes/kubernetes/pull/19755/files#diff-0becc97ac222c3f2838fbfe8446d5375R44)。

このPoCではclusterIPサービスのみをサポートしていることに注意してください。

残念ながら、あなたは一般的な意味で機能しない非常に特定の領域に渡りました。
GCEのようなクラウドは、ルーティングされたネットワークのため、IPVSゲートウェイモードを使用できません。 ゲートウェイが機能したとしても、機能しません
Kubernetesが行うポートの再マッピングをサポートしているため、サービスポート==ターゲットポートの場合にのみ適用されます。

ゲートウェイ側では、これはレイヤー3ネットワーク(オーバーレイを使用)上で正常に機能します。
オーバーレイネットワークを使用せずに、この方法で構築しました。これは、使用するアプローチを移植可能で、サードパーティで機能させる必要があるためです。
雲(GCEなど)。

それがどのように機能するのかわかりません。 マシンレベルの静的ルートが機能しない
GCEで。 たぶん私はあなたが適用したいくつかのテクニックを逃しています。 私
私はこれの専門家ではないことを自由に認めてください:)

制限を修正すると、サービスポート==ターゲットポートになりますが、2つのアプリケーションがない限り、これは実際には問題になりません。
同じポートで実行する必要がある同じコンテナ(これについて考え、「1つのアプリケーション」を想定するのに多くの時間を費やしました
「コンテナごと」のガイドラインでは、このユースケースは1つも見つかりませんでした)。多くのコンテナがすべて同じノードで実行されています。
それらの内部のサービスはすべて同じポート上にあり、すべての負荷が正常に分散されています。 要するに、私たちが使用するアプローチはあなたを止めません
同じノードの同じポートで複数のサービスを実行することから。

バージョンを変更するバックエンドがある場合にも適用されます(例:
etcd1とetcd2の間の移行)またはその他の状況
バックエンドポートは異なる必要があります。 問題はそれです
Kubernetesはそれを表現できるので、人々を確実に表現する必要があります
実際に使用できます(または非推奨にして、機能をEOLします)
ありそうもないようです)。

kubernetesのコアでの課題は、ある種の状況を一般的に処理する方法、または邪魔にならないようにする方法を見つけることです。
自分で設定できるようにします。 ipvs encapモードで何かできるかもしれませんが、パフォーマンスがわかりません
それの意味。

私たちがやったことは、可能な限り一般的なものです(ここで動作し、Amazonで動作し、
拡張する必要がある場合のGCE)、唯一の制限は、ポッド/コンテナで実行されているアプリケーションがサービスと同じポートで実行される必要があることです。シナリオ
これは、E2Eアプリケーションスタックの観点からは制限されます。

私は本当にその方法を理解したいです。 もっとステップバイステップで何かありますか?

また、UDP側についても、説明していただきありがとうございます。 これまで、kube-proxyでUDPが完全にサポートされていることを知りませんでした。
最初にUDPでkube-proxyを試したとき、たくさんのハングが発生しました。 理由はわかりませんが、タイムアウトを増やして
まだ問題がありました。 解決策をすばやく見つける必要があったため、デバッグするのではなく、IPVSを使用して解決策を回避することになりました。 で
時間は非常に低い1秒あたりのパケット数(1k pps未満)でしか機能しませんでしたが、最近は再テストしていません。

iptablesと高速UDPサービスの主な問題は、netfilterconntrackテーブルがいっぱいになることです。 増やしても
conntrackのサイズを100万にすると、マルウェアに感染したエンドユーザーのDDoSがあなたを攻撃したり、DNS増幅に使用しようとしたりします。
攻撃すると、conntrackテーブルが再びいっぱいになります。 一般的に言えば、DNSサーバー(または任意の高レート)のベストプラクティス
UDPサービス)はconntrackを無効にすることです(rawテーブルで-j NOTRACKを使用)。conntrackを無効にすると、iptablesNATと
ステートフルなもの(-m状態)が壊れます。

ええ、UDPのNATは本当に残念です。 非conntrackを見つける
解決策は素晴らしいでしょうが、それはすべてに適用する必要があります
環境またはプラットフォームによってパラメータ化される(それ自体は難しい)
仕方)。

GITリポジトリとは別に、作成を試みる前に確認するのに最適な場所はどこですか
「k8s.io/kubernetes/pkg/proxy/ipvs」モジュール/パッケージ? それとも、これはコードベースをよく知っている人に任せるのが最善ですか?

IPVSに関するgithubの問題を開きましたが、マスカレード(NAT)を使用していました
モードがないとGCEで動作させることができなかったため(および
ポート再マッピング機能)。 ポートの再マッピングがあまり理想的ではないトリガーとなった場合
バランスモード、私はおそらくそれと一緒に住んで、それを文書化することができます
そのような。

このコンボをそこに移動する必要があります-ここで迷子になります。

2016年1月18日12:34 PMに、TimHockinは次のように書いています。

ええ、UDPのNATは本当に残念です。 非conntrackを見つける
解決策は素晴らしいでしょうが、それはすべてに適用する必要があります
環境またはプラットフォームによってパラメータ化される(それ自体は難しい)
仕方)。

(ポッド、ポート)カップルが
ほとんどの1つのサービス(1つのサービスに多くのポッド)?

これは次のようになります。

{from:clientIP:clientPort、to:externalIP:externalPort} --- [プロキシがランダムなポッドを選択] ---> {from:clientIP:clientPort、to:podIP:targetPort} ---> [適切なホストを経由してルーティング...]

帰り道、ファイアウォールにはパケット{from:
podIP:targetPort 、to:any}は{from:からSNATする必要があります
e xternalIP:externalPort 、to:変更なし}。

iptables方言でそれを述べるには:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53 --to-source 1.2.3.4

パケットが外部から来たときにこれが機能しない場所がわかりません
クラスター。

サービスがKubernetesで表現される方法により、単一のポッドを
いくつものサービスが前面に出ているので、これは故障します-私たちは何を知りません
SNATへ。

6:13 PMで日、2016年1月17日には、ミカエルCluseau [email protected]
書きました:

2016年1月18日12:34 PMに、TimHockinは次のように書いています。

ええ、UDPのNATは本当に残念です。 非conntrackを見つける
解決策は素晴らしいでしょうが、それはすべてに適用する必要があります
環境またはプラットフォームによってパラメータ化される(それ自体は難しい)
仕方)。

(ポッド、ポート)カップルが
ほとんどの1つのサービス(1つのサービスに多くのポッド)?

これは次のようになります。

{from:clientIP:clientPort、to:externalIP:externalPort} --- [プロキシは
ランダムポッド] ---> {from:clientIP:clientPort、to:podIP:targetPort} --->
[適切なホストを経由してルーティング...]

帰り道、ファイアウォールにはパケット{from:
podIP:targetPort 、to:any}は{from:からSNATする必要があります
e xternalIP:externalPort 、to:変更なし}。

iptables方言でそれを述べるには:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53
--to-source 1.2.3.4

パケットが外部から来たときにこれが機能しない場所がわかりません
クラスター。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172408290

2016年1月18日午後3時31分、ティムホッキンは次のように書いています。

サービスがKubernetesで表現される方法により、単一のポッドが可能になります
することが
いくつものサービスが前面に出ているので、これは故障します-わかりません

SNATへ。

そのため、私はケースを多対1に限定しました(私の最初の文:-))。
できることとできないことの周りに線を引こうとしているだけです。

確かに、私はそれがなぜそうではないのかを指摘するという不幸な仕事をしているだけです
一般的な十分な解決策:(

20:34の日、2016年1月17日には、ミカエルCluseau [email protected]
書きました:

2016年1月18日午後3時31分、ティムホッキンは次のように書いています。

サービスがKubernetesで表現される方法により、単一のポッドが可能になります
することが
いくつものサービスが前面に出ているので、これは故障します-わかりません

SNATへ。

そのため、私はケースを多対1に限定しました(私の最初の文:-))。
できることとできないことの周りに線を引こうとしているだけです。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172421828

2016年1月18日午後3時46分、TimHockinは次のように書いています。

確かに、私はそれがなぜそうではないのかを指摘するという不幸な仕事をしているだけです
一般的な十分な解決策:(

ええ...でもFAQです。 また、どこかに「if len(services)
== 1 {ステートレスを実装する} else {ステートフルを実装する} "。
初心者には混乱のように見えます。 私は貢献者/エルブ/何かになることもできます...

それは私たちが現在追跡しているものでもありません(
特定のポッドの前面)。 できたと思います。 私はそれに反対していません(たとえそれがあったとしても
ニッチのようです)。 そうするために行うべき実質的な変更のように聞こえます
多くの警告。 それでも、もっと良い答えを考えたいと思います。

20:51の日、2016年1月17日には、ミカエルCluseau [email protected]
書きました:

2016年1月18日午後3時46分、TimHockinは次のように書いています。

確かに、私はそれがなぜそうではないのかを指摘するという不幸な仕事をしているだけです
一般的な十分な解決策:(

ええ...でもFAQです。 また、どこかに「if len(services)
== 1 {ステートレスを実装する} else {ステートフルを実装する} "。
初心者には混乱のように見えます。 私も
contrib / elbs / something .. ..


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172425404

2016年1月18日午後4時7分、ティムホッキンは次のように書いています。

それは私たちが現在追跡しているものでもありません(
特定のポッドの前面)。 できたと思います。 私はそれに反対していません(たとえそれがあったとしても
ニッチのようです)。 そうするために行うべき実質的な変更のように聞こえます
多くの警告。 それでも、もっと良い答えを考えたいと思います。

私は同意しますが、今のところこれ以上のアイデアはありません:-(

専用のSDNでさえ、私が思うものを追跡する必要があります。 多分
MPLSのようなラベルベースのソリューション..?

2016年1月18日午後4時18分、ミカエル・クルソーは次のように書いています。

専用のSDNでさえ、私が思うものを追跡する必要があります。
たぶんMPLSのようなラベルベースのソリューション..?

物事にラベルを付けるという考えでは...サービスごとに1つのIP + 1を割り当てる場合
エンドポイントごとのIP(サービスとポッドのカップル)、およびこれらのエンドポイントIPをに追加します
ポッド、完全にステートレスで動作するはずです:

`` `` `` ``

  • ホストの外部:{from:clientIP:clientPort、to:externalIP:servicePort} ----- [ELB
    1つのエンドポイントを選択します] --------> {from:clientIP:clientPort、to:
    endpointServiceIP:podPort}->ホストへのルート
  • ホストからポッド:{from:clientIP:clientPort、to:endpointServiceIP:podPort}-[標準
    コンテナへのルーティング]-> {from: clientIP:clientPort 、to:
    エンドポイントServiceIP:podPort }

  • ホストへのポッド:{from:endpointServiceIP:podPort、to:clientIP:clientPort}
    -------- [ルーターへの標準ルーティング] -----> {from:
    endpointServiceIP:podPort、to:clientIP:clientPort}-ホストからexternal:{from:endpointServiceIP:podPort、to:clientIP:clientPort} -------- [ELB
    SNATs back] ------------------> {from: clientIP:clientPort 、to:
    e xternalIP:servicePort } `` `

clusterIPでもこれを機能させることができると思います。
`` `` `` ``

GCEでこれを機能させることはできません。また、AWSについてもよくわかりません。
利用可能な静的ルートの数は限られています。

2つのIP範囲を1つにまとめてピギーバックすることでそれができるのだろうか
ルート。 費やすIPはたくさんありますが、それはUDPにとってのみ重要だと思います。
試してみる必要があります。

編集:試してみて動作させることができませんでしたが、何かが足りません。
今後のサービスに応じて、コンテナ内のIPを追加/削除する必要があります
と行きますが、コンテナ内の「余分な」IPを機能させることはできませんでした(
pingは実行しますが、TCPまたはUDPは実行しません。理由はわかりません)。

いつかもう一度やり直さなければなりません。

10時22分PMの日、2016年1月17日には、ミカエルCluseau [email protected]
書きました:

2016年1月18日午後4時18分、ミカエル・クルソーは次のように書いています。

専用のSDNでさえ、私が思うものを追跡する必要があります。
たぶんMPLSのようなラベルベースのソリューション..?

物事にラベルを付けるという考えでは...サービスごとに1つのIP + 1を割り当てる場合
エンドポイントごとのIP(サービスとポッドのカップル)、およびこれらのエンドポイントIPをに追加します
ポッド、完全にステートレスで動作するはずです:

`` `` `` ``

  • ホストの外部:{from:clientIP:clientPort、to:externalIP:servicePort}
    ----- [ELB
    1つのエンドポイントを選択します] --------> {from:clientIP:clientPort、to:
    endpointServiceIP:podPort}->ホストへのルート
  • ホストからポッド:{from:clientIP:clientPort、to:endpointServiceIP:podPort}
    - [標準
    コンテナへのルーティング]-> {from: clientIP:clientPort 、to:
    エンドポイントServiceIP:podPort }

  • ホストへのポッド:{from:endpointServiceIP:podPort、to:clientIP:clientPort}
    -------- [ルーターへの標準ルーティング] -----> {from:
    endpointServiceIP:podPort、to:clientIP:clientPort}-ホストto
    external:{from:endpointServiceIP:podPort、to:clientIP:clientPort}
    -------- [ELB
    SNATs back] ------------------> {from: clientIP:clientPort 、to:
    e xternalIP:servicePort } `` `

clusterIPでもこれを機能させることができると思います。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment-172438133

`` `` `` ``

私は何かを手に入れようとしています(ローカルホストに純粋なネットがあります)
今のところ)。

ホストへのサービスIP範囲に影響を与えるアプローチを試みています
ルーティングエントリの数を減らします。

cli --elb --h1 --c1

| `--- c2

`--- h2 --c2

h1_ep_ip_ranges =(10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges =(10.1.3.0/24)

ping ATMなし(パケットがPREROUTINGチェーンを通過しない...)、および
寝ないといけない。 この明日についてもっと;)

2016年1月18日午後6時28分、TimHockinは次のように書いています。

GCEでこれを機能させることはできません。また、AWSについてもよくわかりません。
利用可能な静的ルートの数は限られています。

2つのIP範囲を1つにまとめてピギーバックすることでそれができるのだろうか
ルート。 費やすIPはたくさんありますが、それはUDPにとってのみ重要だと思います。
試してみる必要があります。

編集:試してみて動作させることができませんでしたが、何かが足りません。
今後のサービスに応じて、コンテナ内のIPを追加/削除する必要があります
と行きますが、コンテナ内の「余分な」IPを機能させることはできませんでした(
pingは実行しますが、TCPまたはUDPは実行しません。理由はわかりません)。

いつかもう一度やり直さなければなりません。

私はもう少し遠くに行きました、しかし私が予測したはずの何かが起こりました。

メインインターフェイスとして10.244.2.8/25を使用し、10.244.2.250 / 25を使用してポッドを設定しました。
その「インサービス」インターフェースとして。 UDPをに送信できることを望んでいました
.250応答を検出し、それらをSNATします。 しかしもちろん、クライアントが
同じ/ 25にない(これはできません)デフォルトルートが開始されます。
.8アドレスから来ています。 tcpdumpは、応答が.8からのものであることを確認します
UDPを使用する場合。

私は再びそれを機能させる方法がわからない場所にいます。 考えるだろう
詳細については。

2:59で月、2016年1月18日には、ミカエルCluseau [email protected]
書きました:

私は何かを手に入れようとしています(ローカルホストに純粋なネットがあります)
今のところ)。

ホストへのサービスIP範囲に影響を与えるアプローチを試みています
ルーティングエントリの数を減らします。

cli --elb --h1 --c1

| `--- c2

`--- h2 --c2

h1_ep_ip_ranges =(10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges =(10.1.3.0/24)

ping ATMなし(パケットがPREROUTINGチェーンを通過しない...)、および
寝ないといけない。 この明日についてもっと;)

2016年1月18日午後6時28分、TimHockinは次のように書いています。

GCEでこれを機能させることはできません。また、AWSについてもよくわかりません。
利用可能な静的ルートの数は限られています。

2つのIP範囲を一緒にピギーバックすることでそれができるのだろうか
独身
ルート。 費やすIPはたくさんありますが、それはUDPにとってのみ重要だと思います。
試してみる必要があります。

編集:私はそれを試してみましたが、それを機能させることができませんでしたが、私は行方不明です
なにか。
今後のサービスに応じて、コンテナ内のIPを追加/削除する必要があります
と行きますが、コンテナ内の「余分な」IPを機能させることはできませんでした(
pingは実行しますが、TCPまたはUDPは実行しません。理由はわかりません)。

いつかもう一度やり直さなければなりません。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456

これがうまくいったとしても、私たちはまだしなければならないことに(Abhishek経由で)私に夜明けします
トラックはどこかに流れるので、とにかく最終的にステートレスではありません。

2016年1月18日月曜日午後9時50分、Tim [email protected]次のように書いています。

私はもう少し遠くに行きました、しかし私が予測したはずの何かが起こりました。

10.244.2.8/25をメインインターフェイスとしてポッドをセットアップし、
「インサービス」インターフェースとしての10.244.2.250/25。 私は私が
UDPを.250に送信し、応答を検出して、それらをSNATすることができます。 しかし、もちろん、
クライアントが同じ/ 25にない場合(これはできません)、デフォルト
.8アドレスからのルートが開始されます。 tcpdumpはそれを確認します
UDPを使用する場合、応答は.8から送信されます。

私は再びそれを機能させる方法がわからない場所にいます。 考えるだろう
詳細については。

2:59で月、2016年1月18日には、ミカエルCluseau [email protected]
書きました:

私は何かを手に入れようとしています(ローカルホストに純粋なネットがあります)
今のところ)。

ホストへのサービスIP範囲に影響を与えるアプローチを試みています
ルーティングエントリの数を減らします。

cli --elb --h1 --c1

| `--- c2

`--- h2 --c2

h1_ep_ip_ranges =(10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges =(10.1.3.0/24)

ping ATMなし(パケットがPREROUTINGチェーンを通過しない...)、および
寝ないといけない。 この明日についてもっと;)

2016年1月18日午後6時28分、TimHockinは次のように書いています。

GCEでこれを機能させることはできません。また、AWSについてもよくわかりません。
利用可能な静的ルートの数は限られています。

2つのIP範囲を一緒にピギーバックすることでそれができるのだろうか
独身
ルート。 費やすIPはたくさんありますが、それはUDPにとってのみ重要だと思います。
試してみる必要があります。

編集:私はそれを試してみましたが、それを機能させることができませんでしたが、私は行方不明です
なにか。
サービスに応じてコンテナ内のIPを追加/削除する必要があります
到来
と行きますが、コンテナ内の「余分な」IPを機能させることができませんでした(それは
たぶん......だろう
pingは実行しますが、TCPまたはUDPは実行しません。理由はわかりません)。

いつかもう一度やり直さなければなりません。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456

それは残念です:-(ところで、理由はわかりません。それでは、MPLSで何かを試してみますが、とにかくそれを学びたいと思います。

サービス用のバックエンドが2つあり、複数のバックエンドを送信する場合
パケット、あなたは何らかの方法でフローを追跡する必要がありますね? それともあなたですか
異なるバックエンドでパケットをスプレーするのが安全だと仮定しますか?

12:24の水曜日、2016年1月20日には、ミカエルCluseau [email protected]
書きました:

それは残念です:-(ところで理由はわかりません。私は何かを試してみます
MPLSでは、とにかくそれを学びたいと思います。


このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -173348973

私は、UDPワークロードの場合はそうだと思いました。 また、UDPの場合でもステートレスにすることもオプションです。 @qokeこれについてコメントはありますか?

また、クライアントIPハッシュなどを使用して、バランスを保ちながらフローをより安定させることもできます(これを「ある種の追跡」と呼ぶことができるかどうかはわかりません:-))。

@MikaelCluseauデフォルトのIPVS動作を使用します。これは、非常に軽量なUDP「スティッキネス」を実行します...

UDPデータグラムをスケジュールする場合、IPVSロードバランサーは構成可能なタイムアウトを使用してUDPデータグラムのスケジュールを記録します。デフォルトのUDPタイムアウトは300秒です。 UDP接続がタイムアウトする前に、同じソケット(プロトコル、IPアドレス、およびポート)からのすべてのUDPデータグラムが同じサーバーに送信されます。

--http //kb.linuxvirtualserver.org/wiki/IPVSから引用

もちろん、これは、多数のクライアントが単一のサービスと通信している場合、または単一のクライアントがさまざまな送信元ポートを使用している場合にのみ機能します。 単一の大容量クライアントがあり、すべてが同じ送信元ポートからトラフィックを送信していて、これを複数のバックエンド間で負荷分散したい場合は、ステートレス/スプレーアンドプレイアプローチを使用することをお勧めします。

多くのDNSトラフィックとRADIUSトラフィックの負荷を分散します-DNSは通常最初のカテゴリ(多くのクライアント、または多くの送信元ポートを持つクライアント)に分類され、RADIUSは通常後者のカテゴリ(少数のクライアント、多くのパケットがすべて同じIP /ポート)。 RADIUSにステートレスハッシュを使用するのではなく、ソースポートをランダム化して均等に分散させることにしました。

スレッド全体を読んだ後でも、kube-proxyのiptablesモードをアクティブ化すると、外部IPが非表示になる問題(#10921)が修正されるかどうかがわかりません。 ここで提案されているように、v1.1でiptablesモードを有効にしましたが、クラスターからのIPはまだ表示されており、ユーザーからの実際のIPは表示されていません。

私たちのクラスターはGCEにあり、稼働する前にHTTPSをサポートするロードバランサーが必要です。 GCEはv.1.2alphaをサポートしていないため、新しいIngress(AFAIKはHTTPSロードバランサーをサポートしています)を使用できません。そのため、ネットワークロードバランサーが唯一のオプションです。 しかし、明らかに、ユーザーからの実際のIPをログに記録する機能がなければライブに移行することはできません。

これに関する新しいユーザーのためのいくつかの説明をいただければ幸いです。 HTTPSのサポートは私たちの多くにとって必須です。 ありがとう!

私はかなり長い間iptablesプロキシのオンとオフを使用しており、クライアントの外部IPがまだ非表示/クラスターIPを表示していることを確認できます。

これまで、ホストネットワークモードで実行されているフロントエンドHTTP / HTTPSプロキシを実行して、送信元IPアドレスを確認することでこれを回避しました。

@maclofフィードバックをありがとう。 回避策について詳しく教えてください。 ホストネットワークで実行されているHTTP / HTTPSとはどういう意味ですか?

@javiercr次のようなポッド仕様を使用します: http//pastie.org/private/zpdelblsob654zif7xus5g

ホストネットワークを使用するということは、ポッドがクラスターIPに割り当てられるのではなく、ホストマシンネットワークで実行されることを意味します。

つまり、nginxサーバーがポート80/443にバインドすると、ホストIPをリッスンし、送信元IPアドレスを確認します。

kubernetes 1.1、 /opt/bin/kube-proxy ... --proxy-mode=iptables --masquerade-all=falseおり、kubeプロキシを持つホストを介してcluserIPネットワークをルーティングしています。 この設定では、私のサービスは外部IPを認識しています。 外部IPとホストへのルートを持つ高可用性ネットワーク名前空間を使用します。

I0221 01:20:32.695440       1 main.go:224] <A6GSXEKN> Connection from 202.22.xxx.yyy:51954 closed.

私はこのスレッドを読んで多くのことを学びました!

参考までに、このドキュメントでは、AWS ELBがTCP接続にラウンドロビンを使用し、http / httpsに最小接続を使用すると述べています: http

ポッドを実行しているノードにのみリクエストを取得し、ローカルポッドにサービスを提供することに焦点を当てることが、それを実現するための最良の方法であることに同意します。 これの良い副次的な利点は、クラスター内のノード間のトラフィックが少なくなることです。サービスからポッドへのローカルリクエストを常に処理することで、レイテンシーが改善されると思います(ノードが同じクラスター内の複数のアベイラビリティーゾーン)。

均等化をサポートしないロードバランサーを使用する場合、ノード上に常に同じ数のポッドを保持し(ノードごとに複数ある場合)、レプリケーションコントローラーでこれを解決し、ノード間で均等に分散することができます。これは、特定の状況でポッドをノードから移動する必要があり、特定のレプリカカウントのみを許可することを意味する場合でも、それらを使用します。 たとえば、サービスがロードバランサーに接続されている4ノードクラスターの場合、受け入れ可能なポッドレプリカの数は1、2、3、4、6、8、9、12、16、20などになります。

また、ローカルポッドのみにルーティングするトラフィックを解決することも検討しています。 サービス用のポッドがローカルに存在しない場合は、ノードポートがノード上で消えても問題ありません。 このように、単純なロードバランサーのTCPヘルスチェックは、要求がそれらのノードに送信されるのを防ぎます。 少なくともこれのiptables \ kube-proxy部分を解決できれば、ポッドがクラスター全体で分散されていない場合の負荷分散の影響がわかると思います。 API呼び出しを使用してノードごとに重みを設定せずに、ロードバランサーでこれを解決する方法があると思います。

ロードバランサーは、他の動的な方法を使用して、これをすでに処理しています。 また、実行しているサービスが各api呼び出しに対してそのコンテナー内で実際に実行していることによっては、ノードに2つのポッドがある場合と1つのポッドがある場合、2倍のトラフィックをサポートできない場合があります。 Kubernetesの制限が設定されていて、ポッドノードで使用量の最大レベルに近づいている場合も、これに影響を与える可能性があります。これにより、外部ロードバランサーで適切なウェイト設定を見つけようとするのがさらに複雑になります。

そのレベルの複雑さから離れて、kubernetesからロードバランサーの重みを設定しようとしないでください。

@yoshiwaanこの問題は現在クローズされているため、ノード間トラフィックの提案について新しい問題を開くことを提案できますか。 個人的には、最初のステップとして、ポッドがローカルノードで実行されていることを確認し、ローカルポッドにルーティングすることをお勧めします。 すべてのノードにポッドが存在するようにRCをスケーリングできるため、これで十分だと思います。

@justinsb +1、また、クライアントIPを確認する必要があるという問題が発生しており、現在の設定では基本的に不可能です。

これはあまりにも単純すぎるかもしれませんが、ユーザースペースモードとiptablesの違いは何ですか? ユーザードキュメントからは本当にわかりません。

ユーザーランドモードとは、kube-proxyがクライアントから接続要求を受信し、サーバーへのソケットを開くことによって接続自体を処理することを意味します。これにより、(1)CPUとメモリの消費量が大幅に増加し、(2)1つのポートの数に制限されます。オープン(<65k)。 iptablesモードは、カーネル内の下位レベルで機能し、代わりに接続トラッキングを使用するため、はるかに軽量で、より多くの接続を処理します*。

(編集)(*)SNATパケットが通過しない限り、パケットがそれらに関連付けられた接続追跡ルールを確実に通過するように設定する必要があります。 たとえば、ルーテッドアクセスデザインを使用すると、SNATを回避できます。これは、サービスのエンドポイントが実際のクライアントのIPを認識できることを意味します。

@MikaelCluseau
つまり、kube-proxyはiptablesルールの設定と維持のみを担当し、iptablesモードではサービスごとにランダムなローカルポートを取得しなくなりました。

2016年4月19日午後10時51分、エマは次のように書いています。

つまり、kube-proxyはセットアップと保守のみを担当します
iptablesと私たちはもはや各サービスのランダムなローカルポートを取得しません
iptablesモードでしょ?

はい。

申し訳ありませんが、私はこれを以前に絶対に逃しました。

(編集)(*)SNATパケットが通過しない限り、パケットがそれらに関連付けられた接続追跡ルールを確実に通過するように設定する必要があります。 たとえば、ルーテッドアクセスデザインを使用すると、SNATを回避できます。これは、サービスのエンドポイントが実際のクライアントのIPを認識できることを意味します。

@MikaelCluseau iptablesはSNATとDNATを採用していると思っていましたが、あなたによるとそうではありません。 これを明確にしていただけませんか。

2016年4月20日午後1時59分、エマは次のように書いています。

@MikaelCluseauhttps ://github.com/MikaelCluseau考えていた
iptablesはSNATとDNATを採用していますが、あなたによるとそうではありません。
これを明確にしていただけませんか。

それはトリッキーな部分です。

(1)サービス/外部IPを使用するにはDNATが必要です。
(2)応答パケットが同じconntrackを通過することが確実な場合
ルール(つまり、同じネットワークスタックまたは複製されたconntrackテーブル)、あなた
SNAT部分(つまり、MASQUERADEルール)をスキップできます。

(2)の条件は、通常、ルーテッドアクセスネットワークの設計では問題ありません。
(これは私が考えることができる最も単純なデザインです)。

たとえば、与えられた

  • クライアント1.0.1.1、
  • サービス1.0.2.1、
  • サービス1.0.3.1を実装するポッド。

それで、

  1. ルーター/ファイアウォール/ロードバランサー/ホスト/パケットを受信するものは何でも
    サービスの場合、パケット「1.0.1.1-> 1.0.2.1」が表示されます。
  2. エンドポイント(ポッド)にDNATするため、パケットは「1.0.1.1->」になります。
    クラスタネットワークでは1.0.3.1 "。
  3. ポッドはパケット「1.0.3.1-> 1.0.1.1」で応答します。
  4. パケットはルーター/ファイアウォール/ロードバランサー/ホスト/その他を通過します
    conntrackルールを使用すると、conntrackシステムはパケットを書き換えます
    クライアントに返送する前に、「1.0.2.1-> 1.0.1.1」に変更してください。

(2)の条件を満たせない場合は、SNAT / MASQUERADINGを使用する必要があります。
パケットが確実に
ルーター/ファイアウォール/ロードバランサー/ホスト/何でもconntrack。

@ MikaelCluseau-google.comのgithub名にメールを送ってください-私は持っています
あなたのために何か

20:20で火、2016年4月19日には、ミカエルCluseau [email protected]
書きました:

2016年4月20日午後1時59分、エマは次のように書いています。

@MikaelCluseauhttps ://github.com/MikaelCluseau考えていた
iptablesはSNATとDNATを採用していますが、あなたによるとそうではありません。
これを明確にしていただけませんか。

それはトリッキーな部分です。

(1)サービス/外部IPを使用するにはDNATが必要です。
(2)応答パケットが同じconntrackを通過することが確実な場合
ルール(つまり、同じネットワークスタックまたは複製されたconntrackテーブル)、あなた
SNAT部分(つまり、MASQUERADEルール)をスキップできます。

(2)の条件は、通常、ルーテッドアクセスネットワークの設計では問題ありません。
(これは私が考えることができる最も単純なデザインです)。

たとえば、与えられた

  • クライアント1.0.1.1、
  • サービス1.0.2.1、
  • サービス1.0.3.1を実装するポッド。

それで、

  1. ルーター/ファイアウォール/ロードバランサー/ホスト/パケットを受信するものは何でも
    サービスの場合、パケット「1.0.1.1-> 1.0.2.1」が表示されます。
  2. エンドポイント(ポッド)にDNATするため、パケットは「1.0.1.1->」になります。
    クラスタネットワークでは1.0.3.1 "。
  3. ポッドはパケット「1.0.3.1-> 1.0.1.1」で応答します。
  4. パケットはルーター/ファイアウォール/ロードバランサー/ホスト/その他を通過します
    conntrackルールを使用すると、conntrackシステムはパケットを書き換えます
    クライアントに返送する前に、「1.0.2.1-> 1.0.1.1」に変更してください。

(2)の条件を満たせない場合は、SNAT / MASQUERADINGを使用する必要があります。
パケットが確実に
ルーター/ファイアウォール/ロードバランサー/ホスト/何でもconntrack。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示してください
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -212230959

@justinsb @yoshiwaan誰かがこれについて問題を作成したことがありますか? 私の検索fuは私を失敗させています、そして私は同様の必要性を持っています。

この問題は現在クローズされているため、ノード間トラフィックの提案に対して新しい問題を開くことを提案できますか? 個人的には、最初のステップとして、ポッドがローカルノードで実行されている場合は、ローカルポッドにルーティングすることをお勧めします。 すべてのノードにポッドが存在するようにRCをスケーリングできるため、これで十分だと思います。

私はそれを自分で上げませんでした

ああ、私はそれを見つけたと思います、これは機能/修正のようです: https

1.5.xの時点でベータ版のようです。

このページは役に立ちましたか?
0 / 5 - 0 評価