DUICUO

3つのオープンソースKubernetesロードバランサーの比較(MetalLB vs PureLB vs OpenELB)

語彙

英語

中国語

述べる

ロードバランサー

ロードバランサ

この記事はKubernetes LoadBalancerについて言及しています

アロケータ(コントローラ)

ディストリビューター(コントローラー)

MetalLB/PureLB独自の用語

スピーカー

スポークスマン

MetalLB用語

失敗後

廃止

MetalLB用語

サービスグル​​ープ

サービスチーム

PureLB独自の用語

比較的オープンソースのKubernetesロードバランサー(LoadBalancer)

この記事では、あらゆる Kubernetes ディストリビューションで使用できる 3 つのオープンソース ロードバランサ コントローラーについて説明します。

  • MetalLB.[1] 最も人気がありよく知られているLoabBalancerコントローラー
  • PureLB[2] 最新版。(完全オープン、私はPureLBの開発に参加しました)
  • OpenELB[3](旧称Porter)。比較的最近プロジェクトに追加されたもので、当初はルーティングの問題にのみ焦点を当てていました。

サービス タイプに対して LoadBalancer 機能を実装するコントローラを追加することは、シンプルでスケーラブルなクラスター操作に必要な重要なネットワーク コンポーネントです。

  • クラスタ サービス/アプリケーションへの制御された外部アクセスを有効にする
  • 外部リソースは事前に構成されています。
  • 自動化されたワークフロー(CI/CD)との統合が容易

最初の点は明白ですが、クラスタ用のロードバランサソリューションを設計する際には、残りの2つも同様に重要です。デプロイメントモデルによっては、クラスタの信頼性の高いネットワークを確保する責任を負うチームと、クラスタを運用するチームが異なることがよくあります。事前構成により、ネットワークチームはセットアップを支援し、運用はクラスタチームに任せることができます。これにより、ロードバランサリソースの使用がKubernetesの標準的な「アプリケーション」定義とワークフローになっているため、CI/CDとの統合が容易になります。

これらのスタンドアロン ロード バランサは、パブリック クラウドで使用される統合ロード バランサや、K3s の Klipper などの実装固有のバンドル ソリューションとは異なり、任意の Kubernetes 環境で実行できます。

すべてのロードバランサーコントローラーはサービスを公開しますが、その実装方法はコントローラーごとに異なり、運用動作や障害モードに影響を与えます。各ロードバランサーコントローラーには、アドレスアロケーターと、ネットワークにアドレスを追加するための1つ以上のメカニズムが含まれています。主な違いは、アドレスの追加と管理に使用されるテクノロジーにあります。

メタルLB


ピュアLB

OpenELB(ポーター)

IPAM

内蔵

内蔵&外付け

内蔵

Linuxネットワークサブシステムの使用

いいえ

はい

いいえ

ローカルアドレス

はい

はい

不完全

ルーティングアドレス

はい

はい

はい

サポートされているプロトコル

BGP

任意(BGP、OSPF、ISIS、RIP)

部分的なBGP

IPv4とIPv6

いいえ

はい

いいえ

ルーティングクラスのCNIとの統合

困難

簡単

おそらく

CRDを使用して設定する

いいえ

はい

はい

冗長性とフェイルオーバー

良い

良い

違い

アドレス割り当て

すべてのロードバランサーには、プールからサービスにIPアドレスを割り当てるための統合IPアドレス管理(IPAM)が搭載されています。これらはすべて同じように動作します。Services API内のIPアドレスを含まないLoadBalancer型を監視し、IPアドレスを使用してkube-apiを更新します。一方、他のロードバランサーコンポーネントとkube-proxyもServices API内のIPアドレスを含むLoadBalancer型を監視し、この情報を使用してネットワークへのアドレス追加をトリガーします。アロケーターやその他のコンポーネントの動作に影響を与える一般的な問題は、Services APIでIPアドレスに使用される型が「abcd」(IPv6の場合は「a::z」)形式のアドレスを含む文字列であることです。ネットワークで使用されるIPアドレスは、サブネットマスクを含むため、「abcd/mask」(「a::z/mask」)のようにプレフィックスと呼ばれることがよくあります。Go言語では`ipNet`型が使用されますが、kube-apiではこのフィールドに文字列が使用されます。これは、アドレス追加プロセスで処理する必要があるため、重要な詳細です。

