쿠버네티스로 인프라 운영하다 보면, 누가(clients) 클러스터에 접근할 수 있는지, 그리고 무엇을(actions) 할 수 있는지를 세밀하게 제어해야 할 때가 많습니다.
이때 사용되는 대표적인 보안 메커니즘이 바로 ServiceAccount와 RBAC(Role-Based Access Control)입니다.
이 글에서는 쿠버네티스의 인증 및 인가 흐름을 중심으로 ServiceAccount와 RBAC이 어떻게 동작하는지 정리해보았습니다.
ServiceAccount와 RBAC의 관계
- ServiceAccount는 클러스터 내부에서 동작하는 애플리케이션(Pod 등)을 대표하는 계정입니다.
- RBAC은 특정 리소스에 대해 어떤 작업을 허용할지를 선언적으로 정의하고, 이를 ServiceAccount에 연결해 권한을 부여합니다.
1. 쿠버네티스의 권한 인증 과정
kubectl 명령어를 실행하면 다음과 같은 흐름으로 요청이 처리됩니다.
- 요청은 API 서버의 HTTP 핸들러에 전달됩니다.
- 핸들러는 먼저 인증(Authentication) 절차를 통해 사용자가 유효한지를 확인하고,
이어서 인가(Authorization)를 통해 해당 작업 수행 권한이 있는지를 체크합니다. - 마지막으로 Admission Controller에서 정책 검증 후, 최종적으로 요청을 허용하거나 거부합니다.
이 과정에서 ~/.kube/config 파일이 중요한 역할을 합니다.
해당 파일에는 클러스터 정보, 인증 정보(x.509 인증서와 개인키), 컨텍스트 정보 등이 포함되어 있으며, base64 인코딩된 형태로 저장됩니다.
2. Role, ClusterRole, 그리고 바인딩
Role과 ClusterRole
- Role: 특정 네임스페이스 안에서만 유효한 권한을 정의합니다.
- ClusterRole: 네임스페이스에 관계없이 전역적으로 적용됩니다.
정의 시 다음 항목들을 지정합니다.
- apiGroups: 오브젝트의 API 그룹 (예: ""는 core 그룹, apps는 Deployment 등)
- resources: 권한을 부여할 리소스 이름
- verbs: 허용할 작업 (예: get, list, create, delete)
RoleBinding과 ClusterRoleBinding
- RoleBinding: 특정 Role을 특정 사용자(User)나 SA(ServiceAccount), 그룹(Group)에 연결합니다.
- ClusterRoleBinding: ClusterRole을 클러스터 전역에서 특정 대상과 연결할 때 사용합니다.
Role Aggregation
자주 사용하는 ClusterRole들을 한데 묶어서 사용할 수 있습니다.
agreegationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/agreegate-to-child-clusterrole: "true"
3. 쿠버네티스 API 서버에 접근하는 방법
3.1 서비스 어카운트의 Secret을 이용한 접근
- kubeadm 클러스터는 보통 6443 포트를, GKE나 kops는 443 포트를 통해 API 서버에 접근합니다.
- API 서버는 기본적으로 HTTPS만 허용하며, 인증 정보는 HTTP 페이로드에 포함시켜 전송해야 합니다.
쿠버네티스는 ServiceAccount 생성 시 연결된 Secret을 통해 API 서버와 인증을 수행합니다.
단, Kubernetes v1.24부터는 SA 생성 시 Secret이 자동 생성되지 않으며,
kubectl create token 명령 등을 통해 명시적으로 생성해야 합니다.
Secret에는 다음 정보가 포함됩니다.
- ca.crt: API 서버의 공개 인증서
- namespace: SA가 속한 네임스페이스
- token: JWT 토큰으로, 인증 시 사용됨
특정 REST API 경로(/logs, /metrics 등)는 기본 SA로는 접근이 제한되어 있어,
별도로 ClusterRole을 설정해줘야 합니다.
3.2 클러스터 내부에서 API 서버 접근
클러스터 내부에서 실행되는 Pod는 kubernetes라는 이름의 내부 Service를 통해 API 서버에 접근할 수 있습니다.
Pod가 생성되면 해당 ServiceAccount의 Secret이 /var/run/secrets/kubernetes.io/serviceaccount 경로에 자동 마운트되며,
이를 통해 인증이 이뤄집니다.
별도 설정이 없다면 기본적으로 default ServiceAccount가 사용됩니다.
3.3 SDK를 활용한 접근
API 서버에 접근하는 방식은 다음 두 가지가 있습니다.
- REST API를 직접 호출
- Kubernetes 공식 SDK (Go, Python, Java 등)를 활용
4. 이미지 레지스트리 접근을 위한 시크릿
ServiceAccount에 이미지 풀(Pull) 권한이 포함된 Secret을 설정해두면,
Pod YAML에서 해당 SA를 serviceAccountName으로 지정했을 때 자동으로 imagePullSecrets가 삽입됩니다.
설정하지 않으면 default SA의 Secret이 마운트되어 사용됩니다.
5. kubeconfig에 SA 인증 정보 설정하기
SA와 연결된 토큰을 kubeconfig의 사용자(user) 항목에 등록하면,
kubectl 명령어도 해당 SA의 권한 범위 내에서 동작하도록 제한할 수 있습니다.
kubeconfig는 크게 아래 3가지 구성으로 되어 있습니다.
- clusters: 클러스터 정보
- users: 인증 정보
- contexts: 클러스터와 사용자의 연결
6. User와 Group의 개념
쿠버네티스는 SA 외에도 User와 Group을 RBAC 대상자로 사용할 수 있습니다.
- 사전에 정의된 시스템 사용자 및 그룹은 system: 접두어를 사용합니다.
예: system:serviceaccount, system:serviceaccounts - YAML에서 kind 항목에 User나 Group을 지정하면 사용할 수 있습니다.
SA vs User
ServiceAccount | User | |
사용 목적 | Pod 등 내부 컴포넌트 인증 | 외부 사용자 인증 |
네임스페이스 | 있음 | 없음 |
Kubernetes 리소스 | 있음 (kind: ServiceAccount) | 없음 (외부에서 관리) |
Group은 여러 User를 묶어 권한을 한 번에 부여할 때 사용됩니다.
7. x.509 인증서를 이용한 사용자 인증
Kubernetes는 설치 시 기본적으로 self-signed 루트 인증서를 생성합니다.
- kubeadm 기준 경로: /etc/kubernetes/pki
- kops 기준 경로: /pki
생성되는 주요 파일은 다음과 같습니다.
- ca.crt: 루트 인증서
- ca.key: 루트 인증서의 개인키
- apiserver.crt: 루트 인증서로 서명된 서버 인증서
기본적으로 kubeconfig 파일에도 인증 정보가 포함되어 있어, x.509 인증서를 기반으로 사용자 인증이 이뤄집니다.
x.509 인증은 보안적으로 강력하지만, 사용자 인증서의 발급·갱신·폐기 관리를 수동으로 해야 하기 때문에
대규모 환경에서는 OIDC 기반 인증이나 외부 인증 서버(GitHub, Google, LDAP 등) 연동이 더 자주 활용됩니다.
마치며
ServiceAccount와 RBAC는 쿠버네티스 보안에서 가장 핵심적인 개념입니다.
클러스터에 대한 권한 모델을 명확하게 설계하고,불필요한 권한은 최소화하며, 필요한 리소스에만 세밀하게 권한을 부여하는 것이 좋을 것 같습니다.
'OPS' 카테고리의 다른 글
DevOps 스터디 - 보안을 위한 인증과 인가 - ServiceAccount와 RBAC #3 (심화) (0) | 2025.05.11 |
---|---|
DevOps 스터디 - 퍼시스턴트 볼륨(PV)과 퍼시스턴트 볼륨 클레임(PVC) #2 (심화) (0) | 2025.05.04 |
DevOps 스터디 - 퍼시스턴트 볼륨(PV)과 퍼시스턴트 볼륨 클레임(PVC) #2 (0) | 2025.05.04 |
Kubernetes Pod와 Deployment 수정 방법 정리 (0) | 2025.04.28 |
DevOps 스터디 - 인그레스(Ingress) #1 (0) | 2025.04.27 |