Kubernetes安全:如何检查服务帐户的令牌?

Rya*_* Lv 2 kubernetes

首先,我创建了一个服务帐户jenkins

> kubectl create serviceaccount jenkins
serviceaccount/jenkins created
Run Code Online (Sandbox Code Playgroud)

其次,为此服务帐户创建一个令牌。

> kubectl create token jenkins
eyJhbGc****************iQS-AVXfIzA
Run Code Online (Sandbox Code Playgroud)

然后,我运行kubectl describe serviceaccount jenkins命令来检查新创建的服务帐户的令牌。

但输出显示 None 标记。

> 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>
Run Code Online (Sandbox Code Playgroud)

问题

  1. 输出显示“无”令牌,我如何知道有与此服务帐户关联的令牌?

  2. 如果我kubectl create token jenkins多次运行命令,kubernetes 会为此帐户创建多个令牌吗?或者最新的会覆盖上一个?

    # first time
    kubectl create token jenkins
    # second time
    kubectl create token jenkins
    # third time
    kubectl create token jenkins
    `
    
    
    Run Code Online (Sandbox Code Playgroud)
  3. 服务帐号和Token之间的映射关系是怎样的?是吗1:n

小智 6

服务帐户和令牌的机制已更改(在 v1.22 中移至稳定版)。

过去,您已经创建了一个服务帐户。然后,当您第一次使用该服务帐户运行 pod 时,Kubernetes 创建了一个长期存在、永不过期的令牌,该令牌以 类型的秘密形式存在kubernetes.io/service-account-token。Kubernetes 通过卷挂载将此令牌附加到 pod。

由于长期代币的不安全性质,这已更改为称为 的东西Bound Service Account Token Volumes

简而言之,Kubernetes 不再使用服务帐户的令牌创建秘密,而是 Kubelet 向 pod 注入一个默认时间跨度为 1 小时的短期令牌,并在过期时刷新它。

当您运行时,kubectl describe serviceaccount jenkins您会看到<none>的 部分Tokens,因为它代表“老式”静态令牌,如上所述,默认情况下不再创建这些令牌。

您可以手动创建这样的静态令牌

> 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
Run Code Online (Sandbox Code Playgroud)

然后当你describe再次运行时,你会得到新的令牌

> kubectl describe serviceaccount jenkins
Name:                jenkins
Namespace:           jenkins-demo
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              jenkins
Events:              <none>
Run Code Online (Sandbox Code Playgroud)

您可以创建多个具有不同名称的令牌,您将在输出中看到所有这些令牌describe

但是创建这些静态令牌是一种不好的做法,因为它们永远不会过期。您应该使用可以使用您提到的命令创建的短期令牌kubectl create token jenkins

您可以控制持续时间--duration <seconds>s并创建有效期最长为 48 小时的令牌。默认值为 1 小时。

新令牌的创建不会覆盖前一个令牌。这些令牌是 JWT - 这意味着它们经过签名和分发,并且不保存在服务器上。如果您想查看令牌的内容,可以将输出粘贴kubectl create token jenkinsjwt.io中。

与静态令牌相同。您可以运行 kubectl get secret jenkins --output=jsonpath='{.data.token}' | base64 -d 输出并将其粘贴到jwt.io中。您可以注意到该令牌没有到期日期。

参考:

  1. https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/
  2. https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#manually-create-an-api-token-for-a-serviceaccount
  3. https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1205-bound-service-account-tokens
  4. https://github.com/kubernetes/enhancements/issues/542