一般的に言えば、操作には主に 2 つの種類があります。

ローカルインターフェースにアドレスを追加する

ローカルインターフェースへのアドレス追加は、小規模なクラスターでは基本的な要件ですが、Kubernetes以外のインフラストラクチャコンポーネントからのローカルアクセスを必要とするサービスを公開する大規模クラスターでも役立ちます。しかし、ローカルアドレスの追加は一見するほど簡単ではありません。ローカルネットワークインターフェース上のアドレスは一意である必要がありますが、Kubernetesはすべてのノードを統一された方法で調整します。そのため、アドレスが1つのノード(理想的には目的のネットワーク上)にのみ追加されることを識別し、確実にするメカニズムを使用する必要があります。kube-proxy(クラスター内でプログラムによる割り当てを行うメカニズム)がIPVSモードで構成されている場合、これはさらに複雑になります。

IPVS。kube-proxy の IPVS 実装は、iptables の使用を減らすことでスケーラビリティを向上させます。iptables 入力チェーンの PREROUTING の代わりに、kube-ipvs0 という偽のインターフェースが作成されます。Kube-proxy は、kube-ipvs0 に負荷分散されたアドレスを追加します。デフォルトでは、Linux カーネルは任意のインターフェースからの ARP/ND 要求に応答し、任意のインターフェース上のアドレスを取得します。この動作の理由は、接続成功率を高めるためです。しかし、ローカルサブネットからアドレスが割り当てられる場合、すべてのホストが ARP/ND に応答し、ARP メッセージが重複するため、問題が発生します。ここで取り上げたすべてのロードバランサーでは、ホストの ARP/ND モードを「strict」に設定する必要があります。これは、複数のインターフェースを持つサーバーにとって推奨される方法です。

運用上の問題をトラブルシューティングするには、アドレスがどのように、どのノードに追加されるかを理解する必要があります。Kubernetes がどのようにしてノードへのアドレス追加を許可しているかを理解することは非常に重要です。ノードのネットワークインターフェースを使用する POD は、`hostNetwork:true` を使用するように設定されており、`NET_ADMIN` 機能、場合によっては `NET_RAW` 機能も許可されています。どの POD がホストネットワークを使用するように設定されているかは簡単にわかります。POD のアドレスがノードのアドレスになります。

割り当てるためにルーターにアドレスを追加します。

割り当てられたアドレスをネットワークルーティングテーブルに追加することは、よりスケーラブルで冗長性の高いソリューションです。ルーティングにより、複数のKubernetesノードが同じアドレスをアドバタイズできます。これにより、ロードバランサーはスイッチ内のルーティングテーブルに等コストマルチパスを適用し、トラフィックがクラスターに入る前にパケット分散レイヤーを提供できます。複数のパスがアドバタイズされるため、より冗長性の高いソリューションとなります。ただし、サービスロードバランサーはkube-proxy(クラスター内トラフィック分散メカニズム)と連携する必要があることに注意してください。

サービストラフィック戦略

`externalTrafficPolicy` は重要な設定です。トラフィックの分散方法について、クラスター全体とクラスター内の2つのオプションを提供します。`Cluster`(デフォルト)に設定すると、kube-proxy によって各ノードがクラスター全体に均等にトラフィックを受信して​​分散するように設定されます。`Local` に設定すると、kube-proxy は POD を実行しているノードでのみトラフィックを受信することを想定します。local 設定は外部アプリケーションで広く使用されています。このモードでは kube-proxy が NAT を必要としないため、POD には NAT されたノードアドレスではなく送信元 IP アドレスが表示されます。信頼性の高いトラフィック配信を実現するには、ロードバランサーがこれらの動作に対応する必要があります。

