k8s提供了2种方式用来权限控制,abac和rbac,abac是基于一堆属性(attribute)描述成的策略(policy)来做的限制。
比如限制某个用户只能对某个namespace下的资源操作,就可以写成类似下面的描述1
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "somenamespace", "resource": "*", "apiGroup": "*"}}
可以看到其实就是user namespace resource apiGroup 等几个选项的排列组合
要启用ABAC需要修改apiserver的启动参数 加上–authorization-mode=ABAC 和 –authorization-policy-file=SOME_FILENAME,这里的SOME_FILENAME 就是个填写了类似以上json的文件,可以填多行,来做多个组合限制,点这里看一个具体的文件列子
策略对象的具体解释
- 版本控制属性:
apiVersion
,字符串类型: 有效值为”abac.authorization.kubernetes.io/v1beta1”,允许版本控制和转换策略格式。kind
,字符串类型: 有效值为 “Policy”,允许版本控制和转换策略格式。
spec
配置为具有以下映射的属性:- 匹配属性:
user
,字符串类型; 来自--token-auth-file
的用户字符串,如果你指定user
,它必须与验证用户的用户名匹配。group
,字符串类型; 如果指定group
,它必须与经过身份验证的用户的一个组匹配,system:authenticated
匹配所有经过身份验证的请求。system:unauthenticated
匹配所有未经过身份验证的请求。
- 匹配属性:
- 资源匹配属性:
apiGroup
,字符串类型; 一个 API 组。- 例:
extensions
- 通配符:
*
匹配所有 API 组。 - “”空字符串匹配系统默认的资源 比如POD之类, kubectl get -o yaml 出来apiVersion 没有/的资源
- 例:
namespace
,字符串类型; 一个命名空间。- 例如:
kube-system
- 通配符:
*
匹配所有资源请求。
- 例如:
resource
,字符串类型; 资源类型。- 例:
pods
- 通配符:
*
匹配所有资源请求。
- 例:
- 非资源匹配属性:
nonResourcePath
,字符串类型; 非资源请求路径。- 例如:
/version
或/apis
- 通配符:
*
匹配所有非资源请求。/foo/*
匹配/foo/
的所有子路径。
- 例如:
readonly
,键入 boolean,如果为 true,则表示该策略仅适用于 get,list 和 watch 操作。
一个具体的例子,限制用户ads只能操作ads nameespace下的东西,注意需要最后2行,否则kubectl由于列不到资源列表无法使用1
2
3{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"ads", "namespace": "ads", "resource": "*","apiGroup": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:unauthenticated", "nonResourcePath": "*", "readonly": true}
限制只能访问基础资源pod configmap ,不能访问如deployment之类的资源1
2
3{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "namespace": "*", "resource": "*","apiGroup": ""}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:unauthenticated", "nonResourcePath": "*", "readonly": true}
如果是要能访问deployment 得加上下面这个1
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "namespace": "*", "resource": "*","apiGroup": "extensions"}}
下面我们扩展下这个功能:实际场景是用户可能会创建一堆namespace,同样的前缀,但是目前k8s官方是只支持*或者完全匹配,不支持前缀匹配
所有相关的代码在pkg/auth/authorizer/abac/abac.go 中
1 | func (pl policyList) Authorize(a authorizer.Attributes) (bool, string, error) { |
另外abac缺失个根据verb做权限限制的功能,比如我不想让人delete namespace,目前就没办法实现,不过可以通过rbac的clusterrole实现。实际看了下也可以改改,有空再说。