自定义服务账户(Service Account)
本文永久链接: https://www.xtplayer.cn/kubernetes/custom-serviceaccount/
Service account 主要是为了方便 Pod 中的进程调用 Kubernetes API 而设计的,为服务提供了一种方便的认证机制。但它不提供授权,需要配合 RBAC 来为 Service Account 鉴权。
用户帐户与服务帐户
Kubernetes 出于多种原因区分用户帐户和服务帐户的概念:
- 用户帐户是为人类使用的,服务帐户用于在 Pods 中运行的进程。
- 用户帐户是全局的,其名称在集群的所有命名空间中必须是唯一的,将来的用户资源将不会被命名空间。服务帐户有命名空间。
- 通常,集群的用户帐户可能是从公司数据库同步的。在公司数据库中,新用户帐户的创建需要特殊的权限,并且与复杂的业务流程相关联。服务帐户的创建旨在更加轻量级,从而允许集群用户为特定任务(即最小特权原则)创建服务帐户。
- 用户账户和服务帐户的审核注意事项可能有所不同。
- 复杂系统的配置可以包括该系统组件的各种服务帐户的定义。因为可以临时创建服务帐户并使用命名空间名称,所以这种配置是可移植的。
服务帐户自动化
Kubernetes 通过三个独立组件的协作实现了服务帐户自动化控制:
- 服务帐户准入控制器
- 令牌控制器
- 服务帐户控制器
服务帐户准入控制器
Pod 的修改是通过名为 Admission Controller 的插件实现的。它是 apiserver 的一部分,它在创建或更新 Pods 时同步地对其进行修改。当这个插件被激活时(在大多数发行版上它是默认的),当一个 Pod 被创建或修改时,它会执行以下操作:
- 如果 Pod 没有设置 ServiceAccount,它将 ServiceAccount 设置为 默认值。
- 它确保 Pod 引用的 ServiceAccount 存在,否则将拒绝创建 Pod。
- 如果 Pod 不包含任何 ImagePullSecrets,则 ServiceAccount 的 ImagePullSecrets 被添加到 Pod 中。
- 它向 Pod 添加一个卷,其中包含用于 API 访问的令牌。
- 它向 Pod 的每个容器添加一个 volumeSource,并挂载在
/var/run/secrets/kubernet.io/serviceaccount
上。
从 v1.13 开始,当启用了 BoundServiceAccountTokenVolume 功能时,您可以将服务帐户卷迁移到 Projected Volume 。服务帐户令牌将在 1 小时后,或者 pod 被删除后过期。查看有关Projected Volume更多详细信息。
令牌控制器
Token Controller 作为控制管理器的一部分,它是异步运行。它:
- 监听 serviceAccount 创建并创建一个对应的 Secret 以允许访问 API 。
- 监听 serviceAccount 删除并删除所有相应的 ServiceAccountToken Secrets。
- 监听 Secrets 添加,并确保引用的 ServiceAccount 存在,并在需要时向该 Secrets 添加令牌。
- 监听 Secrets 删除,并在需要时从相应的 ServiceAccount 中删除引用。
必须使用 --service-account-private-key-file
选项将 服务帐户 的私钥文件传递给控制管理器中的令牌控制器,私钥将用于对生成的服务帐户令牌进行签名。同样,您必须使用 --service-account-key-file
选项将相应的公钥传递给 kube-apiserver ,公钥将在身份验证期间用于验证令牌。
创建额外的 API 令牌
控制器循环确保每个服务帐户都存在一个带有 API 令牌的 Secrets。要为服务帐户创建额外的 API 令牌,需要创建一个类型为ServiceAccountToken 的 secret,并带有引用服务帐户的 annotation ,控制器将用生成的令牌更新它:
secret.json:
{ |
kubectl create -f ./secret.json |
删除服务帐户令牌
kubectl delete secret mysecretname |
服务账户控制器
服务帐户控制器管理命名空间内的 ServiceAccount,并确保每个活动命名空间中都存在一个名为 default
的 ServiceAccount。
默认的 Service account
默认情况下,创建 Pod 时,如果未指定 Service account ,则会在同一命名空间中自动为其分配名为 default 的服务帐户。查看 Pod 的原始 json 或 yaml(例如: kubectl get pods/<podname> -o yaml
),则可以看到 spec.serviceAccountName
字段被自动设置为 default。
这个 default Service account 由 K8S 自动创建,默认没有绑定任何权限。
priority: 0 |
创建自定义 ServiceAccount
有两种方法创建 ServiceAccount:
通过 yaml 文件创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: <ServiceAccount-name>
namespace: <ServiceAccount-namespace>保存以上内容为
ServiceAccount.yaml
,然后运行以下命令创建 ServiceAccount:kubectl apply -f ServiceAccount.yaml
直接通过 kubectl 命令行创建
namespace_name=xxx
serviceaccount_name=xxx
kubectl create serviceaccount --namespace=${namespace_name} ${serviceaccount_name}
服务账户权限控制
前文已说到服务账户本身不提供授权功能,如果要通过 ServiceAccount 去访问集群中某些资源,那么需要通过额外的授权插件和策略来实现授权。常用的授权模式,比如:基于角色(Role)的访问控制(RBAC)
。
基于角色(Role)的访问控制(RBAC)是一种基于组织中各个用户的角色来调节对计算机或网络资源的访问的方法。RBAC 授权使用 rbac.authorization.k8s.io
API Groups 来驱动授权决策,允许您通过 Kubernetes API
动态配置策略。
Role 和 ClusterRole
RBAC Role 或 ClusterRole 包含一组权限规则,权限可以累加。只有允许规则,没有 禁止 规则,默认全部禁止。
- Role 具有命名空间的限制,当您创建一个角色,你必须指定所属的命名空间。一个
Role
只可以用来对某一命名空间中的资源赋予访问权限。 - 相比之下,ClusterRole 是一种没有命名空间限制的资源。
ClusterRole
可以授予的权限和Role
相同, 但是因为ClusterRole
属于集群范围,所以它也可以授予以下访问权限:- 集群范围资源 (比如 nodes)
- 非资源端点(比如 “/healthz“)
- 跨命名空间访问的有名字空间作用域的资源(如 Pods),比如运行命令
kubectl get pods --all-namespaces
时需要此能力
Role 示例
这是 default 命名空间的示例 Role,可用于授予对 Pods 的读取访问权限。
apiVersion: rbac.authorization.k8s.io/v1 |
ClusterRole 示例
这是一个 ClusterRole 示例,可用于授予对以下内容的读取访问权限: secrets 在任何特定的命名空间中,或所有命名空间中。
apiVersion: rbac.authorization.k8s.io/v1 |
RoleBinding 和 ClusterRoleBinding
RoleBinding 将角色中定义的权限授予一个用户或一组用户。它包含一个主题列表(用户、组或服务帐户)和一个对被授予角色的引用。RoleBinding 授予特定命名空间中的权限,而 ClusterRoleBinding 则在整个集群范围内授予访问权限。
RoleBinding 可以引用同一命名空间中的任意 Role,也可以将 ClusterRole 绑定到 RoleBinding 的命名空间。
RoleBinding 示例
以下是 RoleBinding 示例,该示例将 pod-reader
角色授予 default 命名空间中的用户 jane。这允许 jane 读取 default 命名空间中的Pod。
apiVersion: rbac.authorization.k8s.io/v1 |
RoleBinding 还可以引用 ClusterRole,以将该 ClusterRole 中定义的权限授予 RoleBinding 命名空间内的资源。这种引用允许您在集群中定义一组通用角色,然后在多个命名空间中重用它们。
例如以下的例子,即使以下 RoleBinding 引用了 ClusterRole,dave(名称区分大小写)也只能读取 development 命名空间中的Secrets,因为 RoleBinding 的命名空间(在 metadata 中)是 development ,RoleBinding 具有命名空间限制。
apiVersion: rbac.authorization.k8s.io/v1 |
ClusterRoleBinding 示例
要在整个集群上授予权限,可以使用 ClusterRoleBinding。以下 ClusterRoleBinding 允许 manager 组(Group)中的任意用户读取任意命名空间中的 secret。
apiVersion: rbac.authorization.k8s.io/v1 |
更多的 rbac 使用方法,请参考:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
参考链接
1.service-accounts-admin
2.configure-service-account
3.access-authn-authz-rbac