OPA Gatekeeper Cloud Native Design

โดย อ. บอมกิตติทัศน์เจริญพนาสิทธิ์ | อัปเดต 24 ก. พ. 2026 | อ่าน 14 นาที
- OPA และ Gatekeeper คืออะไร — ภาพรวม Policy-as-Code
- ทำไมต้องมี Policy Enforcement บน Kubernetes
- สถาปัตยกรรม Gatekeeper — Admission Webhook Flow
- ติดตั้ง Gatekeeper บน Kubernetes Cluster
- ภาษา Rego — พื้นฐานที่ต้องรู้
- ConstraintTemplate — สร้าง Policy Template
- Constraint — บังคับใช้ Policy จริง
- ตัวอย่าง Policy ที่ใช้บ่อย 10 ข้อ
- Audit Mode — ตรวจสอบ Resource ที่มีอยู่แล้ว
- Mutation — แก้ไข Resource อัตโนมัติ
- Gatekeeper vs Kyverno — เปรียบเทียบ
- Best Practices สำหรับ Production
- Troubleshooting ปัญหาที่พบบ่อย
- สรุปและแหล่งเรียนรู้เพิ่มเติม
OPA และ Gatekeeper คืออะไร — ภาพรวม Policy-as-Code
Open Policy Agent (OPA) เป็น General-purpose Policy Engine แบบ Open Source ที่พัฒนาโดย Styra และเป็น Graduated Project ของ CNCF (Cloud Native Computing Foundation) OPA ทำหน้าที่เป็นจุดตัดสินใจกลาง (Policy Decision Point) รับ Input เป็น JSON แล้วประเมินกับ Policy ที่เขียนด้วยภาษา Rego ให้ผลลัพธ์เป็น Allow/Deny พร้อมเหตุผล OPA สามารถใช้ได้กับทุกระบบไม่จำเป็นต้องเป็น Kubernetes เช่น API Gateway, CI/CD Pipeline, Terraform, Microservices Authorization
Gatekeeper เป็น Project ที่นำ OPA มาใช้เฉพาะกับ Kubernetes ในรูปแบบ Admission Controller ทำงานเป็น Validating Webhook ที่คอยตรวจสอบทุก Request ที่ส่งมายัง Kubernetes API Server ก่อนที่จะถูกสร้างจริงถ้า Request ไม่ผ่าน Policy จะถูกปฏิเสธทันทีพร้อมข้อความ Error ที่อธิบายว่าผิดกฎข้อใด
แนวคิด Policy-as-Code หมายถึงการเขียน Policy เป็นโค้ดที่เก็บใน Git ผ่าน Code Review และ CI/CD เหมือนกับโค้ดโปรแกรมทั่วไปทำให้ Policy มี Version Control, Audit Trail, Automated Testing และ Consistency ข้ามทุก Environment
ทำไมต้องมี Policy Enforcement บน Kubernetes
Kubernetes ให้อิสระสูงมากในการสร้าง Resource ใดก็ได้ Developer สามารถ Deploy Container ที่รันเป็น Root, ใช้ Image จาก Registry ที่ไม่น่าเชื่อถือ, ไม่ตั้ง Resource Limits, เปิด Port ที่อันตรายหรือสร้าง Service แบบ LoadBalancer ที่เปิดสู่ Internet โดยไม่ตั้งใจในองค์กรที่มี Developer หลายสิบทีมใช้ Cluster ร่วมกันการพึ่งพาแค่ความรับผิดชอบของแต่ละคนไม่เพียงพอ
Policy Enforcement ช่วยแก้ปัญหานี้โดยกำหนดกฎเกณฑ์ที่บังคับใช้อัตโนมัติตัวอย่าง Policy ที่องค์กรส่วนใหญ่ต้องการได้แก่ทุก Pod ต้องมี Resource Requests/Limits, ห้ามรัน Container เป็น Root, Image ต้องมาจาก Trusted Registry เท่านั้น, ทุก Namespace ต้องมี Label ระบุ team/cost-center, ห้ามใช้ latest Tag ต้องระบุ Version ชัดเจนและ Ingress ต้อง TLS Only
สถาปัตยกรรม Gatekeeper — Admission Webhook Flow
Gatekeeper ทำงานผ่าน Kubernetes Dynamic Admission Control Flow ดังนี้
- User/CI ส่ง
kubectl applyไปยัง API Server - API Server ผ่าน Authentication และ Authorization (RBAC)
- API Server ส่ง Admission Request ไปยัง Gatekeeper Webhook
- Gatekeeper โหลด ConstraintTemplate + Constraint ที่เกี่ยวข้อง
- OPA Engine ภายใน Gatekeeper ประเมิน Rego Policy
- ถ้าผ่านทุก Policy → Admit (สร้าง Resource ได้)
- ถ้าไม่ผ่าน → Deny พร้อม Error Message กลับไปยัง User
Gatekeeper ประกอบด้วย 3 Component หลักคือ Controller Manager จัดการ CRD (ConstraintTemplate, Constraint) และ Sync ข้อมูล Resource เข้า OPA Cache, Audit Controller ตรวจสอบ Resource ที่มีอยู่แล้วว่าผ่าน Policy หรือไม่ (Background Scan) และ Webhook Server รับ Admission Request จาก API Server แล้วประเมิน Policy
ติดตั้ง Gatekeeper บน Kubernetes Cluster
วิธีติดตั้งที่แนะนำคือใช้ Helm Chart
# เพิ่ม Helm Repository
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
# ติดตั้ง Gatekeeper
helm install gatekeeper gatekeeper/gatekeeper \
--namespace gatekeeper-system \
--create-namespace \
--set replicas=3 \
--set audit.replicas=1 \
--set audit.logLevel=INFO
# ตรวจสอบว่าติดตั้งสำเร็จ
kubectl get pods -n gatekeeper-system
# ควรเห็น gatekeeper-controller-manager และ gatekeeper-audit
# ตรวจสอบ CRD
kubectl get crd | grep gatekeeper
# constrainttemplates.templates.gatekeeper.sh
# configs.config.gatekeeper.sh
หลังติดตั้งเสร็จ Gatekeeper จะลงทะเบียนเป็น Validating Webhook กับ API Server อัตโนมัติทุก Request ที่สร้าง/แก้ไข Resource จะถูกส่งผ่าน Gatekeeper ก่อน
ภาษา Rego — พื้นฐานที่ต้องรู้
Rego เป็นภาษา Declarative ที่ออกแบบมาเฉพาะสำหรับเขียน Policy มีลักษณะคล้าย Datalog ไม่ใช่ภาษาแบบ Imperative อย่าง Python หรือ Go จึงมี Learning Curve ค่อนข้างสูงแต่เมื่อเข้าใจแนวคิดแล้วจะเขียนได้กระชับมาก
# ตัวอย่าง Rego พื้นฐาน
# กฎ: ห้าม Container รันเป็น Root
package kubernetes.admission
# Violation จะถูกสร้างเมื่อพบ Container ที่รัน root
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.runAsUser == 0
msg := sprintf("Container '%v' must not run as root (UID 0)", [container.name])
}
# กฎ: ต้องมี Resource Limits
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits
msg := sprintf("Container '%v' must have resource limits", [container.name])
}
# กฎ: ห้ามใช้ :latest tag
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
endswith(container.image, ":latest")
msg := sprintf("Container '%v' uses :latest tag, must specify version", [container.name])
}
หลักการสำคัญของ Rego ที่ต้องเข้าใจได้แก่ Rules เป็น Declarative บอกว่า "อะไรเป็น True" ไม่ใช่ "ทำอะไรทีละขั้น", Iteration แบบ Implicit ใช้ [_] วนลูป Array อัตโนมัติ, Unification ใช้ := กำหนดค่าและ == เปรียบเทียบและ Short-circuit ถ้าเงื่อนไขบรรทัดใดเป็น False กฎทั้งหมดจะไม่ถูก Trigger
ConstraintTemplate — สร้าง Policy Template
ConstraintTemplate เป็น CRD ของ Gatekeeper ที่ใช้กำหนด "ประเภทของ Policy" โดยเขียน Rego Logic ไว้ภายในพร้อมกำหนด Parameter Schema สำหรับให้ Customize ได้
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
description: "List of required labels"
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Resource missing required labels: %v", [missing])
}
ConstraintTemplate ข้างต้นสร้าง "ประเภท Policy" ชื่อ K8sRequiredLabels ที่ตรวจว่า Resource มี Label ครบตามที่กำหนดหรือไม่จะเห็นว่า Rego Logic ใช้ input.parameters.labels อ้างอิง Parameter ที่จะถูกกำหนดตอนสร้าง Constraint ทำให้ Template นี้ Reusable ได้เช่นบังคับ Label ต่างกันสำหรับ Namespace ต่างกัน
Constraint — บังคับใช้ Policy จริง
Constraint เป็น Instance ของ ConstraintTemplate ที่กำหนด Parameter และ Scope ว่าจะบังคับใช้กับ Resource ประเภทไหนใน Namespace ไหน
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-team-label
spec:
enforcementAction: deny # deny | dryrun | warn
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels:
- "team"
- "cost-center"
- "environment"
Constraint นี้บังคับว่าทุก Namespace ต้องมี Label team, cost-center และ environment ถ้าสร้าง Namespace โดยไม่มี Label เหล่านี้จะถูก Deny ทันที
enforcementAction มี 3 ค่าที่สำคัญมาก deny ปฏิเสธ Request ทันที, dryrun อนุญาตแต่บันทึก Violation ไว้ใน Audit Log เหมาะกับการทดสอบ Policy ใหม่ก่อน Enforce จริงและ warn อนุญาตแต่แสดง Warning ให้ User เห็น
ตัวอย่าง Policy ที่ใช้บ่อย 10 ข้อ
| # | Policy | เหตุผล |
|---|---|---|
| 1 | ห้าม Container รันเป็น Root | ลดความเสี่ยง Container Escape |
| 2 | ต้องมี Resource Requests/Limits | ป้องกัน Noisy Neighbor, ช่วย Scheduler |
| 3 | Image ต้องมาจาก Trusted Registry | ป้องกัน Supply Chain Attack |
| 4 | ห้ามใช้ :latest Tag | Reproducibility, Rollback ได้ |
| 5 | ทุก Resource ต้องมี Required Labels | Cost Allocation, Team Ownership |
| 6 | ห้ามสร้าง Service type LoadBalancer | ใช้ Ingress Controller แทน |
| 7 | ห้าม HostNetwork, HostPID, HostIPC | Isolation ระหว่าง Pod กับ Node |
| 8 | ต้องมี Liveness/Readiness Probe | Self-healing, Graceful Deployment |
| 9 | PDB ต้องมีก่อน Deploy ได้ | ป้องกัน Downtime ตอน Node Drain |
| 10 | ห้าม Privilege Escalation | ป้องกัน Container ได้ Root บน Host |
Gatekeeper มี Library ของ ConstraintTemplate สำเร็จรูปที่ชื่อ Gatekeeper Library (github.com/open-policy-agent/gatekeeper-library) รวม Policy ที่ใช้บ่อยกว่า 30 ข้อสามารถนำมาใช้ได้ทันทีโดยไม่ต้องเขียน Rego เอง
Audit Mode — ตรวจสอบ Resource ที่มีอยู่แล้ว
Gatekeeper ไม่ได้ตรวจแค่ Resource ใหม่เท่านั้นแต่ยังมี Audit Controller ที่ Scan Resource ที่มีอยู่แล้วในระบบว่าผ่าน Policy ปัจจุบันหรือไม่ผลลัพธ์ Audit จะถูกเก็บไว้ใน Status ของ Constraint
# ดูผล Audit ของ Constraint
kubectl get k8srequiredlabels ns-must-have-team-label -o yaml
# ส่วน status.violations จะแสดง Resource ที่ไม่ผ่าน
# status:
# totalViolations: 3
# violations:
# - enforcementAction: deny
# kind: Namespace
# name: default
# message: "Resource missing required labels: {team, cost-center}"
# ดูสรุป Violation ทุก Constraint
kubectl get constraints -o wide
วิธีใช้ Audit ในทางปฏิบัติคือเมื่อสร้าง Policy ใหม่ให้ตั้ง enforcementAction: dryrun ก่อนแล้วรอ Audit รอบถัดไป (Default ทุก 60 วินาที) ดูว่ามี Resource กี่ตัวที่ไม่ผ่านแก้ไขให้ผ่านหมดแล้วค่อยเปลี่ยนเป็น deny
Mutation — แก้ไข Resource อัตโนมัติ
นอกจาก Validation แล้ว Gatekeeper ยังรองรับ Mutation ซึ่งเป็นการแก้ไข Resource อัตโนมัติก่อนสร้างเช่นเพิ่ม Label ที่ขาด, ตั้ง Default Security Context, Inject Sidecar
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: default-security-context
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
scope: Namespaced
kinds:
- apiGroups: [""]
kinds: ["Pod"]
location: "spec.containers[name:*].securityContext.runAsNonRoot"
parameters:
assign:
value: true
Mutation นี้จะเพิ่ม runAsNonRoot: true ให้กับทุก Container ที่ไม่ได้ตั้งค่านี้ไว้ทำให้ไม่ต้องพึ่ง Developer ว่าจะจำตั้ง Security Context หรือไม่ระบบจะตั้งให้อัตโนมัติ
Gatekeeper vs Kyverno — เปรียบเทียบ
| คุณสมบัติ | Gatekeeper (OPA) | Kyverno |
|---|---|---|
| ภาษา Policy | Rego (Declarative) | YAML (Native K8s) |
| Learning Curve | สูง (ต้องเรียน Rego) | ต่ำ (ใช้ YAML ปกติ) |
| ขอบเขตการใช้งาน | Kubernetes + ระบบอื่นๆ | เฉพาะ Kubernetes |
| Mutation | รองรับ (v3.7+) | รองรับ (ตั้งแต่แรก) |
| Generation | ไม่รองรับ | รองรับ (สร้าง Resource ใหม่) |
| Image Verification | ต้องใช้ร่วมกับ Sigstore | Built-in Cosign/Notary |
| CNCF Status | Graduated | Incubating |
| Community | ใหญ่กว่า, มีมานานกว่า | เติบโตเร็ว, Active |
คำแนะนำคือถ้าต้องการ Policy Engine ที่ใช้ได้ทั้งใน Kubernetes, API Gateway, Terraform, CI/CD Pipeline ให้เลือก OPA/Gatekeeper เพราะ Rego ใช้ได้ทุกที่ถ้าต้องการความง่ายและใช้เฉพาะ Kubernetes ให้เลือก Kyverno
Best Practices สำหรับ Production
- เริ่มจาก Dryrun — ทุก Policy ใหม่ควรตั้ง
enforcementAction: dryrunอย่างน้อย 1-2 สัปดาห์ก่อน Enforce จริงดูผล Audit ว่ามี Resource ที่ไม่ผ่านเท่าไร - เก็บ Policy ใน Git — ใช้ GitOps (ArgoCD, Flux) Deploy ConstraintTemplate และ Constraint ผ่าน Git Commit ไม่ใช่ kubectl apply มือ
- Test Policy ด้วย conftest — เขียน Unit Test สำหรับ Rego Policy ด้วย
conftestหรือopa testก่อน Merge เข้า Main Branch - แยก ConstraintTemplate กับ Constraint — Template เก็บ Logic ไม่บ่อยเปลี่ยนส่วน Constraint เก็บ Configuration ที่อาจต่างกันในแต่ละ Environment
- ตั้ง Failure Policy เป็น Ignore สำหรับ Non-critical — ถ้า Gatekeeper ล่ม Policy ที่ Critical ควร Fail Closed (Deny ทุกอย่าง) แต่ Policy ที่ไม่ Critical ควร Fail Open (Allow ทุกอย่าง) เพื่อไม่ให้กระทบ Deployment
- Monitor Webhook Latency — ตั้ง Alert เมื่อ Webhook Latency เกิน 100ms เพราะอาจทำให้ kubectl apply ช้าลง
- ใช้ Exempt Namespaces — ยกเว้น System Namespace เช่น kube-system, gatekeeper-system ไม่ให้ถูก Policy บังคับเพื่อไม่ให้ Cluster Component มีปัญหา
- ใช้ Gatekeeper Library — เริ่มจาก Template สำเร็จรูปก่อนเขียนเองเมื่อ Library ไม่ครอบคลุม
Troubleshooting ปัญหาที่พบบ่อย
- Policy ไม่ทำงาน — ตรวจว่า ConstraintTemplate Status เป็น Ready, ตรวจ Constraint match.kinds ว่า Map ถูก Resource หรือไม่ดู Log ด้วย
kubectl logs -n gatekeeper-system deploy/gatekeeper-controller-manager - Webhook Timeout — Gatekeeper Pod อาจ Resource ไม่พอเพิ่ม CPU/Memory Requests ตรวจจำนวน ConstraintTemplate ว่ามากเกินไปหรือไม่
- Audit ไม่แสดง Violation — ตรวจ Config ว่า Sync Resource ที่ต้องการ Audit ไว้หรือยังด้วย Config CRD
- Rego Error — ใช้
opa evalหรือ Rego Playground (play.openpolicyagent.org) ทดสอบ Rego แยกก่อน Deploy
สรุปและแหล่งเรียนรู้เพิ่มเติม
OPA Gatekeeper เป็นเครื่องมือสำคัญสำหรับการบังคับใช้ Policy บน Kubernetes Cluster ในระดับ Production การเข้าใจ Rego, ConstraintTemplate และ Constraint จะช่วยให้สร้าง Guard Rail ที่ป้องกัน Misconfiguration, Security Risk และ Compliance Issue ได้อย่างมีประสิทธิภาพเมื่อรวมกับ GitOps จะได้ระบบ Policy-as-Code ที่ Auditable, Testable และ Versionable ครบถ้วน
แหล่งเรียนรู้เพิ่มเติมได้แก่ OPA Official Documentation (openpolicyagent.org), Gatekeeper Library (GitHub), Rego Playground สำหรับทดลองเขียน Policy และ Styra Academy สำหรับคอร์สออนไลน์ฟรีติดตามบทความใหม่ๆได้ที่ SiamCafe.net
Q: OPA Gatekeeper คืออะไร
Kubernetes Admission Controller ที่ใช้ OPA เป็น Engine บังคับใช้ Policy บน Cluster ตรวจสอบทุก Resource ก่อนสร้างผ่าน Rego Policy Language