본문 바로가기

Container/Kubernetes

[K8S] Service Account(SA)

Service Account는 클러스터 내에서 애플리케이션이 실행될 때 사용되는 특별한 종류의 계정이다.

일반 사용자 계정과 달리, 서비스 계정은 사람을 위한 것이 아니라 애플리케이션이나 서비스를 위한 것이다. 이 계정은 Kubernetes API 서버와 상호 작용할 때 인증에 사용된다.

 

  1. 기본 제공: Kubernetes는 각 네임스페이스에 기본 서비스 계정을 자동으로 생성한다. 이 기본 서비스 계정은 default라는 이름을 가지며, 네임스페이스 내에서 실행되는 모든 파드는 기본적으로 이 계정을 사용한다.
  2. 인증: 서비스 계정은 토큰을 사용하여 Kubernetes API에 인증합니다. 이 토큰은 파드 내의 파일 시스템에 자동으로 마운트되며, 애플리케이션은 이를 사용하여 API 요청을 인증할 수 있다.
  3. 권한: 서비스 계정에 부여된 권한은 Role 및 RoleBinding(혹은 클러스터 범위에서는 ClusterRole 및 ClusterRoleBinding)을 통해 관리된다. 이를 통해 서비스 계정이 클러스터 내에서 수행할 수 있는 작업을 제어할 수 있다.
  4. 다양한 사용 사례: 서비스 계정은 여러 가지 용도로 사용될 수 있다. 예를 들어, 클러스터 내에서 실행되는 애플리케이션이 Kubernetes API에 접근해야 하는 경우, 해당 애플리케이션은 서비스 계정을 통해 인증을 수행할 수 있다.
  • SA의 역할
    • Pod가 Kubernetes API를 사용할 수 있도록 인증 제공
    • RBAC(Role-Based Access Control)와 결합하여 권한 제한 가능
    • Pod가 자동으로 Service Account의 토큰을 사용하여 API 요청 가능
      • ServiceAccount에 연결된 Secret을 통해 인증 토큰이 주입된다.
  • Pod가 생성될 때마다 default Service Account와 Token이 자동으로 Pod에 Volume mount로 붙는다.
$ kubectl get serviceaccount
NAME      SECRETS   AGE
default   0         3m54s   # SECRETS : 연결된 Secret 개수

# Mount되는 포인트
$ ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt     namespace  token
  • Pod에서 Service Account 확인 가능하다.
controlplane ~ ➜  kubectl describe pod web-dashboard-66d58fc7b8-kc825 
Name:             web-dashboard-66d58fc7b8-kc825
Namespace:        default
Priority:         0
Service Account:  default
Node:             controlplane/192.168.187.171
Start Time:       Mon, 03 Feb 2025 09:28:01 +0000
Labels:           name=web-dashboard
                  pod-template-hash=66d58fc7b8
...
Containers:
  web-dashboard:
    Container ID:   containerd://650a85edad9b9b84d0638179ab2456f1486899d14dcb8f3fed49d16e07ae1606
    Image:          gcr.io/kodekloud/customimage/my-kubernetes-dashboard
    Image ID:       gcr.io/kodekloud/customimage/my-kubernetes-dashboard@sha256:7d70abe342b13ff1c4242dc83271ad73e4eedb04e2be0dd30ae7ac8852193069
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 03 Feb 2025 09:28:04 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      PYTHONUNBUFFERED:  1
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7hrt2 (ro) # SA가 Mount된 곳 확인
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-7hrt2:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

 

  • Service Account 생성
$ kubectl create serviceaccount dashboard-sa
serviceaccount/dashboard-sa created
# 새롭게 추가된 SA에 additional permission 추가.

# authorization token 생성
$ kubectl create token dashboard-sa
eyJhbGciOiJSUzI1NiIsImtpZCI6IjVhX0lGM2hBQ1ZzdGRCSDc2dWNMaXZnOHhTMjV3MFpwZWJiN0E1cnRSOVEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzM4NTc5NTk1LCJpYXQiOjE3Mzg1NzU5OTUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiYjc2MDJlOTUtYzU5OS00NmJlLWJjYjUtNzljYTA1NGYxZDY4Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImRhc2hib2FyZC1zYSIsInVpZCI6IjYxMjM5ODk3LTMyZDctNGM3OC05ODdjLTJiOGNlZjdkN2IxNCJ9fSwibmJmIjoxNzM4NTc1OTk1LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkYXNoYm9hcmQtc2EifQ.BsPVqoGReNphYbAoXPrQg-tFVagOvj7hiUwbO3XyCXfVcQjIQkDUw7u78M5c6FYyXplKjNB3Ofq3D9ds7WpdZGxTyOSvv-PuxlGmIk33U3EgaCvIoHRBCwDbhC7D-5_2g-21cRjNmFyBZwUYya74XaqOZ9E0gWj577-VqyuXfuggew3vMpMHdytB8iwChBXtc4hl9aPjGcJZuy1POd-RakfFRVdfG1Begh9rRvEtJqMa3cqnNT5-r4KV1RtqKDVh69-PELQK4D4PbOi4WN1bjB7sGc-ttFND43Cw80l57HC3Rm5vrGu7a4z4FoWIaGYNZnYL7_WSz3OThGGKs1QT_g

# default 에서 dashboard-sa로 SA 변경하기 위해 Deployment edit하기
# spec의 serviceAccountName:
$ vi dashboard.yaml
..
    spec:
      serviceAccountName: dashboard-sa 
      containers:
      - env:
        - name: PYTHONUNBUFFERED
          value: "1"
        image: gcr.io/kodekloud/customimage/my-kubernetes-dashboard
        imagePullPolicy: Always
        name: web-dashboard
        
# 적용하기
$ kubectl apply -f dashboard.yaml 
Warning: resource deployments/web-dashboard is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
deployment.apps/web-dashboard configured  # Warning은 무시해도 된다.

# 성공적으로 조회되는 것 확인
$ kubectl get deployments
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
web-dashboard   1/1     1            1           27m

 

  • Pod 확인 Service Account는 API 접근 권한이 거의 없음 👉 RBAC(Role-Based Access Control)을 사용하여 필요한 권한을 부여해야 한다.

 

반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] Image Security  (0) 2025.02.03
[K8S] ClusterRole/ClusterRoleBinding  (0) 2025.02.03
[K8S] api-resources  (0) 2025.01.23
[K8S] Authorization  (1) 2025.01.20
[K8S] Certificates API  (0) 2025.01.13