オープンソース

これらのロードバランサコントローラはすべてオープンソースであるため、ドキュメントの内容は様々です。多くの場合、詳細な動作を理解するにはソースコードを読む必要があります。

メタルLB

最初に広く導入されたLoadBalancerは、Googleの10%プロジェクトとして始まり、最近までオープンソースソフトウェアの負荷分散ソリューションを求めるチームにとって唯一の選択肢でした。LoadBalancerは、L2モードとBGPモードの2つの異なるモードで動作します。

MetalLB は configmap を介して構成されます。

コントローラーは 2 つの部分で構成されています。

コントローラー。IPアドレスを割り当てます。各クラスターに1つずつあります。

スピーカー。ノードネットワークを構成します。すべてのノードで実行され、IPアドレスへのアクセスを提供します。

ディストリビューター(コントローラー)

MetalLBアロケータは非常にシンプルです。アドレスプールはconfigmapによって設定されますが、モード設定もアドレスプール設定の一部です。

コントローラーは一貫した動作をし、スピーカーは2つの動作モードを実装しています。MetalLBでは、これらのモードはconfigmapプール内の「プロトコル」として設定されます。

L2モード

MetalLBでは、2つの主要コンポーネントが連携して単一のノードにアドレスを追加します。1つ目は、メンバーリストを用いたノード選出です。これは、サービス名を用いて各ノードが同じ勝者、つまり割り当てられたIPアドレスに応答する単一のノードを選択するようにする、シンプルな選出方式です。

「応答」という言葉を使ったのは、「L2」ではスピーカープロセスがARPとNDを実装しているからです。Kube-proxyはトラフィックをターゲットPODに転送するために必要な設定を追加しており、ARP/ND応答は依然として通信開始の前提条件です。

L2モードでは、MetalLBはARP/ND要求への応答にLinuxネットワークを使用しません。処理はスピーカーのPOD実行ファイル内に実装されています。そのため、MetalLBのARP/ND処理はLinuxとそのネットワークツールからは見えません。どのノードがARP/ND要求に応答しているかを特定するには、他のネットワークホスト上のARP/NDツールを使用するか、スピーカーのPODログを確認する必要があります。

Metallb はノードが使用するアドレス範囲を認識しないため、ARP/ND プロセスは ConfigMap に設定されている任意のネットワークアドレスで応答します。これにより、L2 モードで割り当てられたアドレスが到達不能になる可能性があります。これは、ノードネットワークが複数のホストサブネットにまたがる場合に特に重要です。追加されたアドレスがローカル接続を持つノード上に存在するとは限らないためです。

BGPモード

MetalLBはBGPモードでも動作します。BGPは、隣接ルータにプレフィックス(アドレス/マスク)をアドバタイズするメカニズムを提供します。このルーティングメカニズムは、Linuxのレイヤー3フォワーディングとルーティングプロトコルを組み合わせて、宛先情報を提供します。

configmap は、BGP プロトコルによって識別される BGP 自律システム情報、ピア情報、およびプールを構成します。

スピーカーは各ノード上でデーモンセットとして動作し、各ノードから設定されたピアルータへのBGPピアリング接続を確立します。AS番号は、ピアが外部か内部かを識別します。

プールからアドレスが割り当てられると、各スピーカーはそのアドレスをホストルートとしてアドバタイズします。コントローラーはkube-apiから割り当て文字列を取得し、割り当てられたすべてのアドレスに/32プレフィックスを追加することで単一のIPnetに変換し、すべてのアドレスをホストルートにします。これがBGPネイバーにアドバタイズされるアドレスです。一部のルーターはBGP /32ルートを受け入れないため、これは問題となる可能性があります。MetalLBにはBGPアドレス集約機能がありますが、これは/32アドバタイズを変更するものではなく、上流ルーターに集約を実行するように指示するだけで、ピアルーターは引き続き/32ルートを持ちます。

