web-dev-qa-db-ja.com

Google ComputeEngineで内部/プライベートロードバランサーを作成する方法

2つのクラスターがあります。クラスターA(Googleコンテナーエンジン上)は公開クラスターであり、サービスにアクセスするにはプライベートクラスターB(GCE上のクリックしてデプロイするクラスター)に接続する必要があります。クラスターAをロードバランサーを介してクラスターBに接続したいのですが、すべてのGCEロードバランサーにパブリックIPアドレスが必要であるように見えても機能します https://groups.google.com/d/topic/gce-discussion/Dv6289i4_rg/Discussion (すべてプライベートの場合は希望します)。

単純なファイアウォールルールを設定して標準のGoogleロードバランサーを使用できれば、パブリックIPアドレス自体はそれほど悪くありません。残念ながら、ソースタグはWANしきい値を超えていないようです(またはロードバランサーによって渡されていないだけです)。これは私が使用したいルールです。

gcloud compute firewall-rules create servicename-lb-from-gke-cluster --allow tcp:1234 --source-tags k8s-gke-cluster-node --target-tags servicename #DOES NOT WORK

上記のコマンドを入力した後、クラスターAはtcpポート1234を介して(ロードバランサーを介して)クラスターBと通信できません。

これは機能しますが、ソースクラスターのパブリックIPアドレスの設定を自動化するための監視が必要なため、面倒です。

gcloud compute firewall-rules create servicename-lb-from-gke-cluster --allow tcp:1234 --source-ranges 100.2.3.4/32 100.3.5.9/32 100.9.1.2/32 --target-tags servicename #Does work, but is painful

グーグルグループのスレッドで提案されているように、HAプロキシは別の提案です。

もう1つのアイデアは、ファイアウォールをWAN全体に開放し、クラスターAとBの間に安全な認証を追加することです。とにかくセキュリティ上の理由からこれを行うのは良いアイデアかもしれません。ただし、実行しているクラスターAとBに応じて、ハードになります。より一般的なソリューションがあると便利です。

誰かもっと良いアイデアがありますか?他の誰かが同じ問題を抱えていますか?

3
chrishiestand

これは、公式のGCP内部LBで可能になりました: https://cloud.google.com/compute/docs/load-balancing/internal/

具体的には、kubernetes(GKE)のドキュメントは次のとおりです。 https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing

サービスアノテーションに注意してください:

  annotations:
    cloud.google.com/load-balancer-type: "Internal"

このLBはすでに内部でのみアクセス可能ですが、さらに制限したい場合は、クラスターポッドでは、次のようなことができます。

loadBalancerSourceRanges: 10.4.0.0/14

ポッドのIP範囲を取得するには、次のコマンドを実行できます。gcloud container clusters describe $CLUSTER_NAME |grep clusterIpv4Cidr

1
chrishiestand

複雑さについては申し訳ありません!私はComputeEngineファイアウォールの専門家ではありませんが、内部トラフィックに対してのみ機能するソースタグの制限については正しいと思います。

Kubernetesチームは、複数のクラスターを調整することが難しいことを認識しており、ソリューションの開発に着手していますが、残念ながら、特に堅実で使用可能なものはまだありません。

それまでの間、Google Cloud Load Balancerやhaproxyのようなものを必要とせずに、あるクラスターから別のクラスターにトラフィックを負荷分散するためのハッキーな方法があります。クラスタBのノードの1つの内部IPアドレス(またはトラフィックをクラスタBのノードの1つに転送するGCEルートのIP)を PublicIPsフィールド のサービスで指定できます。あなたが話したい。次に、クラスターAにサービスのポート上のそのIPにリクエストを送信させると、サービスをサポートするすべてのポッド間でリクエストのバランスがとられます。

Kubernetesクラスターの各ノードで実行されているkube-proxyと呼ばれるものがあるため、これは機能するはずです。これは、サービスのIPとポートを対象としたトラフィックを、サービスをバックアップするポッドに自動的にプロキシします。 PublicIPがサービス定義に含まれている限り、kube-proxyがトラフィックのバランスを取ります。

ここで停止すると、これは、トラフィックを送信しているIPのノードと同じくらい信頼できます(ただし、単一ノードの信頼性は実際には非常に高いです)。ただし、本当に凝ったものにしたい場合は、クラスターAからクラスターBのすべてのノードに負荷分散することで、信頼性を少し高めることができます。

これを機能させるには、クラスターBのすべてのノードの内部IP(またはすべてのノードの内部IPへのルート)をサービスのPublicIPsフィールドに配置します。次に、クラスターAで、空のラベルセレクターを使用して個別のサービスを作成し、クラスターBの各IPの(IP、ポート)ペアを使用して作成するときに、エンドポイントフィールドに手動で入力できます。空のラベルセレクターは、 kubernetesインフラストラクチャが手動で入力したエンドポイントを上書きしないようにします。クラスターAのkubeプロキシは、クラスターBのIP間でサービスのトラフィックを負荷分散します。これは、より多くのコンテキストが必要な場合、 PR#245 によって可能になりました。

これについてさらにサポートが必要な場合はお知らせください。

4
Alex Robinson