[CKS] 1-4. Service Accounts

K8s 애플리케이션의 API 접근, 서비스 어카운트 활용 방법과 자동화된 토큰 관리로 클러스터 상호작용의 보안과 효율성을 동시에 높입니다.

개요

Service Accounts 인증, 인가, 역할 기반 접근 제어 등 다른 접근 제어 방식과 연결되어있지만, 시험을 위해선 서비스 어카운트 자체를 k8s에서 사용하는 방법을 학습해야합니다.

Account의 종류

k8s에서는 두 가지 유형의 계정이 존재합니다.

  1. User Account
    1. 사용자가 사용하는 계정
      1. 클러스터에 접근하여 관리 작업을 수행하거나, 개발자가 클러스터에 접근하여 애플리케이션을 배포합니다.
  2. Service Account
    1. 머신이 사용하는 계정
      1. 애플리케이션이 상호작용하기 위해 사용하는 계정
        1. 프로메테우스같이 모니터링 애플리케이션의 경우 Metric 지표를 가져오기 위해 사용
        2. Jenkins 같이 클러스터에 애플리케이션을 배포하기 위해 사용

Service Account

Service Account는 생성될 때 Secret을 같이 생성합니다. 해당 토큰을 가지고 마찬가지로 bearer로 등록하여 요청을 수행할 수 있습니다.

kubectl create serviceaccount dashboard-sa

kubectl describe serviceaccount dashboard-sa
----------------------------------------------
Name:                dashboard-sa
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   dashboard-sa-token-kbbdm
Tokens:              dashboard-sa-token-kbbdm
Events:              <none>
kubectl describe secret dashboard-sa-token-kbbdm

----------------------------------------------
Name:         dashboard-sa-token-kbbdm
Namespace:    default
Labels:       <none>
Type:         kubernetes.io/service-account-token


Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Ij...
curl https://192.168.56.70:6443/api -insecure \
  --header "Authorization: Bearer eyJhbgG..."

서드파티 애플리케이션이 클러스터 자체에 호스팅되어있다면 서비스 계정 토큰을 내보내고 설정하는 과정이필요없습니다. Pod 내부에 서비스 토큰을 볼륨으로 마운트하여 자동으로 수행하게 만들 수 있습니다.

이렇게하면 토큰이 이미 Pod 내부에 배치되어 애플리케이션이 쉽게 읽을 수 있습니다.

또한 각 Namespace에는 고유한 default 계정이 존재합니다. 이후 namespace에 파드가 생성될 때마다 자동으로 토큰이 파드에 볼륨으로 마운트되어 연결됩니다. Volumes에 Secret을 포함하며 /var/run/secrets/kubernetes.io/serviceaccount 위치에 마운트됩니다.

해당 위치에서 사용될 토큰을 확인할 수 있습니다. 다만 매우 제한적으로 설정되어 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: my-kubernetes-dashboard
spec:
  containers:
    - name: my-kubernetes-dashboard
      image: my-kubernetes-dashboard
----------------------------------------------

Name:           my-kubernetes-dashboard
Namespace:      default
Annotations:    <none>
Status:         Running
IP:             10.244.0.15
Containers:
  my-kubernetes-dashboard:
    Image:      my-kubernetes-dashboard
Mounts:
  /var/run/secrets/kubernetes.io/serviceaccount from default-token-j4hkv (ro)
Volumes:
  default-token-j4hkv:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-j4hkv
    Optional:    false

커스텀 Service Account를 등록하려는 경우, 해당 Service Account의 이름을 지정하면 됩니다. 하지만 기억해야할 것은 Service Account는 Edit할 수 없고 반드시 삭제 후 생성해야합니다. Deployment의 경우 자동으로 새로운 Rollout을 트리거하기 때문에 Deployment를 통한 작업을 권장합니다.

1.22 / 1.24 Service Account Secret & Token 변경 사항

정리하면 다음과 같습니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: kube-api-access-6mtg8
          readOnly: true
  volumes:
    - name: kube-api-access-6mtg8

      projected:
        defaultMode: 420
        sources:
          - serviceAccountToken:
              expirationSeconds: 3607
              path: token

          - configMap:
              name: kube-root-ca.crt
              items:
                - key: ca.crt
                  path: ca.crt
          - downwardAPI:
              items:
                - fieldRef:
                    apiVersion: v1
                    fieldPath: metadata.namespace
kubectl create token <서비스_어카운트_이름> -n <네임스페이스> [--audience <청중>] [--duration <유효기간>]

Hands on

kubectl set serviceaccount deploy/web-dashboard dashboard-sa
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /var/run/secrets/tokens
      name: vault-token
  serviceAccountName: build-robot
  volumes:
  - name: vault-token
    projected:
      sources:
      - serviceAccountToken:
          path: vault-token
          expirationSeconds: 7200
          audience: vault