MetalLBには独自のBGP実装があります。これは3つの理由で重要です。

  1. MetalLBは、ルータであるノードのIPアドレスを使用します。つまり、ソフトウェアルータなど、デフォルトのネットワーク名前空間で実行されている別のプロセスは、そのホストアドレスを使用して同じルータとピアリングすることができません。大規模なネットワークでは、このことがBGP構成を非常に複雑にする可能性があります。
  2. BGP 機能は Linux ルーティング テーブルと統合できず、MetalLB によって作成されたプレフィックスを昇格するためにのみ使用できます。
  3. BGP機能はMetalLBのサポートレベルによって制限されており、他のソフトウェアルーターの機能を利用するにはMetalLB向けの特別な開発が必要です。MetalLBには、集約やコミュニティサポートなど、いくつかの追加BGP機能がありますが、いずれも標準ルーターの必須機能とはみなされていません。

両方のモードを同時に使用できますが、各モードには特定の構成が必要です。

交通戦略

MetalLBはこの設定をサポートしていますが、L2モードで「externalTrafficPolicy」を「local」に設定するとパケットロスが発生する可能性があるため、使用しないでください。BGPモードでは、PODが稼働しているノードのみがアドバタイズされます。トラフィックはPODが稼働しているノード間で均等に分配されますが、各ノードは、そのノード上のPodの数に関係なく、同じ割合でトラフィックを受け取ります。

構成

MetalLBは構成にconfigmapsを使用します。これは開発初期段階における主要な構成メカニズムであり、現在でも多くのコントローラーで使用されています。configmapsの問題は、アプリケーションPODが構成を読み取る前に検証する方法がないことです。そのため、構成が不適切だとPODが故障したり、正しく動作しなかったりする可能性があります。故障後のデバッグは、個々のPODのログを確認する以外に方法がありません。

これにより、configmap の複雑さがさらに増します。MetalLB には、導入前に理解しておく価値のある特殊な構成動作があります。誤った構成変更により、configmap が廃止としてマークされる可能性があります。古い構成は configmap に注釈として保存され、引き続き使用されます。たとえば、一度定義して使用すると、アドレスプールを変更するのは困難です。サービスが既存のプールのアドレスを使用している場合、そのプールの設定を変更することはできません。プールを変更すると、構成は廃止としてマークされ、MetalLB は同じアドレスプールを引き続き使用し、新しいサービスは古いプールから割り当てられます。構成が廃止されているかどうかを確認する唯一の方法は、MetalLB POD ログを確認することです。スピーカーを手動で再起動した場合、またはノード障害によって再起動した場合、古いアドレス割り当ては保持されます。ただし、コントローラーを再起動すると、すべてのサービスが新しい構成で再番号付けされます。コントローラーまたはスピーカーが無効な構成で再起動され、その構成が無効な場合、configmap 注釈から最後の構成が読み込まれます。スピーカーのログをチェックして、configmap へのすべての変更が有効であることを確認することが重要です。多数のアドレスが割り当てられた「古い」構成は、ダウンタイムを発生させずにロールバックすることが困難になる可能性があります。

MetalLBには豊富なドキュメントがありますが、その量は限られています。動作を理解するには、ソースコードを読む必要があります。

IPv6

ソースコードを調べると、MetalLBの一部のコンポーネントはIPv6をサポートしていることがわかりますが、システム全体としてはMetalLBはIPv6をサポートしていません。アドレスプールを追加すると、コントローラーとスピーカーに読み込まれた構成が無効になり、「古い」状態になります。

MetalLBの概要

MetalLBはネイティブのLinuxネットワーク機能を使用していないため、標準的なLinuxツールを用いたトラブルシューティングが困難です。独自のBGP実装を採用しており、大規模なBGPインフラストラクチャを管理する機能が不足しています。これらの機能を追加するにはBGPプロトコルの開発が必要であり、これは可能ではあるものの、その機能を完全に実現するには相当な開発作業が必要となるでしょう。MetalLBはBGPルーターであるため、CNIにBGPを使用するノードは、CNIのBGPとMetalLBからのBGPを同じ上流ルーターに同時に接続することはできません。トポロジに関する回避策はいくつかありますが、ルーティングインフラストラクチャの複雑さが著しく増大します。

