[K8s] Open Policy Agentを試す
大前提
まずそもそもOPAで扱われるAdmission Webhookを理解すべし。以下のサイトが非常に分かりやすいです。
何をするのか
のチュートリアルを読んで手元のK8s環境でOpen Policy Agentを試す。
なぜOpen Policy Agentを使うのか
一言で言うと、現時点(2022/07/19)のKubernetes RBAC制御では出来ないことが出来るから (例えば、podのyaml定義で決められたrepositoryのイメージのみを許可する、等、非常にきめ細やかな設定が可能に!)。以下の記事が非常に分かりやすいです。
OPA (aka Gatekeeper v1.0)の進化版、Gatekeeperがあったのでそちらを試します。
- 任意のk8s環境にhelmインストールします。
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace
- https://open-policy-agent.github.io/gatekeeper/website/docs/howto に従って進みます。
- テンプレートを作成する必要があるようです:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/templates/k8srequiredlabels_template.yaml
--
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
# Schema for the `parameters` field
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
- ポリシーを試します:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/constraints/all_ns_must_have_gatekeeper.yaml
--
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-gk
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["gatekeeper"]
- ラベルあり・なしでnamespaceを作ってみます。
$ kubectl create ns hoge
Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [ns-must-have-gk] you must provide labels: {"gatekeeper"}
$ kubectl create namespace hoge --dry-run=client -o yaml|sed '/^metadata\:/a\
labels: {"gatekeeper":"true"}
'| kubectl apply -f -
namespace/hoge created
$ kubectl describe ns hoge
Name: hoge
Labels: gatekeeper=true
kubernetes.io/metadata.name=hoge
Annotations: <none>
Status: Active
困ったこと
- AWS EKS上での
CONNECT
[1]イベントを取得したかったのですが、Gatekeeperのデフォルト設定では、どうもUPDATE, CREATE
の2つしか取得されてませんでした。
AWS公式の情報によると[2]以下の通りの記載あり。
We’ll then create a ValidatingWebhookConfiguration which will tell Kubernetes to send CREATE, UPDATE pod events to allow our policy to validate them:
調べてみるとUPDATE, CREATE
の2つしか定義されてませんでした。
$ kubectl get ValidatingWebhookConfiguration
NAME WEBHOOKS AGE
gatekeeper-validating-webhook-configuration 2 160m
$ kubectl get -o yaml ValidatingWebhookConfiguration gatekeeper-validating-webhook-configuration
- AdmissionReviewのリクエストオブジェクトを見たい
全てをRejectするルールを作成し、Denyをせずにメッセージを吐き出すだけにすればOK
-
kubectl get pod
のようなものを制御したい
結論、Admission Webhook では達成できませんので、Authorization ModeのWebhook[3]を使いましょう。
Admission controllers act on requests that create, modify, delete, or connect to (proxy) an object. Admission controllers do not act on requests that merely read objects. [4]
-
https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-rules ↩︎
-
https://aws.amazon.com/blogs/opensource/using-open-policy-agent-on-amazon-eks/ ↩︎
-
https://kubernetes.io/docs/reference/access-authn-authz/authorization/#authorization-modules ↩︎
-
https://kubernetes.io/docs/concepts/security/controlling-access/#admission-control ↩︎