1. บทนำ: Kyverno คืออะไร?
Kyverno (ออกเสียงว่า "เคิร์ฟ-เวอร์-โน" มาจากภาษากรีกแปลว่า "ปกครอง") เป็น Policy Engine ที่ออกแบบมาโดยเฉพาะสำหรับ Kubernetes ได้รับการพัฒนาภายใต้ CNCF (Cloud Native Computing Foundation) และเป็น Graduated Project ในปี 2025
Kyverno ช่วยให้ Platform Engineers และ DevOps สามารถ ควบคุม, ตรวจสอบ และ บังคับใช้ policies ต่างๆ ใน Kubernetes cluster ได้อย่างง่ายดาย โดยใช้ YAML ซึ่งเป็นภาษาที่ทุกคนคุ้นเคย
Architecture ของ Kyverno
ภาพแสดง Architecture ของ Kyverno ที่ทำงานเป็น Admission Controller ใน Kubernetes
ใช้ YAML / CEL
เขียน policies ด้วย YAML หรือ CEL (Common Expressions Language) ไม่ต้องเรียนรู้ภาษาใหม่
Validate Resources
ตรวจสอบว่า Kubernetes resources สอดคล้องกับ policies ที่กำหนดไว้หรือไม่
Mutate Resources
แก้ไข resources โดยอัตโนมัติ เช่น เพิ่ม labels, annotations, หรือ settings
Generate Resources
สร้าง Kubernetes resources ใหม่โดยอัตโนมัติ เช่น NetworkPolicies, ConfigMaps
Verify Images
ตรวจสอบ container images ด้วย signatures (Cosign, Notary) เพื่อ supply chain security
Policy Reports
รายงานผลการตรวจสอบ policies ในรูปแบบ OpenReport format
2. ทำไมต้องใช้ Kyverno?
ในโลกของ Kubernetes ที่มีความซับซ้อนสูง การจัดการ configuration และความปลอดภัยเป็นสิ่งที่ท้าทายมาก Policy Management ช่วยให้เราสามารถควบคุมและบังคับใช้มาตรฐานต่างๆ ได้อย่างเป็นระบบ
Use Cases ที่ Kyverno ช่วยได้
Security Compliance
บังคับใช้ security policies เช่น ห้ามรัน container เป็น root, ต้องใช้ read-only root filesystem, ห้ามใช้ privileged containers
Resource Governance
บังคับใช้ labels และ annotations เช่น ทุก resource ต้องมี label team, environment, cost-center
Network Security
สร้าง NetworkPolicy ให้ทุก namespace โดยอัตโนมัติ ป้องกันการเข้าถึงระหว่าง namespaces โดยไม่ได้รับอนุญาต
ประโยชน์ของการใช้ Kyverno
| ประโยชน์ | คำอธิบาย |
|---|---|
| Declarative | กำหนด policies เป็น Kubernetes resources ใช้เครื่องมือเดียวกับที่ใช้จัดการ cluster |
| GitOps Ready | จัดการ policies ด้วย Git เช่นเดียวกับ application code |
| No New Language | ใช้ YAML หรือ CEL ไม่ต้องเรียนรู้ Rego เหมือน OPA Gatekeeper |
| Native K8s Experience | ใช้ kubectl, kustomize, และเครื่องมือ K8s อื่นๆ ได้เลย |
| Audit & Reporting | มี built-in reporting และ monitoring capabilities |
3. Kyverno vs OPA Gatekeeper
OPA Gatekeeper เป็นอีก policy engine ยอดนิยมสำหรับ Kubernetes แต่ต้องเขียน policies ด้วย Rego ซึ่งเป็นภาษาที่ต้องใช้เวลาเรียนรู้ ในขณะที่ Kyverno ใช้ YAML ที่ทุกคนคุ้นเคย
| Feature | Kyverno | OPA Gatekeeper |
|---|---|---|
| Policy Language | YAML / CEL (ง่าย) | Rego (ต้องเรียนรู้) |
| Learning Curve | ต่ำ (คุ้นเคย) | ปานกลาง |
| Mutation | Built-in | ต้องใช้ external tool |
| Generation | Built-in | ไม่รองรับโดยตรง |
| Image Verification | Built-in | ต้องใช้ external tool |
| CLI Testing | kyverno CLI | opa test |
| CNCF Status | Graduated | Graduated |
| Best For | ทีมที่ต้องการ simplicity | ทีมที่ต้องการ flexibility |
คำแนะนำ
หากทีมของคุณเพิ่งเริ่มต้นใช้ Policy as Code แนะนำให้เริ่มจาก Kyverno เพราะใช้งานง่ายกว่า แต่หากต้องการ logic ที่ซับซ้อนมากๆ OPA Gatekeeper อาจเหมาะกว่า
4. การติดตั้ง Kyverno
Prerequisites
ก่อนติดตั้ง Kyverno ต้องมี Kubernetes cluster เวอร์ชัน 1.25+ และ kubectl ที่สามารถเชื่อมต่อกับ cluster ได้
วิธีที่ 1: ติดตั้งด้วย Helm (แนะนำ)
# เพิ่ม Kyverno Helm repository
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
# ติดตั้ง Kyverno ใน namespace kyverno
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
# ตรวจสอบสถานะ
kubectl get pods -n kyverno
# ผลลัพธ์ที่ควรเห็น
# NAME READY STATUS RESTARTS AGE
# kyverno-admission-controller-xxx 1/1 Running 0 2m
# kyverno-background-controller-xxx 1/1 Running 0 2m
# kyverno-cleanup-controller-xxx 1/1 Running 0 2m
วิธีที่ 2: ติดตั้งด้วย kubectl
# ติดตั้ง Kyverno ด้วย manifest (เวอร์ชันล่าสุด)
kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.15.0/install.yaml
# หรือติดตั้งเวอร์ชันที่ระบุ
kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.15.0/install.yaml
ตรวจสอบการติดตั้ง
# ตรวจสอบ Kyverno pods
kubectl get pods -n kyverno
# ตรวจสอบ Kyverno CRDs
kubectl get crd | grep kyverno
# ผลลัพธ์ที่ควรเห็น
# clustercleanuppolicies.kyverno.io
# clusterpolicies.kyverno.io
# cleanuppolicies.kyverno.io
# policies.kyverno.io
# policyexceptions.kyverno.io
# ตรวจสอบเวอร์ชัน
kubectl get deployment kyverno-admission-controller -n kyverno -o jsonpath='{.spec.template.spec.containers[0].image}'
ติดตั้ง Kyverno CLI (สำหรับ Local Testing)
# macOS (ด้วย Homebrew)
brew install kyverno
# Linux (ด้วย script)
curl -LO https://github.com/kyverno/kyverno/releases/download/v1.15.0/kyverno_linux_x86_64.tar.gz
tar -xvf kyverno_linux_x86_64.tar.gz
sudo mv kyverno /usr/local/bin/
# ตรวจสอบเวอร์ชัน
kyverno version
# ผลลัพธ์
# Version: 1.15.0
# Git commit: xxx
# Go version: go1.22.x
5. Policy Types ใน Kyverno
Kyverno รองรับ policy types หลายแบบ แต่ละแบบมีหน้าที่แตกต่างกัน ในบทความนี้เราจะเน้นที่ ClusterPolicy ซึ่งเป็น type ที่ใช้บ่อยที่สุด
ภาพแสดง 4 Policy Types หลักของ Kyverno
1. Validate Rules
ใช้ตรวจสอบว่า Kubernetes resources สอดคล้องกับเงื่อนไขที่กำหนดหรือไม่ หากไม่ผ่านจะ ปฏิเสธ (deny) หรือ บันทึก (audit) ขึ้นอยู่กับการตั้งค่า
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce # Enforce = ปฏิเสธถ้าไม่ผ่าน
background: true # ตรวจสอบ resources ที่มีอยู่แล้ว
rules:
- name: check-team-label
match:
any:
- resources:
kinds:
- Pod
- Deployment
- Service
validate:
message: "ทุก resource ต้องมี label 'team'"
pattern:
metadata:
labels:
team: "?*" # ?* = ต้องมีค่า (not empty)
2. Mutate Rules
ใช้แก้ไข resources โดยอัตโนมัติ เช่น เพิ่ม labels, annotations, หรือ settings โดยที่ผู้ใช้ไม่ต้องทำอะไรเพิ่มเติม
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
rules:
- name: add-env-label
match:
any:
- resources:
kinds:
- Deployment
mutate:
patchStrategicMerge:
metadata:
labels:
+(environment): production # + = เพิ่มถ้ายังไม่มี
+(managed-by): kyverno
3. Generate Rules
ใช้สร้าง Kubernetes resources ใหม่โดยอัตโนมัติ เมื่อมี resource บางอย่างถูกสร้างขึ้น เช่น สร้าง NetworkPolicy ให้ทุก namespace ใหม่
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-networkpolicy
spec:
rules:
- name: generate-networkpolicy
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
4. Verify Images Rules
ใช้ตรวจสอบ container images ว่าถูก sign ด้วยผู้เผยแพร่ที่เชื่อถือได้หรือไม่ (ใช้ Cosign, Notary) เป็นส่วนสำคัญของ Software Supply Chain Security
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signatures
spec:
validationFailureAction: Enforce
background: false
rules:
- name: verify-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "myregistry.io/*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----
6. ตัวอย่าง Policies ที่ใช้งานจริง
ต่อไปนี้เป็นตัวอย่าง Kyverno policies ที่ใช้งานจริงใน production environments ซึ่งคุณสามารถนำไปปรับใช้ได้ทันที
ตัวอย่าง 1: ห้าม Privileged Containers
Policy นี้จะป้องกันไม่ให้สร้าง containers ที่มีสิทธิ์ elevated (privileged) ซึ่งเป็นความเสี่ยงด้านความปลอดภัย
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
annotations:
policies.kyverno.io/title: Disallow Privileged Containers
policies.kyverno.io/category: Security
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
ห้ามไม่ให้ containers ทำงานในโหมด privileged
เพราะอาจทำให้เข้าถึง host system ได้
spec:
validationFailureAction: Enforce
background: true
rules:
- name: privileged-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
ห้ามใช้ privileged containers!
กรุณาลบ securityContext.privileged: true
pattern:
spec:
containers:
- =(securityContext):
=(privileged): "false"
ทดสอบ Policy:
# Apply policy
kubectl apply -f disallow-privileged.yaml
# ลองสร้าง privileged pod (ควรถูกปฏิเสธ)
kubectl run test-privileged --image=nginx --privileged
# ผลลัพธ์ (Error):
# Error from server: admission webhook "validate.kyverno.svc-fail" denied the request:
# ห้ามใช้ privileged containers! กรุณาลบ securityContext.privileged: true
ตัวอย่าง 2: บังคับให้กำหนด Resource Limits
Policy นี้จะบังคับให้ทุก Pod ต้องกำหนด resources.limits เพื่อป้องกันการใช้ทรัพยากรเกินไป
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
annotations:
policies.kyverno.io/title: Require Resource Limits
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-memory-limit
match:
any:
- resources:
kinds:
- Pod
validate:
message: "ทุก container ต้องกำหนด memory limits"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
- name: check-cpu-limit
match:
any:
- resources:
kinds:
- Pod
validate:
message: "ทุก container ต้องกำหนด cpu limits"
pattern:
spec:
containers:
- resources:
limits:
cpu: "?*"
ตัวอย่าง 3: บังคับให้ใช้ Non-root User
Policy นี้จะบังคับให้ทุก container ทำงานด้วย non-root user ซึ่งเป็น security best practice
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-non-root
annotations:
policies.kyverno.io/title: Require Non-root Users
policies.kyverno.io/category: Security
policies.kyverno.io/severity: high
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-runAsNonRoot
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Containers ต้องทำงานด้วย non-root user (runAsNonRoot: true)"
pattern:
spec:
containers:
- securityContext:
runAsNonRoot: true
ตัวอย่าง 4: เพิ่ม Labels อัตโนมัติ
Policy นี้จะเพิ่ม labels เริ่มต้นให้ทุก resource ที่ถูกสร้างขึ้น โดยไม่ต้องแก้ไข manifest
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: auto-add-labels
spec:
rules:
- name: add-standard-labels
match:
any:
- resources:
kinds:
- Deployment
- Service
- ConfigMap
- Secret
mutate:
patchStrategicMerge:
metadata:
labels:
+(managed-by): kyverno
+(created-at): "{{ timestamp }}"
+(cluster-name): "{{ @ }}" # @ = cluster name
ตัวอย่าง 5: สร้าง NetworkPolicy ให้ Namespaces ใหม่
Policy นี้จะสร้าง default NetworkPolicy (deny all ingress) ให้ทุก namespace ที่สร้างใหม่โดยอัตโนมัติ
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: default-networkpolicy
annotations:
policies.kyverno.io/title: Default NetworkPolicy
policies.kyverno.io/category: Security
spec:
rules:
- name: generate-default-deny
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: default-deny-all
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
การ Apply Policies
# Apply policy เดียว
kubectl apply -f require-labels.yaml
# Apply หลาย policies
kubectl apply -f ./policies/
# ดู policies ที่มี
kubectl get clusterpolicies
kubectl get cpol # ชื่อย่อ
# ดูรายละเอียด policy
kubectl describe cpol require-labels
# ลบ policy
kubectl delete cpol require-labels
7. Best Practices
1. เริ่มจาก Audit Mode
ก่อนจะ enforce policy ให้ใช้ validationFailureAction: Audit เพื่อทดสอบก่อนว่าจะมีผลกระทบกับ resources ที่มีอยู่หรือไม่
spec:
validationFailureAction: Audit # Audit = บันทึกแต่ไม่ปฏิเสธ
background: true # ตรวจสอบ resources ที่มีอยู่
2. ทดสอบ Policies ด้วย Kyverno CLI
ใช้ kyverno test เพื่อทดสอบ policies ในเครื่อง local ก่อน apply ขึ้น cluster
# สร้างโฟลเดอร์ test
mkdir kyverno-test
cd kyverno-test
# สร้างไฟล์ policy.yaml และ resource.yaml
# รัน test
kyverno test .
# หรือ apply policy กับ resource โดยตรง
kyverno apply policy.yaml --resource resource.yaml
3. เก็บ Policies ใน Git
จัดการ policies เหมือนกับ code ปกติ ใช้ GitOps tools เช่น ArgoCD หรือ Flux เพื่อ sync policies เข้า cluster
4. ใช้ Annotations
เพิ่ม annotations เพื่ออธิบาย policy ทำให้ทีมอื่นเข้าใจวัตถุประสงค์ได้ง่าย
metadata:
name: require-labels
annotations:
policies.kyverno.io/title: Require Labels
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Deployment
policies.kyverno.io/description: >-
Policy นี้บังคับให้ทุก resource มี label 'team'
เพื่อใช้ในการติดตามและรายงาน
5. จัดกลุ่ม Policies ตาม Category
ใช้ labels หรือ namespaces เพื่อจัดกลุ่ม policies ตามวัตถุประสงค์ เช่น Security, Compliance, Governance
8. Troubleshooting
ปัญหา 1: Policy ไม่ทำงาน
อาการ: Apply policy แล้ว แต่ resources ไม่ถูกตรวจสอบ
แก้ไข:
# ตรวจสอบว่า Kyverno pods ทำงานอยู่
kubectl get pods -n kyverno
# ตรวจสอบ logs
kubectl logs -n kyverno deployment/kyverno-admission-controller
# ตรวจสอบ policy status
kubectl get cpol require-labels -o yaml
# ตรวจสอบว่า policy ถูกต้อง
kyverno apply policy.yaml --resource test-resource.yaml -v
ปัญหา 2: Admission Request Timeout
อาการ: kubectl commands ช้าหรือ timeout
แก้ไข: อาจเกิดจาก Kyverno มี load สูงเกินไป ลอง scale up หรือเพิ่ม resources
# ตรวจสอบ resource usage
kubectl top pods -n kyverno
# Scale up admission controller
kubectl scale deployment kyverno-admission-controller -n kyverno --replicas=3
ปัญหา 3: Debug Policy Logic
อาการ: Policy ทำงานแปลกๆ ไม่เป็นไปตามที่คาดไว้
แก้ไข: ใช้ kyverno jp เพื่อทดสอบ JMESPath expressions
# ทดสอบ JMESPath expression
echo '{"name": "test", "labels": {"team": "dev"}}' | kyverno jp "labels.team"
# ผลลัพธ์: "dev"
# ทดสอบกับ resource จริง
kubectl get pod mypod -o json | kyverno jp "metadata.labels"
ปัญหา 4: ดู Policy Reports
วิธีดู: ตรวจสอบผลการตรวจสอบ policies
# ดู policy reports
kubectl get policyreports -A
# ดูรายละเอียด report
kubectl describe policyreport -n default
# ดู cluster policy report
kubectl get clusterpolicyreport
คำสั่งที่มีประโยชน์
# ดู policies ทั้งหมด
kubectl get clusterpolicies
kubectl get policies -A
# ดู policy exceptions
kubectl get policyexceptions -A
# Debug mode
kubectl logs -n kyverno deployment/kyverno-admission-controller -f
# Validate policy syntax
kyverno apply policy.yaml --dry-run
# Generate Kubernetes manifest from policy
kyverno create cluster-role --help
# Check Kyverno metrics
kubectl port-forward -n kyverno svc/kyverno-svc-metrics 8000:8000
# เปิด http://localhost:8000/metrics
สรุป
Kyverno เป็น Kubernetes Policy Engine ที่ทรงพลังและใช้งานง่าย โดยเฉพาะสำหรับทีมที่ต้องการ implement Policy as Code โดยไม่ต้องเรียนรู้ภาษาใหม่
ข้อดีหลัก:
- ใช้ YAML / CEL ไม่ต้องเรียนรู้ Rego
- รองรับ Validate, Mutate, Generate และ Image Verification
- CNCF Graduated Project มี community ที่แข็งแกร่ง
- GitOps-friendly สามารถจัดการ policies ด้วย Git
- Built-in reporting และ monitoring
เริ่มต้นใช้งาน: ติดตั้งด้วย Helm → เขียน policy แรกด้วย YAML → ทดสอบด้วย kyverno CLI → Apply ขึ้น cluster