Calico では、Kubernetes の Service type: LoadBalancer に対するIP払い出しと、そのIPアドレスのBGP広告をCalico側で完結させることができます。
ここでは、以下の構成を例にします。
- Calico AS:
64512 - 外部BGP Router:
172.24.34.1 - 外部Router AS:
65001 - LoadBalancer用アドレス帯:
172.24.35.0/24 - Control Plane Node:
k8s-cp-01 - Worker Node:
k8s-worker-01
構成として必要になるのは、大きく以下の4点です。
- LoadBalancer用IPPoolの定義
- LoadBalancer IPのBGP広告設定
- 外部ルータとのBGPPeer設定
- Control PlaneをLoadBalancer Serviceの経路広告元から除外
LoadBalancer Controllerを有効にする
Calicoから LoadBalancer ServiceにIPアドレスを払い出すため、KubeControllersConfiguration のLoadBalancer Controllerを設定します。
apiVersion: projectcalico.org/v3
kind: KubeControllersConfiguration
metadata:
name: default
spec:
controllers:
loadBalancer:
assignIPs: AllServices
assignIPs: AllServices とすることで、Calico IPAMが LoadBalancer ServiceへのIP割り当てを行います。
LoadBalancer用IPPoolを作成する
次に、LoadBalancer Serviceに割り当てるIPアドレス帯を IPPool として定義します。
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: loadbalancer-ip-pool
spec:
cidr: 172.24.35.0/24
blockSize: 24
natOutgoing: false
disabled: false
assignmentMode: Automatic
allowedUses:
- LoadBalancer
重要なのは以下の部分です。
allowedUses:
- LoadBalancer
これにより、このIPPoolはLoadBalancer Service用のアドレスプールとして使用されます。
この例では 172.24.35.0/24 からLoadBalancer IPが払い出されます。
LoadBalancer IPをBGP広告する
IPPoolを作成しただけでは、外部ネットワークからLoadBalancer IPへ到達することはできません。
そこで、BGPConfiguration の serviceLoadBalancerIPs に、先ほど作成したLoadBalancer用アドレス帯を指定します。
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512
serviceLoadBalancerIPs:
- cidr: 172.24.35.0/24
これにより、172.24.35.0/24 の範囲からLoadBalancer Serviceに割り当てられたIPアドレスが、Calico BGPの広告対象になります。
たとえばServiceに 172.24.35.1 が割り当てられた場合、このLoadBalancer IPへの経路がBGPで外部へ広告されます。
外部ルータとのBGPPeerを設定する
次に、Calicoと外部ルータのBGP Peerを設定します。
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: external-router
spec:
peerIP: 172.24.34.1
asNumber: 65001
この例では、Calico AS 64512 から、172.24.34.1 / AS65001 の外部ルータに対してBGP Peerを確立します。
BGPPeer自体は通常のBGP接続設定として扱います。
Control PlaneをLoadBalancer Serviceの経路広告から除外する
Control Plane NodeからLoadBalancer Serviceの経路を広告したくない場合は、対象Nodeに以下のラベルを付与します。
kubectl label node k8s-cp-01 \
node.kubernetes.io/exclude-from-external-load-balancers=true
この設定によって、k8s-cp-01 は LoadBalancer Serviceの経路広告元から除外されます。
ここで重要なのは、Control Plane NodeそのものをBGPから除外するわけではないという点です。
BGP Peerやその他のCalico BGP経路広告には影響させず、LoadBalancer Serviceの経路広告だけを除外します。
構成としては以下のようになります。
k8s-cp-01
BGP Peer : 維持
その他BGP経路 : 維持
LB Service経路 : 広告しない
k8s-worker-01
BGP Peer : 維持
その他BGP経路 : 維持
LB Service経路 : 広告する
Calico関連設定をまとめた例
Calico側の設定を1つのManifestにまとめると、以下のようになります。
---
apiVersion: projectcalico.org/v3
kind: KubeControllersConfiguration
metadata:
name: default
spec:
controllers:
loadBalancer:
assignIPs: AllServices
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: loadbalancer-ip-pool
spec:
cidr: 172.24.35.0/24
blockSize: 24
natOutgoing: false
disabled: false
assignmentMode: Automatic
allowedUses:
- LoadBalancer
---
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512
serviceLoadBalancerIPs:
- cidr: 172.24.35.0/24
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: external-router
spec:
peerIP: 172.24.34.1
asNumber: 65001
Control Plane Nodeへのラベル付与だけは、別途実施します。
kubectl label node k8s-cp-01 \
node.kubernetes.io/exclude-from-external-load-balancers=true
動作確認
確認用として、単純なLoadBalancer Serviceを作成します。
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
Service作成後、以下で状態を確認します。
kubectl get svc nginx
例えば以下のように表示されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
nginx LoadBalancer 10.201.1.123 172.24.35.1 80:xxxxx/TCP
EXTERNAL-IP に 172.24.35.1 が設定されていれば、CalicoのLoadBalancer IPAMによるIP払い出しが行われています。
処理の流れをまとめると以下のようになります。
IPPool
172.24.35.0/24
|
v
Calico LoadBalancer IPAM
|
v
Service.status.loadBalancer
172.24.35.1
|
v
BGPConfiguration
serviceLoadBalancerIPs
|
v
Calico BGP
|
v
BGPPeer
172.24.34.1 / AS65001
|
v
外部ネットワーク
Control Plane Nodeには、
node.kubernetes.io/exclude-from-external-load-balancers=true
を設定することで、LoadBalancer Serviceの経路広告のみを止めます。
つまり、この構成では LoadBalancer IPの払い出し、BGP広告、外部RouterとのPeer、Control PlaneからのLoadBalancer経路広告除外を、それぞれ独立したCalico/Kubernetesの設定として組み合わせています。


