手当たり次第に書くんだ

飽きっぽいのは本能

MicroK8s MetalLB speaker が socket permission denied を出す原因 – L2 / 権限 / ホストネットワークを切り分ける

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=.lastTimestamp

speaker のログを確認する

MetalLB speaker のログに socket: permission denied が出ていないか確認します。speaker は L2 モードで ARP / NDP 応答を行うため、通常の Pod よりホストネットワークに近い権限の影響を受けます。

microk8s kubectl -n metallb-system logs -l app=metallb,component=speaker --tail=200

L2 モードで何が起きているか

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 neighFAILED になる場合、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 -100

MetalLB の設定を確認する

IPAddressPoolL2Advertisement が意図したアドレス範囲を指しているかも確認します。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=100

MicroK8s 全体の状態が怪しい場合は、影響範囲を理解したうえで 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 の基本と動作確認は、次の記事と合わせて読むとつながりが分かりやすくなります。

まとめ

socket: permission denied は、MetalLB speaker が L2 応答に必要な動作を行えない状態を疑うべきエラーです。Service の EXTERNAL-IP だけを見て正常と判断すると、問題の層を見誤ります。

確認の順番は、Service の IP 割り当て、speaker のログ、クライアント側の近隣解決、Node 側のインターフェース、MetalLB の設定、MicroK8s の状態です。

MetalLB はオンプレミス Kubernetes で便利な仕組みですが、L2 モードでは物理ネットワークに近い部分まで含めて設計・確認する必要があります。

MicroK8s MetalLB speaker が socket permission denied を出す原因 – L2 / 権限 / ホストネットワークを切り分ける

コメントを残す

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

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

トップへ戻る