1. 背景
自宅クラスタで運用している MicroK8s (v1.32.9) 環境において、
突然MetalLBによるL2 LoadBalancerのVIPが応答しなくなった。
症状としては以下の通り:
- 同一セグメント内ホストから
curl https://<VIP>→No route to host ip neigh show <VIP>→FAILEDarping→ 応答なし- ただし、k8sノードそのものへの疎通は正常。
2. 原因の初期推定
最初に疑ったのはNATやルーティング。
しかしtracerouteや他ノードへの疎通テストで異常は見られず、
問題は明らかに VIPに対するARP応答の欠落 にあると判明した。
そこでMetalLB speakerのログを確認したところ、決定的なメッセージが出ていた:
creating ARP responder for "enp1s0": listen packet socket: permission denied
3. 原因の本質
要点はこれ一つ:
MicroK8s 1.32 のアップデートにより、seccompのデフォルトが強化され、speakerがAF_PACKETソケットを開けなくなった。
MetalLBのL2モードでは、ARP/NDPパケットを送出するために
コンテナ内で raw socket (AF_PACKET) を開く必要がある。
これがseccompの RuntimeDefault プロファイルによってブロックされていた。
他のログ・設定からも以下を確認:
pod-security.kubernetes.io/enforce: privilegedは設定済み(PSAは犯人でない)AppArmorは active(DENIEDログはないがpolicyが影響)MetalLB speaker: quay.io/metallb/speaker:v0.13.3(古い世代)
つまり、MetalLB 0.13.x は新しいseccomp設定に非対応だった。
4. 対応策(復旧手順)
seccomp と AppArmor の制限を一時的に解除するパッチを適用:
kubectl -n metallb-system patch ds speaker --type='json' -p='[
{"op":"add","path":"/spec/template/spec/securityContext","value":{"seccompProfile":{"type":"Unconfined"}}},
{"op":"add","path":"/spec/template/metadata/annotations/container.apparmor.security.beta.kubernetes.io~1speaker","value":"unconfined"},
{"op":"add","path":"/spec/template/spec/containers/0/securityContext/allowPrivilegeEscalation","value":true}
]'
kubectl -n metallb-system rollout restart ds speaker
再起動後のログ:
created ARP responder for interface "enp1s0"
service has IP, announcing 10.145.0.192
そしてARP応答が復活:
arping 10.145.0.192
64 bytes from 10.145.0.192: index=0 time=0.512 msec
5. 恒久対応
一時的な kubectl patch は再デプロイで消えるため、
DaemonSetマニフェストに恒久的に反映しておく。
Kubernetes 1.30以降ではAppArmor注釈が非推奨のため、
次の形式が望ましい:
securityContext:
seccompProfile:
type: Unconfined
appArmorProfile:
type: Unconfined
6. 今後の選択肢
- MetalLBを0.14以降に更新
→ seccomp周りの調整が進んでおり、この問題は解消済み。 - BGPモードへの移行
→ ARP/NDP依存を排除し、L2層での権限問題を根本的に回避できる。 - 自作seccompプロファイルで最小権限を許可
→AF_PACKETなど必要最小限のみ許可するローカルプロファイルを作成し、
speakerにlocalhostProfileとして適用する。
7. 教訓
Kubernetes とコンテナランタイムは、
「セキュリティ強化による後方互換性の崩壊」を静かに引き起こす。
L2でのARP/NDP制御のような低レイヤ操作を行うコンポーネントは、
この変化に最も敏感である。
セキュリティが強化された瞬間、それまでの権限前提は壊れる。
8. まとめ
| 項目 | 状態 |
|---|---|
| 問題 | MetalLB speaker が ARP応答を出さずVIPが死んだ |
| 原因 | seccompのデフォルト強化(RuntimeDefault有効化) |
| 対処 | seccomp / AppArmor を Unconfined に設定 |
| バージョン | microk8s v1.32.9, metallb v0.13.3 |
| 教訓 | セキュリティ強化は“静かな破壊”を伴う |





