Open Policy Agent with Kubernetes #2

minikubeでOpenPolicyAgentをAPI ServerのAdmissinReview先として利用し、policyのvalidationが行われる様子を確認します。
以下docのtutorialを進めます。
www.openpolicyagent.org

~/S/O/o/ingress-validation-tutorial ❯❯❯ minikube addons list
|-----------------------------|----------|--------------|
|         ADDON NAME          | PROFILE  |    STATUS    |
|-----------------------------|----------|--------------|
| dashboard                   | minikube | disabled     |
| default-storageclass        | minikube | enabled ✅   |
| efk                         | minikube | disabled     |
| freshpod                    | minikube | disabled     |
| gvisor                      | minikube | disabled     |
| helm-tiller                 | minikube | disabled     |
| ingress                     | minikube | disabled     |
| ingress-dns                 | minikube | disabled     |
| istio                       | minikube | disabled     |
| istio-provisioner           | minikube | disabled     |
| logviewer                   | minikube | disabled     |
| metrics-server              | minikube | disabled     |
| nvidia-driver-installer     | minikube | disabled     |
| nvidia-gpu-device-plugin    | minikube | disabled     |
| registry                    | minikube | disabled     |
| registry-aliases            | minikube | disabled     |
| registry-creds              | minikube | disabled     |
| storage-provisioner         | minikube | enabled ✅   |
| storage-provisioner-gluster | minikube | disabled     |
|-----------------------------|----------|--------------|

~/S/O/o/ingress-validation-tutorial ❯❯❯ minikube addons enable ingress
🌟  The 'ingress' addon is enabled
~/S/O/o/ingress-validation-tutorial ❯❯❯ minikube addons list
|-----------------------------|----------|--------------|
|         ADDON NAME          | PROFILE  |    STATUS    |
|-----------------------------|----------|--------------|
| dashboard                   | minikube | disabled     |
| default-storageclass        | minikube | enabled ✅   |
| efk                         | minikube | disabled     |
| freshpod                    | minikube | disabled     |
| gvisor                      | minikube | disabled     |
| helm-tiller                 | minikube | disabled     |
| ingress                     | minikube | enabled ✅   |
| ingress-dns                 | minikube | disabled     |
| istio                       | minikube | disabled     |
| istio-provisioner           | minikube | disabled     |
| logviewer                   | minikube | disabled     |
| metrics-server              | minikube | disabled     |
| nvidia-driver-installer     | minikube | disabled     |
| nvidia-gpu-device-plugin    | minikube | disabled     |
| registry                    | minikube | disabled     |
| registry-aliases            | minikube | disabled     |
| registry-creds              | minikube | disabled     |
| storage-provisioner         | minikube | enabled ✅   |
| storage-provisioner-gluster | minikube | disabled     |
|-----------------------------|----------|--------------|
~/S/O/o/ingress-validation-tutorial ❯❯❯
~/S/O/o/ingress-validation-tutorial ❯❯❯ kubectl create ns opa
namespace/opa created
~/S/O/o/ingress-validation-tutorial ❯❯❯ kubectl get ns  --show-labels
NAME              STATUS   AGE    LABELS
default           Active   6d3h   <none>
kube-node-lease   Active   6d3h   <none>
kube-public       Active   6d3h   <none>
kube-system       Active   6d3h   <none>
opa               Active   3s     <none>
~/S/O/o/ingress-validation-tutorial ❯❯❯

# 3.deploy OPA on top of Kuberentes
KubernetesとOPAの間ではTLSプロトコルを利用します。
TLSを構成するためにopensslコマンドで権威証明書(CA)とOPAのための証明書/鍵ペアを生成します。

~/S/O/o/ingress-validation-tutorial ❯❯❯ openssl genrsa -out ca.key 2048 #CA用秘密鍵を生成
Generating RSA private key, 2048 bit long modulus
.............+++
.................+++
e is 65537 (0x10001)
~/S/O/o/ingress-validation-tutorial ❯❯❯
~/S/O/o/ingress-validation-tutorial ❯❯❯ openssl req -x509 -new -nodes -key ca.key -days 100000 -out ca.crt -subj "/CN=admission_ca" #CA生成
~/S/O/o/ingress-validation-tutorial ❯❯❯ ls
ca.crt                    ca.key                    ingress-validation-opa.md
~/S/O/o/ingress-validation-tutorial ❯❯❯

