Kubernetes の LoadBalancer Service は、クラウド環境ではクラウド LB と連携して外部 IP を払い出します。一方、オンプレミスや自宅 Kubernetes では、そのままでは外部 IP を払い出す仕組みがありません。そこで使うのが MetalLB です。
MetalLB は、オンプレ環境で Kubernetes の LoadBalancer Service を成立させるための実装です。この記事では、MetalLB を単なるインストール手順ではなく、L2 / BGP の違い、Service と VIP の関係、送信元アドレス、speaker / controller の役割まで含めて整理します。
MetalLB の役割
- オンプレ Kubernetes で
LoadBalancerService に外部 IP を割り当てる - Service に割り当てる VIP のプールを管理する
- L2 または BGP で外部ネットワークへ VIP の到達性を作る
- controller が IP 割り当てを管理する
- speaker がノード上で L2 応答や BGP 広告を担当する
つまり MetalLB は、Kubernetes 内部の Service 抽象化と、外部ネットワークの到達性をつなぐ役割を持ちます。
L2 モードと BGP モード
MetalLB には大きく L2 モードと BGP モードがあります。どちらも VIP を外部から使えるようにする方式ですが、考え方はかなり違います。
- L2 モード: speaker が ARP / NDP に応答して VIP を同一セグメントへ見せる
- BGP モード: speaker がルーターへ VIP 経路を広告する
- L2 は導入しやすいが同一セグメント前提になる
- BGP はネットワーク設計に馴染むがルーター側の設計が必要になる
- どちらも Service、Pod 配置、外部通信の設計と関係する
インストールする
MetalLB はマニフェストや Helm で導入できます。以下はマニフェストを使う例です。バージョンは利用する Kubernetes 環境に合わせて確認します。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
kubectl get pods -n metallb-system -o wide導入後は、controller と speaker が起動しているかを確認します。
kubectl get pods -n metallb-system
kubectl get daemonset -n metallb-system
kubectl get deployment -n metallb-systemL2 モードを設定する
L2 モードでは、Service に割り当てる IP アドレスプールと、L2Advertisement を作成します。
cat <<'EOF' | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: service-pool
namespace: metallb-system
spec:
addresses:
- 10.1.0.192/27
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: service-l2
namespace: metallb-system
spec:
ipAddressPools:
- service-pool
EOFこの場合、10.1.0.192/27 は同一 L2 セグメント上で使える VIP 範囲である必要があります。既存 DHCP や静的 IP と重複させないようにします。
BGP モードを設定する
BGP モードでは、MetalLB speaker がルーターと BGP peer を張り、VIP の経路を広告します。オンプレ環境でルーティング設計をしている場合はこちらの方が自然なことがあります。
cat <<'EOF' | kubectl apply -f -
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: router-peer
namespace: metallb-system
spec:
myASN: 64512
peerASN: 64500
peerAddress: 10.1.0.1
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: bgp-service-pool
namespace: metallb-system
spec:
addresses:
- 10.1.10.0/24
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: bgp-advertisement
namespace: metallb-system
spec:
ipAddressPools:
- bgp-service-pool
EOFBGP モードでは Kubernetes だけでなく、外部ルーター側の経路制御も設計対象になります。FRR や VyOS と組み合わせる場合は、Kubernetes 側とルーター側の両方を見る必要があります。
Service に VIP を割り当てる
MetalLB を設定したら、type: LoadBalancer の Service を作成して VIP が割り当てられるか確認します。
apiVersion: v1
kind: Service
metadata:
name: example
spec:
type: LoadBalancer
selector:
app: example
ports:
- port: 80
targetPort: 80kubectl get svc -A -o wide
kubectl describe svc example送信元アドレスとの関係
MetalLB で外部公開できても、アプリケーションから見える送信元アドレスが期待どおりとは限りません。送信元 IP を保持したい場合は、externalTrafficPolicy: Local の検討が必要です。
spec:
type: LoadBalancer
externalTrafficPolicy: Localただし Local にすると、Pod が存在しないノードでは転送できないため、Pod 配置、ヘルスチェック、ロードバランサーの設計とセットで考えます。
speaker の切り分け
VIP が割り当てられているのに外部から到達できない場合は、speaker の状態を確認します。
kubectl -n metallb-system get pods -o wide
kubectl -n metallb-system logs -l app=metallb,component=speaker --tail=100
ip neigh show <VIP>L2 モードでは ARP / NDP、BGP モードでは BGP peer と経路広告を確認します。Service が正常でも、外部ネットワーク側で到達性が成立していなければ通信はできません。
確認するポイント
- controller と speaker が起動している
- IPAddressPool が作成されている
- Service に EXTERNAL-IP が割り当てられている
- L2 モードでは ARP / NDP が解決できる
- BGP モードでは peer と経路広告が成立している
externalTrafficPolicyと送信元アドレスの扱いを確認する
まとめ
MetalLB は、オンプレ Kubernetes で LoadBalancer Service を成立させるための重要な実装です。ただし、単にインストールすれば外部公開が完成するわけではありません。VIP のアドレス設計、L2 / BGP の選択、speaker の役割、送信元アドレス、外部ネットワークとの接続をまとめて考える必要があります。
L2 モードは導入しやすく、BGP モードはネットワーク設計に馴染みやすいです。どちらを選ぶ場合でも、Kubernetes の Service 抽象化と、外側のネットワーク到達性を分けて確認することが大切です。
書籍
Kubernetes完全ガイド 第2版
Kubernetes の仕組み、リソース、ネットワーク、運用観点を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
関連記事
- MicroK8s MetalLB speaker が socket permission denied を出す原因 – L2 / 権限 / ホストネットワークを切り分ける
- Kubernetes で送信元アドレスが変わる問題 – externalTrafficPolicy、hostNetwork、BGP 経路広告で考える
- Kubernetes Calico eBPF の設計メモ – kube-proxy 代替、DualStack、高可用性をどう見るか
- Kubernetes クラスター構築 – kubeadm で controlPlaneEndpoint と CNI を整理する
- Ubuntu 22.04 Kubernetes 管理ツールのインストール – kubectl / Helm / calicoctl を整理する



