First, I have created a service account jenkins
> kubectl create serviceaccount jenkins
serviceaccount/jenkins created
Second, create a token for this service account.
> kubectl create token jenkins
eyJhbGc****************iQS-AVXfIzA
Then, I run kubectl describe serviceaccount jenkins
command to check the tokens of newly created service account.
But the output shows None tokens.
> kubectl describe serviceaccount jenkins
Name: jenkins
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none> <===== look at this!
Events: <none>
Questions
The output shows "None" tokens, how do I know there is a token associated with this service account?
If I run
kubectl create token jenkins
command multiple times, will kubernetes create multiple tokens for this account? or the latest one will overwrite the previous one?# first time kubectl create token jenkins # second time kubectl create token jenkins # third time kubectl create token jenkins `
What's the mapping relation between the service account and the token? is it
1:n
?
CodePudding user response:
The mechanism of service accounts and tokens has been changed (Moved to stable in v1.22).
In the past, you have created a service account. Then in the first time you ran a pod with that service account, Kubernetes created a long-lived, never expired, token that resided in secret of type kubernetes.io/service-account-token
. Kubernetes attached this token to the pod via volume mount.
Due to the unsecured nature of long-lived tokens this has been changed to something called Bound Service Account Token Volumes
.
In short, Kubernetes no more creates a secret with a token for the service account but instead Kubelet injects a short-lived token with a default timespan of 1 hour to the pod and refresh it when it's expired.
When you ran kubectl describe serviceaccount jenkins
you saw <none>
in the section of the Tokens
because it represents the 'old fashioned' static tokens that as mentioned are not created by default anymore.
You can manually create such a static token with
> cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: jenkins
annotations:
kubernetes.io/service-account.name: jenkins
EOF
and then when you run describe
again and you will the new token
> kubectl describe serviceaccount jenkins
Name: jenkins
Namespace: jenkins-demo
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: jenkins
Events: <none>
You can create multiple tokens with different names and you will see all of them in the describe
output.
BUT This is a bad practice to create these static tokens because they never expired. You should use short-lived token that you can create with the command you mentioned kubectl create token jenkins
You can control the duration with --duration <seconds>s
and create a token with an expiration of up to 48h. The default is 1h.
The creation of new token doesn't overwrite the previous one. These tokens are JWTs - meaning they are signed and distributed, and are not kept on the server. If you want to see the content of a token you can paste the output
of kubectl create token jenkins
in jwt.io.
Same as with the static token. You can run
kubectl get secret jenkins --output=jsonpath='{.data.token}' | base64 -d
and paste the output in jwt.io. You can notice this token doesn't have an expiration date.
Reference:
- https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#manually-create-an-api-token-for-a-serviceaccount
- https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1205-bound-service-account-tokens
- https://github.com/kubernetes/enhancements/issues/542