ry's Tech blog

Cloud Native技術などについて書いていきます。

入門 kyverno

kyvernoとは

Kubernetes NativeなPolicy Managerです!

github.com

有名なところで行くと、OPA(Open Policy Agent)などがあります。

ではこのkyvernoのなにがいいかと言うと、 Policyを割り当てるのに、KubernetesのManifest形式で書いて適用できることです。

例えば、OPAではRegoと言う言語を学ばなければならなかったりするのですが、 こういった学習コストが排除されています。

Kyvernoの機能

  • Validating Resources
    • リソースをもとに作成するか拒否するかを判断する。
  • Mutating Resources
    • 指定リソースに対して、予め指定した要素を足したり変更したりできる。
  • Generating Resources
    • 生成ルールを使用して、新しいリソースが作成されたときに追加のリソースを作成できる。
  • Variable Substitution
    • mutationとは違い、リクエストから抜き出した要素を用いて、変更をかけていきます。
  • Preconditions
    • InやEqualを用いて、Policyを適用する際の前提条件を記述できます。
  • etc

ValidationやMutationはよく使われるものですね!

今回はその中でもValidationについて見ていきます。

Deploy

とても簡単で、ManifestとHelmが選べますが、今回はmanifestから行なっていきます。

# kubectl create -f https://raw.githubusercontent.com/nirmata/kyverno/master/definitions/release/install.yaml
namespace/kyverno created
customresourcedefinition.apiextensions.k8s.io/clusterpolicies.kyverno.io created
customresourcedefinition.apiextensions.k8s.io/clusterpolicyviolations.kyverno.io created
customresourcedefinition.apiextensions.k8s.io/generaterequests.kyverno.io created
customresourcedefinition.apiextensions.k8s.io/policyviolations.kyverno.io created
serviceaccount/kyverno-service-account created
clusterrole.rbac.authorization.k8s.io/kyverno:customresources created
clusterrole.rbac.authorization.k8s.io/kyverno:generatecontroller created
clusterrole.rbac.authorization.k8s.io/kyverno:policycontroller created
clusterrole.rbac.authorization.k8s.io/kyverno:userinfo created
clusterrole.rbac.authorization.k8s.io/kyverno:webhook created
clusterrole.rbac.authorization.k8s.io/kyverno:policyviolations created
clusterrole.rbac.authorization.k8s.io/kyverno:view-clusterpolicyviolations created
clusterrole.rbac.authorization.k8s.io/kyverno:view-policyviolations created
clusterrolebinding.rbac.authorization.k8s.io/kyverno:customresources created
clusterrolebinding.rbac.authorization.k8s.io/kyverno:generatecontroller created
clusterrolebinding.rbac.authorization.k8s.io/kyverno:policycontroller created
clusterrolebinding.rbac.authorization.k8s.io/kyverno:userinfo created
clusterrolebinding.rbac.authorization.k8s.io/kyverno:webhook created
configmap/init-config created
service/kyverno-svc created
deployment.apps/kyverno created

では、確認していきます。

# kubectl get all -n kyverno
NAME                           READY   STATUS    RESTARTS   AGE
pod/kyverno-5b986d6576-c7tmk   1/1     Running   0          94s

NAME                  TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kyverno-svc   ClusterIP   10.0.1.99    <none>        443/TCP   94s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kyverno   1/1     1            1           94s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/kyverno-5b986d6576   1         1         1       95s

Policyの適用

今回はこのようなPolicyを適用していきます!

# vi clusterpolicy-label.yaml

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: enforce
  rules:
  - name: check-for-labels
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "label `app.kubernetes.io/name` is required"
      pattern:
        metadata:
          labels:
            app.kubernetes.io/name: "?*"

内容としては、Podに対してlabelにapp.kubernetes.io/name: "任意の文字"がなければ、

"label app.kubernetes.io/name is required"と言うメッセージとともに弾くと言うPolicyです。

では適用していきます。

# kubectl apply -f clusterpolicy-label.yaml 
clusterpolicy.kyverno.io/require-labels created


# kubectl get clusterpolicy                           
NAME             AGE
require-labels   19s

ではDeployment経由でPodを作成していきます。

# kubectl create deployment nginx --image=nginx 
Error from server: admission webhook "nirmata.kyverno.resource.validating-webhook" denied the request: 

resource Deployment/test/nginx was blocked due to the following policies

require-labels:
  autogen-check-for-labels: 'Validation error: label `app.kubernetes.io/name` is required;Validation rule autogen-check-for-labels failed at path /spec/template/metadata/labels/app.kubernetes.io/name/'

先ほど指定したMessageとともに、しっかりと弾いてくれました!

では、labelを付加していきます。

# kubectl create deployment nginx --image=nginx --dry-run -o yaml > deploy.yaml


# vi deploy.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        app.kubernetes.io/name: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

このmanifestは、先ほどのコマンドに--dry-runオプションをつけて、作成しています。

Podのmetadataに、app.kubernetes.io/name: nginxと言うLabelを付けました。

では適用して見ましょう。

# kubectl apply -f deploy.yaml 
deployment.apps/nginx created


# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-84b679fbc8-hqb5g   1/1     Running   0          11s

しっかりPolicyを通過して作成されることが、確認できました。

最後に

8/25 (火)に主宰させていただきます、Kubernetes Novice Tokyo #4が開催されます!! ぜひ、お時間のご都合がよろしい方は、ご参加ください!

k8s-novice-jp.connpass.com

Networkの話や、監視用UI、CICDについてなど、 とても勉強になる内容が盛り沢山です!

どうぞ、よろしくお願いいたします!