MicroK8s 環境で MetalLB の VIP が応答せず、speaker のログに socket: permission denied が出たときの切り分けメモです。Service の EXTERNAL-IP だけを見るのではなく、MetalLB speaker、L2 応答、ホストネットワーク、MicroK8s の権限境界を分けて確認します。
この記事の位置づけ
この記事は、MicroK8s で MetalLB speaker が socket: permission denied を出す場合に、どの層で問題が起きているかを切り分ける記事です。MetalLB の設定値だけでなく、speaker がホストネットワーク側で ARP / NDP に関与する点を前提に確認します。
このエラーは、単に Service が壊れているというより、MetalLB speaker が L2 モードで ARP / NDP に応答しようとしたときに、ホストネットワークや権限の制約にぶつかっている可能性を示します。
症状
典型的には、Kubernetes 側では Service に外部 IP アドレスが割り当たっているように見えるのに、クライアントから VIP へ接続できません。ここで重要なのは、IP が割り当たったことと、その IP に対して同一セグメントから到達できることは別だという点です。
- 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 モードで何が起きているか
MetalLB の L2 モードでは、speaker が VIP に対する ARP / NDP 応答を担当します。そのため、Kubernetes の Service 定義だけで完結する話ではなく、Node のインターフェース、ホストネットワーク、権限、同一 L2 セグメントの見え方が関係します。
socket: permission denied は、speaker が必要なソケット操作を行えない状態を疑うべきログです。CNI が悪い、MetalLB が悪い、と一段で決めるより、speaker がホスト側で何をしようとしているのかを先に分けて見る方が見通しやすいです。
クライアント側から確認する
クライアント側では、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 環境より切り分ける層が増えます。
オンプレミス環境で LoadBalancer Service を使う場合、Service、MetalLB、CNI、物理ネットワークを一つの塊として見ないことが重要です。それぞれの責務を分けて見ると、VIP が割り当たっているのに通信できない、という状態の原因を追いやすくなります。
まとめ
socket: permission denied は、MetalLB speaker が L2 応答に必要な動作を行えない状態を疑うべきエラーです。Service の EXTERNAL-IP だけを見て正常と判断すると、問題の層を見誤ります。
確認の順番は、Service の IP 割り当て、speaker のログ、クライアント側の近隣解決、Node 側のインターフェース、MetalLB の設定、MicroK8s の状態です。
MetalLB はオンプレミス Kubernetes で便利な仕組みですが、L2 モードでは物理ネットワークに近い部分まで含めて設計・確認する必要があります。
関連する記事
- Kubernetes MetalLB の導入 – LoadBalancer Service をオンプレ環境で成立させる
MetalLB の基本構成と LoadBalancer Service の入口を確認します。 - Kubernetes に LoadBalancer はないのか – Service、MetalLB、CNI BGP を分けて考える
LoadBalancer Service と外部公開の責務分界を確認します。 - MicroK8s で IPv6 / IPv4 デュアルスタックが動かない時に見ること
MicroK8s のネットワーク問題を CNI、Service、外部経路に分けて確認します。
次に進む
- Kubernetes で送信元アドレスが変わる問題 – externalTrafficPolicy、hostNetwork、BGP 経路広告で考える
Service 公開時の送信元アドレスと経路設計を確認します。 - Kubernetes 運用設計ガイド
Kubernetes 系記事の全体導線に戻ります。
参考書籍
書籍
Kubernetes 完全ガイド 第 2 版
Kubernetes の Service、ネットワーク、運用設計を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。

