More Related Content Similar to PodSecurityPolicy からGatekeeper に移行しました / Kubernetes Meetup Tokyo #57 (20) More from Preferred Networks (20) PodSecurityPolicy からGatekeeper に移行しました / Kubernetes Meetup Tokyo #572. 2
● 薮内 秀仁 (YABUUCHI Hidehito)
● Preferred Networks (PFN) (2020/04 ~)
● オンプレ Kubernetes クラスタの
運用・開発
● 社内 CI 基盤の開発
自己紹介
3. 3
● PodSecurityPolicy (PSP) のおさらい
● PFN での PSP からの移行
○ どう移行先を選定したか
○ どうセキュリティポリシを設計したか
○ どう移行したか
● ブログ記事も参照ください!
○ Kubernetes クラスタの PodSecurityPolicy を Gatekeeper に移行しました -
Preferred Networks Research & Development
本日お話しする内容
5. 5
● Kubernetes 組み込みのセキュリティ機構
○ Pod が満たすべきセキュリティポリシを定義し、
○ Pod リソースの spec をポリシに適合するよう変更・
適合するポリシがない pod の作成を拒否
PodSecurityPolicy (PSP)
kind: PodSecurityPolicy
spec:
# Privileged コンテナの利用を制御
# Pod の spec.containers[].securityContext.privileged フィールド
privileged: false
# コンテナの UID を制御
# Pod の spec.securityContext.runAsUser などのフィールド
runAsUser:
rule: "MustRunAsNonRoot"
6. 6
● PFN のクラスタ向けにカスタムしたセキュリティポリシの適用に利用
○ 一般的なセキュリティ要件
■ Privileged コンテナの禁止など
○ PFN のワークロード向けにカスタムした要件
■ 使用できる Linux capabilities など
○ NFS・ノードローカルストレージのアクセス制御
■ HostPath を使う場合、ユーザごとに UID / GID を特定の値に制限
■ HostPath を使わない場合、root 権限で動くコンテナを許可
■ Pod spec によってポリシを切り替え
PFN での PSP の利用
7. 7
● Pod が PSP リソースを使用する(適用されうる)権限のソースが複数
○ Pod 作成者 または pod に紐づく ServiceAccount が use できる PSP
■ Deployment などの場合、作成者 = コントローラ
● 複数の PSP がある場合、複雑なルールでどれが適用されるか決まる
PSP の主な問題点:挙動のわかりにくさ
RBAC (use verb)
ServiceAccount
Pod spec を変更・検証
PodSecurityPolicy
PodSecurityPolicy
8. 8
● 互換性を保ちつつ問題点を解決するのも難しい
○ Kubernetes 1.21 (2021/04) で非推奨
○ Kubernetes 1.25 (2022/08) で削除
○ PodSecurityPolicy Deprecation: Past, Present, and Future |
Kubernetes
● PFN では 2023/01 に Kubernetes 1.25 に更新
○ PSP からの移行をおこなった
PSP の廃止
10. 10
● セキュリティレベルを落とさず PSP を代替できること
○ カスタムしたセキュリティポリシを利用できること
○ Pod spec によって適用するポリシを選択できること
■ NFS・ノードローカルストレージのアクセス制御のため
● 扱いやすいこと
○ 単体での扱いやすさというより、扱いやすい運用方法を
設計できること
移行先の要件
11. 11
移行先候補の比較
Pod Security
Admission (PSA)
Gatekeeper Kyverno
カスタムした
セキュリティポリシ
No
Pod Security
Standards の3種類
Yes
Rego 言語で記述
Yes
YAML 上に
独自記法で記述
Pod spec によって
ポリシを選択
No
ネームスペース
ごとに固定
Yes*
ラベルや名前など
で適用対象を選択
Yes*
ラベルや名前など
で適用対象を選択
*: 別途 Admission Webhook と組み合わせる
12. 12
● PFN のユースケースで Gatekeeper と Kyverno に大きな違いはない
● Gatekeeper でセキュリティポリシの PoC を書き、
扱いやすそうだったのでそのまま採用
○ セキュリティポリシの作成には Gatekeeper Library を利用
■ 自分で Rego はほぼ書かなかった
■ PSP の allowedUnsafeSysctls 相当の機能だけ pull request
● open-policy-agent/gatekeeper-library#253
移行先の選定
13. 13
1. ConstraintTemplate リソースで制約テンプレートを定義 → CRD が作られる
2. パラメータを指定して CRD から制約リソースを作成
Gatekeeper の概要
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spspforbiddensysctls
spec:
crd:
spec:
names: # 作る CRD の名前
kind: K8sPSPForbiddenSysctls
validation:
openAPIV3Schema:
properties: # 制約のパラメータ
allowedSysctls: ...
forbiddenSysctls: ...
targets:
- rego: ... # 制約の内容
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPForbiddenSysctls
metadata:
name: baseline-forbidden-sysctls
spec:
match: # 制約の適用対象
scope: Namespaced
kinds:
- ...
labelSelector: ...
parameters: # パラメータを指定
allowedSysctls:
- ...
①
②
15. 15
● Gatekeeper では pod の属性ごとに制約が別々のリソースになる
○ 制約リソースごとに適用対象も別々となりうる
● → どんな制約リソースを作るか、どう組織化するかの設計が重要
○ セキュリティポリシを Pod に漏れなく適用
○ Pod にどの制約が適用されるか簡単に把握
設計の必要性
kind: K8sPSPPrivilegedContainer
metadata:
name: privileged-container-0
kind: K8sPSPCapabilities
metadata:
name: capabilities-0
Pod
Pod
Pod
Pod
適用
16. 16
● PSP の利点を引き継ぐ
○ 🙆 各 pod に一つの PSP が適用され、ポリシの内容がまとまっている
○ 🙆 Pod にどの PSP が適用されたか簡単に把握できる
○ 🙆 ポリシに適合するよう、Pod spec を自動で mutate する
● PSP の欠点を解消する
○ 🙅 PSP が複数ある場合、どれが適用されるかわかりにくい
○ 🙅 Pod spec の mutation が暗黙的
設計上の観点
17. 17
● 🙆 各 pod に一つの PSP が適用され、ポリシの内容がまとまっている
○ 課題:Gatekeeper は pod の属性ごとに制約が別々のリソースに
■ Privileged コンテナ、UID / GID, ...
● 🙆 Pod にどの PSP が適用されたか簡単に把握できる
○ 課題:Gatekeeper は制約リソースから適用対象の pod を選択する形
■ spec.match フィールドの条件にマッチした pod に適用される
● → 解決策:セキュリティポリシの単位で制約リソースをまとめ
「ポリシ」を構成
PSP の利点をどう引き継ぐか
18. 18
制約リソースをまとめ「ポリシ」を構成
baseline ポリシ
kind: Pod
metadata:
labels:
gatekeeper.k8s.preferred.jp/policy: baseline
.
.
.
kind: K8sPSPForbiddenSysctls
spec:
match:
labelSelector:
matchLabels:
gatekeeper.k8s.preferred.jp/policy: baseline
kind: K8sPSPForbiddenSysctls
spec:
match:
labelSelector:
matchLabels:
gatekeeper.k8s.preferred.jp/policy: baseline
kind: K8sPSPForbiddenSysctls
spec:
match:
labelSelector:
matchLabels:
gatekeeper.k8s.preferred.jp/policy: baseline
ポリシ内の制約リソースは
同じラベルセレクタをもつ
1. Pod のラベルでポリシを指定 2. ポリシ内の制約がすべて適用される
19. 19
● 🙆 各 pod に一つの PSP が適用され、ポリシの内容がまとまっている
○ 結果:各 pod に一つのポリシが適用され、ポリシ内に制約リソー
スがまとまっている
● 🙆 Pod にどの PSP が適用されたか簡単に把握できる
🙅 PSP が複数ある場合、どれが適用されるかわかりにくい
○ 結果:Pod のラベルにどのポリシを適用するか明示され、pod 側
からポリシを指定する形に
PSP の利点の引き継ぎ・欠点の解消
20. 20
● 🙆 ポリシに適合するよう、Pod spec を自動で mutate する
🙅 Pod spec の mutation が暗黙的
○ Gatekeeper ではリソースの mutation も可能
■ 例:Pod の runAsUser フィールドにユーザごとの UID を書き込む
○ Mutation 操作は Assign などのカスタムリソースで明示的に表現
● → 結果:PSP の利点をすべて引き継ぎ・欠点をすべて解消
Mutation
21. 21
● ユーザ向け:スムーズな移行のため、既存の PSP と同等のポリシ
○ root
■ Pod が root 権限で動くことを許可
■ UID / GID 以外の制約が強い(HostPath 禁止など)
○ non-root
■ Pod が一般ユーザ権限で動くことを強制
● クラスタアドオン向け:Pod Security Standards に準拠したポリシ
○ restricted
○ baseline
○ privileged(制約リソースなし)
用意したポリシ
22. 22
● すべての pod に適切なポリシが適用されていることを担保したい
○ クラスタアドオン
■ 解決策:デフォルトで restricted ポリシを適用
○ ユーザの pod
■ 課題:どのポリシを適用するかは pod のラベルで指定
● ユーザは pod のラベルを自由に設定できる
■ 課題:Pod spec によって適用するポリシを選択したい
■ → 解決策:Mutating admission webhook と組み合わせ
ポリシ適用の強制
23. 23
Mutating admission webhook との連携
kind: Pod
metadata:
labels:
gatekeeper.k8s.preferred.jp/policy: root
Pod spec に応じてポリシを選択
Mutating
admission webhook
Gatekeeper
kind: Pod
metadata:
labels: {}
● ポリシを指定するラベルを検証
● ポリシに応じて制約を満たすか検証
26. 26
1. Gatekeeper の制約リソースを spec.enforcementAction: warn で作成
a. 違反時も pod 作成・更新は拒否せず、警告のみ
b. クラスタアドオンを稼働させたままにできる
2. ポリシ違反が解消されるまで、クラスタアドオンを一つずつ修正
a. Gatekeeper の audit controller のログで違反を確認
i. 定期的にクラスタ上の pod を検査
b. ほとんどのアドオンは securityContext を明示的に設定すること
で restricted ポリシに適合できた
クラスタアドオンのポリシ違反をすべて修正
28. 28
● Kubernetes 1.25 への更新を契機に PSP から Gatekeeper に移行した
○ PSP の利点を引き継ぎつつ欠点を解消するよう、制約リソースを
組織化し「ポリシ」を構成
○ ユーザに影響なく クラスタアドオンをポリシに適合させていき、
スムーズな更新を達成
● 今後:社内の admission webhook の機能を Gatekeeper に移植する
ことを検討
○ ポリシの宣言的な記述・リリース作業の簡略化のため
まとめと今後