Skip to content

Thực hành: RBAC & Security

🎯 Mục tiêu

🎯 Sau bài thực hành này, bạn sẽ:

  • Tạo Role, RoleBinding và ServiceAccount theo Least Privilege
  • Cấu hình SecurityContext: non-root, readOnlyRootFilesystem, drop capabilities
  • Kiểm chứng rằng Pod đã được hardening đúng cách

Mô tả bài tập

Team phát triển cần deploy ứng dụng mới. Bạn (Platform Engineer) phải thiết lập quyền truy cập RBAC giới hạn và đảm bảo Pod tuân thủ security hardening standards trước khi lên production.

Yêu cầu

Bài 1: ServiceAccount & RBAC

Tạo namespace dev-team, ServiceAccount, Role và RoleBinding:

yaml
# 1. Tạo namespace
apiVersion: v1
kind: Namespace
metadata:
  name: dev-team
---
# 2. Tạo ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: developer-sa
  namespace: dev-team
automountServiceAccountToken: false
---
# 3. TODO: Tạo Role cho phép:
#    - pods: get, list, watch, create, delete
#    - services: get, list
#    - deployments: get, list, create, update
#    - KHÔNG được: delete deployments, access secrets
---
# 4. TODO: Tạo RoleBinding gắn Role với ServiceAccount

Kiểm tra:

bash
# Phải trả về "yes"
kubectl auth can-i list pods --as=system:serviceaccount:dev-team:developer-sa -n dev-team
# Phải trả về "no"
kubectl auth can-i delete deployments --as=system:serviceaccount:dev-team:developer-sa -n dev-team
kubectl auth can-i get secrets --as=system:serviceaccount:dev-team:developer-sa -n dev-team

Bài 2: Pod Security Hardening

Tạo Pod với đầy đủ security hardening:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: hardened-app
  namespace: dev-team
spec:
  serviceAccountName: developer-sa
  securityContext:
    # TODO: Pod-level security
    # runAsNonRoot, runAsUser, fsGroup
  containers:
  - name: app
    image: nginx:1.24-alpine
    ports:
    - containerPort: 8080
    securityContext:
      # TODO: Container-level security
      # allowPrivilegeEscalation, readOnlyRootFilesystem
      # capabilities: drop ALL
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: cache
      mountPath: /var/cache/nginx
    - name: run
      mountPath: /var/run
  volumes:
  - name: tmp
    emptyDir: {}
  - name: cache
    emptyDir: {}
  - name: run
    emptyDir: {}

Kiểm tra:

bash
# Phải FAIL (non-root)
kubectl exec hardened-app -n dev-team -- whoami  # Không phải root
# Phải FAIL (readOnly filesystem)
kubectl exec hardened-app -n dev-team -- touch /usr/share/nginx/html/hack.txt

Bài 3: Audit — Phát hiện Pod không an toàn

Viết command kiểm tra tất cả Pod trong cluster đang chạy với root:

bash
# TODO: Viết kubectl command để tìm Pods chạy root
# Hint: kubectl get pods --all-namespaces -o jsonpath=...

Tìm Pod nào có automountServiceAccountToken: true (mặc định):

bash
# TODO: Liệt kê Pods có service account token mounted

Gợi ý

💡 Xem gợi ý
  • Bài 1: Role apiGroups: [""] cho core resources (pods, services), apiGroups: ["apps"] cho deployments
  • Bài 2: NGINX alpine cần ghi vào /var/cache/nginx, /var/run, /tmp — mount emptyDir cho các path này khi dùng readOnlyRootFilesystem
  • Bài 2: Dùng user 101 (nginx user trong alpine image), fsGroup 101
  • Bài 3: JSONPath: kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.securityContext.runAsNonRoot}{"\n"}{end}'
  • automountServiceAccountToken mặc định là true nếu không set explicit

Lời giải

✅ Xem lời giải

Bài 1: RBAC hoàn chỉnh

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-role
  namespace: dev-team
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: dev-team
subjects:
- kind: ServiceAccount
  name: developer-sa
  namespace: dev-team
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io

Bài 2: Hardened Pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: hardened-app
  namespace: dev-team
spec:
  serviceAccountName: developer-sa
  securityContext:
    runAsNonRoot: true
    runAsUser: 101
    runAsGroup: 101
    fsGroup: 101
  containers:
  - name: app
    image: nginx:1.24-alpine
    ports:
    - containerPort: 8080
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: cache
      mountPath: /var/cache/nginx
    - name: run
      mountPath: /var/run
  volumes:
  - name: tmp
    emptyDir: {}
  - name: cache
    emptyDir: {}
  - name: run
    emptyDir: {}

Bài 3: Audit Commands

bash
# Tìm Pods chạy root
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: runAsNonRoot={.spec.securityContext.runAsNonRoot}{"\n"}{end}' | grep -v "true"

# Tìm Pods có token mounted
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: automount={.spec.automountServiceAccountToken}{"\n"}{end}'

Liên kết liên quan