ピュアLB

PureLBは最新のオープンソースロードバランサです。コードを調べると、MetalLBのフォークとして始まったものの、動作は大きく異なることがわかります。PureLBには「動作」モードやプロトコルモードはなく、アドレスプールを含むサービスグル​​ープから各インターフェースにアドレスを自動的に割り当てます。これらのインターフェースは、ローカルネットワークのリクエストに応答するか、独立したルーティングソフトウェアを介してルートを割り当てます。

PureLB はカスタム リソース (CRD) を使用して構成されます。

コントローラーは 2 つの部分で構成されています。

  • アロケータ。IPアドレスを割り当てます。各クラスタに1つずつあります。
  • lbnodeagent。ノードネットワークを構成します。すべてのノードで実行され、IPアドレスへのアクセスを提供します。

PureLBには「プロトコルモード」はなく、アドレスを持つサービスグル​​ープのみが含まれています。PureLBはLinuxネットワーク機能を使用してローカルで使用するためのアドレスを追加し、その後、ルータによって再割り当てされます。最小限の設定で済みますが、特定のネットワークインターフェースが必要な場合は、カスタムリソースでインターフェースのデフォルトを上書きできます。

卸売業者

PureLBのアロケータには統合IPAMが搭載されていますが、外部IPAMシステムもサポートしています。現在サポートされている外部IPAMは、人気のオープンソースであるNetBoxのみです。アロケータはカスタムリソースを使用して構成されます。各アドレスプールは、固有のサービスグル​​ープに含まれます。サービスグル​​ープには追加のネットワーク情報が含まれており、lbnodeagentは必要なプレフィックスを構築したり、IPNetを追加したりできます。アロケータはアドレスの使用方法に関係なく一貫して動作し、「プロトコル」設定は必要ありません。

ローカルネットワークアドレス

PureLBでは、「ローカル」アドレスとは、ノードのプライマリネットワークインターフェースに第2レベルのアドレスとして追加されるアドレスです。PureLBは、デフォルトルートを持つインターフェースを認識することで、プライマリネットワークアダプタを識別します。アドレスプールから割り当てられたアドレスがプライマリネットワークインターフェースのプレフィックスと一致する場合、PureLBはメンバーリストを使用してノードを選択し、そのアドレスを第2レベルのアドレスとしてインターフェースに追加します。

このアドレスはセカンダリネットワークインターフェースとして追加されるため、LinuxネットワークはARP/NDリクエストに応答します。PureLBは独自のARP/NDプロセスを実装していません。さらに、このアドレスはiproute2などの標準的なLinuxネットワークツールで表示できるため、割り当て場所も標準的なLinuxツールで確認できます。

さらに、PureLB がアドレスを割り当てると、サービスには IPAM ソースと割り当てられたアドレスがアノテーションとして追加されます。ローカルアドレスの場合は、選択されたノードとインターフェースもアノテーションとしてサービスに追加されます。

PureLB はノードネットワークを熟知しているため、ローカルネットワークに一致するサービスグル​​ーププールのみがローカルインターフェースに適用されます。これにより、確立されたローカル接続を持つアドレスへのアクセスが確保され、ルーティングが必要なアドレスは仮想インターフェースメカニズムを使用します。

仮想ネットワークアドレス

PureLB は、サービス グループ プール内のローカル ノード インターフェイスと一致しないアドレスを、kube-lb0 という名前の仮想インターフェイスに追加します。lbnodeagent は、POD の起動時にこのインターフェイスを追加します。

仮想インターフェースは、ルーティングを介してアクセスされる任意のネットワークを追加するために使用できます。効率的なルーティングを実現するために、PureLBでは、アドレス追加時にデフォルトまたは設定済みのアドレス集約マスクを使用できます。サービスグル​​ープに追加されたこのマスクは、作成され仮想インターフェースに追加されたipNetに適用されます。Linuxカーネルは、インターフェースへのアドレスの追加と正しいルートの作成を担当します。これにより、「externalTrafficPolicy: cluster」を使用する場合はサブネットを1回だけアドバタイズでき、localに設定するとホストルートをアドバタイズできます。ネットワーク設計者は、アドレス集約を使用してルーティングテーブルのサイズを制御します。集約をサポートすることで、ネットワークの柔軟性が大幅に向上します。

