ServiceAccount

ServiceAccount是一种运行在 pod中的应用程序和 API服务器身份认证的一种方式。应用程序通过在请求中传递 ServiceAccount token来实现这一点。

ServiceAccount就像 Pod、Secret、ConfigMap等一样都是资源,它们作用在单独的命名空间,为每个命名空间自动创建一个默认的 ServiceAccount(你的pod会一直使用)。 可以像其他资源那样查看ServiceAccount列表:

kubeclt get sa

每个 pod 都与一个 ServiceAccount 相关联,但是多个pod可以使用同一个ServiceAccount。pod只能使用同一个命名空间中的ServiceAccount。

在 pod 的 manifest 文件中,可以用指定账户名称的方式将一个 ServiceAccount 赋值给一个 pod。如果不显式地指定 ServiceAccount的账户名称,pod 会使用在这个命名空间中的默认 ServiceAccount。

当API服务器接收到一个带有认证 token 的请求时,服务器会用这个 token 来验证发送请求的客户端所关联的 ServiceAccount 是否允许执行请求的操作。API服务器通过管理员配置好的系统级别认证插件来获取这些信息。其中一个现成的授权插件是基于角色控制的插件 (RBAC)。

创建ServiceAccount

每个命名空间都拥有一个默认的 ServiceAccount,也可以在需要时创建额外的 ServiceAccount。但是为什么应该费力去创建新的ServiceAccount 而不是对所有的 pod 都使用默认的 ServiceAccount? 显而易见的原因是集群安全性。不需要读取任何集群元数据的 pod 应该运行在一个受限制的账户下,这个账户不允许它们检索或修改部署在集群中的任何资源。需要检索资源元数据的 pod 应该运行在只允许读取这些对象元数据的 ServiceAccount 下。反之,需要修改这些对象的 pod 应该在它们自己的 ServiceAccount 下运行,这些 ServiceAccount 允许修改 API 对象。

kubectl create serviceaccount foo

这里 SA 的 token 就和 secret 关联了,可以用kubectl describe secret foo-token-qzq7j查看密钥里面的数据。

将ServiceAccount分配给pod

在创建另外的 ServiceAccount之后,需要将它们赋值给 pod。通过在 pod 定义文件中的 spec.serviceAccountName 字段上设置 ServiceAccount的名称来进行分配。

注意 pod 的ServiceAccount 必须在 pod 创建时进行设置,后续不能被修改。

自定义的 ServiceAccount 可以允许列出pod。这可能是因为集群没有使用 RBAC授权插件,给了所有的 ServiceAccount 全部的权限。 如果集群没有使用合适的授权,创建和使用额外的 ServiceAccount 并没有多大意义,因为即使默认的 ServiceAccount 也允许执行任何操作。

RBAC:基于角色的权限控制 Role-Based Access Control

Kubernetes API服务器可以配置使用一个授权插件来检查是否允许用户请求的动作执行。因为 API服务器对外暴露了 REST 接口,用户可以通过向服务器发送 HTTP请求来执行动作,通过在请求中包含认证凭证来进行认证(认证token、用户名和密码或者客户端证书)。

但是有什么动作?REST客户端发送 GET、POST、 PUT、DELETE 和其他类型的 HTTP 请求到特定的 URL 路径上,这些路径表示特定的 REST 资源。在 Kubernetes 中,这些资源是 Pod、Service、 Secret 等等。

RBAC授权插件将用户角色作为决定用户能否执行操作的关键因素。主体(可以是一个人、一个 ServiceAccount,或者一组用户或ServiceAccount)和一个或多个角色相关联,每个角色被允许在特定的资源上执行特定的动词。

如果一个用户有多个角色,他们可以做任何他们的角色允许他们做的事情。如果用户的角色都没有包含对应的权限,例如,更新密 钥,API服务器会阻止用户3个“他的”对密钥执行PUT或PATCH请求。

通过 RBAC 插件管理授权是简单的,这一切都是通过创建四种 RBAC 特定的 Kubernetes 资源来完成的。

RBAC授权规则是通过四种资源来进行配置的,它们可以分为两个组:

  • Role(角色)和ClusterRole(集群角色),它们指定了在资源上可以执行哪些动词。

  • RoleBinding (角色绑定)和 ClusterRoleBinding (集群角色绑定),它们将上述角色绑定到特定的用户、组或ServiceAccounts上。

角色定义了可以做什么操作,而绑定定义了谁可以做这些操作

角色和角色绑定是命名空间的资源,而集群角色和集群角色绑定是集群级别的资源(不是命名空间的)

Pod -> ServiceAccount -> RoleBinding -> Role

1、创建一个 Role 或 ClusterRole,定义所需的权限。

2、创建一个 RoleBinding 或 ClusterRoleBinding,将 Role 或 ClusterRole 绑定到一个或多个主体(如 ServiceAccount)。

3、当一个 Pod 使用某个 ServiceAccount 运行时,该 Pod 继承了该 ServiceAccount 所关联的角色的权限。

因此,RBAC 的权限是通过 ServiceAccount 绑定到 Pod 的,而不是直接绑定到 Pod 本身。这样可以集中管理权限,并使权限与具体的工作负载解耦。