IPVS を使用すると、大規模クラスターでパフォーマンス上の利点が得られますが、それをサポートするには特定の条件も必要です。条件が満たされていない場合は、iptables モードを使用するように自動的にダウングレードされます。現在の環境では、カーネル バージョンは 3.10.0 です。最初、システムは CentOS. 7.6 でしたが、カーネルはそれを完全にサポートするためにバージョン 4.1 にアップグレードされました。
1. SVCの概要
1.1 プロキシモードの概要
Kubernetes クラスターでは、各ノードが kube-proxy プロセスを実行します。kube-proxy は、ExternalName の代わりに Service の VIP (仮想 IP) の形式を実装する責任があります。
Kubernetes v1.0 では、プロキシは完全にユーザー空間内にあります。Kubernetes v1.1 バージョンでは、iptables プロキシが新しいですが、これはデフォルトの動作モードではありません。Kubernetes v1.2 以降、デフォルトは iptables プロキシです。Kubernetes v1.8.0-beta.0 では、ipvs プロキシが追加されました。Kubernetes バージョン 1.14 以降、デフォルトで ipvs プロキシが使用されます。
1.2 IPVS の利点
Kubernetes に IPVS を選択する理由は何ですか?
Kubernetes の使用が増えるにつれて、そのリソースのスケーラビリティがますます重要になります。特に、大規模なワークロードを実行する開発者/企業が Kubernetes を導入するには、サービスのスケーラビリティが重要です。
Kube-proxy はサービス ルーティングの構成要素であり、ClusterIP や NodePort などのコア サービス タイプをサポートするために強化された iptables に依存します。ただし、iptables は純粋にファイアウォール用に設計されており、カーネル ルール リストに基づいているため、数千のサービスに拡張するのが困難です。
Kubernetes はバージョン v1.6 ですでに 5000 ノードをサポートしていますが、iptables を使用する kube-proxy が実際にはクラスターを 5000 ノードに拡張する際のボトルネックになっています。たとえば、5000 ノードのクラスターで NodePort サービスを使用する場合、2000 のサービスがあり、各サービスに 10 個のポッドがある場合、各ワーカー ノードに少なくとも 20000 の iptable レコードが生成され、カーネルが非常にビジーになる可能性があります。
一方、この場合、IPVS ベースのクラスタ内サービスのロード バランシングを使用すると、非常に役立ちます。IPVS は負荷分散用に設計されており、ほぼ無制限のスケーリングを可能にするより効率的なデータ構造 (ハッシュ テーブル) を使用します。
タイプ | アプリケーションの紹介 |
---|---|
rr |
ラウンドロビン |
lc |
最小接続数 |
dh |
ターゲットハッシュ |
sh |
ソースハッシュ |
sed |
予想される最小遅延 |
nq |
キューのスケジュール設定なし |
2. カーネルをアップグレードする
カーネル バージョンがすでに 4.1 より大きい場合、このカーネル バージョンは IPVS を完全にサポートできるため、この手順は無視できます。現在のカーネル バージョンを例に取ると、サービス モードが iptables から ipvs に変更されると、次の問題が発生する可能性があります。 :
- ipvs が指すバックエンド ノードは正しくありません。svc を削除して再構築すれば正しいです。
- レプリカの数が変化すると、ipvs はすぐには認識できません
- ドメイン名を直接使用して svc にアクセスすると、解決できません。
# 开始环境的系统信息
# uname -r
3.10.0-1160.41.1.el7.x86_64
# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
# 在 3.10 内核版本中改用ipvs,kube-proxy 会报如下错误
# kubectl -n kube-system logs kube-proxy-6pp2d
E0415 09:46:55.397466 1 proxier.go:1192] Failed to sync endpoint for service: 172.16.0.82:30080/TCP, err: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398639 1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398658 1 proxier.go:1533] Failed to sync endpoint for service: 10.10.1.35:30080/TCP, err: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398751 1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
...
2.1 カーネルパッケージのダウンロード
1) Alibaba Cloudからダウンロード
2.2 カーネルパッケージのインストール
# 更新内核时,对系统的cpu的负载很高,因此建议一台一台更新
# yum install kernel-4.9.215-36.el7.x86_64.rpm -y
# init 6
# uname -r
4.9.215-36.el7.x86_64
3. モード変更
3.1 オープンipvs
カーネルが ipvs をロードしているかどうかを確認し、ロードしていない場合は、個別にロードしてインストールします。
# lsmod | grep -e ip_vs
ip_vs_sh 16384 0
ip_vs_wrr 16384 0
ip_vs_rr 16384 9
ip_vs 147456 15 ip_vs_wrr,ip_vs_rr,ip_vs_sh
nf_conntrack 106496 8 ip_vs,nf_conntrack_proto_sctp,nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
libcrc32c 16384 2 ip_vs,xfs
# lsmod |grep nf_conntrack_ipv4
nf_conntrack_ipv4 16384 8
nf_defrag_ipv4 16384 1 nf_conntrack_ipv4
nf_conntrack 106496 8 ip_vs,nf_conntrack_proto_sctp,nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_na
# cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# yum -y install ipset ipvsadm
3.2 svcモードの変更
# kubectl edit configmap kube-proxy -n kube-system
...
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: "ipvs" # "" 改成 ipvs
nodePortAddresses: null
oomScoreAdj: null
...
configmap/kube-proxy edited
--
# 删除现有的 kube-proxy pod,相当于重启后才会变更成 ipvs
# kubectl get pods -n kube-system|grep kube-proxy
kube-proxy-6pp2d 1/1 Running 1 8h
kube-proxy-mcfp6 1/1 Running 1 8h
kube-proxy-qmdhp 1/1 Running 1 8h
# kubectl delete pod/kube-proxy-6pp2d -n kube-system
pod "kube-proxy-6pp2d" deleted
# kubectl delete pod/kube-proxy-mcfp6-n kube-system
pod "kube-proxy-mcfp6" deleted
# kubectl delete pod/kube-proxy-qmdhp -n kube-system
pod "kube-proxy-qmdhp" deleted
3.3 ビューの検証
# kubectl -n kube-system logs kube-proxy-qmdhp|grep ipvs
I0415 10:48:49.984477 1 server_others.go:259] Using ipvs Proxier.
# 在 kube-proxy pod 看到如上信息后说明是启用ipvs的
# 测试使用的是 deployment 2个nginx, 一个 svc 指向 nginx pod
# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 127.0.0.1:30080 rr
-> 172.16.100.8:80 Masq 1 0 0
-> 172.16.100.197:80 Masq 1 0 0
TCP 172.16.0.1:443 rr
-> 10.10.1.35:6443 Masq 1 4 0
TCP 172.16.0.10:53 rr
-> 172.16.100.9:53 Masq 1 0 0
-> 172.16.100.10:53 Masq 1 0 0
TCP 172.16.0.10:9153 rr
-> 172.16.100.9:9153 Masq 1 0 0
-> 172.16.100.10:9153 Masq 1 0 0
...
注: ipvs はまだ安定していないため、注意して使用してください。また、--masquerade-all オプションは Calico セキュリティ ポリシー制御と互換性がないため、必要に応じて使用することを検討してください (Calico では、ネットワーク ポリシーを実行するときにこのオプションを有効にできない必要があります)制限)
参照:
https://blog.csdn.net/weixin_43936969/article/details/106175580
https://blog.csdn.net/qq_25854057/article/details/122469765
https://kubernetes.io/zh/blog/2018/07/ 09/ipvs-based-in-cluster-load-balancing-deep-dive/