Kubernetes (K8s) เป็นแพลตฟอร์มจัดการ Container ที่ได้รับความนิยมสูงสุดในปัจจุบัน แต่ด้วยความซับซ้อนของระบบ ทำให้การรักษาความปลอดภัยเป็นสิ่งที่ต้องให้ความสำคัญตั้งแต่เริ่มต้น หากตั้งค่าไม่เหมาะสมหรือขาดการป้องกันที่ดี อาจนำไปสู่ช่องโหว่ร้ายแรง เช่น การเข้าถึง Cluster โดยไม่ได้รับอนุญาต การรั่วไหลของข้อมูลสำคัญ หรือการโจมตีจากภายในระบบเอง
บทความนี้รวบรวมแนวทางปฏิบัติด้านความปลอดภัยสำหรับ Kubernetes ที่ครอบคลุมตั้งแต่การจัดการสิทธิ์ผู้ใช้ การควบคุมเครือข่าย การรักษาความปลอดภัยของ Container Image ไปจนถึงการตรวจสอบและเฝ้าระวังระบบ เหมาะสำหรับผู้ดูแลระบบที่ต้องการยกระดับความปลอดภัยของ K8s Cluster บน Cloud VPS
RBAC (Role-Based Access Control) — จัดการสิทธิ์อย่างเข้มงวด
RBAC เป็นกลไกหลักในการควบคุมว่าใครสามารถทำอะไรได้บ้างภายใน Kubernetes Cluster โดยยึดหลัก Least Privilege คือให้สิทธิ์เฉพาะที่จำเป็นเท่านั้น การตั้งค่า RBAC ที่ดีช่วยป้องกันไม่ให้ผู้ใช้หรือ Service Account เข้าถึงทรัพยากรที่ไม่ควรเข้าถึงได้
แนวทางปฏิบัติที่สำคัญสำหรับ RBAC มีดังนี้
- ใช้ Role และ RoleBinding สำหรับสิทธิ์ระดับ Namespace แทนการใช้ ClusterRole ทุกกรณี
- หลีกเลี่ยงการใช้
cluster-adminกับผู้ใช้ทั่วไป — สงวนไว้สำหรับงาน administration เท่านั้น - สร้าง Service Account แยกสำหรับแต่ละแอปพลิเคชัน ไม่ใช้ default Service Account
- ตรวจสอบสิทธิ์ที่มีอยู่เป็นประจำด้วยคำสั่ง
kubectl auth can-i
ตัวอย่างการสร้าง Role ที่อนุญาตให้อ่าน Pod ได้เฉพาะใน Namespace ที่กำหนด
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: production
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
นอกจากนี้ควรปิดการใช้งาน auto-mount ของ Service Account Token สำหรับ Pod ที่ไม่จำเป็นต้องเรียกใช้ Kubernetes API โดยกำหนด automountServiceAccountToken: false ใน Pod spec
Network Policy — ควบคุมการสื่อสารระหว่าง Pod
โดยค่าเริ่มต้น Pod ทุกตัวใน Kubernetes สามารถสื่อสารกันได้อย่างอิสระ ซึ่งหมายความว่าหาก Pod ใดถูกโจมตีสำเร็จ ผู้โจมตีสามารถเคลื่อนตัวไปยัง Pod อื่น ๆ ได้ทันที (Lateral Movement) การใช้ Network Policy ช่วยจำกัดการสื่อสารให้เฉพาะเส้นทางที่จำเป็น
หลักการสำคัญคือเริ่มจาก Default Deny ก่อน จากนั้นค่อยเปิดอนุญาตเฉพาะ traffic ที่จำเป็น ตัวอย่างการตั้งค่า Default Deny สำหรับ Ingress traffic ทั้งหมดใน Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
จากนั้นสร้าง Network Policy เพิ่มเติมเพื่ออนุญาตเฉพาะ traffic ที่ต้องการ เช่น อนุญาตให้เฉพาะ Frontend Pod เชื่อมต่อไปยัง Backend Pod บน port 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
ข้อควรระวังคือ Network Policy ต้องใช้ร่วมกับ CNI Plugin ที่รองรับ เช่น Calico, Cilium หรือ Weave Net หาก CNI ไม่รองรับ Network Policy จะไม่มีผลใด ๆ
Pod Security Standards (PSS) — กำหนดมาตรฐานความปลอดภัยของ Pod
Pod Security Standards เป็นมาตรฐานที่ Kubernetes กำหนดขึ้นเพื่อแบ่งระดับความปลอดภัยของ Pod ออกเป็น 3 ระดับ ได้แก่ Privileged (ไม่จำกัด), Baseline (ป้องกันช่องโหว่พื้นฐาน) และ Restricted (เข้มงวดสูงสุด) โดยบังคับใช้ผ่าน Pod Security Admission ซึ่งมาแทนที่ PodSecurityPolicy ตั้งแต่ Kubernetes 1.25 เป็นต้นไป
แนวทางที่แนะนำคือใช้ระดับ Restricted สำหรับ Namespace ที่รัน workload จริง และใช้ Baseline สำหรับ Namespace ที่ต้องการความยืดหยุ่นมากกว่า ตัวอย่างการตั้งค่า Pod Security Admission ระดับ Restricted
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
เมื่อกำหนดระดับ Restricted แล้ว Pod ที่จะรันใน Namespace นี้ต้องปฏิบัติตามข้อกำหนด เช่น
- ห้ามรันในโหมด Privileged
- ต้องรันในฐานะ Non-root user โดยกำหนด
runAsNonRoot: true - ต้องกำหนด
seccompProfileเป็น RuntimeDefault หรือ Localhost - ห้าม mount host path หรือใช้ host network
- ต้อง drop ALL capabilities และเพิ่มเฉพาะที่จำเป็น
ตัวอย่าง Pod spec ที่ผ่านมาตรฐาน Restricted
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: production
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myregistry/app:v1.2.3
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
Container Image Security — ความปลอดภัยของ Image
Container Image เป็นจุดเริ่มต้นของทุก workload ใน Kubernetes หาก Image มีช่องโหว่หรือถูกแทรกแซง ไม่ว่าจะตั้งค่าระบบดีเพียงใดก็ยังเสี่ยงต่อการถูกโจมตี การจัดการ Image อย่างปลอดภัยจึงเป็นพื้นฐานสำคัญ
แนวทางปฏิบัติสำหรับ Image Security ที่ควรนำไปใช้
- ใช้ Image จาก Private Registry ที่เชื่อถือได้ หลีกเลี่ยงการดึง Image จาก Public Registry โดยไม่ตรวจสอบ
- ระบุ Image Tag เป็นเวอร์ชันที่ชัดเจน เช่น
nginx:1.25.3แทนการใช้latestซึ่งอาจเปลี่ยนแปลงได้ตลอดเวลา - ใช้ Image Digest (SHA256) เพื่อยืนยันว่า Image ไม่ถูกแก้ไข เช่น
nginx@sha256:abc123... - สแกน Image หาช่องโหว่ด้วยเครื่องมือเช่น Trivy หรือ Grype ก่อนนำไป deploy
- ใช้ Base Image ที่เล็กที่สุดเท่าที่จะทำได้ เช่น Alpine หรือ Distroless เพื่อลดพื้นผิวการโจมตี
- ตั้งค่า ImagePullPolicy เป็น Always สำหรับ production เพื่อให้ดึง Image ใหม่ทุกครั้ง
ตัวอย่างการสแกน Image ด้วย Trivy
# สแกน Image หาช่องโหว่
trivy image myregistry/app:v1.2.3
# สแกนเฉพาะช่องโหว่ระดับ HIGH และ CRITICAL
trivy image --severity HIGH,CRITICAL myregistry/app:v1.2.3
# สแกนและ fail หากพบช่องโหว่ CRITICAL (ใช้ใน CI/CD Pipeline)
trivy image --exit-code 1 --severity CRITICAL myregistry/app:v1.2.3
Secret Management — จัดการข้อมูลลับอย่างปลอดภัย
Kubernetes Secret เป็นวิธีเก็บข้อมูลที่เป็นความลับ เช่น รหัสผ่าน API Key และ Certificate แต่โดยค่าเริ่มต้น Secret จะถูกเก็บในรูปแบบ Base64 ซึ่งสามารถ decode ได้ง่าย ไม่ใช่การเข้ารหัสที่แท้จริง จึงต้องมีมาตรการเพิ่มเติมเพื่อปกป้องข้อมูลเหล่านี้
แนวทางการจัดการ Secret อย่างปลอดภัย
- เปิดใช้งาน Encryption at Rest สำหรับ Secret ใน etcd โดยกำหนด EncryptionConfiguration
- ใช้ External Secret Manager เช่น HashiCorp Vault, AWS Secrets Manager หรือ Azure Key Vault แทนการเก็บ Secret ใน Kubernetes โดยตรง
- ห้ามเก็บ Secret ใน Git Repository เด็ดขาด แม้จะเป็น Private Repo ก็ตาม
- จำกัดสิทธิ์การเข้าถึง Secret ด้วย RBAC ให้เฉพาะ Pod หรือ Service Account ที่จำเป็น
- หมุนเวียน (Rotate) Secret เป็นประจำ และกำหนดนโยบายการหมดอายุ
ตัวอย่างการตั้งค่า Encryption at Rest สำหรับ Secret
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <BASE64_ENCODED_SECRET_KEY>
- identity: {}
สำหรับการใช้งานจริงในระบบ production ควรพิจารณาใช้ Sealed Secrets หรือ External Secrets Operator เพื่อจัดการ Secret แบบอัตโนมัติและปลอดภัยมากยิ่งขึ้น
API Server Security — ปกป้อง Control Plane
API Server เป็นหัวใจของ Kubernetes Cluster เนื่องจากทุกการสื่อสารภายในระบบต้องผ่าน API Server ทั้งหมด หากผู้โจมตีเข้าถึง API Server ได้ ก็เท่ากับสามารถควบคุม Cluster ได้ทั้งหมด
แนวทางการรักษาความปลอดภัยของ API Server
- ปิดการเข้าถึง API Server จากอินเทอร์เน็ตสาธารณะ จำกัดให้เข้าถึงได้เฉพาะจาก IP ที่ได้รับอนุญาตผ่าน Firewall
- บังคับใช้ TLS สำหรับการสื่อสารทั้งหมดกับ API Server
- เปิดใช้งาน Audit Logging เพื่อบันทึกทุกการเรียกใช้ API
- ปิด Anonymous Authentication โดยกำหนด
--anonymous-auth=false - จำกัด Rate Limit เพื่อป้องกันการโจมตีแบบ Brute Force
- ใช้ Admission Controllers เช่น ValidatingAdmissionWebhook เพื่อตรวจสอบ request ก่อนยอมรับ
ตัวอย่างการกำหนด flag สำหรับ API Server เพื่อเพิ่มความปลอดภัย
# ตัวอย่าง flag ที่ควรกำหนดใน kube-apiserver
--anonymous-auth=false
--enable-admission-plugins=NodeRestriction,PodSecurity
--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-maxage=30
--audit-log-maxbackup=10
--audit-log-maxsize=100
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
--tls-min-version=VersionTLS12
Node Security — รักษาความปลอดภัยระดับ Node
แม้จะตั้งค่าความปลอดภัยภายใน Kubernetes ได้ดีเพียงใด แต่หาก Node (เครื่อง host) ที่รัน Cluster ไม่ปลอดภัย ก็เท่ากับเปิดช่องโหว่ให้ผู้โจมตีเข้าถึงระบบทั้งหมดได้ การ hardening ระดับ Node จึงเป็นสิ่งจำเป็น
แนวทางปฏิบัติสำหรับ Node Security
- อัปเดต OS และ Kubernetes เป็นเวอร์ชันล่าสุดเสมอ เพื่อรับ Security Patch
- ใช้ OS ที่ออกแบบมาสำหรับ Container โดยเฉพาะ เช่น Flatcar Container Linux หรือ Bottlerocket เพื่อลดพื้นผิวการโจมตี
- จำกัดการเข้าถึง SSH เฉพาะผู้ดูแลระบบ และใช้ Key-based Authentication แทน Password
- ใช้ AppArmor หรือ SELinux เพื่อจำกัดสิ่งที่ Container สามารถทำได้บน Node
- แยก Control Plane Node ออกจาก Worker Node และห้ามรัน workload บน Control Plane
- ตรวจสอบความปลอดภัยของ Node ด้วย CIS Kubernetes Benchmark
ตัวอย่างการรัน CIS Benchmark ด้วย kube-bench
# ติดตั้งและรัน kube-bench เพื่อตรวจสอบ CIS Benchmark
docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro \
-v $(which kubectl):/usr/local/mount-from-host/bin/kubectl \
-v ~/.kube:/.kube -e KUBECONFIG=/.kube/config \
aquasec/kube-bench:latest run --targets node
# หรือรันเฉพาะการตรวจสอบ Master Node
docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro \
aquasec/kube-bench:latest run --targets master
Audit Logging — บันทึกและเฝ้าระวังกิจกรรมใน Cluster
Audit Log เป็นเครื่องมือสำคัญในการตรวจจับพฤติกรรมที่ผิดปกติและสืบสวนเหตุการณ์ด้านความปลอดภัย Kubernetes สามารถบันทึกทุกการเรียกใช้ API ได้อย่างละเอียด ตั้งแต่ใครเป็นผู้ร้องขอ ร้องขออะไร และผลลัพธ์เป็นอย่างไร
Audit Policy กำหนดว่าจะบันทึกเหตุการณ์ใดบ้างและในระดับรายละเอียดเท่าไร โดยมี 4 ระดับ ได้แก่ None (ไม่บันทึก), Metadata (บันทึกเฉพาะข้อมูลทั่วไป), Request (บันทึกรวม request body) และ RequestResponse (บันทึกทั้ง request และ response)
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# บันทึกการเปลี่ยนแปลง Secret ในระดับ Metadata (ไม่บันทึกเนื้อหาเพื่อความปลอดภัย)
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
# บันทึกการเปลี่ยนแปลง RBAC ในระดับ RequestResponse
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
# บันทึกการสร้าง/ลบ Pod ในระดับ Request
- level: Request
resources:
- group: ""
resources: ["pods"]
verbs: ["create", "delete"]
# บันทึก Metadata สำหรับ request อื่น ๆ ทั้งหมด
- level: Metadata
omitStages:
- RequestReceived
ควรส่ง Audit Log ไปยังระบบ centralized logging เช่น Elasticsearch, Loki หรือ Splunk เพื่อให้สามารถค้นหาและวิเคราะห์ได้สะดวก รวมถึงตั้ง Alert สำหรับเหตุการณ์ที่น่าสงสัย เช่น การสร้าง ClusterRoleBinding ใหม่หรือการเข้าถึง Secret จำนวนมากในเวลาสั้น ๆ
เครื่องมือสแกนและตรวจสอบความปลอดภัย
นอกจากการตั้งค่าความปลอดภัยด้วยตนเองแล้ว ยังมีเครื่องมือ Open Source หลายตัวที่ช่วยสแกนและตรวจสอบความปลอดภัยของ Kubernetes Cluster ได้แบบอัตโนมัติ
| เครื่องมือ | หน้าที่ | จุดเด่น |
|---|---|---|
| Trivy | สแกน Image, Filesystem, Config | ใช้งานง่าย ครอบคลุมทั้ง vulnerability และ misconfiguration |
| kube-bench | ตรวจ CIS Kubernetes Benchmark | ตรวจสอบการตั้งค่า Cluster ตามมาตรฐาน CIS |
| Falco | Runtime Security Monitoring | ตรวจจับพฤติกรรมผิดปกติแบบ real-time เช่น shell access ใน Container |
| Kubescape | สแกน Cluster ตาม NSA/CISA Framework | รองรับหลาย framework และให้คะแนนความเสี่ยง |
| Polaris | ตรวจ Best Practice ของ Deployment | ตรวจ resource limits, security context, health checks |
| OPA Gatekeeper | Policy Enforcement | บังคับใช้ policy ผ่าน Admission Controller ด้วยภาษา Rego |
ตัวอย่างการสแกน Cluster ด้วย Kubescape
# สแกน Cluster ตาม NSA Framework
kubescape scan framework nsa
# สแกนเฉพาะ Namespace ที่ต้องการ
kubescape scan framework nsa --include-namespaces production
# สแกนไฟล์ YAML ก่อน deploy
kubescape scan framework nsa -f deployment.yaml
Checklist สรุปแนวทางรักษาความปลอดภัย
ตารางสรุปแนวทางรักษาความปลอดภัยสำหรับ Kubernetes ที่ควรตรวจสอบเป็นประจำ
| หมวด | รายการตรวจสอบ | ความสำคัญ |
|---|---|---|
| RBAC | ใช้ Least Privilege, แยก Service Account ต่อแอป | สูงมาก |
| Network | ตั้ง Default Deny, เปิดเฉพาะ traffic ที่จำเป็น | สูงมาก |
| Pod Security | ใช้ PSS ระดับ Restricted, ห้ามรัน root | สูงมาก |
| Image | สแกน vulnerability, ใช้ specific tag, Private Registry | สูง |
| Secret | เข้ารหัส at rest, ใช้ External Secret Manager | สูงมาก |
| API Server | ปิด anonymous auth, จำกัด IP, เปิด audit log | สูงมาก |
| Node | อัปเดต patch, ใช้ CIS Benchmark, จำกัด SSH | สูง |
| Audit | เปิด Audit Logging, ส่งไป centralized logging | สูง |
| Scanning | ใช้เครื่องมือสแกนอัตโนมัติในทุกขั้นตอน CI/CD | สูง |
สรุป
การรักษาความปลอดภัยใน Kubernetes ไม่ใช่สิ่งที่ทำครั้งเดียวแล้วจบ แต่เป็นกระบวนการต่อเนื่องที่ต้องดูแลตั้งแต่การตั้งค่า Cluster การ deploy แอปพลิเคชัน ไปจนถึงการเฝ้าระวังระบบตลอดเวลา หลักการสำคัญคือยึดแนวคิด Defense in Depth โดยวางมาตรการป้องกันหลายชั้น ตั้งแต่ RBAC, Network Policy, Pod Security Standards, Image Security ไปจนถึง Audit Logging
ควรเริ่มจากมาตรการที่ให้ผลกระทบสูงก่อน เช่น การตั้งค่า RBAC อย่างเข้มงวด การใช้ Network Policy และการเปิดใช้ Pod Security Standards จากนั้นค่อยเพิ่มมาตรการอื่น ๆ ตามลำดับ และอย่าลืมใช้เครื่องมือสแกนอัตโนมัติเป็นประจำเพื่อตรวจจับปัญหาก่อนที่จะถูกโจมตีจริง
