暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

kubernetes系列之RBAC授权控制篇

kubernetes爱好者 2020-01-31
288

一、前言

    众所周知,kubernetes API是kubernetes的核心组件,kubernetes API以REST接口的形式将Pods、Service、Deployment等信息定义为资源,而这些资源我们又是怎样操作它们的呢?在kubernetes 1.6之后社区逐渐使用RBAC的认证模式,下面将会详细介绍这种认证模式。


二、kubernetes的认证机制

    1)如何访问kubernetes API

    使用者可以通过kubectl客户端、各个代码语言的客户端库程序或者通过发送REST请求来访问kubernetes API接口。

    2)kubernetes API概览

Kubernetes API是标准的REST格式,kubernetes中所有资源的操作都是通过API操作完成的。为了消除字段或者重构,kubernetes支持多个API版本,每个版本都有不同的路径,如/api/v1 /apis/extensions/v1beta1,而不同的资源在不同的API路径中,比如ingress在v1bea1中而不是在v1中。不同的API版本也有不同的安全级别。如Alpha版本可能存在bug,同时默认情况下有些功能是禁止的,Bata版本是稳定的经过测试的,所以大家在调用kubernetes API时要注意使用的版本。

    3)访问kubernetes API过程

如图所示,首先访问kubernetes API的主体大致分为两类:一类是User Account,以用户的身份访问API,另一类是Service Account,主要是kubernetes中的服务程序访问APi接口,比如创建calico网络插件、coredns等时会先创建对应的Service Account。Kubernetes API 为了保证传输层安全端口运行在6443上,同时使用证书认证,在构建kubernetes集群时,会将认证信息写入到$USER/.kube/config中。

Authentication认证,在TLS第一次建立时,就会开始完成认证操作步骤。身份认证的模块包括客户端证书、密码、Token令牌、JWT Tokens、BootstrapTokens等,如果请求认证不能通过,kubernetes会返回HTTP 401状态码。虽然kubernetes使用username作为认证主体,但是不会写入存储中。

Authorization授权,当请求通过认证之后,会经过授权操作步骤。一次授权操作必须包括请求者的用户名、请求的操作动作和受影响的对象,可以理解为语文语法的主谓宾结构,请求主体、有哪种权限操作、操作对象又是什么。Kubernetes支持多种授权模式,比如ABAC模式、RBAC模式、Webhook模式等。如果授权没有通过,会返回HTTP 403状态码。


Admission control准入控制,准入控制作为Authorization授权模式的补充操作,可以对请求对象实现创建、删除、更新操作,通过准入控制可以更灵活的操作整个认证过程。在完成上述操作后,请求信息会写入对象存储中。值得注意的是,在传统的3A认证中,最后一个为Accounting记账或审计,kubernetes面向的是云原生不是一个云计算厂商,不会实现记账系统的模块,但是可以通过准入控制来完成上述的功能。


三、kubernetes之RBAC模式

    1)RBAC模式概述

RBAC的全称是Role Base Access Control,既是基于角色的访问控制,它是一种灵活的访问控制机制,可以将用户作为角色,通过角色绑定完成资源的权限分配。由于kubernetes API本身不需要有任何改动,所以在权限控制和重新定义时无需重启APIserver端。

RBAC使用rbac.authorization.k8s.io这个API Group,通过这个API Group可以允许用户动态配置策略,在kubernetes 1.8之后RBAC模式的API版为rbac.authorization.k8s.io/v1

在apiserver启动时可以通过--authorization-mode=RBAC启用RBAC模式

上图为RBAC模式的认证结构,在指定的namespace下,用户主体通过角色绑定将API资源赋予相应的权限。

    2)Role和ClusterRole角色和集群角色

在RBAC的API中,Role包含一组权限的规则,它可以像Role作用于单个namespace,也可以像ClusterRole一样作用于整个集群中。

Role和ClusterRole示例对比如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]

Role会指定namespace,然后赋予pods资源类型相应的get、watch、list权限

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]

ClusterRole不需要指定namespace,因为它作用于整个namespace上。ClusterRole与Role的主要区别有:

  • 可以针对集群资源(如nodes)

  • 可以作用于非资源类型endpoints(如/healthz)

  • 可以作用于整个namespace上(如kubectl get pods--all-namespaces上的资源)

    3)RoleBinding和ClusterRoleBinding绑定角色和集群角色

