k8s RBAC 权限控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+-----------------------------------------------------------------------------------------------------------+
| |
| +---------------------------------------------------------------------------+ +--------+ |
| | | | | |
| +--------+ | +------------------+ +----------------+ +--------------+ +------+ | | | |
| | | | | | | | | Admission | | | | | | |
| | Client +------> | Authentication +-> | Authorization +-> | Control +-> |Logic | +--> | Others | |
| | | | | | | | | | | | | | | |
| +--------+ | +------------------+ +----------------+ +--------------+ +------+ | | | |
| | | | | |
| | | | | |
| | Kube-apiserver | | | |
| +---------------------------------------------------------------------------+ +--------+ |
| |
+-----------------------------------------------------------------------------------------------------------+

K8S 为它提供了三类安全访问的措施。分别是:

用于识别用户身份的认证(Authentication),
用于控制用户对资源访问的授权(Authorization)
用于资源管理方面的准入控制(Admission Control)

K8S 中的用户

1
2
3
4
5
6
一般用户:
一般用户只能通过外部服务进行管理,由管理员进行私钥分发。这也意味着 K8S 中并没有任何表示一般用户的对象,所以一般用户是无法通过 API 直接添加到集群的。

Service Account:
由 K8S API 管理的用户,与特定的 NameSpace(命名空间)绑定。由 API Server 自动创建或者通过 API 手动进行创建。
同时,它会自动挂载到 Pod 中容器的 /var/run/secrets/kubernetes.io/serviceaccount/ 目录中,其中会包含 NameSpace token 等信息,并允许集群内进程与 API Server 进行交互。对集群操作的 API 都是与用户相关联的,或者被视为匿名请求。匿名请求可通过 kube-apiserver 的 --anonymous-auth 参数进行控制,默认是开启的,匿名用户默认的用户名为 system:anonymous,所属组为 system:unauthenticated。

K8S 支持以下认证机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
X509 客户端证书:
搭建集群时,虽然没有指定配置文件,但 kubeadm 已经添加了默认参数 --client-ca-file=/etc/kubernetes/pki/ca.crt
而在进行认证时,将会使用客户端证书 subject 的 CN 域(Common Name)用作用户名,O 域(Organization)用作组名。
引导 Token:
当集群通过 kubeadm init 初始化完成后,将会展示一行提示,其中便携带着引导 Token。
如果不使用 kubeadm 时,需要设置 --enable-bootstrap-token-auth=true。
静态 Token 文件:
启动 Kube-apiserver 时,设置 --token-auth-file=SOMEFILE 并在请求时,加上 Authorization: Bearer TOKEN 的请求头即可。
静态密码文件:
与静态 Token 文件类似,设置 --basic-auth-file=SOMEFILE 并在请求时,加上 Authorization: Basic BASE64ENCODED(USER:PASSWORD) 的头即可。
Service Account Token:
这是默认启用的机制,关于 Service Account 前面也已经介绍过了,不再赘述。
OpenID:
其实是提供了 OAuth2 的认证支持,像 Azure 或 Google 这类云厂商都提供了相关支持。
认证代理:
主要是配合身份验证代理进行使用,比如提供一个通用的授权网关供用户使用。
Webhook:
提供 Webhook 配合一个远端服务器使用。

可选择同时开启多个认证机制。使用 kubeadm 创建集群时,默认便会开启 X509 客户端证书和引导 Token 等认证机制

K8S 支持以下授权机制:

1
2
3
4
5
6
7
8
9
10
11
12
ABAC(Attribute-Based Access Control):
基于属性的访问控制,在使用时需要先配置 --authorization-mode=ABAC 和 --authorization-policy-file=SOME_FILENAME 。ABAC 本身设计是非常好的,但是在 K8S 中使用却有点过于繁琐,这里不再赘述。
RBAC(Role-based access control):
基于角色的访问控制,自 K8S 1.6 开始 beta,1.8 进入稳定版,已被大量使用。而当我们使用 kubeadm 安装集群的时候,默认将会添加 --authorization-mode=Node,RBAC 的参数,表示同时开启 Node 和 RBAC 授权机制。当然,如果你对 MongoDB 有所了解或者比较熟悉的话,这部分的内容就会很容易理解,因为 MongoDB 的权限控制也使用了 RBAC (Role-based access control)。
Node:
这是一种特殊用途的授权机制,专门用于对 kubelet 发出的 API 请求做授权验证。
Webhook:
使用外部的 Server 通过 API 进行授权校验,需要在启动时候增加 --authorization-webhook-config-file=SOME_FILENAME 以及 --authorization-mode=Webhook
AlwaysAllow:
默认配置,允许全部。
AlwaysDeny:
通常用于测试,禁止全部。

k8s 中的 Role:

1
2
3
4
Role:
可以当作是一组权限的集合,但被限制在某个 Namespace 内(K8S 的 Namespace)。
ClusterRole:
对于集群级别的资源是不被 Namespace 所限制的,并且还有一些非资源类的请求,所以便产生了它。

在 K8S 中用户授权称之为 binding,即 rolebinding 和 clusterrolebinding

查看Role:

1
2
3
4
5
kubectl get roles --all-namespaces=true
kubectl get rolebindings --all-namespaces=true

kubectl get clusterroles
kubectl get clusterrolebindings

查看用户权限:

1
2
3
# kubectl config current-context   # 获取当前上下文,  名为 kubernetes-admin 的用户,在名为 kind 的 cluster 上
kubernetes-admin@kind
# kubectl config view -o yaml # 查看 user 配置,以下省略了部分内容

client-certificate-data 的部分默认是不显示的,而它的内容实际是通过 base64 加密后的证书内容。我们可以通过通过以下方式进行查看

1
2
kubectl config view --raw -o jsonpath='{ .users[?(@.name == "kubernetes-admin")].user.client-certificate-data}' |base64 -d  
kubectl config view --raw -o jsonpath='{ .users[?(@.name == "kubernetes-admin")].user.client-certificate-data}' |base64 -d |openssl x509 -text -noout //当前的用户是 kubernetes-admin (CN 域),所属组是 system:masters (O 域)

clusterrolebindings 中的 cluster-admin:

1
kubectl get clusterrolebindings  cluster-admin  -o yaml

重点内容在 roleRef 和 subjects 中,名为 cluster-admin 的 ClusterRole 与名为 system:masters 的 Group 相绑定

ClusterRole 的实际内容:

1
kubectl get clusterrole cluster-admin -o yaml

rules 中定义了它所能操作的资源及对应动作,* 是通配符。当前用户 kubernetes-admin 属于 system:masters 组,而这个组与 cluster-admin 这个 ClusterRole 所绑定,所以用户也就继承了其权限。具备了对多种资源和 API 的相关操作权限。