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 的相关操作权限。