ルーティングプロトコル

PureLB は、仮想インターフェースに追加されたアドレスの到達可能性を割り当てるためにソフトウェアルーターの追加を必要とするルーティングプロトコルを直接実装していません。クラスターにインフラストラクチャまたは CNI 用のルーティングソフトウェアがない場合、PureLB はバンドルされた事前設定済みの BIRD ルーターデーモンを提供します。このルーターは、「再割り当て」と呼ばれる汎用関数を使用して仮想インターフェースに関連付けられたルートを読み取り、設定されたルーティングプロトコルを使用して割り当てるように設定されています。

このメカニズムを使用することで、ルーティングソフトウェアがサポートする任意のルーティングプロトコルを使用してロードバランサのアドレスを割り当てることができるため、ルーティングプロトコルの開発とロードバランサ自体の開発を切り離すことができます。BIRDルータスイートは、IPv4およびIPv6のBGP、OSPF、RIPをサポートしています。FRRなどの他のプロトコルもISISとIGRPをサポートしており、市販のルーティングソフトウェアも使用できます。このメカニズムの主な利点の一つは、ルーティングソフトウェアが各ルーティングプロトコルの完全な実装を提供することで、ネットワーク設計とルート割り当ての柔軟性を最大限に高めることができることです。到達可能性のためにOSPFを使用しているネットワークでは、BGPを必要とせずにOSPFを使用してロードバランサのアドレスを割り当てることができます。

CNIが複数のサブネットにまたがるトンネルやPODネットワークを使用するように構成されていない場合、ルーティングプロトコルが必要です。場合によっては、CNIのルーティング機能がその動作の一部として組み込まれています。このような場合、PureLBは同一ノード上で2つのルーティングインスタンスを実行しようとすることで発生する問題を回避できます。CNIのルーティングプロセスは、仮想インターフェースからルートを再割り当てし、必要なルーティングポリシーを適用するだけで、よりシンプルで自然なルーティングトポロジを作成します。

交通戦略

PureLB は、仮想ネットワークアドレスに対して `externalTrafficPolicy:local` をサポートしています。仮想ネットワークアドレスは、POD が存在する場合にのみノードに追加されます。トラフィックは POD を実行しているノード間で均等に分散されますが、各ノードは POD の数に関係なく、均等にトラフィックを受け取ります。PureLB は、ローカルネットワークアドレスに対して `externalTrafficPolicy:local` をサポートしていません。実際、ローカルネットワークアドレスに対して `externalTrafficPolicy` を `local` に設定しようとすると、PureLB はそれを `Cluster` にリセットし、kube-proxy が正しく構成され、選択されたすべての POD にトラフィックが到達できるようにします。

構成

PureLB はカスタムリソースを通じて構成されます。システム構成全体に対して 1 つの CR があり、各サービスグル​​ープに対して 1 つの CR があります。各 CR は独立しており、作成時に検証できるため、PureLB は一貫した構成を維持し、必要に応じてアドレスプールを変更できます。PureLB は既に割り当てられたアドレスを変更することはありません。アドレスの変更は意図的なものと想定しているため、アドレスの変更にはサービスの追加または削除が必要です。

PureLB が実行されると、負荷分散を提供するサービスに注釈が追加され、サービス イベント ログが更新され、POD ログを確認しなくてもサービスから重要なサービス情報とステータスを抽出できるようになります。

IPv6

PureLBはIPv6をサポートしています。アドレスとネットワーク情報を含むサービスグル​​ープが定義され、プールの使用時にIPv6アドレスがローカルまたは仮想的に追加されます。ルーティングプロトコルによる割り当てを行うには、ソフトウェアルータで適切なIPv6ルーティングプロトコルを設定する必要があります。パッケージ化されたBIRDルータはIPv6をサポートしています。

