Service accounts are used by “bots” / software to access the k8s API
# Create a service account
k create sa <new-sa-name>
# View service accounts
k get sa
# Vew the token created by the SA
k describe sa <new-sa-name>
The token that is generated by the SA is what is used by the app to talk to the Kubernetes API
The token is stored as a secret
# For a service account called 'nats-operator'
k get secret nats-operator-token-gmv96 -o=jsonpath='{.data.token}' | base64 -d
We can then use the token to call the api with curl
curl https://<controller>:6443/api -insecure --header "Authorization: Bearer <token>"
If the third party application is hosted on the kubernetes cluster that the secret is on then we can mount the service account token secret as a volume and use it in the pod
Every namespace has a default service account created
By default, when a pod is created, the default service account is mounted automatically
The default service account has very limited permissions
To disable mounting the default service account, set
automountServiceAccountToken: false in the pod spec section.
Use a custom service account in a pod spec:
spec:
container:
# container stuff
serviceAccount: service-account-name
Kubernetes 1.22 and 1.24 SA Updates
Service Account tokens are JWTs that were generated in previous version of Kubernetes were not time bound or bound to an audience. Each service account also required a secret which resulted in a scalability issue with larger clusters.
Kubernetes 1.22 TokenRequestAPI
Token generated by the TokenRequestAPI are
- Audience bound
- Time bound
- Object bound
New pods now no longer rely on the service accounts secret token, they create a projected volume to the
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: vault-token
serviceAccountName: build-robot
volumes:
- name: vault-token
projected:
sources:
- serviceAccountToken:
path: vault-token
expirationSeconds: 7200
audience: vault
The kubelet will request and store the token on behalf of the pod, make the token available to the pod at a configurable file path, and refresh the token as it approaches expiration. The kubelet proactively rotates the token if it is older than 80% of its total TTL, or if the token is older than 24 hours.
The application is responsible for reloading the token when it rotates. Periodic reloading (e.g. once every 5 minutes) is sufficient for most use cases.
Kubernetes 1.24 Reduction of Secret-based Service Account Tokens
Service accounts not longer automatically creates a secret with a token
SA secret tokens can be created manually by creating a secret as shown below.
Warning: This is a non expiring token that can be a security risk. Only do this if you can’t use the token request API
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token