Introduction to Service Accounts
Service Accounts in Kubernetes are special accounts used by Pods (not humans) to interact with the Kubernetes API. Unlike regular user accounts that may be managed externally, Service Accounts are managed within the Kubernetes cluster.
Creating and Managing Service Accounts
To create a new service account, you can use the kubectl
command:
kubectl create serviceaccount my-service-account
You can also create it using a YAML file:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
Apply it using:
kubectl apply -f service-account.yaml
Using Service Accounts with Pods
By default, Pods use the default
service account within their namespace. To specify a different service account, set the serviceAccountName
field in the Pod specification.
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-service-account
containers:
- name: my-container
image: my-image
RBAC and Service Accounts
Role-Based Access Control (RBAC) can be applied to service accounts to define what actions they can perform. You can bind a Role or ClusterRole to a Service Account using a RoleBinding or ClusterRoleBinding.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: my-service-account
namespace: default
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: pod-reader
Tokens Related to Service Accounts
When a service account is created, a secret containing a token is automatically generated and associated with the service account. This token is used to authenticate the service account when interacting with the Kubernetes API.
Viewing Tokens
To view the token for a service account, first find the associated secret:
kubectl get serviceaccounts my-service-account -o jsonpath='{.secrets[*].name}'
Then, to view the token, describe the secret:
kubectl get secret [SECRET_NAME] -o jsonpath='{.data.token}' | base64 --decode
Mounting Tokens to Pods
The service account token is automounted to /var/run/secrets/kubernetes.io/serviceaccount/
in each Pod using that service account. To disable this, use automountServiceAccountToken
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-service-account
automountServiceAccountToken: false
...
Best Practices and Considerations
- Least Privilege: Only grant the permissions necessary for the service account to perform its tasks.
- Audit: Regularly review and audit permissions for service accounts.
- Namespace Isolation: Use different service accounts for different namespaces.
- Token Review: Service account tokens are long-lived; rotate them or set expiration where applicable.
- Automate Management: Automate the creation, deletion, and permissions management for service accounts.
Troubleshooting Exercise
Setup Commands
Create a service account and a Pod that uses it:
kubectl create serviceaccount troubleshooting-sa
kubectl run troubleshooting-pod --image=busybox --serviceaccount=troubleshooting-sa -- sleep 3600
Exercise
Your Pod is not able to read ConfigMaps, even though it should have the permission.
Debugging Steps
-
Check the service account token mounted in the Pod.
kubectl exec -it troubleshooting-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
-
Check the Role and RoleBinding for the service account.
kubectl get role,rolebinding -o yaml
Solution
Make sure the service account is properly bound to a Role that has permission to read ConfigMaps:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-configmaps
subjects:
- kind: ServiceAccount
name: troubleshooting-sa
namespace: default
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: configmap-reader
Apply the changes:
kubectl apply -f role-and-rolebinding.yaml