SUPER-G.EEK.JP

twitter: @hum_op_dev
github: ophum

K8s Validating Admission Policyを試す

目次

Kubernetes でマニフェストを適用する際に、独自のバリデーションをかけることができる Validating Admission Policy を試してみます。

https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/

ClusterIP の Service のみ許可する Policy を作成する

「Service は ClusterIP のみ定義できる」というバリデーションを設定してみます。

こんな感じで services リソースで spec.type が ClusterIP なら許可し、ClusterIP 以外なら拒否します。

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: admissionregistration.k8s.io/v1
 3kind: ValidatingAdmissionPolicy
 4metadata:
 5  name: "only-cluster-ip-policy"
 6spec:
 7  failurePolicy: Fail
 8  matchConstraints:
 9    resourceRules:
10      - apiGroups: [""]
11        apiVersions: ["v1"]
12        operations: ["CREATE", "UPDATE"]
13        resources: ["services"]
14  validations:
15    - expression: "object.spec.type == 'ClusterIP'"
16EOF
17)

ポリシーを Binding します。

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: admissionregistration.k8s.io/v1
 3kind: ValidatingAdmissionPolicyBinding
 4metadata:
 5  name: "only-cluster-ip-policy-binding"
 6spec:
 7  policyName: "only-cluster-ip-policy"
 8  validationActions: [Deny]
 9  matchResources:
10    namespaceSelector:
11      matchLabels:
12        environment: test
13EOF
14)

ポリシーが適用されるネームスペースを作成します。

1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
2apiVersion: v1
3kind: Namespace
4metadata:
5  name: only-cluster-ip-policy-ns
6  labels:
7    environment: test
8EOF
9)

ClusterIP な Service を作成してみる

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: cluster-ip-svc
 6  namespace: only-cluster-ip-policy-ns
 7spec:
 8  type: ClusterIP
 9  selector:
10    app: my-app
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 8080
15EOF
16)

作成できました。

1hum@ryzen5pc:~$ kubectl get svc -n only-cluster-ip-policy-ns
2NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
3cluster-ip-svc   ClusterIP   10.106.82.125   <none>        80/TCP    8s

NodePort な Service を作成してみる

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: node-port-svc
 6  namespace: only-cluster-ip-policy-ns
 7spec:
 8  type: NodePort
 9  selector:
10    app: my-app
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 8080
15EOF
16)

以下のようなエラーが出て作成できませんでした。

The services "node-port-svc" is invalid: : ValidatingAdmissionPolicy 'only-cluster-ip-policy' with binding 'only-cluster-ip-policy-binding' denied request: failed expression: object.spec.type == 'ClusterIP'
1hum@ryzen5pc:~$ kubectl get svc -n only-cluster-ip-policy-ns
2NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
3cluster-ip-svc   ClusterIP   10.106.82.125   <none>        80/TCP    86s

LoadBalancer な Service を作成してみる

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: load-balancer-svc
 6  namespace: only-cluster-ip-policy-ns
 7spec:
 8  type: LoadBalancer
 9  selector:
10    app: my-app
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 8080
15EOF
16)

こちらも NodePort と同じくエラーになり作成できませんでした。

The services "load-balancer-svc" is invalid: : ValidatingAdmissionPolicy 'only-cluster-ip-policy' with binding 'only-cluster-ip-policy-binding' denied request: failed expression: object.spec.type == 'ClusterIP'
1hum@ryzen5pc:~$ kubectl get svc -n only-cluster-ip-policy-ns
2NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
3cluster-ip-svc   ClusterIP   10.106.82.125   <none>        80/TCP    3m16s

ClusterIP から NodePort に変更してみる

 1hum@ryzen5pc:~$ kubectl apply -f <(cat <<EOF
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: cluster-ip-svc
 6  namespace: only-cluster-ip-policy-ns
 7spec:
 8  type: NodePort
 9  selector:
10    app: my-app
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 8080
15EOF
16)

エラーになり更新できませんでした。

The services "cluster-ip-svc" is invalid: : ValidatingAdmissionPolicy 'only-cluster-ip-policy' with binding 'only-cluster-ip-policy-binding' denied request: failed expression: object.spec.type == 'ClusterIP'
1hum@ryzen5pc:~$ kubectl get svc -n only-cluster-ip-policy-ns
2NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
3cluster-ip-svc   ClusterIP   10.106.82.125   <none>        80/TCP    6m2s