[CKA] ServiceAccount
ServiceAccount의 핵심 개념과 구성 방법, 실습 풀이를 정리합니다.
쿠버네티스 계정에는 두 가지 유형이 있습니다.
사용자 계정은 사람이 사용하고 서비스 계정은 다른 서드 파티같은 서비스들이 사용합니다.
사용자 계정 예시)
관리 작업을 수행하기 위해 클러스터에 접근하는 Admin이 될 수 있고 응용 프로그램 배포 등을 위해 개발자가 클러스터에 접근하는 Developer가 있다.
서비스 계정 예시)
모니터링 어플리케이션을 통해 쿠버네티스 API의 성능을 뽑아내는 Prometheus, 자동화된 빌드 툴을 이용해 쿠버네티스 클러스터에 응용 프로그램을 배포하는 Jenkins
응용 프로그램이 Kubernetes API를 호출하려면 인증이 필요합니다. 현재 Kubernetes에서는 ServiceAccount를 생성해도 장기 토큰 Secret이 자동 생성되지 않습니다.
Pod는 기본적으로 TokenRequest로 발급된 짧은 수명의 회전 토큰을 projected volume으로 받습니다. 외부 애플리케이션에 토큰이 필요하면 kubectl create token으로 필요한 기간의 토큰을 발급하는 방식을 우선 사용합니다.
또한 쿠버네티스의 모든 네임스페이스에는 default라고 명명된 Service Account가 자동으로 생성됩니다.
ServiceAccount를 지정하지 않은 Pod는 해당 네임스페이스의 default ServiceAccount를 사용하며, 별도로 비활성화하지 않으면 짧은 수명의 토큰이 잘 알려진 경로에 마운트됩니다.
Pod 안의 /var/run/secrets/kubernetes.io/serviceaccount에서 토큰, CA 인증서와 네임스페이스 정보를 확인할 수 있습니다. 현재 기본 토큰은 장기 Secret 토큰이 아니라 projected volume으로 제공됩니다.
ServiceAccount의 권한은 RBAC 등 인가 설정으로 결정됩니다. default ServiceAccount라고 해서 관리자 권한이 자동 부여되는 것은 아닙니다.
다른 Service Account를 사용하고 싶다면 파드 정의 파일을 수정해서 serviceAccountName 필드가 새로운 Service Account의 이름을 참조하도록 해야한다.
기존 파드의 Service Account는 수정할 수 없기 때문에 파드를 삭제하고 다시 만들어야 한다.
하지만 deployment의 경우, 파드 정의 파일에 변화가 생기면 자동으로 deployment를 위해 rollout하기 때문에 새로운 Service Account으로 새 파드를 삭제하고 재생성한다.
쿠버네티스에서 아무것도 명시하지 않으면 자동으로 default Service Account를 마운트한다는 것을 명심해라!!
automountServiceAccountToken 필드를 false로 설정하면 Service Account를 자동으로 마운트하지 않는다.
과거 동작과 1.22·1.24 이후의 변화
과거에는 ServiceAccount마다 만료되지 않는 토큰 Secret을 자동 생성하고 Pod에 마운트했습니다.
파드 정의에서 Mounts 된 항목을 확인해볼 수 있습니다.
JWT payload를 로컬에서 디코딩해보면 이 과거 방식의 토큰에는 만료 시각이 없습니다. 토큰 Secret이나 ServiceAccount를 삭제하는 등의 별도 폐기가 필요합니다. 더구나 각 JWT는 서비스 당 개별 Secret 개체를 요구하여 확장성 문제가 발생합니다.
버전 1.22부터 Pod는 TokenRequest API로 발급한 짧은 수명의 bound token을 projected volume으로 받는 방식이 기본이 되었습니다.
TokenRequest API에서 생성된 토큰은 audience, 시간과 객체에 묶을 수 있습니다. 버전 1.22 이후 새 Pod는 ServiceAccount의 장기 Secret token 대신 정해진 만료 시간이 있는 토큰을 volume으로 받습니다.
버전 1.24부터 ServiceAccount를 만들 때 장기 토큰 Secret이 자동으로 생성되지 않습니다. 필요하면 ServiceAccount 이름을 지정해 kubectl create token으로 짧은 수명의 토큰을 발급합니다.
생성한 토큰을 해독해보면 시간 ‘exp’ 만료 날짜가 정의되어 있다. 시간 제한을 명시하지 않았다면 보통 1시간으로 제한한다. 명령에 추가 옵션을 전달해 토큰의 만료 기간을 늘릴 수도 있다.
버전 1.24에서 옛날 방식으로 Secret token을 이용한 service account를 만들고 싶다면 Secret 정의 파일을 통해 만들 수 있다. kind: Secret, type: kubernetes.io/service-account-token을 지정합니다. metadata.annotations 아래 kubernetes.io/service-account.name에 ServiceAccount 이름을 명시합니다.
서비스 계정을 먼저 생성하고 그 다음에 Secret을 생성하기 때문에 secret 개체가 특정 service account와 연결되는 것이다.
그래서 service-account-token 타입으로 secret을 만들면 service account와 관련된 secret 개체에 만료되지 않는 토큰을 생성할 것이다.
kubectl create token <service-account-name> --duration=24h
- 자동 토큰 순환:
- kubelet이 토큰이 만료되기 전에 자동으로 새 토큰을 요청합니다.
- 파드에 마운트된 토큰은 자동으로 업데이트됩니다.
- 이는 애플리케이션의 중단 없이 토큰이 갱신됨을 의미합니다.
Pod에 projected volume으로 마운트된 토큰은 kubelet이 회전시킵니다. 외부에서 발급한 토큰은 애플리케이션의 사용 기간과 갱신 방식을 별도로 설계해야 합니다.
Deployment에서는 Pod 템플릿의 spec에 serviceAccountName을 지정합니다. 다음은 기존 Deployment에 넣을 필드 부분입니다.
spec:
template:
spec:
serviceAccountName: dashboard-sa
kubectl create serviceaccount dashboard-sa
kubectl set serviceaccount deploy/web-dashboard dashboard-sa
kubectl get pods
kubectl describe pod <pod-name>