Skip to main content

Chapter 9.2 - Service Accounts

Learning Objectives​

By the end of this chapter, you will be able to:

  • Understand what a Service Account is
  • Create and use Service Accounts
  • Bind Service Accounts to Pods
  • Understand tokens and secrets
  • Manage permissions with RBAC
  • Use Service Accounts for API access

Introduction​

A Service Account provides an identity for Pods running in the cluster. It allows applications to interact with the Kubernetes API securely.


What is a Service Account?​

A Service Account is a Kubernetes identity used by Pods to:

  • Authenticate with the Kubernetes API
  • Access resources according to RBAC permissions
  • Interact with other services in the cluster

By default: Each namespace has a default Service Account.


Creating a Service Account​

Basic Service Account​

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default

Service Account with Annotations​

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-role

Using in a Pod​

Specifying the Service Account​

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-app-sa
containers:
- name: app
image: my-app:1.0

Result: The Pod uses my-app-sa instead of the default Service Account.

Automatic Service Account​

If serviceAccountName is not specified, the Pod uses the default Service Account of the namespace.


Tokens and Secrets​

Automatic Token​

Kubernetes automatically creates a token (Secret) for each Service Account:

# View automatically created secrets
kubectl get secrets | grep my-app-sa

# Token details
kubectl describe secret my-app-sa-token-xxxxx

Token Mounting​

The token is automatically mounted in the Pod at /var/run/secrets/kubernetes.io/serviceaccount/:

# Inside the Pod
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

RBAC Permissions​

Binding a Service Account to a Role​

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: default
roleRef:
kind: Role
name: app-role
apiGroup: rbac.authorization.k8s.io

Complete Example​

Step 1: Create the Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader-sa
namespace: default

Step 2: Create the Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]

Step 3: Create the RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: default
subjects:
- kind: ServiceAccount
name: pod-reader-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

Step 4: Use in a Pod

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
serviceAccountName: pod-reader-sa
containers:
- name: app
image: my-app:1.0

Result: The Pod can read Pods in the default namespace.


Accessing the Kubernetes API​

Using the Token in the Application​

import os
import requests

# Read the token
with open('/var/run/secrets/kubernetes.io/serviceaccount/token', 'r') as f:
token = f.read().strip()

# Read the namespace
with open('/var/run/secrets/kubernetes.io/serviceaccount/namespace', 'r') as f:
namespace = f.read().strip()

# API call
api_url = f"https://kubernetes.default.svc/api/v1/namespaces/{namespace}/pods"
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}

response = requests.get(api_url, headers=headers, verify='/var/run/secrets/kubernetes.io/serviceaccount/ca.crt')
print(response.json())

Image Pull Secrets​

Service Accounts can have imagePullSecrets to access private Docker registries:

apiVersion: v1
kind: ServiceAccount
metadata:
name: private-registry-sa
namespace: default
imagePullSecrets:
- name: regcred

Result: All Pods using this Service Account can pull images from the private registry.


Default Service Account​

Disabling Automatic Mounting​

apiVersion: v1
kind: ServiceAccount
metadata:
name: no-token-sa
namespace: default
automountServiceAccountToken: false

Result: The token is not mounted in Pods using this Service Account.

At the Pod Level​

apiVersion: v1
kind: Pod
metadata:
name: no-token-pod
spec:
serviceAccountName: my-app-sa
automountServiceAccountToken: false
containers:
- name: app
image: my-app:1.0

Best Practices​

1. One Service Account per Application​

Create a dedicated Service Account for each application.

2. Principle of Least Privilege​

Grant only the necessary permissions via RBAC.

3. Avoid Default Service Account​

Avoid using the default Service Account in production.

4. Disable Token if Not Needed​

Use automountServiceAccountToken: false if the application does not need API access.

5. Token Rotation​

Tokens are automatically renewed by Kubernetes.


Useful Commands​

Management​

# Create a Service Account
kubectl create serviceaccount my-app-sa

# View Service Accounts
kubectl get serviceaccounts
kubectl get sa

# Details
kubectl describe serviceaccount my-app-sa

# View associated secrets
kubectl get secrets | grep my-app-sa

Usage​

# Create a Pod with a Service Account
kubectl run my-pod --image=my-app:1.0 --serviceaccount=my-app-sa

# View the token in a Pod
kubectl exec my-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token

Summary​

In this chapter, you learned:

Service Account: Identity for Pods in Kubernetes
Creation: Simple Kubernetes resource
Usage: Via serviceAccountName in Pods
Tokens: Automatically created and mounted at /var/run/secrets/kubernetes.io/serviceaccount/
RBAC: Bind Service Accounts to Roles for permissions
API Access: Use the token to call the Kubernetes API
Image Pull Secrets: To access private registries
Best practices: One Service Account per application, least privilege


Next Steps​

Chapter 9.3: Network Policies
Chapter 9.4: Pod Security Standards
Lab 9.2: Service Accounts and Permissions


Chapter created on: December 2024