This article provides a comprehensive guide on service accounts in Kubernetes, focusing on their creation, management, and security features.
Welcome to this comprehensive guide on service accounts in Kubernetes. In this article, we will explain how to work with service accounts—an essential mechanism that enables applications and machines to interact securely with the Kubernetes API. While Kubernetes includes various security features, such as authentication, authorization, and role-based access controls, this guide specifically focuses on service accounts to support application development. For more details on broader security topics, please refer to the CKA Certification Course - Certified Kubernetes Administrator.
User Account: Used by humans (e.g., administrators or developers).
Service Account: Used by applications or machines (e.g., monitoring tools like Prometheus or CI/CD systems like Jenkins).
Consider a simple example of a Kubernetes dashboard written in Python. The dashboard queries the Kubernetes API to list all Pods and displays the output on a web interface. To authenticate with the Kubernetes API, the dashboard leverages a service account.
To create a service account for your application, run the following command. In this example, we create a service account named dashboard-sa:
Copy
Ask AI
kubectl create serviceaccount dashboard-sa
After creation, view all service accounts in the current namespace using:
Copy
Ask AI
kubectl get serviceaccount
When a service account is created, Kubernetes automatically generates a token and stores it as a Secret object. This token is then used by your application for API authentication. An example output could be:
Copy
Ask AI
kubectl create serviceaccount dashboard-sa# Output:kubectl get serviceaccount# Output:# NAME SECRETS AGE# default 1 218d# dashboard-sa 1 4d
You can inspect the details of the service account, including the token, by running:
Copy
Ask AI
kubectl describe serviceaccount dashboard-sa
This command provides information similar to the following:
If your third-party application is deployed within the Kubernetes cluster (for example, a custom dashboard or Prometheus), Kubernetes can automatically mount the service account token as a volume inside the pod. This simplifies token management since the token becomes immediately accessible without manual intervention.
By default, every Kubernetes namespace contains a default service account. When a pod is created without specifying a service account, Kubernetes mounts the default service account’s token automatically. Consider the following pod definition for a custom Kubernetes dashboard application:
If you prefer to use the dashboard-sa service account created earlier, update your pod specification as shown below. Note that changing the service account for a running pod requires deletion and recreation. Deployments, however, automatically trigger a rollout when updated:
After deployment, verify the pod uses the new service account:
Copy
Ask AI
kubectl describe pod my-kubernetes-dashboard
The volume mount should now reference dashboard-sa-token-kbbdm.If you wish to prevent the automatic mounting of a service account token, set the field automountServiceAccountToken: false as shown:
Before Kubernetes v1.22, every service account was automatically associated with a Secret containing an unbounded token without an expiry date. For example:
Copy
Ask AI
kubectl get serviceaccount# Output:# NAME SECRETS AGEkubectl describe pod my-kubernetes-dashboard# (Output shows the secret mounted as described above)
With Kubernetes v1.22, the token request API was introduced (KEP 1205). Tokens generated via this API are:
Audience-bound
Time-bound
Object-bound
When a pod is created now, Kubernetes communicates with the token controller API to produce a token with a defined lifetime. The following example demonstrates a pod definition using a projected volume:
Starting with Kubernetes v1.24, service accounts no longer automatically create a Secret with an unbounded token. Instead, you need to generate a token explicitly through the token request API:
Copy
Ask AI
kubectl create token dashboard-sa
This command outputs a token with an expiry (default is one hour unless configured otherwise). To inspect token details, you can decode it using tools such as JWT.io or by running:
If you decide to revert to the old method of manually creating a Secret, you can do so by defining a Secret with the type kubernetes.io/service-account-token and adding the appropriate annotation:
Ensure that the service account exists before creating the Secret to guarantee proper association. However, the recommended practice is to utilize the token request API for better security and token management.
The diagram above illustrates how tokens without an expiry can cause security and scalability concerns; these issues are mitigated by the token request API.
With Kubernetes v1.22 and later, tokens are audience-bound and time-bound, eliminating issues associated with indefinitely valid tokens. Kubernetes v1.24 further refines this approach by minimizing non-expiring secret-based tokens in favor of tokens generated via the token request API.
Below is an additional example of a pod using a projected volume, reflecting the token generation via the token request API:
Prior to these enhancements, the service account token was mounted as a traditional Secret. Today, it is provided as a projected volume that interacts dynamically with the token controller API.
If you require a non-expiring token and are aware of the security implications, you can create a Secret manually. However, using the token request API is strongly recommended for enhanced security.
To generate a token using this approach, run:
Copy
Ask AI
kubectl create token dashboard-sa
This command returns a token with a defined lifetime, ensuring higher security standards.
For further information on these changes, please consult the following resources: