使用 ABAC 授权
基于属性的访问控制 (ABAC) 定义了一种访问控制范式,其中通过结合属性的策略来授予用户访问权限。
策略文件格式
要启用 ABAC 模式,请在启动时指定 --authorization-policy-file=SOME_FILENAME 和 --authorization-mode=ABAC。
文件格式是 每行一个 JSON 对象。不应有包围的列表或映射,每行只有一个映射。
每一行都是一个“策略对象”,其中每个这样的对象都是一个包含以下属性的映射
- 版本属性
apiVersion,类型 string;有效值是 "abac.authorization.kubernetes.io/v1beta1"。允许策略格式的版本控制和转换。kind,类型 string:有效值是 "Policy"。允许策略格式的版本控制和转换。
spec属性设置为包含以下属性的映射- 主体匹配属性
user,类型 string;来自--token-auth-file的用户字符串。如果你指定user,它必须与认证用户的用户名匹配。group,类型 string;如果你指定group,它必须与认证用户的组之一匹配。system:authenticated匹配所有认证请求。system:unauthenticated匹配所有未认证请求。
- 资源匹配属性
apiGroup,类型 string;一个 API 组。- 例如:
apps,networking.k8s.io - 通配符:
*匹配所有 API 组。
- 例如:
namespace,类型 string;一个命名空间。- 例如:
kube-system - 通配符:
*匹配所有资源请求。
- 例如:
resource,类型 string;一种资源类型- 例如:
Pod,Deployment - 通配符:
*匹配所有资源请求。
- 例如:
- 非资源匹配属性
nonResourcePath,类型 string;非资源请求路径。- 例如:
/version或/apis - 通配符
*匹配所有非资源请求。/foo/*匹配/foo/的所有子路径。
- 例如:
readonly,类型 boolean,当为 true 时,表示资源匹配策略仅应用于 get、list 和 watch 操作,非资源匹配策略仅应用于 get 操作。
- 主体匹配属性
注意
未设置的属性与设置为其类型的零值(例如空字符串、0、false)的属性相同。但是,为了可读性,首选未设置。
将来,策略可能以 JSON 格式表达,并通过 REST 接口管理。
授权算法
一个请求具有与策略对象的属性对应的属性。
当收到请求时,会确定其属性。未知属性会设置为其类型的零值(例如空字符串、0、false)。
属性设置为 "*" 将匹配相应属性的任何值。
属性元组会对照策略文件中的每个策略进行匹配检查。如果至少有一行与请求属性匹配,则该请求被授权(但可能会在后续验证中失败)。
要允许任何已认证用户执行操作,请编写一个将 group 属性设置为 "system:authenticated" 的策略。
要允许任何未认证用户执行操作,请编写一个将 group 属性设置为 "system:unauthenticated" 的策略。
要允许用户执行任何操作,请编写一个将 apiGroup、namespace、resource 和 nonResourcePath 属性都设置为 "*" 的策略。
Kubectl
Kubectl 使用 apiserver 的 /api 和 /apis 端点来发现提供的资源类型,并使用位于 /openapi/v2 的模式信息验证通过 create/update 操作发送到 API 的对象。
使用 ABAC 授权时,必须通过策略中的 nonResourcePath 属性显式公开这些特殊资源(参见下面的示例)
/api、/api/*、/apis和/apis/*用于 API 版本协商。/version用于通过kubectl version获取服务器版本。/swaggerapi/*用于 create/update 操作。
要检查特定 kubectl 操作涉及的 HTTP 调用,你可以提高详细程度。
kubectl --v=8 version
示例
Alice 可以对所有资源执行任何操作
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}kubelet 可以读取任何 Pod
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}kubelet 可以读写 Event
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}Bob 只能读取 namespace "projectCaribou" 中的 Pod
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}任何人都可以对所有非资源路径发起只读请求
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}} {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
关于 ServiceAccount 的简要说明
每个 ServiceAccount 都有一个对应的 ABAC 用户名,并且该 ServiceAccount 的用户名是根据命名约定生成的
system:serviceaccount:<namespace>:<serviceaccountname>
创建新的 Namespace 会导致创建新的 ServiceAccount,格式如下
system:serviceaccount:<namespace>:default
例如,如果你想使用 ABAC 授予默认 ServiceAccount(在 kube-system Namespace 中)对 API 的完全权限,你可以在策略文件中添加这一行
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
apiserver 需要重启才能加载新的策略行。