Skip to content
Published on

Kubernetes RBAC 완벽 가이드: Golden Kubestronaut 시험 대비 실전 핸즈온

Authors
  • Name
    Twitter

1. RBAC이란 무엇인가

Kubernetes의 **RBAC(Role-Based Access Control)**은 클러스터 내 API 리소스에 대한 접근을 역할 기반으로 제어하는 인가(Authorization) 메커니즘이다. kube-apiserver--authorization-mode=RBAC 플래그가 설정되어 있으면 활성화된다.

RBAC의 핵심 원칙은 **최소 권한 원칙(Principle of Least Privilege)**이다. 모든 사용자와 서비스 어카운트는 업무 수행에 필요한 최소한의 권한만 부여받아야 한다.

1.1 RBAC의 4가지 핵심 리소스

리소스스코프용도
Role네임스페이스특정 네임스페이스 내 리소스 권한 정의
ClusterRole클러스터 전체클러스터 범위 리소스 또는 여러 네임스페이스 공통 권한
RoleBinding네임스페이스Role 또는 ClusterRole을 특정 네임스페이스에서 Subject에 바인딩
ClusterRoleBinding클러스터 전체ClusterRole을 클러스터 전체에서 Subject에 바인딩

2. Role과 ClusterRole 상세

2.1 네임스페이스 Role 생성

# dev-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: pod-reader
rules:
- apiGroups: [""]          # core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]

2.2 ClusterRole 생성

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-viewer
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["nodes"]
  verbs: ["get", "list"]

2.3 Aggregated ClusterRole

