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