보안: ServiceAccount와 RBAC
- 10.1 쿠버네티스의 권한 인증 체계
- 10.2 ServiceAccount
- 10.3 롤과 클러스터 롤 (RBAC)
- 10.4 kubeconfig 파일
- 10.5 x509 인증서 인증
누가 어떤 리소스에 접근할 수 있는지를 제어하지 않으면 프로덕션 환경에서 사고가 터져. 쿠버네티스는 이를 위해 ServiceAccount, RBAC, 인증서 기반 인증 같은 메커니즘을 제공해.
쿠버네티스 API 서버에 요청을 보내면 세 단계를 거쳐:
- 인증(Authentication): "너 누구야?" — 요청자의 신원을 확인
- 인가(Authorization): "너 이거 할 수 있어?" — 해당 작업을 수행할 권한이 있는지 확인
- 어드미션 컨트롤(Admission Control): "이 요청 내용이 정책에 맞아?" — 요청의 내용을 검증하고 변경
인증 방법은 여러 가지야:
- x509 클라이언트 인증서: kubeconfig에서 가장 흔히 쓰는 방식
- Bearer Token: ServiceAccount의 토큰
- OIDC(OpenID Connect): 외부 인증 서비스(Google, GitHub 등) 연동
- Webhook Token: 외부 서비스에 인증을 위임
인가 방법 중 현재 표준은 **RBAC(Role-Based Access Control)**이야. "이 사용자는 이 역할을 가지고 있고, 이 역할은 이런 권한이 있다"를 정의하는 방식이지.
ServiceAccount는 파드가 API 서버에 접근할 때 사용하는 계정이야. 사람이 아닌 **프로세스(파드)**를 위한 계정이라고 보면 돼. 모든 네임스페이스에는 default ServiceAccount가 자동으로 생성되고, 별도 설정 없이 파드를 만들면 이 default ServiceAccount가 할당돼.
kubectl create serviceaccount my-sa
kubectl get serviceaccounts
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
namespace: default
파드에 ServiceAccount를 지정할 때:
spec:
serviceAccountName: my-sa
containers:
- name: app
image: my-app
파드 안에서 ServiceAccount의 토큰은 /var/run/secrets/kubernetes.io/serviceaccount/ 경로에 자동으로 마운트돼. 이 토큰으로 API 서버에 인증할 수 있어. 쿠버네티스 1.24부터는 ServiceAccount에 자동으로 시크릿(토큰)이 생성되지 않아. 대신 TokenRequest API를 통해 시간 제한이 있는 토큰이 자동 발급되고 파드에 주입되는데, 보안이 더 강화된 거지.
RBAC는 네 가지 오브젝트로 구성돼:
- Role: 특정 네임스페이스 내에서의 권한을 정의
- ClusterRole: 클러스터 전체 범위의 권한을 정의
- RoleBinding: Role을 사용자/ServiceAccount에 연결
- ClusterRoleBinding: ClusterRole을 사용자/ServiceAccount에 연결
# 특정 네임스페이스에서 파드를 읽을 수 있는 Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
# Role을 ServiceAccount에 연결
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: dev
subjects:
- kind: ServiceAccount
name: my-sa
namespace: dev
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Role은 네임스페이스 범위야. 해당 네임스페이스 내의 리소스에만 적용돼. ClusterRole은 클러스터 범위라서 네임스페이스에 속하지 않는 리소스(노드, PV 등)나 모든 네임스페이스의 리소스에 접근할 때 사용하지.
# 클러스터 전체에서 노드 정보를 읽을 수 있는 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
verbs에 사용할 수 있는 값들은 get, list, watch, create, update, patch, delete이고, *를 쓰면 모든 동작을 허용해.
실무에서는 **최소 권한 원칙(Principle of Least Privilege)**을 따라야 해. 필요한 리소스에 필요한 동작만 허용하는 Role을 만들어서 부여하는 거지. cluster-admin 같은 전체 관리자 권한을 남발하면 보안 사고의 원인이 돼.
kubectl이 어떤 클러스터에 어떤 사용자로 접근할지를 정의하는 설정 파일이 kubeconfig야. 기본 경로는 ~/.kube/config이고, 세 가지 요소로 구성돼:
- clusters: 접근할 쿠버네티스 클러스터 정보 (API 서버 주소, CA 인증서)
- users: 인증 정보 (클라이언트 인증서, 토큰 등)
- contexts: cluster + user + namespace의 조합. "이 클러스터에 이 사용자로 이 네임스페이스에서 작업하겠다"는 설정
apiVersion: v1
kind: Config
clusters:
- cluster:
server: https://192.168.1.100:6443
certificate-authority-data: LS0tLS1...
name: my-cluster
users:
- name: admin
user:
client-certificate-data: LS0tLS1...
client-key-data: LS0tLS1...
contexts:
- context:
cluster: my-cluster
user: admin
namespace: default
name: my-context
current-context: my-context
kubectl config get-contexts # 컨텍스트 목록
kubectl config use-context my-context # 컨텍스트 전환
kubectl config current-context # 현재 컨텍스트 확인
여러 클러스터를 관리할 때 컨텍스트 전환으로 간편하게 오갈 수 있어. kubectx 같은 도구를 쓰면 더 편하지.
쿠버네티스에서 가장 기본적인 사용자 인증 방식은 x509 클라이언트 인증서야. kubeadm으로 클러스터를 설치하면 자동으로 CA(Certificate Authority)가 생성되고, 이 CA로 서명된 인증서를 가진 사용자만 API 서버에 접근할 수 있어.
새로운 사용자를 추가하는 흐름은 이래:
- 개인 키 생성:
openssl genrsa -out user.key 2048 - CSR(Certificate Signing Request) 생성:
openssl req -new -key user.key -out user.csr -subj "/CN=username/O=groupname" - 쿠버네티스 CSR 오브젝트 생성: CSR을 base64 인코딩해서 쿠버네티스에 제출
- CSR 승인:
kubectl certificate approve user-csr - 인증서 추출: 승인된 인증서를 kubeconfig에 등록
CSR의 **CN(Common Name)**이 사용자 이름이 되고, **O(Organization)**가 그룹이 돼. RoleBinding에서 이 이름이나 그룹에 Role을 바인딩하면 되지.
이 과정이 꽤 번거로운데, 대규모 조직에서는 OIDC 연동으로 기존 인증 시스템(LDAP, Google Workspace 등)과 통합하는 게 더 현실적이야.
정리
10장 읽고 기억할 거 세 가지:
- API 서버 접근은 인증 → 인가 → 어드미션 컨트롤 순서로 처리된다. RBAC가 인가의 표준.
- ServiceAccount는 파드용 계정이고, Role/ClusterRole로 권한을 부여한다. 최소 권한 원칙을 지켜서 필요한 권한만 부여해야 함.
- kubeconfig로 클러스터/사용자/네임스페이스 조합을 관리한다. 여러 클러스터를 오갈 때 컨텍스트 전환을 사용.