Skip to main content

restrictedを有効にしたらServiceLBが死んだ。K3sのPod Security Admissionに潜む、汎用ガイドにない設定差分

K3sクラスタでPod Security Admission(PSA)のrestrictedプロファイルを有効にした途端、LoadBalancer型のServiceが軒並み外部IPを失った——そんな経験をした運用者は少なくないはずだ。Kubernetes公式ドキュメントの手順通りにnamespaceへラベルを付けただけなのに、なぜK3sだけが壊れるのか。本記事では、K3s vs 標準Kubernetesの構成差分という観点からPod Security Admissionの落とし穴を整理する。

1. Pod Security Admissionとは何か ― K3sと標準Kubernetesで前提が違う

section01

Pod Security Admission(PSA)は、Podの作成リクエストを検査しセキュリティ基準への準拠を強制するadmission controllerだ。privileged(無制限)、baseline(既知の権限昇格を防ぐ最低限の制限)、restricted(Podハードニングのベストプラクティスに従う厳格な制限)という3つのレベルを持ち、それぞれをenforce(違反時にブロック)・audit(監査ログに記録)・warn(警告のみ)の3モードで運用できる(kubernetes.io公式ドキュメント)。

PSAは2022年にリリースされたKubernetes v1.25で安定版(stable)となり、長年ベータのまま塩漬けになっていた旧来のPodSecurityPolicy(PSP)を置き換える形で導入された(TechTargetの解説記事)。PSPはユーザーやサービスアカウントへのバインドという複雑な権限モデルを持っていたため運用が難しく、v1.25で完全に削除されている(Teleportの移行ガイド)。

ここで押さえておきたいのは、PSAはデフォルトでは何も強制しないという設計思想だ。既存ワークロードを壊さずに段階的に導入できるよう、管理者が明示的にnamespaceへラベルを付けるまでは何のポリシーも適用されない。

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: v1.37

標準的なkubeadmクラスタでPSA導入を解説する記事の多くは、この「何もしなければ何も起きない」という前提で書かれている。だがK3sは事情が異なる。K3s公式のCISハードニングガイドは、「K3sはデフォルトでPod SecurityもNetworkPolicyも一切含まない」と明記しており、K3sならではの同梱コンポーネントが後述する落とし穴を生む。こうした構成差分を自前で追いかけ続ける運用コストは、KuboのようなマネージドK3sサービスを検討する動機のひとつにもなる。

2. 標準Kubernetesの手順通りにrestrictedを適用したら、K3sのServiceLBが止まった

section02

典型的な事故のシナリオはこうだ。CISベンチマーク対応のためK3sクラスタ全体にrestrictedを適用しようと、kubernetes.io公式の手順に従ってkubectl labelを全namespaceへ実行する。Baselineプロファイルの時点で既に、hostPathボリュームの使用はspec.volumes[*].hostPathが未定義であることを要求され禁止される(Pod Security Standards公式ドキュメント)。Restrictedはこれをさらに厳格化したものだ。

適用直後、クラスタ内のLoadBalancer型Serviceが次々と外部IPを失う。原因を追うと、K3sが標準で同梱しているロードバランサ機能「ServiceLB」が提供するsvclb-*という名前のPodが、新しく作成できなくなっていることが分かる。ServiceLBはServiceごとにPodをスケジュールし、ホストのポートを直接bindする仕組みで動作する(K3s公式のネットワーキング解説)。この仕組みが、restrictedプロファイルの制約と正面から衝突する。

標準Kubernetesクラスタでは外部ロードバランサはクラウドプロバイダーのLBサービスに委ねられ、クラスタ内にこの種のPodは存在しない。つまり**「標準Kubernetesの手順では問題にならないものが、K3sでは致命的な障害になる」**という典型例がServiceLBなのだ。

3. 原因はServiceLBが要求するNET_ADMINとunsafe sysctls

section03

K3s公式のCISハードニングガイドには、restrictedを有効化する際に用意すべき3種類のポリシー例が明記されている。

  • restricted-psp: 標準的な制限ポリシー
  • system-unrestricted-psp: kube-systemのシステムPod用に権限を緩和したポリシー
  • svclb-psp: ServiceLB専用。以下を明示的に許可する
yaml
allowedCapabilities:
  - NET_ADMIN
allowedUnsafeSysctls:
  - net.ipv4.ip_forward
  - net.ipv6.conf.all.forwarding

ServiceLBはポートを直接bindしIPフォワーディングを制御する都合上、NET_ADMINケーパビリティと特定のunsafe sysctlsを必要とする。これらはrestrictedプロファイルが原則として禁止する項目であり、例外として明示的に許可しない限りPodの作成自体が拒否される。

