이 가이드는 개발자가 특정 네임스페이스에서만 작업할 수 있도록 RBAC를 설정하는 방법을 설명합니다.
먼저 개발용 네임스페이스를 생성합니다.
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev-team-a
labels:
name: dev-team-a
team: development
kubectl apply -f namespace.yaml
개발자를 위한 ServiceAccount를 생성합니다.
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: dev-team-a-user
namespace: dev-team-a
kubectl apply -f serviceaccount.yaml
네임스페이스 내에서 필요한 권한을 정의한 Role을 생성합니다.
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-team-a
name: dev-team-a-role
rules:
# Pod 관련 권한
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# Service 관련 권한
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# ConfigMap, Secret 관련 권한
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# PersistentVolumeClaim 관련 권한
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# Deployment, ReplicaSet 관련 권한
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# Ingress 관련 권한
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# Job, CronJob 관련 권한
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
kubectl apply -f role.yaml
Role과 ServiceAccount를 연결하는 RoleBinding을 생성합니다.
# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-a-binding
namespace: dev-team-a
subjects:
- kind: ServiceAccount
name: dev-team-a-user
namespace: dev-team-a
roleRef:
kind: Role
name: dev-team-a-role
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebinding.yaml
Kubernetes 1.24 이후부터는 ServiceAccount 토큰을 수동으로 생성해야 합니다.
# token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dev-team-a-user-token
namespace: dev-team-a
annotations:
kubernetes.io/service-account.name: dev-team-a-user
type: kubernetes.io/service-account-token
kubectl apply -f token-secret.yaml
이제 개발자용 kubeconfig 파일을 생성합니다.
# 클러스터 정보 가져오기
CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
CLUSTER_ENDPOINT=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CLUSTER_CA=$(kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
# ServiceAccount 토큰 가져오기
TOKEN=$(kubectl get secret dev-team-a-user-token -n dev-team-a -o jsonpath='{.data.token}' | base64 -d)
echo "클러스터 이름: $CLUSTER_NAME"
echo "클러스터 엔드포인트: $CLUSTER_ENDPOINT"
echo "토큰 길이: ${#TOKEN}"
# kubeconfig 파일 생성
cat > dev-team-a-kubeconfig.yaml << EOF
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: $CLUSTER_CA
server: $CLUSTER_ENDPOINT
name: $CLUSTER_NAME
contexts:
- context:
cluster: $CLUSTER_NAME
namespace: dev-team-a
user: dev-team-a-user
name: dev-team-a-context
current-context: dev-team-a-context
users:
- name: dev-team-a-user
user:
token: $TOKEN
EOF
생성된 kubeconfig로 권한을 테스트합니다.
# 새 kubeconfig로 테스트
export KUBECONFIG=./dev-team-a-kubeconfig.yaml
# 현재 컨텍스트 확인
kubectl config current-context
# 네임스페이스 내 리소스 조회 (성공해야 함)
kubectl get pods
kubectl get services
kubectl get deployments
# 다른 네임스페이스 접근 시도 (실패해야 함)
kubectl get pods -n kube-system
kubectl get nodes
# 클러스터 레벨 리소스 접근 시도 (실패해야 함)
kubectl get namespaces
생성된 dev-team-a-kubeconfig.yaml 파일을 개발자에게 전달하고, 다음과 같이 사용하도록 안내합니다.
# kubeconfig 파일 설정
export KUBECONFIG=/path/to/dev-team-a-kubeconfig.yaml
# 또는 기본 kubeconfig에 병합
kubectl config view --flatten > ~/.kube/config.backup
KUBECONFIG=~/.kube/config:/path/to/dev-team-a-kubeconfig.yaml kubectl config view --flatten > ~/.kube/config
# 컨텍스트 전환
kubectl config use-context dev-team-a-context
네임스페이스 간 네트워크 격리를 위한 NetworkPolicy:
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dev-team-a-netpol
namespace: dev-team-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: dev-team-a
egress:
- to:
- namespaceSelector:
matchLabels:
name: dev-team-a
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
네임스페이스 리소스 사용량 제한:
# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-team-a-quota
namespace: dev-team-a
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
persistentvolumeclaims: "10"
services: "10"
secrets: "10"
configmaps: "10"
ServiceAccount 토큰이 만료되거나 갱신이 필요한 경우:
# 기존 토큰 시크릿 삭제
kubectl delete secret dev-team-a-user-token -n dev-team-a
# 새 토큰 시크릿 생성
kubectl apply -f token-secret.yaml
# 새 kubeconfig 생성 (6단계 반복)
이 가이드를 통해 개발자는 지정된 네임스페이스에서만 작업할 수 있으며, 클러스터의 다른 리소스에는 접근할 수 없습니다.