OPA側が利用する、先ほどのCA証明書に紐づく証明書。
~/S/O/o/ingress-validation-tutorial ❯❯❯ cat > server.conf <<EOF
heredoc else> [req]
heredoc else> req_extensions = v3_req
heredoc else> distinguished_name = req_distinguished_name
heredoc else> [req_distinguished_name]
heredoc else> [v3_req]
heredoc else> basicConstraints = CA:FALSE
heredoc else> keyUsage = nonRepudiation, digitalSignature, keyEncipherment
heredoc else> extendedKeyUsage = clientAuth, serverAuth
heredoc else> EOF

~/S/O/o/ingress-validation-tutorial ❯❯❯ openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus
..............+++
....................+++
e is 65537 (0x10001)

#server.confとserver.keyを元に、証明書署名リクエストを生成
~/S/O/o/ingress-validation-tutorial ❯❯❯ openssl req -new -key server.key -out server.csr -subj "/CN=opa.opa.svc" -config server.conf
~/S/O/o/ingress-validation-tutorial ❯❯❯ ls
ca.crt                    ca.key                    ingress-validation-opa.md server.conf               server.csr                server.key
#生成した署名リクエストを、CA側の秘密鍵(とCAの証明書)で署名。
~/S/O/o/ingress-validation-tutorial ❯❯❯ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000 -extensions v3_req -extfile server.conf
Signature ok
subject=/CN=opa.opa.svc
Getting CA Private Key
~/S/O/o/ingress-validation-tutorial ❯❯❯ ls
ca.crt                    ca.srl                    server.conf               server.csr
ca.key                    ingress-validation-opa.md server.crt                server.key
~/S/O/o/ingress-validation-tutorial ❯❯❯
CN(common name)は、のちに作成するOPAのサービスと一致している必要がある。

secretとして登録。

~/S/O/o/ingress-validation-tutorial ❯❯❯ kubectl create secret -n opa tls opaserver --cert=server.crt --key=server.key
secret/opaserver created
~/S/O/o/ingress-validation-tutorial ❯❯❯
~/S/O/o/ingress-validation-tutorial ❯❯❯ kubectl get secret -n opa opaserver
NAME        TYPE                DATA   AGE
opaserver   kubernetes.io/tls   2      74s
~/S/O/o/ingress-validation-tutorial ❯❯❯

必要なマニフェストファイルを適用する。

~/S/O/o/ingress-validation-tutorial ❯❯❯ kubectl apply -n opa -f admission-controller.yaml
clusterrolebinding.rbac.authorization.k8s.io/opa-viewer created
role.rbac.authorization.k8s.io/configmap-modifier created
rolebinding.rbac.authorization.k8s.io/opa-configmap-modifier created
service/opa created
deployment.apps/opa created
configmap/opa-default-system-main created
~/S/O/o/ingress-validation-tutorial ❯❯❯

OPAのインスタンスが起動すると、kube-mgmtコンテナがロードされる。
このサイドカーKubernetes APIサーバーをwatchし、Kuberentesオブジェクトのキャッシュに一貫性を持って?アクセスする。
次に、OPAをadmission controllerとして登録する。
このwebhookの設定は、openpolicyagent.org/webhook=ignoreのラベルの存在するnsについて検知しない。
>|sh||
~/S/O/o/ingress-validation-tutorial ❯❯❯ cat > webhook-configuration.yaml << EOF
heredoc else> kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1beta1
metadata:
name: opa-validating-webhook
webhooks:
- name: validating-webhook.openpolicyagent.org
namespaceSelector:
matchExpressions:
- key: openpolicyagent.org/webhook
operator: NotIn
values:
- ignore
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
clientConfig:
caBundle: $(cat ca.crt | base64 | tr -d '\n')
service:
namespace: opa
name: opa
heredoc else> EOF
|