要約

この新製品は、外部IPAM、IPv6、そして最も重要なLinuxネットワーク機能を提供することで他社製品との差別化を図っています。PureLBは、ネットワークやルーティングプロトコルを刷新するのではなく、Linuxのルーティング機能を最大限に活用します。CNI、ストレージ、管理ネットワークなど、クラスター内に既に存在する他の要素へのアクセスがルーティングに必要となる複雑なインフラストラクチャでも、PureLBは容易に実装できます。コードを調べると、PureLBとフォーク版のMetalLBとの大きな違いが明らかになります。MetalLBのシンプルさは、コード行数が約半分であることからも明らかです。

OpenELB(ポーター)

Porterは比較的新しいオープンソースのロードバランサーです。スタンドアロンの開発プロジェクトです。当初はBGPのみをサポートしていましたが、最近ローカルアドレスのサポートが追加されました。Porterは、コントローラーとエージェント間で機能を分散する方法が異なります。PorterもBGPを実装していますが、ローカルネットワーク上にBGPルーターとカスタムポート設定が必要です。

Porter はカスタム リソース構成を使用します。

コントローラーは 2 つの部分で構成されています。

  • ポーターマネージャ。アドレスを割り当て、ネットワーク機能を構成します。
  • porter-agent はノードに関する特定の情報を収集し、porter-manager はその情報を使用してネットワークを構成します。

卸売業者

アロケータはporter-managerの一部です。porter-managerのインスタンスは1つだけです。プールはEIPと呼ばれるカスタムリソースに設定されています。EIPには、アドレス到達可能性に使用されるアドレスとプロトコルが含まれています。

ポーターにはデフォルトのロード バランサ アドレス プールの概念がないため、コメントが常に必要となることに注意してください。

Porter は porter-manager でネットワーク構成を集中管理しますが、porter-agent は単にイベントを収集し、特定のノード情報を追加して、この情報を porter-manager に返します。

L2

L2 モードでは、Porter は Linux ネットワークを使用しません。porter-manager 実行ファイルは独自の ARP プロセスを実装します。EIP プールからアドレスが割り当てられると、porter-manager はターゲット ノードに代わってそのアドレスの要求に応答します。サービスの ARP プロセスは、マネージャ内で集中管理されます。このメカニズムは効率的であるはずですが、ARP 処理の動作に厳密に準拠しているわけではありません。porter-manager は、最初の要求がブロードキャストされるため、それに応答します。ただし、ARP キャッシュ処理では、キャッシュされたエントリを検証するためにユニキャスト ARP メッセージを使用し、ユニキャスト ARP が失敗した場合にのみブロードキャストにフォールバックします。porter-manager はユニキャスト ARP 要求に応答しません。これにより、ブロードキャスト トラフィックが増加し、非標準の動作に依存します。ハードウェア MAC アドレスを追跡するレイヤ 2 スイッチのセキュリティ メカニズムがこの操作に干渉し、レイヤ 2 機能が失敗する可能性があります。

さらに事態を複雑にするのは、デプロイメントがスケールアップされたり、デーモンセットが存在する場合、ポーターマネージャーがポッドを実行している各ノードのMACアドレスを誤って返してしまうことがあり、結果としてネットワーク上でIPアドレスが重複してしまうことです。L2モードを使用できるのは、クラスターにポッドが1つしかない場合のみです。

最後に、継続的な運用は、Kubernetes標準のPOD障害検出メカニズムを使用するporter-managerに依存します。そのため、porter-managerの再起動には長い時間がかかり、新規サービスと既存サービスがARP応答を得られなくなるため、それらに影響を与える可能性があります。

BGP

Porterはgobgpを用いてBGPを実装していますが、gobgpの機能のごく一部しか実装していません。PorterのBGP実装は、ローカルネットワークセグメント上のルーターと同等の機能を果たすために必要な機能のみを備えています。

