权限控制

kubernetes内置的编排对象很难完全满足所有需求,需要基于插件机制来设计自己的编排对象,实现自己的控制器模式。kubernetes中所有的API对象都是保存在Etcd中,但是,对于这些API对象的操作,却一定要通过访问kube-apiserver实现,这是因为需要API-Server来帮助完成授权工作。

在kubernetes中,负责授权工作的机制就是RBAC,基于角色的访问控制(Role-Based Access Control),RBAC的三个基本概念:

  1. Role:一组规则,定义了一组对kubernetesAPI对象的操作权限

  2. Subject:被作用者,可以是人,也可以是机器,也可以是kubernetes中定义的用户

  3. RoleBinding:定义了被作用者和角色之间的绑定关系

Kuberentes API 请求

请求的发起分为两个部分:

  • 第一个部分是人机交互的过程。 是大家非常熟悉的用 kubectl 对 api-server 的一个请求过程;

  • 第二个部分是 Pod 中的业务逻辑与 api-server 之间的交互。

当 api-server 收到请求后,就会开启访问控制流程。这里面分为三个步骤:

  1. Authentication 认证阶段:判断请求用户是否为能够访问集群的合法用户。如果用户是个非法用户,那 api-server 会返回一个 401 的状态码,并终止该请求;

  2. 如果用户合法的话,我们的 api-server 会进入到访问控制的第二阶段 Authorization:鉴权阶段。在该阶段中 api-server 会判断用户是否有权限进行请求中的操作。如果无权进行操作,api-server 会返回 403 的状态码,并同样终止该请求;

  3. 如果用户有权进行该操作的话,访问控制会进入到第三个阶段:AdmissionControl。在该阶段中 api-server 的 Admission Control 会判断请求是否是一个安全合规的请求。如果最终验证通过的话,访问控制流程才会结束。

此时请求将会转换为一个 Kubernetes objects 相应的变更请求,最终持久化到 ETCD 中。

Role

Role是Kubernetes的API对象,定义如下:

Namespace是kubernetes项目里的逻辑管理单位,不同Namespace的API对象,在通过kubectl命令操作的时候,是相对隔离的(逻辑上的隔离并不提供实际的隔离或者多租户能力)。

RoleBinding

RoleBinding本身也是一个kubernetes的API对象,定义如下:

需要注意的是,在kubernetes中,并没有user这个API对象。

User

在kubernetes中的User,即用户,只是一个授权系统里的逻辑概念

  1. 它需要通过外部认证服务,如Keystone来提供

  2. 直接给APIServer自定义一个用户名和密码文件,kubernetes的授权系统,能够从这个文件里找到对应的用户

Role和RoleBinding都是Namespaced对象,只能在某个namespace中。对于non-namespace对象,或者某个对象要作用于所有的namespace时,使用ClusterRole和ClusterRoleBinding,用法与Role完全一样,只是没有namespace字段。

rules字段也可以针对某一个具体的对象进行权限设置:

kubernetes中有一个内置的用户,ServiceAccout。

创建一个ServiceAccount:

编写Rolebinding,进行权限分配:

kubernetes会为ServiceAccount自定创建并分配一个Secret对象,这个Secret就是与ServiceAccount对应的,用来与APIServer进行交互的授权文件(称为Token)。Token文件的内容一般是证书或者密码,以一个secret对象的方式保存在Etcd中。

使用这个ServiceAccount

定义的pod使用的是example-sa这个ServiceAccount,等pod运行后,该ServiceAccount的token(也就是secret对象),被kubernetes自动挂载到容器的/var/run/secretc/kubernetes.io/serviceaccount目录下。

容器中的应用可以会用这个ca.crt来访问APIServer,此时应用只能进行GET、WATCH、LIST操作,因为ServiceAccount的权限被Role限制了。

如果一个pod没有声明ServiceAccount,kubernetes会自动在它的Namespace下创建一个叫default的默认ServiceAccount,然后被分配给这个Pod。在这种情况下,默认ServiceAccount并没有关联任何Role,此时它有访问APIServer的绝大多数权限。这个访问所需要的Token还是默认的ServiceAccount对应的Secret对象提供。

kubernetes会自动为默认ServiceAccount创建并绑定一个特殊的Secret:

  • 类型为:kubernetes.io/service-account-token

  • Annotation:kubernetes.io/service-account.name=default(这个secret会跟同一Namespace下名叫default的ServiceAccount进行绑定)

Group

除了user、还有group的概念,如果为kubernetes配置外部认证服务,这个用户组由外部认证服务提供。对于kubernetes的内置用户ServiceAccount来说,上述用户组的概念也同样适用,实际上,一个ServiceAccount,在kubernetes里对应用户的名字是:

它对应的内置用户组的名字:

这两个很重要,在RoleBinding里定义如下的subjects:

这就意味着,这个Role的权限规则,作用于mynamespace里所有ServiceAccount,用到了用户组的概念。

意味着这个Role作用于整个系统里所有的ServiceAccount。

在kubernetes中已经预置了很多系统保留的ClusterRole,都是以System:开头,通过使用kubectl get clusterroles来查看。这些一般是绑定给kubernetes系统组件对应的ServiceAccount使用的。

system:kube-scheduler这个clusterRole定义的权限规则是kube-scheduler运行所必须的权限。

这个clusterRole会被绑定给kube-system Namespace下名叫kube-scheduler的ServiceAccount,它正是kubernetes调度器的Pod声明使用的ServiceAccount。

kubernetes预置了四个clusterRole:

  1. cluster-admin:kubernetes中的最权限,verb=*

  2. admin

  3. edit

  4. view:规定被作用这只有kubernetes API的只读权限

最后更新于