Creating and Assigning ServiceAccounts
The default ServiceAccount works, but every Pod in the namespace shares it. If you grant that ServiceAccount any permissions, every Pod in the namespace inherits them. That is a real security problem: a compromised Pod could abuse permissions intended for a completely different application. The fix is straightforward: create one dedicated ServiceAccount per application.
Creating a ServiceAccount
Creating a ServiceAccount requires a single command.
kubectl create serviceaccount my-appKubernetes creates a namespaced object called my-app in the current namespace. It has no permissions yet. It is purely an identity. Permissions come from RBAC bindings, which are covered in the RBAC module.
Verify the ServiceAccount exists alongside the automatic default.
kubectl get serviceaccountsYou will see both default and my-app in the list. The AGE column on my-app will be just a few seconds old.
You run kubectl create serviceaccount my-app. What can this ServiceAccount do in the cluster immediately after creation?
Reveal answer
Nothing. A ServiceAccount is an identity with no permissions attached by default. It cannot read, write, or watch any resource until a RoleBinding or ClusterRoleBinding connects it to a Role. Creating the SA is just the first step.
Assigning a ServiceAccount to a Pod
Once the ServiceAccount exists, you declare it in the Pod manifest under spec.serviceAccountName. Open a new file.
nano app-pod.yamlStart with the basic metadata.
apiVersion: v1kind: Podmetadata: name: app-pod namespace: defaultAdd the spec block and put the ServiceAccount name first, before the containers.
spec: serviceAccountName: my-appThen add the container definition below it.
containers: - name: app image: nginx:stableThe complete manifest is ready to apply.
kubectl apply -f app-pod.yamlAfter the Pod starts, inspect its stored spec to confirm the assignment was recorded correctly.
kubectl get pod app-pod -o yamlLook for spec.serviceAccountName: my-app in the output. That field confirms the identity. You will also notice a volumes entry and a corresponding volumeMounts entry added automatically by Kubernetes. That is the projected token volume, which delivers the ServiceAccount credentials into the container filesystem. Lesson 03 explains exactly how that works.
After applying the manifest, which field in kubectl get pod app-pod -o yaml confirms the ServiceAccount assignment?
Try it: kubectl get pod app-pod -o yaml
Reveal answer
The field spec.serviceAccountName: my-app confirms it. The presence of a projected volume mount under spec.volumes and spec.containers[].volumeMounts also confirms that the token injection is active.
What happens when the ServiceAccount does not exist
Here is the failure case you need to understand before working with ServiceAccounts in production.
nano bad-pod.yamlapiVersion: v1kind: Podmetadata: name: bad-pod namespace: defaultspec: serviceAccountName: nonexistent-sa containers: - name: app image: nginx:stablekubectl apply -f bad-pod.yamlThe API server may accept the manifest and create the Pod object, but the Pod will never reach Running status. The kubelet requires the referenced ServiceAccount to exist before it can set up the token volume. The Pod stays in Pending with an event describing the missing ServiceAccount. Always verify that the ServiceAccount exists before applying a Pod that references it. Use kubectl get serviceaccounts to confirm before you apply.
Check the Pod status after applying.
kubectl get pod bad-podThe STATUS column will not show Running. Describe the Pod to see the events explaining why.
kubectl describe pod bad-podThe events section will contain the reason. This is a common source of confusion when deploying to a new namespace where the required ServiceAccount was not yet created.
You apply a Pod manifest that references serviceAccountName: nonexistent-sa, but that SA was never created. What is the most likely outcome?
- The Pod uses the
defaultServiceAccount as a fallback - The Pod object is created but stays in Pending because the SA is missing
- The
kubectl applycommand fails immediately with a validation error
Reveal answer
The Pod object is created but stays in Pending. The API server does not validate foreign key references at admission time by default, so the manifest is accepted. It is the kubelet that cannot proceed because the token volume cannot be prepared without the SA.
A dedicated ServiceAccount per application, explicitly assigned in the Pod spec, is the foundation of workload identity in Kubernetes. Now that you can create and assign ServiceAccounts, lesson 03 explains how Kubernetes delivers the actual token into the container filesystem through a projected volume.