ポーターは、ポーター・マネージャ・ノードからクラスタに対して単一のBGPピアを確立します。BGPマルチホップを設定できないため、BGPピアはローカルネットワークセグメント上に存在する必要があります。

サービスが定義されると、porter-manager は割り当てられたアドレスを公開します。このアドレスのネクストホップはコンテナを実行しているノードです。デプロイメントをスケールアップし、POD を複数のノードに分散させると、ECMP 用のルートが追加されます。割り当てられた各アドレスはホストルート (/32) に変換されます。しかし、このトラフィックポリシーの動作は誤りであり、これについては後ほど詳しく説明します。

さらに、Porterは、単一のルートに複数の同時パスを追加するメカニズムであるAddPathをサポートしていると主張しています。この機能の用途はやや分かりにくいようです。MetalLBの投稿では、これは複数のPODを持つノード間でトラフィック分散のバランスを改善するためのメカニズムではないかと示唆されていました。これはAddPathの目的ではありません。AddPathは、通常複数のパスが集約されるルーティングテーブルの安定性を確保するために使用されます。もし彼らの実装がAddPathを使用して同じノードにECMPネクストホップを追加している場合、これはベンダー固有の動作である可能性が高いです。いずれにせよ、ほとんどのBGP実装はAddPathの数を表示しており、porter-managerが上流ルーターのこれらのカウントをノード上のPODの数を反映して更新するのを見たことはありません。

BGP プロセスはポーター マネージャの一部として実行されるため、ポーター マネージャに障害が発生すると上流ルーターのピアがダウンし、ソフトウェア ルーターはポーターから学習したすべてのルートを取り消します。

単一ノードに2台のルーターが存在することで発生する問題を解決するため、porterは異なるポート番号を使用して上流ルーターに接続します。これにより問題は部分的に解決されますが、ホストIPアドレスを使用して重複するルーターを作成するのではなく、ルーターIDを手動で設定する必要があります。

交通戦略

Porter の `externalTrafficPolicy:local` を変更すると、確かに動作が変わります。Porter は常にトラフィックをノードまたは POD を持つノードに送信します。これは Kubernetes で説明されている動作に違反します。BGP モードでは、すべてのサービスを `externalTrafficPolicy:Local` に設定する必要があります。これは、この設定に関わらず、Porter の動作そのものだからです。この設定により、kube-proxy が正しく設定され、不要な NAT ステップが削除され、送信元 IP アドレスが保持されます。Porter のレイヤー 2 オペレーションには複数の POD があり、IP アドレスが重複するため、この設定が既存の誤ったネットワーク動作にどのように影響するかについての詳細な議論は無意味です。

構成

構成はカスタム リソースを通じて実現されます。各 EIP には、アドレス範囲と関連プロトコルが含まれています。

L2では追加の設定は必要ありませんが、BGP CR(BgpConfとBgpPeer)が2つあります。BgpConfではRouterIDの定義が必要であり、BGPの実装が限定的であることがさらに強調されます。従来、これはホストデバイス上のアドレスになりますが、KubernetesがこのPODをスケジュールするため、これは混乱を招くため、静的識別子として別のアドレスを使用する必要があります。ほとんどの実装とは異なり、Porterには有効なアドレスを自動的に選択するメカニズムがありません。

Porter のドキュメントは、設定に関する部分が非常に限られています。ドキュメントからインストールして設定することは可能ですが、評価のために動作原理を理解する必要がある場合は、Go のコードを読む準備をしてください。

IPv6

PorterはIPv6をサポートしていません。コードスキャン中にIPv6のサポートは検出されませんでした。

要約

これらのロードバランサーコーディネーターの構築は決して容易ではありません。Kubernetesネットワークをホストおよびルーティングプロトコルと統合するには、かなりの知識とスキルが必要です。だからこそ、開発者の方々の尽力に敬意を表します。

参考リンク

[1] MetalLB.: https://metallb.universe.tf/

[2] PureLB: https://purelb.gitlab.io/docs/

[3] OpenELB: https://github.com/kubesphere/openelb