はじめに
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.
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