重要なのは、このsvclb-pspという概念がK3s公式ドキュメントにしか出てこないという点だ。汎用的なPod Security Admission解説記事や、標準Kubernetes向けのCISベンチマーク対応ガイドをいくら読んでも、ServiceLBという単語は登場しない。K3sをマネージドK8sの選択肢として検討する際、「標準Kubernetesの知識で十分」と思い込んでいると、こうした同梱コンポーネント固有の例外設定を見落としやすい。Kubo CloudのようにPure Kubernetes構成をベースにしたサービスであれば、こうした既知の落とし穴を踏まえた標準構成が最初から提供される余地がある。

4. K3sのPSA導入で見落としやすい、もう一つの落とし穴

section04

ServiceLB以外にも、K3s標準構成の中にはPSA導入時に注意すべきコンポーネントがある。

K3sの既定ストレージであるlocal-path-provisionerは、PVCのプロビジョニング時に内部でhelperPodを生成しhostPathを扱う実装になっている。この仕組み自体はPod自身がhostPathボリュームを直接マウントするわけではないため、アプリケーションPodがrestrictedポリシーに抵触することは基本的にない。ただし設定ミスがセキュリティリスクに直結する点は意識しておきたい。実際に、local-path-configConfigMapへの書き込み権限を持つユーザーがhelperPodテンプレートを操作し、特権コンテナやhostPathマウントを注入できる脆弱性(CVE-2026-44543)が報告され、0.0.36で修正されている(OSV.devの脆弱性データベース)。PSAのrestrictedポリシーを適切に運用することは、こうした設定ミス由来の攻撃経路を狭める効果もある。

また、監視基盤として一般的なnode-exporterのようなDaemonSetは、ホストのメトリクスを取得するためhostNetworkやhostPathを必要とし、baseline・restrictedいずれのプロファイルにも非準拠となる(OneUptimeの技術解説)。これはK3s固有の問題ではなく標準Kubernetesでも同様に起きるが、K3sクラスタをまとめてrestrictedにする際は、ServiceLBとあわせて事前に洗い出しておくべき対象として押さえておきたい。

5. 安全にPod Security Admissionを導入するためのK3sチェックリスト

section05

K3sクラスタにPSAを安全に導入するには、次の手順を踏むとよい。

  1. v1.25以降ならPSA設定ファイルを用意する: --kube-apiserver-arg="admission-control-config-file=..."でAdmissionConfigurationを指定し、svclb-psp相当の例外を事前に組み込む(K3s公式ハードニングガイド)
  2. いきなりenforceにしない: まずwarn・auditモードで全namespaceに適用し、違反が出るワークロードを洗い出す(kubernetes.io公式ドキュメント)
  3. kube-system・ServiceLB関連namespaceは個別に扱う: 一律ラベルではなく、システムコンポーネントが稼働するnamespaceだけ例外ポリシーを設計する
  4. hostPath/hostNetworkに依存するコンポーネントを棚卸しする: local-path-provisionerのhelperPod、監視エージェント等を事前にリストアップする
  5. 段階的にenforceへ移行する: 違反がゼロになったnamespaceから順にenforceへ切り替える

この手順を自前で毎回組み立て、K3sのバージョンアップごとに例外ポリシーの差分を追い続けるのは、決して小さくない運用コストだ。KuboのようなK3sベースのマネージドサービスであれば、こうした既知の設定差分を踏まえた構成をあらかじめ提供できる余地がある。

6. まとめ ― 「標準Kubernetesの知識」だけでは足りない

K3sはCNCF認定の軽量Kubernetesディストリビューションであり、APIレベルでは標準Kubernetesと高い互換性を持つ。しかしServiceLBのような同梱コンポーネントは、標準Kubernetesのクラウド依存のロードバランサ構成とは根本的に異なる前提で動いている。Pod Security Admissionという「Kubernetes標準機能」を導入する場面でも、この構成差分が思わぬ障害を引き起こす。

K3s vs 標準Kubernetesという比較軸で技術選定をする際は、機能一覧やベンチマーク数値だけでなく、「同梱コンポーネントがセキュリティポリシーとどう干渉するか」まで踏み込んで確認しておきたい。

運用負荷の高いセキュリティ設定の棚卸しや例外ポリシーの維持を外部に任せたい場合は、Kubo CloudのPure Kubernetes構成とAI-Driven Deploymentが選択肢になる。EKS/AKSのコストと複雑さに悩まされず、K3sベースの本格的なKubernetesをそのまま使える。

一方、金融機関や医療機関のようにデータ主権・Air-Gapped環境が求められる現場では、ハードニング済みの構成を自社インフラ内に閉じて運用できるKubo On-Premiseが適している。CISベンチマーク対応やPod Security Admissionの例外設計をゼロから自前で積み上げる前に、こうした選択肢も検討してみる価値はあるはずだ。

セキュリティ設定の見直しやK3s移行を具体的に検討しているなら、お問い合わせから相談してみてほしい。

Related articles

← Back to all posts