使用 ABAC 授权
基于属性的访问控制 (ABAC) 定义了一种访问控制范式,通过使用将属性组合在一起的策略来授予用户访问权限。
策略文件格式
要启用 ABAC
模式,请在启动时指定 --authorization-policy-file=SOME_FILENAME
和 --authorization-mode=ABAC
。
文件格式为 每行一个 JSON 对象。不应有封闭的列表或映射,每行只有一个映射。
每行都是一个“策略对象”,其中每个对象都是一个具有以下属性的映射
- 版本控制属性
apiVersion
,类型为字符串;有效值为“abac.authorization.kubernetes.io/v1beta1”。允许版本控制和策略格式的转换。kind
,类型为字符串:有效值为“Policy”。允许版本控制和策略格式的转换。
spec
属性设置为一个具有以下属性的映射- 主体匹配属性
user
,类型为字符串;来自--token-auth-file
的用户字符串。如果指定user
,它必须与已认证用户的用户名匹配。group
,类型为字符串;如果指定group
,它必须与已认证用户的组之一匹配。system:authenticated
匹配所有已认证的请求。system:unauthenticated
匹配所有未认证的请求。
- 资源匹配属性
apiGroup
,类型为字符串;一个 API 组。- 例如:
apps
、networking.k8s.io
- 通配符:
*
匹配所有 API 组。
- 例如:
namespace
,类型为字符串;一个命名空间。- 例如:
kube-system
- 通配符:
*
匹配所有资源请求。
- 例如:
resource
,类型为字符串;一个资源类型- 例如:
pods
、deployments
- 通配符:
*
匹配所有资源请求。
- 例如:
- 非资源匹配属性
nonResourcePath
,类型为字符串;非资源请求路径。- 例如:
/version
或/apis
- 通配符
*
匹配所有非资源请求。/foo/*
匹配/foo/
的所有子路径。
- 例如:
readonly
,类型为布尔值,当为 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
的模式信息来验证通过创建/更新操作发送到 API 的对象。
当使用 ABAC 授权时,这些特殊资源必须通过策略中的 nonResourcePath
属性显式公开(参见下面的 示例)
/api
、/api/*
、/apis
和/apis/*
用于 API 版本协商。/version
用于通过kubectl version
检索服务器版本。/swaggerapi/*
用于创建/更新操作。
要检查特定 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 可以读取和写入事件
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
Bob 只能读取命名空间“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": "*"}}
关于服务帐户的快速说明
每个服务帐户都有一个相应的 ABAC 用户名,并且该服务帐户的用户名是根据命名约定生成的
system:serviceaccount:<namespace>:<serviceaccountname>
创建新的命名空间会导致以下格式的新服务帐户的创建
system:serviceaccount:<namespace>:default
例如,如果您想授予默认服务帐户(在 kube-system
命名空间中)对 API 的完全权限,使用 ABAC,您将向策略文件添加以下行
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
apiserver 需要重新启动才能获取新的策略行。