Service Account
December 25, 2025
Service Account
개념
- 이전까지는 사람이 클러스터에 접근할 때, 인증서 등의 방법으로 접근하는 방식을 다루었다.
ServiceAccount는 사람 외의 리소스(예: 봇, 애플리케이션)이 쿠버네티스 API와 통신할 때 사용하는 리소스이다.- 예:
Prometheus: 클러스터 성능 지표를 수집하기 위해 API 서버와 통신Jenkins: 애플리케이션 배포를 위해 클러스터에 접근할 때 API 서버와 통신
헷갈릴 수 있는 부분
- User(쿠버네티스 리소스는 아님)와
ServiceAccount는 각각 'Authentication(인증)' 방식은 인증서 vs 토큰으로 다르지만, 'Authorization(인가)' 단계에서는 똑같이Role/ClusterRole-RoleBinding/ClusterRoleBinding방식의 RBAC를 사용한다.
인증 방식 (토큰)
- User의 경우 인증서, Static Token File 과 같은 방식으로 인증하였다.
- 하지만,
ServiceAccount는 Token을 통해 인증한다.- 여기서의 Token은 JWT 기반 토큰으로, Static Token File과는 다르다.
ServiceAccount는 API 서버와 통신시 HTTP 헤더에Bearer Token으로 포함하여 전송한다.
기본 동작
쿠버네티스 클러스터가 생성되면 기본적으로 모든 네임스페이스에
default라는 이름의ServiceAccount가 생성된다. (제한적인 권한)
- 자동 할당
Pod가 생성될 때, 별도의ServiceAccount를 지정하지 않는다면,defaultServiceAccount가 할당된다.default는 권한이 제한적이므로 특정 권한이 필요한 경우 별도의 서비스 어카운트를 생성해서 관련 권한에 바인딩해야한다.
- 토큰 마운트
- 쿠버네티스는 자동으로 토큰을 생성하여
Pod내부의Projected Volume에 마운트한다.Projected Volume은Secret,ConfigMap,serviceAccountToken등의 리소스를 동일한 디렉토리에 보관하는 'Pod내부 볼륨'이라고 생각하면 된다.- 경로:
/var/run/secrets/kubernetes.io/serviceaccount/token
- 쿠버네티스는 자동으로 토큰을 생성하여
토큰은 누가 자동갱신하나요?
kubelet이ServiceAccount를 감시하며, 토큰이 만료되기 전에 갱신한다.
생성
Service Account
Imperative
kubectl create serviceaccount dashboard-sa
- yaml 로 생성할 수도 있지만, 넣을 리소스가 많지 않기 때문에 그냥 위처럼 imperative하게 생성하는 것이 빠르다.
Declarative(YAML)
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-sa
namespace: default
automountServiceAccountToken: false
- 하지만, git 등으로 관리해야할 경우 yaml로 저장하는 것이 좋다.
- 만약 토큰이 자동으로 마운트되는 것을 원치않는다면
automountServiceAccountToken: false로 지정하면 된다. (기본값이true)- 주로 정적 웹서버, Job 등의 경우 API 서버와의 통신이 아예 불필요하므로 이 설정을 하는 것이 보안상 좋다.
Pod에 할당
apiVersion: v1
kind: Pod
metadata:
name: my-dashboard-pod
spec:
serviceAccountName: dashboard-sa # 여기에 서비스 어카운트 이름 지정
containers:
- name: my-dashboard
image: my-dashboard-image
automountServiceAccountToken: false
Pod에ServiceAccount를 할당할 때는spec.serviceAccountName필드에 지정하면 된다.automountServiceAccountToken옵션은Pod레벨에서도 지정 가능하다.
외부 접속을 위한 토큰 생성
- CI/CD 툴이나 외부 모니터링 도구처럼 클러스터 외부에서 접속해야 할 때는 수동으로 토큰을 생성해서 이 토큰으로
ServiceAccount의 권한을 가지고 클러스터에 접근해야한다.
kubectl create token <serviceAccount이름>
- 위 명령어로 토큰 값을 출력할 수 있다.
- 기본 유효기간은 1시간이며,
--duration플래그로 연장할 수 있다.
수동 갱신의 불편함 해결방법
- 근데, 외부에서 토큰을 사용할 경우
kubelet이 자동 갱신하지 못하는데, CI/CD 툴이나 외부 모니터링 도구를 사용할 때 위처럼 토큰을 발급받아서 사용한다면 수동으로 갱신해야하는건가? AWS Secret Manager등의 외부 보안 볼트 시스템을 사용하여 토큰을 안전하게 보관하고, 외부 툴은 이 볼트 시스템에 접근하여 토큰을 사용한다.cron job,AWS Lambda등으로 주기적으로 클러스터에 접근하여 새로운 토큰을 발급받는다.
- 이로써 토큰 수명을 짧게 유지함 + 최소 권한 원칙을 동시에 만족시킬 수 있다.
쿠버네티스 버전별 변화
| 구분 | ~ v1.21 (과거) | v1.22 ~ v1.23 (과도기) | v1.24+ (현재) |
|---|---|---|---|
| 서비스 어카운트 생성 시 | 영구 토큰(Secret 객체 형태) 자동 생성됨 | 영구 토큰(Secret) 자동 생성됨 (하지만 파드는 이걸 안 씀) | 영구 토큰(Secret) 생성 안 됨 |
| 파드에 마운트되는 것 | 자동 생성된 Secret | TokenRequest로 받은 단기 토큰 (Projected Volume) | TokenRequest로 받은 단기 토큰 (Projected Volume) |
| 외부 접속용 토큰 | 생성된 Secret 값 복사해서 사용 | 생성된 Secret 값 복사해서 사용 | kubectl create token 명령어로 직접 발급 |
레퍼런스
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
- Udemy - Certified Kubernetes Administrator (CKA) with Practice Tests (Mumshad)