MicroK8s 環境で MetalLB の VIP が応答せず、speaker のログに socket: permission denied が出たときの切り分けメモです。
この記事の位置づけ
この記事は、MicroK8s の MetalLB speaker が socket permission denied を出す場合の切り分け記事です。L2 広報、権限、hostNetwork のどこで詰まっているのかを確認します。
このエラーは、単に Service が壊れているというより、MetalLB speaker が L2 モードで ARP / NDP に応答しようとしたときに、ホストネットワークや権限の制約にぶつかっている可能性を示します。
次に読む記事
書籍
Kubernetes 完全ガイド 第 2 版
Kubernetes の Service、ネットワーク、運用設計を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
症状
典型的には、Kubernetes 側では Service に外部 IP アドレスが割り当たっているように見えるのに、クライアントから VIP へ接続できません。
- Service の
EXTERNAL-IPは割り当たっている - 同一セグメントから VIP に接続しても応答しない
ip neigh show <VIP>がFAILEDになる- Node 自体への SSH や Kubernetes API は生きている
- MetalLB speaker のログに
socket: permission deniedが出る
まず見るべき状態
最初に、MetalLB の Pod、Service、イベントを確認します。Pod が Running であっても、L2 応答ができていなければ VIP は外部から使えません。
microk8s kubectl get pods -n metallb-system -o wide
microk8s kubectl get svc -A
microk8s kubectl get events -A --sort-by=.lastTimestampspeaker のログを確認する
MetalLB speaker のログに socket: permission denied が出ていないか確認します。speaker は L2 モードで ARP / NDP 応答を行うため、通常の Pod よりホストネットワークに近い権限の影響を受けます。
microk8s kubectl -n metallb-system logs -l app=metallb,component=speaker --tail=200L2 モードで何が起きているか
L2 モードの MetalLB では、VIP 宛の ARP または NDP に対して、選ばれた Node 上の speaker が応答します。つまり、VIP は Kubernetes 内部だけで完結する仮想アドレスではなく、同一 L2 セグメント上で解決できる必要があります。
- VIP がクライアントと同じ L2 セグメントにある
- speaker が ARP / NDP に応答できる
- Node のインターフェースが該当セグメントに接続している
- ホスト側の権限や制約で raw socket が阻害されていない
- CNI や MicroK8s addon の状態が壊れていない
ここを誤解すると、Service や Pod だけを見てしまい、実際には L2 の近隣解決が失敗している問題を見落とします。
クライアント側から確認する
クライアント側では、VIP の近隣解決ができているかを確認します。ip neigh が FAILED になる場合、HTTP や Nginx 以前に L2 の応答が成立していない可能性があります。
ip neigh show <VIP>
ping <VIP>
curl -v http://<VIP>/Node 側で確認する
Node 側では、speaker がどの Node で動いているか、該当 Node のインターフェースと経路がどうなっているかを確認します。MicroK8s では snap 管理のサービスも関係するため、MicroK8s 側のログも見ます。
microk8s kubectl get pods -n metallb-system -o wide
ip addr
ip route
journalctl -u snap.microk8s.daemon-kubelite --no-pager | tail -100MetalLB の設定を確認する
IPAddressPool や L2Advertisement が意図したアドレス範囲を指しているかも確認します。Service に IP が割り当たっていても、その IP が実ネットワーク側で成立しない範囲であれば外部からは使えません。
microk8s kubectl -n metallb-system get ipaddresspool,l2advertisement -o yaml
microk8s kubectl -n metallb-system describe ipaddresspool
microk8s kubectl -n metallb-system describe l2advertisement復旧手順の考え方
一時的な不整合であれば、speaker の再起動で復旧することがあります。ただし、根本原因が権限、CNI、addon の破損、または MicroK8s 側の制約であれば再発します。
microk8s kubectl -n metallb-system rollout restart daemonset speaker
microk8s kubectl -n metallb-system get pods -o wide
microk8s kubectl -n metallb-system logs -l app=metallb,component=speaker --tail=100MicroK8s 全体の状態が怪しい場合は、影響範囲を理解したうえで MicroK8s の再起動を検討します。稼働中のワークロードがある環境では、安易に実行しない方がよいです。
sudo snap restart microk8s
microk8s status --wait-ready
microk8s kubectl get nodes
microk8s kubectl get pods -A設計上の見方
この種の問題は、MetalLB だけの問題として見るより、Kubernetes と物理ネットワークの境界で起きる問題として見た方が整理しやすいです。
MetalLB の L2 モードは手軽ですが、同一セグメント、ARP / NDP、Node のネットワークインターフェース、ホスト権限に依存します。MicroK8s では snap や addon の構成も加わるため、通常の kubeadm 環境より切り分ける層が増えます。
関連する記事
MetalLB の基本と動作確認は、次の記事と合わせて読むとつながりが分かりやすくなります。
- Kubernetes MetalLB の導入 – LoadBalancer Service をオンプレ環境で成立させる
- Kubernetes Nginx コンテナと Service LoadBalancer – MetalLB で外部 IP を確認する
- Kubernetes MetalLB を Helm で導入する – Harbor で Chart を管理する考え方
まとめ
socket: permission denied は、MetalLB speaker が L2 応答に必要な動作を行えない状態を疑うべきエラーです。Service の EXTERNAL-IP だけを見て正常と判断すると、問題の層を見誤ります。
確認の順番は、Service の IP 割り当て、speaker のログ、クライアント側の近隣解決、Node 側のインターフェース、MetalLB の設定、MicroK8s の状態です。
MetalLB はオンプレミス Kubernetes で便利な仕組みですが、L2 モードでは物理ネットワークに近い部分まで含めて設計・確認する必要があります。




