前回MetalLBの動作の仕組みについて説明しました。
Kubernetesのオンプレ環境で負荷分散するためにMetalLBを設定します。
概要
今回はKubernetesの外部通信を負荷分散するためにMetalLBでBGP+ECMP+BFDの環境を構築します。
ルータはFortigateを利用しています。(ルータではないという突っ込みは無しで…)
構成は下図になります。
環境
NW環境
名前 | バージョン |
---|---|
Fortigate | v7.2.3 |
Kubernetes環境
名前 | バージョン |
---|---|
CentOS-Stream-9 | |
kubelet | v1.26.2 |
kubeadm | v1.26.2 |
containerd | v1.6.16 |
calico | v3.25 |
metallb | v0.13.9 |
設定手順
Fortigateの設定
ECMP設定
クラスタが3台構成なのでECMPのMAXパスに3を設定します。
config system settings
set ecmp-max-paths 3
end
BGP設定
「高度なルーティング」が有効になっていなければGUIで有効化します。
CLIで下記設定を投入します。(ECMPの設定はCLIでのみ設定可能です)
config router bgp
set as 65000
set router-id 10.20.30.254
set keepalive-timer 10
set holdtime-timer 30
set ebgp-multipath enable
config neighbor
edit "10.20.30.1"
set bfd enable
set capability-default-originate enable
set soft-reconfiguration enable
set remote-as 65001
next
edit "10.20.30.2"
set bfd enable
set capability-default-originate enable
set soft-reconfiguration enable
set remote-as 65001
next
edit "10.20.30.3"
set bfd enable
set capability-default-originate enable
set soft-reconfiguration enable
set remote-as 65001
next
end
config redistribute "connected"
end
config redistribute "rip"
end
config redistribute "ospf"
end
config redistribute "static"
end
config redistribute "isis"
end
config redistribute6 "connected"
end
config redistribute6 "rip"
end
config redistribute6 "ospf"
end
config redistribute6 "static"
end
config redistribute6 "isis"
end
end
BFD設定
CLIでBFDの有効化とネイバーを設定します。
config system interface
edit "dmz"
set bfd enable
next
end
config router bfd
config neighbor
edit 10.20.30.1
set interface "dmz"
next
edit 10.20.30.2
set interface "dmz"
next
edit 10.20.30.3
set interface "dmz"
next
end
end
ipvsに変更
kube-proxyの設定をiptablesからipvsに変更します。
コマンドで編集モードで入ります。
kubectl edit configmap -n kube-system kube-proxy
ipvsを有効化するのにARPの設定が必要になります。
下記設定を変更しipvsに切り替えます。
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
補足:以下コマンドでdiff取りと設定変更が可能です。
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
sed -e "s/mode: \"\"/mode: \"ipvs\"/" | \
kubectl diff -f - -n kube-system
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/mode: \"\"/mode: \"ipvs\"/" | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
kube-proxyのPodを再起動します。
kubectl get pods -A |grep proxy #Pod名を確認
kubectl delete pod --namespace=kube-system [kube-proxy名]
MetalLB構築
KubernetesにMetalLBを導入していきます。
MetalLBのデプロイ
BFDを使いたいのでMetalLBのFRRモードを利用します。
下記コマンドでMetalLBをデプロイします。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-frr.yaml
MetalLBの設定
IPアドレスプールやBGP、BFDのマニュフェストを作成して適用します。
metallb-config.yamlで作成します。
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 172.16.200.1-172.16.200.254
autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: BGPPeer
metadata:
name: bgp-peer
namespace: metallb-system
spec:
myASN: 65001
peerASN: 65000
peerAddress: 10.20.30.254
peerPort: 179
bfdProfile: bfdprofile
---
apiVersion: metallb.io/v1beta1
kind: BFDProfile
metadata:
name: bfdprofile
namespace: metallb-system
spec:
receiveInterval: 25
transmitInterval: 25
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: external
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
aggregationLength: 24
マニュフェストを適用します。
kubectl apply -f metallb-config.yaml
MetalLB動作確認
MetalLBの状態確認
kubectl get pods –namespace=metallb-system -o wideでControllerとSpeakerがRunningになっていることを確認します。
[user001@k8s-mas01~]# kubectl get pods --namespace=metallb-system -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
metallb-system controller-7dd7f6785b-nbv9w 1/1 Running 25 (159d ago) 90d 10.240.235.205 k8s-mas01 <none> <none>
metallb-system speaker-5pbzn 4/4 Running 124 (159d ago) 97d 10.20.30.1 k8s-mas01 <none> <none>
metallb-system speaker-6bnz7 4/4 Running 116 (159d ago) 97d 10.20.30.2 k8s-nod01 <none> <none>
metallb-system speaker-blfm8 4/4 Running 108 (159d ago) 97d 10.20.30.3 k8s-nod02 <none> <none>
Fortigateの状態確認
get router info bgp networkでピアからルートを受信してマルチホップで見えることを確認できます。
FortiGate # get router info bgp network
VRF 0 BGP table version is 280, local router ID is 10.20.30.254
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight RouteTag Path
* 172.16.200.0/24 10.20.30.3 0 0 0 65001 i <-/->
* 10.20.30.1 0 0 0 65001 i <-/->
*> 10.20.30.2 0 0 0 65001 i <-/1>
Total number of prefixes 1
get router info bfd neighborでBFDステータスがアップしていることを確認できます。
FortiGate # get router info bfd neighbor
OurAddress NeighAddress State Interface LDesc/RDesc
10.20.30.254 10.20.30.1 UP dmz 3/124
10.20.30.254 10.20.30.2 UP dmz 2/254
10.20.30.254 10.20.30.3 UP dmz 1/111
テスト用Podを起動
Nginxデプロイ
テスト用にNginxを6つ稼働させます。
nginx-test.yamlで作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 6
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- port: 80
selector:
app: nginx
マニュフェストを適用します。
kubectl apply -f nginx-test.yaml
Nginx状態確認
kubectl get pods –output=wideでPod状態一覧を表示して確認してみます。
6つ全てがRunningになっていることを確認できます。
[user001@k8s-mas01~]# kubectl get pods --output=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-6b7f675859-896df 1/1 Running 0 2m35s 10.240.235.198 k8s-mas01 <none> <none>
my-nginx-6b7f675859-fvxnh 1/1 Running 0 2m35s 10.240.58.219 k8s-nod02 <none> <none>
my-nginx-6b7f675859-gcdh8 1/1 Running 0 2m35s 10.240.85.212 k8s-nod01 <none> <none>
my-nginx-6b7f675859-m8xgx 1/1 Running 0 2m35s 10.240.235.245 k8s-mas01 <none> <none>
my-nginx-6b7f675859-mms4c 1/1 Running 0 2m35s 10.240.85.209 k8s-nod01 <none> <none>
my-nginx-6b7f675859-tq6hg 1/1 Running 0 2m35s 10.240.58.213 k8s-nod02 <none> <none>
kubectl get svcでサービス状態を確認します。
LoadBalancerタイプでExternal-IPが割り振られていることが確認できます。
[user001@k8s-mas01~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-svc LoadBalancer 10.105.165.234 172.16.200.1 80:31890/TCP 101s
外部端末からブラウザでアクセスできることを確認できます。
テスト用Pod削除
下記のコマンドでPod設定を削除します。
kubectl delete -f nginx-test.yaml
最後に
最後までお読みいただきありがとうございます。
Kubernetesは仕組みが複雑で詰まるところも多いので、毎日試行錯誤する日々です。
ただ、KubernetesだけでなくISPやNW機器周りで書きたいことが溜まっているので出来るだけそちら方面も記事に起こしていこうと思います。