Home > Blog > tech

Kubernetes RBAC คืออะไร? สอน Role, ClusterRole, ServiceAccount อย่างละเอียด 2026

Kubernetes RBAC Deep Dive Guide 2026
2026-04-16 | tech | 3500 words

Kubernetes RBAC (Role-Based Access Control) เป็นระบบควบคุมสิทธิ์ใน Kubernetes cluster ที่กำหนดว่า ใคร (Who) สามารถทำ อะไร (What) กับ ทรัพยากรอะไร (Which resources) ใน Namespace ไหน (Where) ถ้าคุณเป็น DevOps Engineer หรือ Platform Engineer การเข้าใจ RBAC อย่างลึกซึ้งเป็นสิ่งจำเป็น

RBAC Fundamentals

RBAC ใน Kubernetes ประกอบด้วย 4 Resources หลัก:

ResourceScopeหน้าที่
RoleNamespaceกำหนดสิทธิ์ใน Namespace เดียว
ClusterRoleCluster-wideกำหนดสิทธิ์ทั้ง Cluster หรือ Non-namespaced resources
RoleBindingNamespaceผูก Role/ClusterRole กับ User/Group/ServiceAccount ใน Namespace
ClusterRoleBindingCluster-wideผูก ClusterRole กับ User/Group/ServiceAccount ทั้ง Cluster

Role

# Role: อนุญาตให้ get, list, watch pods ใน namespace "development"
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: pod-reader
rules:
- apiGroups: [""]          # "" = core API group
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get"]

ClusterRole

# ClusterRole: อนุญาตให้จัดการ Nodes (cluster-wide resource)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-manager
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch", "patch"]
- apiGroups: [""]
  resources: ["nodes/status"]
  verbs: ["get", "patch"]

---
# ClusterRole ยังใช้กับ Namespaced resources ได้
# เมื่อผูกกับ RoleBinding = สิทธิ์ใน Namespace นั้น
# เมื่อผูกกับ ClusterRoleBinding = สิทธิ์ทุก Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deployment-manager
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

RoleBinding

# RoleBinding: ผูก Role "pod-reader" กับ User "jane"
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: development
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

---
# ผูก ClusterRole กับ RoleBinding (จำกัดใน Namespace)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-deployment-manager
  namespace: development
subjects:
- kind: Group
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: deployment-manager
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding

# ClusterRoleBinding: ให้สิทธิ์ทั้ง Cluster
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding
subjects:
- kind: User
  name: admin@example.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

ServiceAccount

Default ServiceAccount

ทุก Namespace มี Default ServiceAccount ที่ Pods ใช้โดยอัตโนมัติ:

# ดู ServiceAccounts
kubectl get serviceaccounts -n default

# Default ServiceAccount มีสิทธิ์น้อยมาก (เกือบไม่มีสิทธิ์)
# Best practice: สร้าง Custom ServiceAccount สำหรับแต่ละ Application

Custom ServiceAccount

# สร้าง ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-service-account
  namespace: production

---
# Role สำหรับ Application
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: app-role
rules:
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

---
# ผูก Role กับ ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-role-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: app-service-account
  namespace: production
roleRef:
  kind: Role
  name: app-role
  apiGroup: rbac.authorization.k8s.io

---
# ใช้ ServiceAccount ใน Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  template:
    spec:
      serviceAccountName: app-service-account
      automountServiceAccountToken: true
      containers:
      - name: app
        image: my-app:latest

ServiceAccount Token

# Kubernetes 1.24+: Token ไม่ถูกสร้างอัตโนมัติ
# ต้องสร้าง TokenRequest API หรือ Secret

# วิธีที่ 1: TokenRequest (Recommended - Short-lived)
kubectl create token app-service-account -n production --duration=3600s

# วิธีที่ 2: Long-lived token via Secret
apiVersion: v1
kind: Secret
metadata:
  name: app-sa-token
  namespace: production
  annotations:
    kubernetes.io/service-account.name: app-service-account
type: kubernetes.io/service-account-token

Common RBAC Patterns

Pattern 1: Dev Team (Read-only + Deploy)

