# k8s 管理 Service Accounts
# User Accounts 与 Service Accounts
k8s 区分普通帐户(user accounts)和服务帐户(service accounts)的原因:
- 普通帐户是针对(人)用户的,服务账户针对 Pod 进程。
- 普通帐户是全局性。在集群所有 namespaces 中,名称具有惟一性。
- 通常,群集的普通帐户可以与企业数据库同步,新的普通帐户创建需要特殊权限。服务账户创建目的是更轻量化,允许集群用户为特定任务创建服务账户。
- 普通帐户和服务账户的审核注意事项不同。
- 对于复杂系统的配置包,可以包括对该系统的各种组件的服务账户的定义。
# Service account automation
三个独立的组件协作,来实现 service account 的自动化:
- 一个 service account 准入控制器(admission controller)
- 一个 Token controller
- 一个 service account controller
# Service Account Admission Controller
通过 Admission Controller 插件来实现对 pod 修改,它是 apiserver 的一部分。创建或更新 pod 时会同步进行修改 pod。当插件处于激活状态(在大多数发行版中都默认情况)创建或修改 pod 时,会按以下操作执行:
- 如果 pod 没有设置 ServiceAccount,则将 ServiceAccount 设置为 default。
- 确保 pod 引用的 ServiceAccount 存在,否则将会拒绝请求。
- 如果 pod 不包含任何 ImagePullSecrets,则将 ServiceAccount 的 ImagePullSecrets 会添加到 pod 中。
- 为包含 API 访问的 Token 的 pod 添加了一个 volume。
- 把 volumeSource 添加到安装在 pod 的每个容器中,挂载在/var/run/secrets/kubernetes.io/serviceaccount。
# Token controller
TokenController 作为 controller-manager 的一部分运行。异步行为:
- 观察 serviceAccount 的创建,并创建一个相应的 Secret 来允许 API 访问。
- 观察 serviceAccount 的删除,并删除所有相应的 ServiceAccountToken Secret
- 观察 secret 添加,并确保关联的 ServiceAccount 存在,并在需要时向 secret 中添加一个 Token。
- 观察 secret 删除,并在需要时对应 ServiceAccount 的关联
需要使用--service-account-private-key-file 参数选项将 Service Account 密匙(key)文件传递给 controller-manager 中的 Token controller。key 用于 Service Account Token 签名。同样,也需要使用--service-account-key-file 参数选项将相应的(public key)公匙传递给 kube-apiserver,公钥用于在认证期间验证 Token。
# To create additional API tokens
controller loop 能确保每个 Service Account 都存在一个带有 API Token 的 secret。如要为 Service Account 创建额外的 API Token,可以使用创建 ServiceAccountToken 类型的 secret,添加与 Service Account 对应的 annotation 属性,controller 会更新令牌:
secret.json:
{
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "mysecretname",
"annotations": {
"kubernetes.io/service-account.name": "myserviceaccount"
}
},
"type": "kubernetes.io/service-account-token"
}
kubectl create -f ./secret.json
kubectl describe secret mysecretname
# 要删除/使 Service Account token 无效
kubectl delete secret mysecretname
# Service Account Controller
Service Account Controller 在 namespaces 里管理 ServiceAccount,并确保每个有效的 namespaces 中都存在一个名为“default”的 ServiceAccount。