CKS 시험에서 자주 나오는 Aggregated ClusterRole 패턴:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-endpoints
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
  resources: ["services", "endpoints", "pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: []  # 자동으로 채워짐

3. RoleBinding과 ClusterRoleBinding

3.1 RoleBinding: 네임스페이스 내 권한 부여

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: development
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
  name: ci-bot
  namespace: development
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

3.2 ClusterRole을 RoleBinding으로 사용 (중요!)

ClusterRole을 RoleBinding에 연결하면 해당 네임스페이스에서만 유효하다. 공통 권한 세트를 여러 네임스페이스에 재사용할 때 매우 유용:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-staging
  namespace: staging
subjects:
- kind: Group
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole      # ClusterRole이지만
  name: pod-reader        # RoleBinding이므로 staging NS에서만 유효
  apiGroup: rbac.authorization.k8s.io

4. ServiceAccount와 RBAC

4.1 ServiceAccount 토큰 (1.24+)

Kubernetes 1.24부터 SA에 자동 시크릿이 생성되지 않는다:

# ServiceAccount 생성
kubectl create serviceaccount monitoring-sa -n monitoring

# 단기 토큰 생성 (1시간)
kubectl create token monitoring-sa -n monitoring --duration=3600s

# 장기 토큰 (레거시 호환용)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: monitoring-sa-token
  namespace: monitoring
  annotations:
    kubernetes.io/service-account.name: monitoring-sa
type: kubernetes.io/service-account-token
EOF

4.2 Pod에서 SA 토큰 마운트 비활성화

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  automountServiceAccountToken: false
  containers:
  - name: app
    image: nginx:1.27

5. 실전 핸즈온: 멀티테넌트 RBAC 구성

5.1 시나리오

  • frontend-team: frontend NS — Deployment, Service, ConfigMap 관리
  • backend-team: backend NS — 모든 워크로드 + Secrets 읽기
  • platform-team: 클러스터 전체 — 읽기 전용 + Node/PV 관리

5.2 구현

kubectl create ns frontend
kubectl create ns backend

# 1) frontend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: frontend
  name: frontend-developer
rules:
- apiGroups: ["", "apps"]
  resources: ["deployments", "services", "configmaps", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["pods/log", "pods/exec"]
  verbs: ["get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: frontend
  name: frontend-team-binding
subjects:
- kind: Group
  name: frontend-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: frontend-developer
  apiGroup: rbac.authorization.k8s.io
EOF

# 2) backend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: backend
  name: backend-developer
rules:
- apiGroups: ["", "apps", "batch"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: backend
  name: backend-team-binding
subjects:
- kind: Group
  name: backend-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: backend-developer
  apiGroup: rbac.authorization.k8s.io
EOF

# 3) platform-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: platform-admin
rules:
- apiGroups: [""]
  resources: ["nodes", "persistentvolumes"]
  verbs: ["*"]
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: platform-team-binding
subjects:
- kind: Group
  name: platform-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: platform-admin
  apiGroup: rbac.authorization.k8s.io
EOF

5.3 권한 검증

# frontend-team이 frontend NS에서 pod 목록 가능?
kubectl auth can-i list pods --namespace=frontend --as=jane --as-group=frontend-team
# yes

# frontend-team이 backend NS에서 pod 삭제 가능?
kubectl auth can-i delete pods --namespace=backend --as=jane --as-group=frontend-team
# no

# 전체 권한 목록 (CKS 시험 팁!)
kubectl auth can-i --list --as=jane --as-group=frontend-team -n frontend

6. CKS 시험 빈출 RBAC 시나리오

6.1 위험한 권한 탐지

# cluster-admin 바인딩 찾기
kubectl get clusterrolebindings -o json | jq -r '
  .items[] |
  select(.roleRef.name == "cluster-admin") |
  .metadata.name + " -> " +
  (.subjects[]? | .kind + "/" + .name)'

# 와일드카드(*) 권한이 있는 Role 찾기
kubectl get roles,clusterroles -A -o json | jq -r '
  .items[] |
  select(.rules[]?.verbs[]? == "*" or .rules[]?.resources[]? == "*") |
  .metadata.namespace + "/" + .metadata.name'

6.2 Secret 접근 감사

kubectl get roles,clusterroles -A -o json | jq -r '
  .items[] |
  select(.rules[]? | .resources[]? == "secrets") |
  "\(.metadata.namespace // "cluster")/\(.metadata.name)"'

6.3 Pod Security Standards + RBAC 조합

apiVersion: v1
kind: Namespace
metadata:
  name: secure-ns
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

7. RBAC 모범 사례 (Best Practices)

  1. 최소 권한 원칙: 와일드카드(*) 사용 금지, 필요한 verb만 명시
  2. ClusterRoleBinding 최소화: 가능하면 RoleBinding + ClusterRole 조합 사용
  3. ServiceAccount 분리: Pod마다 전용 SA 생성, default SA 사용 금지
  4. 토큰 마운트 비활성화: automountServiceAccountToken: false 기본 설정
  5. 정기 감사: kubectl auth can-i --list로 주기적 권한 검토
  6. Aggregated ClusterRole 활용: 모듈화된 권한 관리
  7. Impersonation 활용: --as 플래그로 권한 테스트 후 적용

8. 자주 하는 실수와 해결

실수문제해결
ClusterRole + RoleBinding vs ClusterRoleBinding 혼동스코프 불일치Binding 타입이 스코프 결정
apiGroups: [""] 누락core 리소스 접근 불가core API = 빈 문자열
subresource 미포함pods/log, pods/exec 접근 불가별도 명시 필요
SA 토큰 만료 미인지1.24+ 단기 토큰 기본--duration 설정

9. 퀴즈

Q1. Role과 ClusterRole의 가장 큰 차이점은?

Role은 특정 네임스페이스 내에서만 유효하고, ClusterRole은 클러스터 전체 범위의 권한을 정의한다. ClusterRole은 Node, PV 같은 비네임스페이스 리소스에도 권한을 부여할 수 있다.

Q2. ClusterRole을 RoleBinding에 연결하면 어떻게 되는가?

ClusterRole에 정의된 권한이 RoleBinding이 속한 네임스페이스에서만 유효하게 된다.

Q3. Kubernetes 1.24+ 이후 ServiceAccount 토큰 관련 변경사항은?

자동 Secret 생성 중단. kubectl create token으로 단기 토큰(기본 1시간) 생성하거나 kubernetes.io/service-account-token Secret을 수동 생성해야 한다.

Q4. automountServiceAccountToken: false를 설정하는 이유는?

Pod 내 불필요한 SA 토큰 마운트를 방지하여, 컨테이너 탈취 시 공격자의 K8s API 접근을 차단. 최소 권한 원칙의 일환.

Q5. kubectl auth can-i delete pods --as=jane -n production은 무엇을 하는가?

Impersonation 기능으로 jane 사용자가 production NS에서 Pod 삭제 권한이 있는지 확인.

Q6. Aggregated ClusterRole의 동작 원리는?

aggregationRule의 label selector에 매칭되는 다른 ClusterRole의 rules가 자동으로 합쳐진다. 새 ClusterRole 추가 시 자동 반영.

Q7. 과도한 권한(cluster-admin) 바인딩을 찾는 방법은?

kubectl get clusterrolebindings -o json | jqroleRef.name == "cluster-admin"인 바인딩을 필터링.

Q8. KCSA 시험 RBAC 주요 출제 포인트 3가지는?

(1) 최소 권한 원칙 — 와일드카드 지양 (2) SA 보안 — 토큰 마운트 비활성화, default SA 미사용 (3) 정기 감사 — can-i --list, 과도한 ClusterRoleBinding 탐지