特性介绍
社区实现的pod 通过 volume 方式引用service account 的 token,支持audience和token有效期设置。在1.11引入(Alpha),在1.12为Beta。
使用
ServiceAccountTokenVolumeProjection 在 k8s 1.11版本需要手动设置 TokenRequestProjection
这个feature gate 为 true 来启用此功能,在1.12版本 TokenRequestProjection
默认为true
kubelet可以将service account token挂载到pod中。并且可以指定token的一些期望的属性,例如audience 和expirationSeconds。这些属性在default service account token下无法配置。一旦Pod和ServiceAccount被删除,service account token会跟着变成invalid
可以在pod的yaml中定义使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| kind: Pod apiVersion: v1 metadata: name: nginx spec: containers: - image: nginx name: nginx volumeMounts: - mountPath: /var/run/secrets/tokens name: vault-token serviceAccountName: acct volumes: - name: vault-token projected: sources: - serviceAccountToken: path: vault-token expirationSeconds: 7200 audience: vault
|
audience字段
包含token的目标受众(audience)。token的接收者必须使用token的audience中指定的标识符(identifier)来标识自己,否则接收者应该拒绝该token。此参数为可选,默认为api server的identifier(api)
expirationSeconds字段
指定service account token的有效时间。默认1小时,最小需要10分钟
path字段
指定projected volume的挂载点的相对路径
创建pod之后,kubelet会替Pod请求和储存这个token,让pod在可配置的文件路径下访问到此token,并且一旦达到配置的到期时间,就会刷新token。
一旦token达到总TTL的80%,或者token已经超过24小时,kubelet 将主动更新token(rotate token)
kubelet实现
pkg\kubelet\kubelet.go
1 2 3 4 5 6 7 8
| func NewMainKubelet(...)(*Kubelet, error) { ... tokenManager := token.NewManager(kubeDeps.KubeClient) ... klet.volumePluginMgr, err = NewInitializedVolumePluginMgr(klet, secretManager, configMapManager, tokenManager, kubeDeps.VolumePlugins, kubeDeps.DynamicPluginProber) ... }
|
pkg\kubelet\volume_host.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| func NewInitializedVolumePluginMgr( kubelet *Kubelet, secretManager secret.Manager, configMapManager configmap.Manager, tokenManager *token.Manager, plugins []volume.VolumePlugin, prober volume.DynamicPluginProber) (*volume.VolumePluginMgr, error) { ... kvh := &kubeletVolumeHost{ kubelet: kubelet, volumePluginMgr: volume.VolumePluginMgr{}, secretManager: secretManager, configMapManager: configMapManager, tokenManager: tokenManager, mountPodManager: mountPodManager, } ... }
func (kvh *kubeletVolumeHost) GetServiceAccountTokenFunc() func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) { return kvh.tokenManager.GetServiceAccountToken }
|
pkg\kubelet\token\token_manager.go
GetServiceAccountToken 从 cache 或者 TokenRequest API 里获取service account token
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| func (m *Manager) GetServiceAccountToken(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) { key := keyFunc(name, namespace, tr)
ctr, ok := m.get(key) if ok && !m.requiresRefresh(ctr) { return ctr, nil } tr, err := m.getToken(name, namespace, tr) if err != nil { switch { case !ok: return nil, fmt.Errorf("failed to fetch token: %v", err) case m.expired(ctr): return nil, fmt.Errorf("token %s expired and refresh failed: %v", key, err) default: klog.Errorf("couldn't update token %s: %v", key, err) return ctr, nil } }
m.set(key, tr) return tr, nil }
|
相关内容
projected
projected volume 映射多个存在的volume 资源到同一目录。
所有资源要求必须和pod在同一个namespace。
当前有四种volume资源可以被映射(projected):
- secret
- downwardAPI
- configMap
- serviceAccountToken