IPVS モードで kube-proxy を実行する - Amazon EKS

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

IPVS モードで kube-proxy を実行する

IP Virtual Server (IPVS) モードでの EKS は、レガシー iptables モードで実行されている kube-proxy を使用して 1,000 を超えるサービスで大規模なクラスターを実行するときによく見られるネットワークレイテンシーの問題を解決します。このパフォーマンスの問題は、パケットごとに iptables パケットフィルタリングルールを順次処理した結果です。このレイテンシーの問題は、iptables の後継である nftables で解決されています。ただし、この執筆時点では、kube-proxy は nftables を活用するためにまだ開発中です。この問題を回避するには、クラスターを kube-proxy IPVS モードで実行するように設定できます。

概要

Kubernetes バージョン 1.11 以降 GA であった IPVS は、線形検索ではなくハッシュテーブルを使用してパケットを処理し、数千のノードとサービスを持つクラスターに効率を提供します。IPVS はロードバランシング用に設計されており、Kubernetes ネットワークパフォーマンスの問題に適したソリューションです。

IPVS には、バックエンドポッドにトラフィックを分散するためのいくつかのオプションがあります。各オプションの詳細については、Kubernetes の公式ドキュメントに記載されていますが、以下に簡単なリストを示します。ラウンドロビン接続と最小接続は、Kubernetes の IPVS ロードバランシングオプションで最も人気のある選択肢の 1 つです。

- rr (Round Robin)
- wrr (Weighted Round Robin)
- lc (Least Connections)
- wlc (Weighted Least Connections)
- lblc (Locality Based Least Connections)
- lblcr (Locality Based Least Connections with Replication)
- sh (Source Hashing)
- dh (Destination Hashing)
- sed (Shortest Expected Delay)
- nq (Never Queue)

実装

EKS クラスターで IPVS を有効にするために必要なステップはわずかです。まず、EKS ワーカーノードイメージに Linux Virtual Server 管理ipvsadmパッケージがインストールされていることを確認します。Amazon Linux 2023 などの Fedora ベースのイメージにこのパッケージをインストールするには、ワーカーノードインスタンスで次のコマンドを実行します。

sudo dnf install -y ipvsadm

Ubuntu などの Debian ベースのイメージでは、インストールコマンドは次のようになります。

sudo apt-get install ipvsadm

次に、上記の IPVS 設定オプションのカーネルモジュールをロードする必要があります。これらのモジュールは、再起動後も存続するように、 /etc/modules-load.d/ ディレクトリ内のファイルに書き込むことをお勧めします。

sudo sh -c 'cat << EOF > /etc/modules-load.d/ipvs.conf ip_vs ip_vs_rr ip_vs_wrr ip_vs_lc ip_vs_wlc ip_vs_lblc ip_vs_lblcr ip_vs_sh ip_vs_dh ip_vs_sed ip_vs_nq nf_conntrack EOF'

次のコマンドを実行して、既に実行されているマシンにこれらのモジュールをロードできます。

sudo modprobe ip_vs sudo modprobe ip_vs_rr sudo modprobe ip_vs_wrr sudo modprobe ip_vs_lc sudo modprobe ip_vs_wlc sudo modprobe ip_vs_lblc sudo modprobe ip_vs_lblcr sudo modprobe ip_vs_sh sudo modprobe ip_vs_dh sudo modprobe ip_vs_sed sudo modprobe ip_vs_nq sudo modprobe nf_conntrack
注記

これらのワーカーノードステップは、ユーザーデータスクリプトを介して、またはカスタムワーカーノード AMI を構築するために実行されるビルドスクリプトで、ワーカーノードのブートストラッププロセスの一部として実行することを強くお勧めします。

次に、IPVS モードで実行するようにクラスターの kube-proxy DaemonSet を設定します。これを行うには、 kube-proxy mode を に設定ipvsし、 ipvs schedulerを上記のロードバランシングオプションのいずれかに設定します。例えば、ラウンドロビンrrの場合です。

警告

これは破壊的な変更であり、時間外に実行する必要があります。影響を最小限に抑えるために、最初の EKS クラスターの作成時にこれらの変更を行うことをお勧めします。

kube-proxy EKS アドオンを更新することで、AWS CLI コマンドを発行して IPVS を有効にできます。

aws eks update-addon --cluster-name $CLUSTER_NAME --addon-name kube-proxy \ --configuration-values '{"ipvs": {"scheduler": "rr"}, "mode": "ipvs"}' \ --resolve-conflicts OVERWRITE

または、クラスターの ConfigMap kube-proxy-config を変更することでこれを行うことができます。

kubectl -n kube-system edit cm kube-proxy-config

scheduler設定を見つけipvsrrRound Robin など、上記の ipvs ロードバランシングオプションの 1 つに値を設定します。デフォルト設定が である mode設定を見つけiptables、値を に変更しますipvs。どちらのオプションの結果も、次の設定のようになります。

iptables: masqueradeAll: false masqueradeBit: 14 minSyncPeriod: 0s syncPeriod: 30s ipvs: excludeCIDRs: null minSyncPeriod: 0s scheduler: "rr" syncPeriod: 30s kind: KubeProxyConfiguration metricsBindAddress: 0.0.0.0:10249 mode: "ipvs" nodePortAddresses: null oomScoreAdj: -998 portRange: "" udpIdleTimeout: 250ms

これらの変更を行う前にワーカーノードがクラスターに結合されている場合は、kube-proxy DaemonSet を再起動する必要があります。

kubectl -n kube-system rollout restart ds kube-proxy

検証

いずれかのワーカーノードで次のコマンドを発行することで、クラスターとワーカーノードが IPVS モードで実行されていることを検証できます。

sudo ipvsadm -L

少なくとも、 の Kubernetes API Server サービスのエントリ10.100.0.1と の CoreDNS サービスのエントリを示す、次のような結果が表示されます10.100.0.10

IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP ip-10-100-0-1.us-east-1. rr -> ip-192-168-113-81.us-eas Masq 1 0 0 -> ip-192-168-162-166.us-ea Masq 1 1 0 TCP ip-10-100-0-10.us-east-1 rr -> ip-192-168-104-215.us-ea Masq 1 0 0 -> ip-192-168-123-227.us-ea Masq 1 0 0 UDP ip-10-100-0-10.us-east-1 rr -> ip-192-168-104-215.us-ea Masq 1 0 0 -> ip-192-168-123-227.us-ea Masq 1 0 0
注記

この出力例は、サービス IP アドレス範囲が の EKS クラスターから取得されます10.100.0.0/16