シンプルなポリシーの作成
Kyvernoには2種類のポリシーリソースがあります:クラスター全体のリソースに使用されるClusterPolicyと、名前空間付きリソースに使用されるPolicyです。Kyvernoポリシーの理解を深めるために、まずはDeploymentに対するラベル要件から始めましょう。
以下は、PodテンプレートにCostCenterラベルを持たないDeploymentをブロックするClusterPolicyのサンプルです:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
rules:
- name: check-team
match:
any:
- resources:
kinds:
- Deployment
validate:
allowExistingViolations: false
message: "Label 'CostCenter' is required on the Deployment pod template"
pattern:
spec:
template:
metadata:
labels:
CostCenter: "?*"
spec.validationFailureActionは、検証されるリソースを許可して報告する(Audit)か、ブロックする(Enforce)かをKyvernoに指示します。デフォルトはAuditですが、この例ではEnforceに設定されています
rulesセクションには、検証する1つ以上のルールが含まれています
matchステートメントはチェックの範囲を設定します。この場合、すべてのDeploymentリソースが対象になります
validateステートメントは、定義された内容を肯定的にチェックしようとします。このステートメントがリクエストされたリソースと比較して真の場合、許可されます。偽の場合は、ブロックされます
allowExistingViolations: falseは、既に違反しているDeploymentへの更新もブロックされることを保証します。デフォルトでは、Kyvernoはポリシーが適用される前に存在していた非準拠リソースへの更新を許可し、ワークロードの中断を回避します。これをfalseに設定することで、このギャップを閉じ、すべてのアドミッションリクエストに対してポリシーを厳密に適用します
messageは、このルールが検証に失敗した場合にユーザーに表示されるメッセージです
patternオブジェクトは、リソースでチェックされるパターンを定義します。この場合、Deployment spec内のPodテンプレートラベルでspec.template.metadata.labelsにCostCenterがあるかをチェックします
次のコマンドを使用してポリシーを作成します:
clusterpolicy.kyverno.io/require-labels created
次に、uiのDeploymentを確認し、Podテンプレートのラベルを見てください:
{"app.kubernetes.io/component": "service",
"app.kubernetes.io/created-by": "eks-workshop",
"app.kubernetes.io/instance": "ui",
"app.kubernetes.io/name": "ui"
}
Podテンプレートには必要なCostCenterラベルが欠けています。では、uiのDeploymentの強制的なロールアウトを試みてみましょう:
error: failed to patch: admission webhook "validate.kyverno.svc-fail" denied the request:
resource Deployment/ui/ui was blocked due to the following policies
require-labels:
check-team: 'validation error: Label ''CostCenter'' is required on the Deployment
pod template. rule check-team failed at path /spec/template/metadata/labels/CostCenter/'
ロールアウトは、require-labels Kyvernoポリシーによりアドミッションウェブフックがリクエストを拒否したため、失敗しました。
次に、以下のKustomizationパッチを使用して、uiのDeploymentに必要なラベルCostCenterを追加します:
- Kustomize Patch
- Deployment/ui
- Diff
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
spec:
template:
metadata:
labels:
CostCenter: IT
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/type: app
name: ui
namespace: ui
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: service
app.kubernetes.io/instance: ui
app.kubernetes.io/name: ui
template:
metadata:
annotations:
prometheus.io/path: /actuator/prometheus
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
labels:
CostCenter: IT
app.kubernetes.io/component: service
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/instance: ui
app.kubernetes.io/name: ui
spec:
containers:
- env:
- name: JAVA_OPTS
value: -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/urandom
- name: METADATA_KUBERNETES_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: METADATA_KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: METADATA_KUBERNETES_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
envFrom:
- configMapRef:
name: ui
image: public.ecr.aws/aws-containers/retail-store-sample-ui:1.2.1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 45
periodSeconds: 20
name: ui
ports:
- containerPort: 8080
name: http
protocol: TCP
resources:
limits:
memory: 1.5Gi
requests:
cpu: 250m
memory: 1.5Gi
securityContext:
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
fsGroup: 1000
serviceAccountName: ui
volumes:
- emptyDir:
medium: Memory
name: tmp-volume
prometheus.io/path: /actuator/prometheus
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
labels:
+ CostCenter: IT
app.kubernetes.io/component: service
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/instance: ui
app.kubernetes.io/name: ui
namespace/ui unchanged
serviceaccount/ui unchanged
configmap/ui unchanged
service/ui unchanged
deployment.apps/ui configured
deployment "ui" successfully rolled out
{"CostCenter": "IT",
"app.kubernetes.io/component": "service",
"app.kubernetes.io/created-by": "eks-workshop",
"app.kubernetes.io/instance": "ui",
"app.kubernetes.io/name": "ui"
}
ポリシーが満たされ、ロールアウトが成功しました。