RoleBinding或ClusterRoleBinding主要的作用是将主体(如user、serviceaccount等)与Role或ClusterRole进行绑定,这样就可以使得user、group或serviceAccount主体具有指定角色的权限规则。

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io

如图所示,subjects为作用的主体可以为user或者serviceAccount,roleRef代表与Role或者ClusterRole进行绑定,这样jane用户就具有pod-reader对应的权限了。

需要注意的是,如果想通过更改当前Role或者ClusterRole中的规则来改变权限规则,这样是错误的,可以通过删除现有规则重新绑定的方法来实现。可以使用kubectl auth命令更新现有规则。

可以使用kubectl get role, rolebinding -n kube-system查看现有集群role使用情况

    4)Aggregated ClusterRoles聚合类ClusterRoles

在1.9版本之后,ClusterRoles可以使用aggregationRule规则,将具有相同标签的规则作为统一主体完成授权操作。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Rules are automatically filled in by the controller manager.

      通过aggregationRule选项,将匹配matchLabels中包含monitoring标签的规则。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
# These rules will be added to the "monitoring" role.
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]

      可以通过这种标签聚会的方式,将多个ClusterRole聚会成统一的规则策略。


四、RBAC模式下的操作实战

    1)创建用户凭证

使用openssl创建用户私钥,如下所示:

openssl genrsa-out liyinda.key 2048

为用户私钥创建一个证书签名请求文件,CN代表用户名,O代表组

openssl req-new -key liyinda.key -out liyinda.csr -subj "/CN=liyinda/O=liyinda"

     通过签名请求文件向kubernetes的CA生成证书文件crt,有效期为365天

openssl x509-req -in liyinda.csr -CA /etc/kubernetes/pki/ca.crt -CAkey/etc/kubernetes/pki/ca.key -CAcreateserial -out liyinda.crt -days 365

查看当前目录下是否生成证书文件

ls
liyinda.crt liyinda.csr liyinda.key

通过创建好的证书文件和私钥文件生成kubernetes集群凭证

kubectl configset-credentials liyinda --client-certificate=liyinda.crt --client-key=liyinda.key

通过创建好的凭证为kubernetes生成上下文context

kubectl configset-context liyinda-context --cluster=kubernetes --namespace=kube-system--user=liyinda

查看kubernetes集群凭证信息

kubectl config view

使用创建好的用户凭证使用kubectl命令查看默认namespace下的pods,可以发现该用户没有对应权限。

kubectl get pods --context=liyinda-context

    2)创建Role角色

     创建user之后,我们定义一个Role的yaml文件来定义权限规则,如下所示:

apiVersion:rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: liyinda-role
namespace: kube-system
rules:
- apiGroups:["", "extensions", "apps"]
resources: ["deployments","replicasets", "pods"]
verbs: ["get", "list","watch", "create", "update", "patch","delete"]

     创建role规则

kubectl apply -f role.yaml

    3)创建RoleBinding绑定角色

     创建完Role规则后,就可以将user和Role规则进行绑定,如下所示:

apiVersion:rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: liyinda-rolebinding
namespace: kube-system
subjects:
- kind: User
name: liyinda
apiGroup: ""
roleRef:
kind: Role
name: liyinda-role
apiGroup: ""

     创建绑定用户角色

kubectl apply -f rolebinding.yaml

    4)验证权限

使用之前创建好的上下文来查看名称为kube-system的namespace上的pods,可以看到已经添加对应权限。

kubectl get pods --context=liyinda-context --namespace=kube-system


五、结束语

技术重要也不重要,我一直是这么认为的:
重要,是因为它是我们可以安身立命的能力,就像厨师需要做好菜、画家需要画好画一样,如果连这个都不重视就没有什么可说的了。
不重要,是因为不要过分的看重它,把它锁起来像自己的宝贝一样,而不去想着分享,那么它就变得不重要了。

kubernetes系列我会定期更新,在工作中的问题也试着总结起来,欢迎大家分享和留言~


文章转载自kubernetes爱好者,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论