Kubernetes Security Best Practices สำหรับ Cloud VPS

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
FalcoRuntime Security Monitoringตรวจจับพฤติกรรมผิดปกติแบบ real-time เช่น shell access ใน Container
Kubescapeสแกน Cluster ตาม NSA/CISA Frameworkรองรับหลาย framework และให้คะแนนความเสี่ยง
Polarisตรวจ Best Practice ของ Deploymentตรวจ resource limits, security context, health checks
OPA GatekeeperPolicy 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 จากนั้นค่อยเพิ่มมาตรการอื่น ๆ ตามลำดับ และอย่าลืมใช้เครื่องมือสแกนอัตโนมัติเป็นประจำเพื่อตรวจจับปัญหาก่อนที่จะถูกโจมตีจริง