# Dev Team: ดูได้ทุกอย่าง, Deploy ได้เฉพาะ Namespace ของตัวเอง
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dev-team-viewer
rules:
- apiGroups: ["", "apps", "batch"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-team-ns
  name: dev-team-deployer
rules:
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]  # ห้าม create/update secrets

Pattern 2: Ops Team (Full Namespace Control)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ops-team-admin
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["roles", "rolebindings"]
  verbs: ["get", "list", "watch"]  # ดู RBAC ได้ แต่แก้ไม่ได้

Pattern 3: CI/CD Pipeline

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cicd-deployer
  namespace: production

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: cicd-role
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "patch", "update"]
  # ไม่ให้ create/delete — ป้องกัน Pipeline สร้าง/ลบ Deployment
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
  # ไม่ให้ delete pods — ป้องกัน Pipeline ลบ Pods

Pattern 4: Monitoring (Read-only Cluster-wide)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints", "nodes", "namespaces"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]
- nonResourceURLs: ["/metrics", "/healthz"]
  verbs: ["get"]

Aggregated ClusterRoles

# Aggregated ClusterRole: รวมสิทธิ์จากหลาย ClusterRoles
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-view
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: ["monitoring.coreos.com"]
  resources: ["prometheusrules", "servicemonitors"]
  verbs: ["get", "list", "watch"]

---
# Aggregated ClusterRole ที่รวม roles ที่มี label ตรง
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: aggregate-monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: []  # rules จะถูกเติมอัตโนมัติจาก aggregation

Debugging RBAC

kubectl auth can-i

# ตรวจสอบสิทธิ์ของตัวเอง
kubectl auth can-i create pods
kubectl auth can-i delete deployments -n production
kubectl auth can-i '*' '*'  # admin check

# ตรวจสอบสิทธิ์ของ User อื่น
kubectl auth can-i create pods --as jane
kubectl auth can-i delete deployments --as jane -n production

# ตรวจสอบสิทธิ์ของ ServiceAccount
kubectl auth can-i get secrets   --as system:serviceaccount:production:app-service-account   -n production

# ดูทุกสิทธิ์ของ User
kubectl auth can-i --list --as jane
kubectl auth can-i --list --as jane -n development

Audit Logs

# เปิด Audit logging ใน kube-apiserver:
# --audit-log-path=/var/log/kubernetes/audit.log
# --audit-policy-file=/etc/kubernetes/audit-policy.yaml

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log RBAC failures
- level: Metadata
  resources:
  - group: ""
    resources: ["pods", "secrets", "configmaps"]
  verbs: ["create", "update", "delete"]

# ค้นหา RBAC denial ใน Audit logs:
# grep "Forbidden" /var/log/kubernetes/audit.log | jq '.user.username, .objectRef'

RBAC + Admission Controllers (OPA)

# OPA Gatekeeper ช่วยเพิ่ม Policy layer เหนือ RBAC:
# RBAC: ใครทำอะไรได้
# OPA: ทำได้ แต่ต้องตรงตามเงื่อนไข

# ตัวอย่าง: ทุก Pod ต้องมี resource limits
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredResources
metadata:
  name: require-resource-limits
spec:
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
  parameters:
    limits:
    - cpu
    - memory

# ตัวอย่าง: ห้ามใช้ image tag "latest"
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowedTags
metadata:
  name: no-latest-tag
spec:
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
  parameters:
    tags: ["latest"]

RBAC กับ External Identity (OIDC, LDAP)

# Kubernetes API Server + OIDC Provider (เช่น Keycloak, Okta, Azure AD)
# kube-apiserver flags:
# --oidc-issuer-url=https://keycloak.example.com/realms/kubernetes
# --oidc-client-id=kubernetes
# --oidc-username-claim=email
# --oidc-groups-claim=groups

# User "jane@example.com" อยู่ใน Group "dev-team" บน Keycloak
# Kubernetes RBAC:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-team-binding
  namespace: development
subjects:
- kind: Group
  name: dev-team              # ตรงกับ OIDC groups claim
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: dev-team-deployer
  apiGroup: rbac.authorization.k8s.io

