手当たり次第に書くんだ

飽きっぽいのは本能

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点です。

  1. LoadBalancer用IPPoolの定義
  2. LoadBalancer IPのBGP広告設定
  3. 外部ルータとのBGPPeer設定
  4. 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へ到達することはできません。

そこで、BGPConfigurationserviceLoadBalancerIPs に、先ほど作成した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-01LoadBalancer 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-IP172.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の設定として組み合わせています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る