쿠버네티스에서 멀티 테넌트 환경을 운영할 때, 특정 사용자나 그룹이 특정 네임스페이스의 리소스만 관리할 수 있도록 접근을 제한하는 것이 중요합니다.
이번 글에서는 RBAC(Role-Based Access Control)을 활용하여 사용자 및 그룹별 리소스 접근을 제어하는 방법을 다룹니다.
📌 글에서 다루는 상황들
1️⃣ RBAC(Role-Based Access Control)을 활용한 사용자 및 그룹별 접근 제어
2️⃣ ServiceAccount를 통한 특정 리소스 접근 제한
각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.
1️⃣ RBAC(Role-Based Access Control)을 활용한 사용자 및 그룹별 접근 제어
❓ 문제 상황
운영팀에서 각 팀(테넌트)의 개발자가 자신의 네임스페이스에서만 리소스를 관리할 수 있도록 설정해야 하는 요구사항이 생겼습니다.
기본적으로 쿠버네티스 클러스터에서는 모든 사용자가 모든 네임스페이스에 접근할 수 있기 때문에, 보안 및 운영 관리를 위해 RBAC를 활용한 접근 제어가 필요합니다.
• team-a의 개발자는 자신의 네임스페이스에서만 Deployment, Pod을 생성 및 관리할 수 있어야 합니다.
• team-b의 개발자는 자신의 네임스페이스에서만 Deployment, Pod을 생성 및 관리할 수 있어야 합니다.
• admin 사용자는 모든 네임스페이스에서 모든 리소스를 관리할 수 있어야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. Role을 생성하여 특정 네임스페이스에서만 사용자가 리소스를 관리할 수 있도록 설정합니다.
2. RoleBinding을 활용하여 특정 사용자를 Role에 연결하여 접근을 제한합니다.
3. ClusterRole을 사용하여 admin 사용자가 모든 네임스페이스에서 리소스를 관리할 수 있도록 설정합니다.
✅ 정답 Manifest (RBAC 사용자 및 그룹별 접근 제한 설정)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-a
name: team-a-developer
rules:
- apiGroups: [""]
resources: ["pods", "deployments"]
verbs: ["create", "delete", "get", "list", "watch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-a-developer-binding
namespace: team-a
subjects:
- kind: User
name: "developer-a" # team-a의 개발자 계정
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-a-developer
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-binding
subjects:
- kind: User
name: "admin" # 전체 클러스터 관리 계정
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
📌 적용 후 예상 결과 값
1. RBAC 설정 확인 (team-a 개발자가 team-b에서 리소스를 생성할 수 있는지 확인)
kubectl auth can-i create pods --as=developer-a -n team-b
💡 예상 출력 값
no
2. team-a 개발자가 자신의 네임스페이스에서 리소스를 생성할 수 있는지 확인
kubectl auth can-i create pods --as=developer-a -n team-a
💡 예상 출력 값
yes
3. admin 사용자가 모든 네임스페이스에서 리소스를 관리할 수 있는지 확인
kubectl auth can-i create pods --as=admin -n team-b
💡 예상 출력 값
yes
2️⃣ ServiceAccount를 통한 특정 리소스 접근 제한
❓ 문제 상황
운영팀에서 특정 애플리케이션(서비스)이 특정 리소스만 접근할 수 있도록 제한해야 하는 요구사항이 생겼습니다.
기본적으로 Pod에서 실행되는 애플리케이션은 기본 ServiceAccount를 사용하지만, 이를 커스텀 ServiceAccount로 변경하여 접근 권한을 제한할 수 있습니다.
• team-a 네임스페이스에서 실행되는 특정 애플리케이션은 ConfigMap과 Secrets만 읽을 수 있어야 합니다.
• Pod에서 실행되는 컨테이너가 불필요한 리소스에 접근할 수 없도록 제한해야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. 새로운 ServiceAccount를 생성합니다.
2. ServiceAccount에 ConfigMap 및 Secret 읽기 권한만 부여합니다.
3. Pod에서 해당 ServiceAccount를 사용하도록 설정합니다.
✅ 정답 Manifest (ServiceAccount 및 Role 설정)
apiVersion: v1
kind: ServiceAccount
metadata:
name: limited-reader
namespace: team-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-secret-reader
namespace: team-a
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: limited-reader-binding
namespace: team-a
subjects:
- kind: ServiceAccount
name: limited-reader
namespace: team-a
roleRef:
kind: Role
name: configmap-secret-reader
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
name: app-with-limited-access
namespace: team-a
spec:
serviceAccountName: limited-reader
containers:
- name: app
image: busybox
command: ["sleep", "3600"]
📌 적용 후 예상 결과 값
1. Pod이 ServiceAccount를 제대로 사용하고 있는지 확인
kubectl get pod app-with-limited-access -n team-a -o=jsonpath='{.spec.serviceAccountName}'
💡 예상 출력 값
limited-reader
2. Pod 내부에서 ConfigMap 및 Secret 접근 확인
kubectl exec -n team-a app-with-limited-access -- kubectl get configmaps
💡 예상 출력 값
NAME DATA AGE
app-config 2 10m
3. Pod 내부에서 다른 리소스(예: Pod) 접근 차단 확인
kubectl exec -n team-a app-with-limited-access -- kubectl get pods
💡 예상 출력 값
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:team-a:limited-reader" cannot list resource "pods" in API group "" in the namespace "team-a"