Common RBAC Mistakes

  1. ให้ cluster-admin ทุกคน: อันตรายมาก ทุกคนสามารถลบ Production ได้ ใช้ Least privilege เสมอ
  2. ใช้ Default ServiceAccount: Default SA มีสิทธิ์น้อย แต่ถ้าถูก Compromise ก็อันตราย สร้าง Custom SA สำหรับแต่ละ App
  3. ไม่ปิด automountServiceAccountToken: ถ้า Pod ไม่ต้องเรียก Kubernetes API ให้ปิด automountServiceAccountToken: false
  4. Orphaned RoleBindings: ลบ User แล้วลืมลบ RoleBinding ทำให้ User ใหม่ที่ชื่อเหมือนกันได้สิทธิ์ที่ไม่ควรได้
  5. Too permissive wildcards: ใช้ resources: ["*"] หรือ verbs: ["*"] โดยไม่จำเป็น
  6. ไม่แยก Namespace: ใส่ทุกอย่างใน Default namespace ทำให้ RBAC ไม่มีประสิทธิภาพ
  7. ไม่ Review RBAC เป็นประจำ: สิทธิ์ที่เคยจำเป็นอาจไม่จำเป็นแล้ว

RBAC Best Practices Checklist

Checklistรายละเอียด
Least Privilegeให้สิทธิ์น้อยที่สุดที่จำเป็น เพิ่มทีหลังเมื่อต้องการ
ใช้ Groups แทน Usersจัดการสิทธิ์ผ่าน Group ง่ายกว่าจัดการรายคน
แยก Namespaceแต่ละทีม/แอพมี Namespace ของตัวเอง
Custom ServiceAccountสร้าง SA เฉพาะสำหรับแต่ละ Application
ปิด automountถ้า Pod ไม่เรียก K8s API ให้ปิด automountServiceAccountToken
Audit RBACReview สิทธิ์ทุก Quarter ลบ Orphaned bindings
ใช้ OIDCผูก Identity กับ Corporate Identity Provider
CI/CD SA แยกServiceAccount สำหรับ CI/CD มีสิทธิ์จำกัด (deploy only)
ห้าม edit RBAC ใน ProdRBAC changes ต้องผ่าน GitOps / Code review
Enable Audit logsบันทึกทุก API call เพื่อตรวจสอบย้อนหลัง

RBAC Automation

# สร้าง RBAC จาก Audit logs:
# 1. เปิด Audit logging
# 2. ให้ User ใช้งาน Cluster ปกติ
# 3. วิเคราะห์ Audit logs ว่า User เรียก API อะไรบ้าง
# 4. สร้าง Role ที่ครอบคลุมเฉพาะ API ที่ User ใช้จริง

# Tools:
# - audit2rbac: สร้าง RBAC จาก Audit logs
#   https://github.com/liggitt/audit2rbac
# - rbac-lookup: ดู RBAC bindings ง่ายๆ
#   kubectl krew install rbac-lookup
#   kubectl rbac-lookup jane
# - rakkess: ดู Access matrix
#   kubectl krew install access-matrix
#   kubectl access-matrix --as jane -n development

สรุป

Kubernetes RBAC เป็นระบบที่ทรงพลังสำหรับการควบคุมสิทธิ์ใน Cluster การเข้าใจ Role, ClusterRole, RoleBinding, ClusterRoleBinding และ ServiceAccount อย่างลึกซึ้ง ช่วยให้คุณออกแบบ Security policies ที่ปลอดภัยตามหลัก Least Privilege

เริ่มต้นด้วยการ Audit สิทธิ์ปัจจุบัน ใช้ kubectl auth can-i ตรวจสอบ จากนั้นออกแบบ RBAC policies สำหรับแต่ละทีมและ Application แยก Namespace ใช้ Custom ServiceAccount และ Review RBAC เป็นประจำ เพราะ Security ที่ดีเริ่มจากการจัดการสิทธิ์ที่ดี


Back to Blog | iCafe Forex | SiamLanCard | Siam2R