Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Open Policy Agent / Gatekeeper 勉強会
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Akihiro Ikezoe
August 26, 2019
Technology
3k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Open Policy Agent / Gatekeeper 勉強会
Akihiro Ikezoe
August 26, 2019
More Decks by Akihiro Ikezoe
See All by Akihiro Ikezoe
Kubernetesコントローラーのパフォーマンスチューニング
zoetrope
4
2.2k
Kubernetes Admission Webhook Deep Dive
zoetrope
8
1.6k
Kubernetesオペレータのアンチパターン&ベストプラクティス
zoetrope
11
4.9k
Production-Ready Kubernetesに至るまでの3年間とこれから
zoetrope
4
950
オンプレKubernetesでMySQLクラスタの運用を自動化するためにOperatorを自作している話
zoetrope
5
2.5k
サイボウズを支える技術~インフラ刷新プロジェクトNecoを中心に紹介~
zoetrope
1
1.3k
Kuebernetesクラスタのマルチテナンシーベストプラクティス
zoetrope
8
6.9k
クラウドネイティブなチームづくり
zoetrope
7
4k
Kubernetesクラスタの自動管理システムのつくりかた
zoetrope
3
19k
Other Decks in Technology
See All in Technology
Djangoユーザが知っ得なPostgreSQL機能 - 設計の選択肢を増やす / Djang-use-PostgreSQL
soudai
PRO
0
210
ブロックチェーン / Blockchain
ks91
PRO
0
110
「嘘をつくテスト」の失敗例から学ぶ 良いテストコード #frontend_phpcon_do
asumikam
0
590
自律型AIエージェントは何を破壊するのか
kojira
0
130
ChatworkとBPaaS 異なる特性で学んだAI機能開発の ベストプラクティス
kubell_hr
2
3.3k
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
0
320
Microsoft Build Keynoteふりかえり
tomokusaba
0
120
やさしいA2A入門
minorun365
PRO
7
940
【Gen-AX】20260530開催_JJUG CCC 2026 Spring
genax
1
450
タクシーアプリ『GO』の実践的データ活用
mot_techtalk
3
180
個人の発見を、組織の知恵に 〜生成AI活用を"探索"から"組織の仕組み"へ〜
kintotechdev
3
1.1k
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
490
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Site-Speed That Sticks
csswizardry
13
1.2k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Thoughts on Productivity
jonyablonski
76
5.2k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Deep Space Network (abreviated)
tonyrice
0
170
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
It's Worth the Effort
3n
188
29k
Documentation Writing (for coders)
carmenintech
77
5.4k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
22k
Transcript
Open Policy Agent Gatekeeper 勉強会 2019/08/26 (2019/11/24改訂) 池添 明宏
目次 • OpenPolicyAgent とは • Document • Rego • Gatekeeper
とは • ポリシーの作り方 • 機能紹介 2
Open Policy Agent とは • 軽量な汎用ポリシーエンジン • ポリシーに基づいて入力データの検証をおこなう • 特徴
• 宣言的な記述でポリシーの読み書きがしやすい • コンパイルし直すことなくポリシーの変更が可能 3
何に使えるの? • 例えば Kubernetes において、RBAC よりも柔軟なルールを適用でき る。 • 例: •
Pod に resource フィールドの指定を強制する • 利用可能なコンテナレジストリを制限する • 特定のユーザーに一部のリソースへのアクセスを制限する 4
Data & Policy 5 • Data (Document) • サービスやユーザーが用意するデータ •
JSON 形式 • Policy (Rule) • データに適用する検証ルール • Rego という独自言語で定義 出展: https://www.openpolicyagent.org/docs/latest/how-does-opa-work/
Document の種別 • Base Documents • サービスやユーザーが用意した データ • Virtual
Documents • Rule を適用した結果データ • Virtual Documents にさらに Rule を適用することも可能 6 出展: https://www.openpolicyagent.org/docs/latest/how-does-opa-work/
Documents の構造 • data • 検証に利用する静的なデータ • Rule を適用した結果データ •
input • 検証対象の入力データ 7 出展: https://www.openpolicyagent.org/docs/latest/how-does-opa-work/
Rule から Document へのアクセス • import で Document にアクセス できる
• 例えば opa.examples.allow とい うルールを適用した結果の Virtual Document は、data.opa.example s.allow に入っている。 8 import data.opa.examples.allow import data.servers rule { server := servers[_] input.server == server allow[server] }
Rules • Rego という独自言語でデータの検証ルールを記述する • Rego • Datalog という Prolog
系言語をインスパイア • 宣言的な記述が可能 • The Rego Playground で試してみよう • https://play.openpolicyagent.org/ 9
Rego による Rule の定義 10 # BODYの条件を満たした場合 # HEADの値を返す rule_name
<HEAD> { <BODY> } # 条件を満たさなかった場合 # undefinedを返す # 配列の場合は空配列を返す # HEADの省略は =trueと同じ rule1 { input.x < input.limit } # 固定値を返す rule2 = "abc" { input.x < input.limit } # 変数を返すことも可能 rule3 = x { x := input.x x < input.limit }
AND 条件と OR 条件 11 # 羅列するとAND条件 rule_name <HEAD> {
<CONDITION1> <CONDITION2> <CONDITION3> } # OR条件は同一名のルールを # 複数個用意する rule_name <HEAD1> { <CONDITION1> } rule_name <HEAD2> { <CONDITION2> }
Go 言語と比較してみる 12 # Rego default allow = false allow
= true { input.size != 0 input.size < data.limit } # Go func allow() bool { if input.size == 0 { return false } if input.size >= data.limit { return false } return true }
else • 同一名の複数ルールは適用順序が考 慮されない。矛盾したルールは記述 することができない。 • 順序を考慮する場合は else キーワー ドを利用する。
13 rule_name <HEAD1> { <CONDITION1> } else <HEAD2> { <CONDITION2> }
繰り返し 14 containers = { "ap": { "image": "ubuntu:18.04" },
"db": { "image": "mysql:latest" }, } # latestイメージを抽出してkeyを返す rule[key] = image { image := containers[key].image endswith(image, ":latest") } numbers = [1, 2, 3, 4, 5] # 偶数だけを抽出 rule[x] { x := numbers[_] x % 2 == 0 }
For Any, For All 15 # For All # 条件を逆にして否定する
positive { not isNegative } isNegative { x := numbers[_] x < 0 } # 内包表記 positives { negative := [x | x := numbers[_]; x < 0] count(negatives) == 0 } # For Any numbers = [1, 2, 3, 4, 5] # 1つでも条件に一致すればtrue rule { x := numbers[_] x >= 0 }
Go 言語と比較してみる 16 # Rego images = [ "quay.io/cybozu/ubuntu", "docker.io/nginx",
"localhost/nginx" ] repos = [ "quay.io", "docker.io" ] rule[img] { img := images[_] rep := repos[_] startswith(img, rep) } # Go func rule() []string { var result []string for _, img := range images { for _, rep := range repos { if strings.HasPrefix(img, rep) { result = append(result, img) } } } return result }
関数定義 • ルールと似たような記法で関数 を定義することができる。 • 関数は引数を受け取ることがで きる。 • ルールのように Virtual
Document は生成されない 17 starts_with_foo(s) { startswith(s, "foo") } remove_prefix_foo(s) = r { starts_with_foo(s) r := substring(s, 3, -1) }
組み込み関数 • 集計: count(), sum(), sort(), all(), any() • 文字列:
contains(), startswidt(), endswith(), replace(), split(), sprintf(), substring() • 正規表現: re_match(), regex.split() • 型判定: is_number(), is_string(), is_set() • エンコーディング: json.marshal()/unmarshal(), yaml.marshal()/unmarshal() • そのほか Token Signing/Verification, 時間, HTTP通信 などなど 18
集合演算 • 集合を扱うことができる • 和集合、差集合、積集合などの 計算が可能 • 空集合は {} ではなく
set() 19 resources = { "pod", "service", "deployment", "node" } apps = { "pod", "deployment" } hello[x] { # 差集合の計算 x := resources - apps }
コマンドラインツール • バイナリダウンロード • https://github.com/open-policy-agent/opa/releases • 文法チェック • opa check
hoge.rego • 実行 • opa eval --input input.json --data hoge.rego –format pretty "data.query" • フォーマット • opa fmt -w hoge.rego 20
テスト • with xxx as yyy 構文を利用して、 テスト対象のルールに任意の入力 を与えることができる。 •
下記のコマンドでテスト実行 • opa test -v . 21 package k8s.test_admission import data.k8s.admission test_deny { input1 := { "review": { "namespace": "kube-system" }, "parameters": { "systemNamespaces": [ "kube-system", "kube-public" ] } } # k8s.admission.violation というルールをテスト res := admission.violation with input as input1 count(res) > 0 }
Gatekeeper • Open Policy Agent を Kubernetes で使えるようにしたもの • Kubernetes
の Admission Controller Webhook による呼び 出し • ポリシーを Custom Resource と して定義可能 • 共通処理をライブラリとして利用 可能 22 出展: vhttps://kubernetes.io/blog/2019/08/06/opa- gatekeeper-policy-and-governance-for-kubernetes/
Admission Controller Webhook • Kubernetes の拡張機能のひとつ • Kubernetes のリソースを作成、更新、削除するタイミング で外部の
Webhook API を呼び出す • Validating: リソースが条件を満たしているかチェック • Mutating: リソースの一部を書き換える • Gatekeeper v3 では未対応 (対応中) 23
Gatekeeper の歴史 • Gatekeeper v1 • OpenPolicyAgent + kube-mgmt •
Gatekeeper v2 • OpenPolicyAgent + kube-mgmt + kube-policy-controller • Gatekeeper v3 • kubebuilder を利用して全面刷新 24
動かしてみよう • https://github.com/zoetrope/gatekee per-demo • kind をセットアップ • kind create
cluster --name gatekeeper --config cluster.yaml • kubectl apply -f https://raw.githubuse rcontent.com/open-policy-agent/gate keeper/master/deploy/gatekeeper.ya ml 25 # cluster.yaml kind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 kubeadmConfigPatches: - | apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration metadata: name: config apiServer: extraArgs: "enable-admission-plugins": "ValidatingAdmissionWebhook" nodes: - role: control-plane - role: worker
動かしてみよう • 特定のレジストリ以外のコンテナイメージの利用を禁止するポリ シーを用意する • ポリシーを記述した ConstraintTemplate カスタムリソースを作成 • ポリシーの適用対象とパラメータを記述した
Constraint カスタムリ ソースを作成 26
カスタムリソース • ConstraintTemplate • Gatekeeper が Custom Resource Definition を用意している
• Constraint の名前とスキーマを定義 • ポリシーを Rego で記述 • Constraint • ConstraintTemplate から動的に作られる Custom Resource Definition • ポリシー適用対象リソースとパラメータを指定 27
ConstraintTemplate 28 apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sallowedrepos spec:
crd: spec: names: kind: K8sAllowedRepos # Constraint の Custom Resource 名 validation: # `parameters` フィールドのスキーマ openAPIV3Schema: properties: repos: type: array items: type: string targets: # 後述
ConstraintTemplate 29 apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sallowedrepos spec:
crd: # 省略 targets: - target: admission.k8s.gatekeeper.sh # 固定 rego: | package k8sallowedrepos violation[{"msg": msg}] { container := input.review.object.spec.containers[_] satisfied := [good | repo = input.parameters.repos[_]; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf("container <%v> has an invalid image repo <%v>", [container.name, container.image]) }
Constraint 30 apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sAllowedRepos metadata: name: repo-is-cybozu spec:
match: # 対象リソースを指定 kinds: - apiGroups: [""] kinds: ["Pod"] parameters: # パラメータの指定。rego から input.parameters としてアクセス可能 repos: - "quay.io/cybozu/"
入力データ 31 { "review": { # AdmissionReview "uid": "705ab4f5-6393-11e8-b7cc-42010a800002", "kind":
{"group":"apps","version":"v1","kind":"Pod"}, "resource": {"group":"apps","version":"v1","resource":"pods"}, "operation": "CREATE", "userInfo": { "username": "admin", "groups": ["system:authenticated","system:masters"], }, "object": { "apiVersion":"v1","kind":"Pod",... }, }, # Constraintで指定したパラメータ "parameters": {"repos": ["quay.io/cybozu",...]} }
検証してみよう $ kubectl apply -f nginx.yaml Error from server ([denied
by repo-is-cybozu] container <nginx> has an invalid image repo <nginx:latest>): error when creating "nginx.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by repo-is-cybozu] container <nginx> has an invalid image repo <nginx:latest> 上記のようなメッセージが表示されたら成功 32 # nginx.yaml apiVersion: v1 kind: Pod metadata: labels: run: nginx name: nginx namespace: default spec: containers: - name: nginx image: nginx:latest
データの同期 • Kubernetes クラスタの特定リ ソースを Rego から利用できるよ うにする。 • client-go/informer
により結果を キャッシュ。 • Audit 機能や namespaceSelector を利用するときにも必要。 33 apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: "gatekeeper-system" spec: sync: syncOnly: - group: "" version: "v1" kind: "Namespace" - group: "" version: "v1" kind: "Pod"
同期データの利用方法 • Cluster-scoped Resource • data.inventory.cluster[<groupVe rsion>][<kind>][<name>] • Namespaced Resource
• data.inventory.namespace[<na mespace>][<groupVersion>][<k ind>][<name>] 34 allPods[name] = pod { # 全namespaceのPodを取得 pod := data.inventory .namespace[_][_]["Pod"][name] }
Audit • ValidatingAdmissionWebhook はリソースの作成、更新、削除など のタイミングで実行される • Audit 機能を利用すると、定期的にポリシーのチェックが実施される • 検証対象のリソースは同期設定しておく必要ある
• Constraint リソースの Status に検証結果が保存される 35
トレース • トレース機能を利用すると、検証に 利用した入力データや検証結果がロ グに出力される • 大量にログが出力されるので、デ バッグ用途での利用を推奨 • 正直トレースの読み方がわからない
36 apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: "gatekeeper-system" spec: validation: traces: - user: "kubernetes-admin" kind: group: "" version: "v1" kind: "Pod" dump: "All"
Rego のテスト • ConstraintTemplate の中に Rego が埋め込まれてるのでテストしにくい。 • ConstraintTemplate のベースファイルに
Rego を埋め込む Kustomize プラグイ ンをつくってみた。 • https://github.com/zoetrope/ConstraintTemplateGenerator 37
おしまい(所感) • 最初はとっつきにくいかもしれないけど、慣れればそれなりに書き やすい。 • デバッグしにくいので、トレース周りは改善してほしい。 • argo-cd と相性悪いのをなんとかしたい。 •
パフォーマンスがよくないかも? • https://github.com/open-policy-agent/gatekeeper/issues/266 38