はじめに
Service Accountについて、動かしながら基本的な部分を理解していきたいと思います。
ServiceAccountとは
サービスアカウント(Service Account)は、Kubernetes内で管理されているアカウントで、Podと紐づけることでPodからKubernetesAPIを操作できるようになります。

【Kubernetes】ユーザー管理について理解する
はじめに Kubernetesのユーザーについてざっくりまとめて、実際にユーザーを作成(?)して
Service Accountは、Podに紐づいたAPIの認証情報であるtokenを利用して、PodからKubernetesAPIを利用します。
ver1.24から、今まで自動で作成されていたtoken用のSecretが作成されなくなり、Pod内にtokenが紐付くようになったようです。
kubernetes/CHANGELOG/CHANGELOG-1.24.md at master · kubernetes/kubernetes
Production-Grade Container Scheduling and Management - kubernetes/kubernetes

Secrets
A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in a container image. Using a Secret means that you don't need to include confidential data in your application code. Because Secrets can be created independently of the Pods that use them, there is less risk of the Secret (and its data) being exposed during the workflow of creating, viewing, and editing Pods.
Service account secret is not listed. How to fix it?
I have used kubectl create serviceaccount sa1 to create service account. Then I used kubectl get serviceaccount sa1 -oyaml command to get service account info. But it returns as below. apiVersion: v1
defaultのServiceAccount
まずは、各Namespaceにデフォルトで作成されるdefaultというServiceAccountについて、確認していきます。
1❯ kubectl get sa
2NAME SECRETS AGE
3default 0 4h39m
4
5
6❯ kubectl describe sa default
7Name: default
8Namespace: default
9Labels: <none>
10Annotations: <none>
11Image pull secrets: <none>
12Mountable secrets: <none>
13Tokens: <none>
14Events: <none>自分で作成していないdefaultというServiceAccountが確認できます。また、SECRETSの列が0になっており、tokenも紐づいていなくなっていることがわかります。
defaultのServiceAccountとPod
このdefaultというアカウントがどのように使われているか確認します。
まず、簡単なPodを作成します。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: nginx
5spec:
6 containers:
7 - image: nginx
8 name: nginx1kubectl apply -f nginx.yml作成されたPodをyaml形式で確認してみます。
1❯ kubectl get pod
2NAME READY STATUS RESTARTS AGE
3nginx 1/1 Running 0 19s
4
5
6❯ kubectl get pod nginx -o yaml
7apiVersion: v1
8kind: Pod
9
10...
11
12spec:
13 containers:
14 - image: nginx
15 imagePullPolicy: Always
16 name: nginx
17
18 ...
19
20 volumeMounts:
21 - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
22 name: kube-api-access-d9mtw
23 readOnly: true
24
25 ...
26
27 serviceAccount: default
28 serviceAccountName: default
29
30 ...
31
32 volumes:
33 - name: kube-api-access-d9mtw
34 projected:
35 defaultMode: 420
36 sources:
37 - serviceAccountToken:
38 expirationSeconds: 3607
39 path: token
40
41...defaultのServiceAccountが自動で利用されており、token用のボリュームがマウントされていることが確認できます。
マウントされているtokenのファイルを見てみます。
1❯ kubectl exec -it nginx -- ls /var/run/secrets/kubernetes.io/serviceaccount
2ca.crt namespace token
3
4
5❯ kubectl exec -it nginx -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
6eyJhbGciOiJSUzI1NiIsImtpZCI6InF2TDhTTHNtenhubFpZcnpwbU5UV2hOSjlYWHpyY0loNzdDREJIZGdwa0kifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg2NDU5ODk1LCJpYXQiOjE2NTQ5MjM4OTUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJuZ2lueCIsInVpZCI6IjkwZmYxNjM0LTBkZWEtNDViOC04OWU2LWY5YzBlYjI2NDE0YyJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6Ijk2MDE0NzE0LWViOTctNDEyYy1hYjZlLWYzY2FjZjEwNDQ3ZSJ9LCJ3YXJuYWZ0ZXIiOjE2NTQ5Mjc1MDJ9LCJuYmYiOjE2NTQ5MjM4OTUsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.tRGnrq3F0zVDZGk_lquPVsApIGtRkxxJWs_dvD3kUcktqdwtkT3nUKt5nr7RwJEA__O7yL3PmbdMqD0HevulnOyTQouoA3Ieu7Q8w539KmBJfXozB-1vzmi0XJVExv7SAx3JfOA-QQRn9I_CQSQXuZkXRnypWZ_i15uNMsC2CskEyW3UuwbVl0O79rI7p6OWT1pusmuPjBZCLF9c6ZgsC3bqbFihaXkU8_fmkGyuF4JQy6EqxCwYOmestCgYAVM9uYtA_yavwcNnqgDOctUKQeftcIvKxThNx2cQDaDe1a6RrnWvE6jytCFH9lLsohsS2zbQPl-uFYW73tnLjw4rlQtoken用のファイルがあり、その中にJWTが記述されています。
試しにデコードすると、tokenの内容が確認できます。
1❯ jwt decode "eyJhbGciOiJSUzI1NiIsImtpZCI6InF2TDhTTHNtenhubFpZcnpwbU5UV2hOSjlYWHpyY0loNzdDREJIZGdwa0kifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg2NDU5ODk1LCJpYXQiOjE2NTQ5MjM4OTUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJuZ2lueCIsInVpZCI6IjkwZmYxNjM0LTBkZWEtNDViOC04OWU2LWY5YzBlYjI2NDE0YyJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6Ijk2MDE0NzE0LWViOTctNDEyYy1hYjZlLWYzY2FjZjEwNDQ3ZSJ9LCJ3YXJuYWZ0ZXIiOjE2NTQ5Mjc1MDJ9LCJuYmYiOjE2NTQ5MjM4OTUsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.tRGnrq3F0zVDZGk_lquPVsApIGtRkxxJWs_dvD3kUcktqdwtkT3nUKt5nr7RwJEA__O7yL3PmbdMqD0HevulnOyTQouoA3Ieu7Q8w539KmBJfXozB-1vzmi0XJVExv7SAx3JfOA-QQRn9I_CQSQXuZkXRnypWZ_i15uNMsC2CskEyW3UuwbVl0O79rI7p6OWT1pusmuPjBZCLF9c6ZgsC3bqbFihaXkU8_fmkGyuF4JQy6EqxCwYOmestCgYAVM9uYtA_yavwcNnqgDOctUKQeftcIvKxThNx2cQDaDe1a6RrnWvE6jytCFH9lLsohsS2zbQPl-uFYW73tnLjw4rlQ"
2
3Token header
4------------
5{
6 "alg": "RS256",
7 "kid": "qvL8SLsmzxnlZYrzpmNTWhNJ9XXzrcIh77CDBHdgpkI"
8}
9
10Token claims
11------------
12{
13 "aud": [
14 "https://kubernetes.default.svc.cluster.local"
15 ],
16 "exp": 1686459895,
17 "iat": 1654923895,
18 "iss": "https://kubernetes.default.svc.cluster.local",
19 "kubernetes.io": {
20 "namespace": "default",
21 "pod": {
22 "name": "nginx",
23 "uid": "90ff1634-0dea-45b8-89e6-f9c0eb26414c"
24 },
25 "serviceaccount": {
26 "name": "default",
27 "uid": "96014714-eb97-412c-ab6e-f3cacf10447e"
28 },
29 "warnafter": 1654927502
30 },
31 "nbf": 1654923895,
32 "sub": "system:serviceaccount:default:default"
33}ServiceAccountを作成する
次は、自分でServiceAccountを作成してみます。
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: test-sa1kubectl apply -f test-sa.ymltest-saというServiceAccountが作成できました。Secretもtokenも紐付いていません。
1❯ kubectl get sa
2NAME SECRETS AGE
3default 0 5h18m
4test-sa 0 6m37s
5
6
7❯ kubectl describe sa test-sa
8Name: test-sa
9Namespace: default
10Labels: <none>
11Annotations: <none>
12Image pull secrets: <none>
13Mountable secrets: <none>
14Tokens: <none>
15Events: <none>作成したServiceAccountをPodに紐付ける
作成したtest-saにRoleをつけて、Podに紐付けて、動きを見ていきます。
作成するRoleはPodの読み取り権限です。RoleBindingを使って、test-saにRoleを付与します。
1apiVersion: rbac.authorization.k8s.io/v1
2kind: Role
3metadata:
4 name: role-pod-read
5 namespace: default
6rules:
7 - apiGroups: [""]
8 resources: ["pods"]
9 verbs: ["get", "watch", "list"]
10---
11apiVersion: rbac.authorization.k8s.io/v1
12kind: RoleBinding
13metadata:
14 name: service-account-rolebinding
15 namespace: default
16subjects:
17 - kind: ServiceAccount
18 name: test-sa
19roleRef:
20 kind: Role
21 name: role-pod-read
22 apiGroup: rbac.authorization.k8s.io1kubectl apply -f role.yml次に、test-saを紐づけるPodを作成します。kubectl get podを実行するコンテナになります。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: kubectl-pod
5spec:
6 containers:
7 - image: bitnami/kubectl
8 name: kubectl
9 command:
10 - sh
11 - -c
12 - |
13 while true
14 do
15 kubectl get pod
16 sleep 30
17 done
18 serviceAccountName: test-sa1kubectl apply -f kubectl-pod.ymlログを確認すると、kubectl get podが実行できていることが確認できます。
1❯ kubectl logs kubectl-pod
2NAME READY STATUS RESTARTS AGE
3kubectl-pod 0/1 ContainerCreating 0 4s
4nginx 1/1 Running 0 51m
5NAME READY STATUS RESTARTS AGE
6kubectl-pod 1/1 Running 0 34s
7nginx 1/1 Running 0 51m
8NAME READY STATUS RESTARTS AGE
9kubectl-pod 1/1 Running 0 64s
10nginx 1/1 Running 0 52m試しに、kubectl get deployに変更してみると、下記のようなエラーになります。
1❯ kubectl logs kubectl-pod
2Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:test-sa" cannot list resource "deployments" in API group "apps" in the namespace "default参考
- Configure Service Accounts for Pods | Kubernetes
- Secrets | Kubernetes
- kubernetes - Service account secret is not listed. How to fix it? - Stack Overflow
- kubernetes/CHANGELOG-1.24.md at master · kubernetes/kubernetes
- BIG change in K8s 1.24 about ServiceAccounts and their Secrets | by Kim Wuestkamp | May, 2022 | ITNEXT
- ContainerSolutions/kubernetes-examples: Minimal self-contained examples of standard Kubernetes features and patterns in YAML
- bitnami/kubectl - Docker Image | Docker Hub





