kubernetes认证、授权、准入控制

1 总述

1 概述

kubernetes 中的资源访问类型有两种,一种是由POD提供的服务资源,其可通过service或 ingress提供接口以供外部访问,这种访问不需要经过API server的认证,而另一种对集群内部资源的操作则需要经过一定的认证授权操作才能完成。

2 认证,授权,准入控制概述

1 概述

任何客户端在操作相关资源对象时必须经过三个步骤:
认证: 身份鉴别,正确的账号,能够通过认证,其只能证明其是合法的账户。
授权: 权限检查,对资源进行相应的操作。其可操作某些资源,其某些资源需要关联其他资源,其对此种相关关联的资源的操作则无相关权限,此时便需要准入控制了。
准入控制: 用于补充授权机制以实现更加精细的访问控制功能。这次操作会关联到其他资源或影响其他操作。一般在创建,修改,删除和代理方面做某些限制操作。
其认证,授权、准入控制是有各种插件实现,其可经由管理员用户选择确认使用哪种插件来完成对其的操作。及何种控制方式。

2 API serever

API server 是kubernetes 集群系统的网管,是访问及管理资源对象的唯一入口,其余的资源都必须经由网关进行集群访问和管理,这些客户端需要经由 API server防护或改变集群状态并完成数据存储,并经由它对每一次访问进行合法性验证,包括身份鉴别,操作权限鉴别以及操作是否符合全局规范约束等,所有检查正常后且对象配置信息合法性校验无误后才能访问或存储数据存入etcd系统中。


API server依次调用为其配置的认证插件来验证客户端的身份,直到其中一个插件可识别出请求者身份才允许进入。
kubernetes 中內建的用于特殊目的的组。
system : unauthenicated: 未能通过任何一个授权插件检验的账户,及未通过认证测试的用户所属的组。

system: authenticationd: 认证成功后的用户会自动加入一个组,用于快捷引用所有正常通过认证的用户账号。

system: serviceaccount : 当前系统上所有service account对象

system serviceaccount: <namespace>: 特定名称空间内所有service account对象A

3 API 请求类型及相关内容

1 api 请求需要验证的信息

客户端发起对API SERVER的请求,其API server需要验证客户端用户的那些身份:
1 user: username userid
2 group :组信息
3 extra : 额外字段

2 API 相关概述

其发起对API server的请求是请求某些API 资源,其具体是请求那个版本的那个API资源对象,需要进行标识,而标识则需要通过用户在HTTP请求中的URL 和 PATH 来识别。
其允许同一个服务下的版本并存,其可实现相关的兼容

[root@master ~]# kubectl api-versions
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1   
apps/v1beta1  
apps/v1beta2  

所有名称空间级别的资源访问都必须指定其名称空间的名称 (无名称空间的资源 PV,namespace),有名称空间的资源pod,deployment,pvc,service等其他大部分资源。

/apis/apps/v1/namespaces/default(namespaces 中default名称空间)/deployments/nginx
其可进行相关的增删改查操作,其kubectl的相关操作实质上是被转换为对应的URL 进行相关的操作。

使用kubectl 不需要认证信息,但使用curl需要认证信息,原因是在创建集群时已经将相关的认证信息拷贝到了.kube/中,而需要直接进行此项操作,则需要使用本地起代理的方式进行相关的操作

kubernetes 反向代理开启,其proxy和api server进行认证,而客户端curl则不需要相关的认证。

 kubectl proxy  --port=8080  #其需要确保8080端口未被占用

通过kubectl 反向代理至API SERVER
访问名称空间

curl   http://localhost:8080/api/v1/namespaces  #其默认显示该kubernetes集群上的所有名称空间列表,可使用kubectl create namespace 进行创建,然后查看 ,其请求通过URL访问,结果是一个json的相应结果。

类:
1 对象类(namespace)
2 同一类型下的所有对象的集合成为集合,成为list (namespaces) 其包含了资源下的子资源。
访问其具体的资源。

# 获取默认名称空间的基本信息
curl http://localhost:8080/api/v1/namespaces/default  

其默认的,核心组查询时使用 http://localhost:8080/api ,其他非核心群组查看使用http://localhost:8080/apis 起始。其只要不是apiversion只要不是V1,则都是apis起始。


#获取对应default名称空间下的deployment下的Nginx对象的信息
curl  http://localhost:8080/apis/apps/v1/namespaces/default/deployments/nginx
API SERVER 请求报文包含的信息
    1 API: 用于定义其你去的目标是否是一个API资源。
    2 requests path:请求的非资源型路径,如/api和/healthz。
    3 API  group : 要访问的API组,仅对资源请求有效,默认为核心API组。
    4 NameSpace:目标资源所属的名称空间,仅对隶属于名称空间的资源有效(PV无效,namespace也是集群级别的)。
    5 API request verb(动作):API请求类的操作,及资源型请求,包括get,list、create、update、patch、watch、proxy、redirect、delete和deletecollection等。
    6 HTTP request verb: HTTP 请求类的操作,及非资源型请求要执行的操作,如get、post、put和delete。使用CURL 就必须标明动作。创建的时候需要带一个请求格式的数据,在删除时只需要给定URL即可。
    7 Resource: 请求的目标资源ID或名称。
    8 Subresource: 请求的子资源。
[root@master ~]# kubectl get svc    # POD请求API server时使用的接口
NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kubernetes                          ClusterIP   10.96.0.1       <none>        443/TCP         10d

[root@master ~]# kubectl describe  svc kubernetes  # 其是引入其中的
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.90.100:6443
Session Affinity:  None
Events:            <none>

API server将自己的证书发送到客户端,客户端去校验服务端的身份,同时,API server还需要校验客户端的身份,如果在apiserver 上自己手动创建证书,则需要保证证书的持有者名称能够解析两条A记录及10.96.0.1 和 192.168.90.100

POD 客户端需要有证书,API server 需要验证客户端,POD需要和API server打交道,则需要进行相关的认证操作,POD 中的某些资源需要和API server之间提供相关的认证操作,其需要通过serviceAccountName去承载相关的认证信息完成对应的交互操作。默认每一个POD在运行时都要和API server打交道

4 kubernetes 的用户类型:

1 分类

serviceaccount (服务账号):指由kubernetes API 管理的账号,用于为POD中的服务进程在访问kubernetes API 时提供身份标识,service account 通常需要绑定于特定的名称空间,其由 API server创建,或者通过API 调用创建,其会附带一组存储为secret的用于访问API server的凭据。其隶属于名称空房间

useraccount (用户账号):一般是指独立于kubernetes之外的其他服务管理的用户账号,kubernetes中不存在标识此类用户账号的对象,因此其不能被直接添加进kubernetes系统中,其通常用于较为复杂的业务逻辑管控,作用于系统全局,其必须全局唯一。


K8S 通过三个独立的组件键的相互协作来实现服务账户的自动化,三个组件具体是:

  1. service account 准入控制器

其是api server 一部分,负责在创建或更新POD时对其按需进行service account对象相关信息的修改。
若POD没有明确定义使用的serviceaccount对象,则将其设置为default
确保POD明确引用的serviceaccount存在,否则请求将被拒绝
若POD对象中不包含imagepullsecrets,则吧service account 的imagepullsecret添加于其上
为带有访问API的令牌的POD添加一个存储卷
为POD 对象中的每个同期添加一个volumesMounts,挂载至 /var/run/secrets/kubernetes.io/serviceaccount

2 . 令牌控制器:

其是controller-manager的子组件,工作与异步模式,负责如下
1 监控service account的创建操作,并为其添加用于访问API的sercret 对象
2 监控 service Account 的删除操作,并删除相关的所有service account 令牌密钥
3 监控sercret对象的添加操作,确保其引用的service account(账户)已存在,并在必要时为secret对象添加认证令牌
监控sercret对象的删除操作,以确保删除每个service account中对此sercret的引用
为确保完整性,必须为kube-controller-manager 使用"--service-account-private-key-file"选项指定一个私钥文件,用于对生成的服务账户令牌进行签名,此私钥文件必须是pem格式,类似的,需要为kube-apiserver 使用 --service-account-key-file 指定与前面私钥对的公钥文件,以用于在认证期间进行令牌校验

3 . service account 账户控制器

为名称空间管理相应的资源,并确保每个名称空间中都存在一个名为default 的 service account 对象。

Volumes:
  default-token-68rj7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-68rj7
    Optional:    false

其以存储卷的方式关联到POD上,从而完成POD与apiserver之间的信息交互。

其名称空间中默认的secret

[root@master ~]# kubectl get secret 
NAME                  TYPE                                  DATA   AGE
default-token-68rj7   kubernetes.io/service-account-token   3      10d

2 创建和使用serviceaccount

[root@master ~]# kubectl create namespace  data  # 创建一个名称空间
namespace/data created
[root@master ~]# kubectl get secret -n data  #查看其名称空间中的资源,因此其每一个POD都能获取连接API server的信息。但其只能获取当前POD自身的相关信息,其不能获取其他POD信息和属性
NAME                  TYPE                                  DATA   AGE
default-token-bxchn   kubernetes.io/service-account-token   3      12s

如果想要扩展POD,及管理其他POD或管理其他deployment,则需要重新创建serviceaccount。
serviceaccount 属于标准的K8S资源。

创建serviceaccount 资源,其默认只是一个账号,其需要通过RBAC进行相关授权

kubectl create serviceaccount   -h
kubectl create serviceaccount  web

查看
kubernetes认证、授权、准入控制
其会生成一个专门的token,查询如下
kubernetes认证、授权、准入控制

此便是创建的token ,其是认证信息,是认证


定义pod使用自定义的SA账号

[root@master all]# cat pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: dem-dem1
    namespace: default
spec:
    containers:
        - name: dem-po2
          image: nginx:1.14
    serviceAccountName: web  #指定上述创建的serviceaccount 

部署

kubectl apply  -f pod2.yaml

查看
kubernetes认证、授权、准入控制
此处与创建的secret相同

3 配置使用serviceaccount 中的认证拉取私有镜像仓库镜像

其拉去需要认证的私有镜像仓库的镜像时,除了配置pod.spec.imagePullSecrets 还可以在sa中配置相关的秘钥来完成 。

kubernetes认证、授权、准入控制

实例如下

#[root@master2 all]# cat sa1.yaml 
apiVersion: v1
kind: Secret
metadata:
    name: web1   #配置Secret 名称
    namespace: default
stringData:
    key: Admin  #配置私有镜像仓库密码
---
apiVersion: v1
kind: ServiceAccount
metadata:
    name: web
    namespace: default
imagePullSecrets:
    - name: web1  #调用上述服务
---
apiVersion: v1
kind: Pod
metadata:
    name: nginx1
    namespace: default
spec:
    containers:
        - name: nginx1
          image: 192.168.1.10/test/nginx:1.14
          ports:
            - name: http
              containerPort: 80
    serviceAccountName: web  #调用上述serviceaccount

部署

kubectl apply -f sa1.yaml

kubernetes认证、授权、准入控制
kubernetes认证、授权、准入控制

2 认证

1 概述

kubernetes 使用身份认证插件对API 请求进行身份认证,支持包括客户端证书、承载令牌、身份验证代理或http basic 认证等,API server接受到访问请求时,将调用认证插件尝试将以下属性与访问请求相关联。

username: 用户名
UID :用户的数字标签符,用于确保用户身份的唯一性
Groups:用户所属的组,用于权限指派和集成
extra: 键值数据类型的字符串,用于提供认证时所需要的额外信息。

api server 支持同是启用多种认证机制,分为service account 和 user account ,其各自启用一个认证插件,同时支持多种认证机制,认证过程以串行方式进行,直到一种认证机制认证通过后成功,请求者会被识别为某个具体的用户,并随后都以此用户身份进行认证,若无匹配条件,则返回401。

2 API server 支持的认证方式:

1 X509 客户端证书认证:客户端在请求报文中携带X509格式的数字证书用于认证,认证通过后,证书中的主体标识 (subject)被识别为用户标识。其中CN字段是用户名,O 是用户属组。


2 静态令牌文件 (static token file): K8S 提供的是restful 风格的接口,其所有的认证都是通过HTTP进行传递的,因此其认证信息只能经由HTTP的认证守护进行传递,这种认证守护在传递时,传递的是预共享秘钥的编码信息,其通常被成为认证令牌,及token,经由HTTP的守护从客户端将其转为HTTP的传输到API server进行认证,其只需要交换预共享秘钥即可。 保存者令牌信息的文件,由kube-apiserver的命令行选项--token-auth-file 加载,且服务器启动后不可更改,HTTP 客户端也能使用承载令牌进行身份验证,将令牌进行编码后,通过请求报文中的authorization 首部承载传递给API SERVER 即可 像mysql一样


3 引导令牌: 一种动态管理承载令牌进行身份认证的方式,常用于简化新建的k8S集群的节点认证过程,需要通过--experimental-bootstrap-token-auth 选项启用;有新的工作节点首次加入时,master使用引导令牌确认节点身份的合法性之后自动为其签署数字证书用于后续的安全通信,使用kubeadm join 命令将节点加入 kubeadm初始化的集群时使用的及时这种认证方式。这些令牌作为secret存储在kube-sytem名称空间中,可以动态管理和创建,而controller manager 中包含一个tokencleaner 控制器,用于删除过期的引导令牌


4 静态密码文件: 用户名和密码等令牌以明文格式存储的CSV格式文件,由kube-apiserver使用 --basic-auth-file 选项进行加载,客户端在HTTP basic 认证中加认证用户名和密码编码后以承载令牌的格式进行认证。


5 服务账户令牌:由 kube-apiserver自动启动,并可使用可选选项加载 --service-account-key-file 验证承载令牌的密钥,省略时将使用的kube-apiserver 自己的证书匹配到私钥文件,service account通常由 API service 自动创建,并通过service account 准入控制器将其注入POD对象,包括service account上的承载领跑,容器中的应用程序请求API server的服务完成身份认证


6 OPENID 连接令牌: OAuth2 的一种认证风格,由AZURE AD,salesforce 和Google 等服务上支持。


7 webhook 令牌: HTTP身份验证允许将对服务的URL注册为webhook,并接受带有令牌的POST 请求进行身份认证,客户端使用kubeconfig 格式的配置文件,在文件中,"users"指的是API 服务器 Webhook. Cluster 指API server


8 认证代理:API server支持从请求首部中的值中识别用户,如 X-REMOTE-USER 首部,他旨在与身份验证代理服务相结合,并由该代理设置相应的请求头部。


9 keystone 密码: 借助外部的keystone 服务器进行身份验证


10 匿名请求: 未被任何验证机制明确拒绝的用户及被视为匿名用户,其被自动标识为用户名system : anonymous,并隶属于system: unauthorized用户组,在API server 启用了除alwatsallow 外的认证机制,匿名用户处于启动状态,管理员可通过 --anonymous-auth=false 选项将其禁用。


API SERVER 还允许用户通过模拟(impersonation)首部来冒充另一个用户,这些请求可以以手动的方式覆盖请求中用于身份验证的用户信息.

3 kubernetes 中的SSL/TLS 认证

kubernetes 支持https客户端证书认证、token认证以及http basic 认证中的认证方式,基于SSL/TLS 协议的客户端证书认证安全性更高。

SSL/TLS 最常见的是场景是将X.509证书与服务器端关联,但不为客户端使用证书,及客户端认证度武器端身份,服务器端无法认证客户端身份

kubernetes 中各个集群节点的信息状态都是以明文的方式存储在etcd中的,因此其etcd集群内各节点间通信,以及各节点与其客户端之前通信都应是加密传输的方式进行。


1 etcd 集群内对等节点通信,etcd 集群内个节点间的集群事务通信,默认监听TCP 的 2380 端口,基于 SSL/TLS 通信时需要peer 类型的数字证书,可实现节点间的身份认证及通信安全,这些证书需要由专用CA进行管理。

2 etcd 服务器与客户端通信:ETCD 的rest API 服务,默认监听与TCP 的2379 ,用于接受并发响应客户端的请求,基于SSL/TLS 通信,支持服务端认证和双向认证,而且要使用一个专用CA来管理此类证书,kube-apiserver就是etcd 服务的主要客户端。

4 客户端配置文件 kubeconfig

1 简介

使用kubeadmin初始化集群后生成的/etc/kubernetes/admin.conf 文件就是kubernetes 格式的配置文件,其由kubeadm init 命令自动生成,可由kubectl 加载厚用于接入服务器,包括kubectl kubelet和kube-controller-manager等在内的API server的各类客户端都可以使用kubeconfig配置文件提供接入多个集群的相关配置。

2 查看

kubectl config view

kubernetes认证、授权、准入控制

3 其包含的字段:

1 cluster : 集群列表,包含访问API server的URL 和 所属集群的名称。

clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED   #认证的认证方式
    server: https://192.168.90.100:6443  #访问服务器的API server 路径
  name: kubernetes  # 集群名称

2 users: 用户列表,包含访问API server 时的用户名和认证信息

users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED  #客户端证书
    client-key-data: REDACTED #客户端私钥,其需要被服务端认证

3 context: kubectl 的可用上下文列表,有用户列表的某特定用户名称和集群列表中某特定的名称组合而成,用于指明那个账号能够访问那个集群

contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes

4 current-context : kubectl 当前使用的上下文名称,及当前账户访问的集群环境

current-context: kubernetes-admin@kubernetes

kubeconfig 是一个文本文件,但希望能够使用kubectl config 命令进行相关设定,其能够自动进行语法检测等功能。

4 常用命令

kubectl  config  view  #打印kubeconfig 文件内容
kubectl  config set-cluster  #设置kubeconfig 的cluster端
kubectl  config set-credentials #设置kubeconfig的user端
kubectl  config set-context  # 设置kubeconfig的context字段,设定用户可以访问的集群
kubectl config use-context  #切换账号

使用kubeadm 部署的kubernetes 集群默认提供了拥有者集群权限的kubeconfig配置文件,其可以被复制到任何有kubectl 的主机上用于管理整个集群。

kubernetes认证、授权、准入控制

5 配置kubeconfig

1 创建秘钥

为目标账户web 创建私钥及证书文件保存于/etc/kubernetes/pki目录中,需要在master节点上以root 用户执行

A 生成私钥文件,其权限为600,并放置于专用目录

cd /etc/kubernetes/pki/
(umask  077;openssl genrsa -out  web.key 2048)

B 创建证书签署请求,-subj选项中CN将被kubeconfig作为用户名使用,O的值将被识别为用户组

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

C 关联基于kubeadm 安装kubernetes集群时生成的CA证书,并配置其有效期

openssl x509 -req -in web.csr -CA  ca.crt -CAkey ca.key -CAcreateserial -out web.crt -days 3650

D 验证证书信息

openssl x509 -in web.crt -text -noout 

E 查看
kubernetes认证、授权、准入控制

2 配置此用户加入当前集群

1 配置用户加入当前集群中

格式

  kubectl config set-credentials NAME [--client-certificate=path/to/certfile] [--client-key=path/to/keyfile]
[--token=bearer_token] [--username=basic_user] [--password=basic_password] [--auth-provider=provider_name]
[--auth-provider-arg=key=value] [options]

创建

kubectl config set-credentials web --client-certificate=./web.crt --client-key=./web.key --embed-certs=true
# --embed-certs=true表示密文显示

注:此命令需在上述创建的秘钥文件目录中进行,否则需指定此秘钥文件的全局路径

查看
kubernetes认证、授权、准入控制

2 绑定用户和集群

格式

kubectl config set-context [NAME | --current] [--cluster=cluster_nickname] [--user=user_nickname]
[--namespace=namespace] [options]

绑定

kubectl config set-context web@kubernetes --cluster=kubernetes --user=web

web@kubernetes 表示设置的用户名称,其是user@group形式的配置。其后端--cluster指定其加入集群的名称,--user 指定要加入该集群的用户的用户名

查看
kubernetes认证、授权、准入控制

3 用户账号切换

kubectl config use-context web@kubernetes

查看其环境
kubernetes认证、授权、准入控制

4 执行相关操作

kubernetes认证、授权、准入控制
提示无相关权限

5 切换回来

kubectl config use-context kubernetes-admin@kubernetes

kubernetes认证、授权、准入控制

3 定义一个新集群并添加上述配置的秘钥信息

1 创建证书

cd /etc/kubernetes/pki/
(umask  077;openssl genrsa -out  user.key 2048)
openssl req -new -key user.key -out user.csr -subj "/CN=user/O=web"
openssl  x509 -req -in user.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user.crt -days 3650 

2 创建一个新集群,定义其名称为web1

格式

kubectl config set-cluster NAME [--server=server] [--certificate-authority=path/to/certificate/authority]
[--insecure-skip-tls-verify=true] [options]

创建

kubectl config set-cluster  web1 --kubeconfig=/tmp/web1.conf --server="https://192.168.90.100:6443"  --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true

3 配置客户端证书及秘钥,用户名信息通过命令从subject的CN值自动提取,而组名则来自于上述的O=kubernetes的定义

kubectl config set-credentials user --embed-certs=true --client-certificate=/etc/kubernetes/pki/user.crt --client-key=/etc/kubernetes/pki/user.key --kubeconfig=/tmp/web1.conf

4 配置context,用来组合cluster和credentials,及访问的集群的上下文

kubectl config set-context user@web1 --cluster=web1 --user=user --kubeconfig=/tmp/web1.conf

5 指定上下文切换

 kubectl config use-context user@web1  --kubeconfig=/tmp/web1.conf

3 授权

1 总述

kubernetes 自1.6 后支持基于RBAC 的认证授权,认证检查机制,基于角色的访问控制,其有许可授权,没有拒绝授权,

API SERVER 支持的內建授权插件,其可以同时启动
Node: 基于POD资源的目标调度节点来完成对kubernetes的访问控制。

ABAC: attribute-based access control 基于属性的访问控制。

RBAC:role-based access control 基于角色的访问控制。通常只有许可授权,没有拒绝授权,其使用kubeadm默认强制使用RBAC的认证机制。

webhook: 基于http回调机制通过外部REST服务检查用户授权的访问控制。

always deny: 总是拒绝,用于测试
always allow:总是允许,用于不期望进行授权检查时直接接受检查阶段放行的所有操作,启动api server时,"authorization-mode" 选项用于定义要启用的授权机制,多个选项之间彼此以逗号分隔。

2 RBAC简介

RBAC 是一种新型、灵活且使用广泛的访问控制机制,其是基于角色的配置,将权限授予角色之上,与传统的权限赋予使用者的方式不同。其他为账号赋予到多个角色从而让其具有角色上的权限,其中账号可以是用户账号、用户组、服务账号及相关的组等,而同时关联至多个角色的账号锁拥有的权限是多个角色之上的权限集合。 其用于界定"对象用户(subject)"能不能操作(verb)那些对象或类(object),动作的发出者即是主体,通常是以账户为载体,其即可是常规用户,也可以是服务账号,操作(verb)用于标明要执行的具体操作,包括创建、删除、修改和查看等,对应kubectl来说,其通常由create/apply/delete/update/patch/edit和get 等子命令给出,而"客体"则是指操作施加于的目标实体,对kubernetes API 来说主要是指各类资源对象及URL。


RBAC 相比其他授权机制的优势
1 对集群中的资源和非资源URL的权限实现了完整覆盖
2 整个RBAC完全由少数几个API对象实现,而且同其他API对象一样可以通过kubectl 或 API 调用进行操作
3 支持权限运行时调整,无需重启API server。


RBAC 授权插件支持role和clusterrole两类角色,其中role作用于名称空间级别,用于定义名称空间内的资源权限集合,而clusterrole则是用于集群级别的资源权限集合,一般来说,clusterrole 的许可授权可作用与整个集群,因此常用于控制role无法生效的资源对象,这包括集群级别的资源,(如 NODES等)、非资源类型的端点(如/healthz)和作用于所有名称空间的资源。


对于这两中角色授权,需要用到rolebinding和clusterrolebinding,rolebinding 用于将role上的许可权限绑定到一个或一组用户上,其隶属于且仅能作用于一个名称空间,绑定时,可以引用同一个名称空间中的role,也可以引用集群级别的clusterrole,而clusterrolebinding则把clusterrole中定义的许可权限绑定在一个或一组用户至上,它仅可以引用集群级别的clusterrole。

一个名称空间中可以包含多个role和rolebinding对象,类似的,集群级别也可以同时存在多个clusterrole和clusterrolebinding对象,而一个账户也可经由rolebinding或clusterrolebinding 关联至多个角色,从而具有多重许可授权。

3 role 和 rolebinding

1 role

1 概述

role 仅是一组许可权限的集合,其描述了对那些资源可执行哪种操作,资源配置清单中使用rules资源嵌套授权规则。


2 核心字段

role.rules.verbs: 定义对资源可执行的操作列表,包括 create/apply/delete/update/patch/edit/list/get/proxy/redirect等
role.rules.apiGroups: 包含可资源的API组名称,空串标识核心组
role.rules.resourceNames: 规则应用的目标资源名称组成的列表,如POD资源中的那些资源的操作等
role.rules.resources: 规则应用的目标资源类型组成的列表,如pods,deployment等
role.rules.nonResourceURLs: 用于定义用户应该投权限访问的网址列表,其不是名称空间级别的资源,其只能应用于clusterrole 和 clusterrolebinding。


大多数资源均可通过其资源类型的名称引用,如pods或services等,这些名字与他们在API endpoint中的形式相同,某些资源类型还支持子资源(subresource),如Pod对象中的/log,Node对象中的/status等,其URL格式通常如下

http://localhost:8080/api/v1/namespaces/{NAMESAPCES}/pods/{NAME}/log

在RBAC角色定义中,若要引用此类资源,则需要使用resource/subresource格式。另外,还可以通过给定资源名称直接引用某些特定的资源,支持此类子资源的操作通常有get、delete、update和patch。

3 role配置清单配置

实例

[root@master all]# cat role1.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
    name: web-role
    namespace: default  #其是名称空间级别的资源,需指定名称空间,若不指定,则默认是default名称空间 
rules:
    - verbs: ["get","list","create","delete","watch","patch"]  # 定义其可指定的操作。操作可指定为*,表示可以执行所有的操作
      resources: ["pods","service","deployment","pods/log"]  #定义其可对那些资源对象进行操作
      apiGroups: [""]  #"" 表示核心API组

部署

kubectl apply  -f role1.yaml 

查看
kubernetes认证、授权、准入控制

4 role命令行形式配置

其也可以使用kubectl create role 命令进行快速创建操作,相关创建如下

格式

 kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run] [options]

创建可对pod 进行查看,监控和列出的角色

kubectl create role pod-list  --verb=get,list,watch --resource=pods  -n default    #pod-list 角色名称   --verb= 角色列表 --resource 可进行操作的资源名称  -n 指定其作用的名称空间。默认作用于default名称空间

查看
kubernetes认证、授权、准入控制

2 rolebinding

1 概述

用于将role中定义的权限赋予一个或一组用户,它由一组主体,以及一个要引用来赋予这组主体的role或clusterrole组成,rolebinding仅能够引用同一名称空间中的role对象完成授权。

2 核心字段解析

subjects 字段,主体信息绑定字段
rolebinding.subjects.apiGroup: 要引用的主体所属的API群组,对serviceaccount类的主体来说默认是"",而User和Group类主体的默认值为"rbac.authorization.k8s.io"
rolebinding.subjects.kind: 要应用的主体类型。有User,Group和ServiceAccount三种选择,必选字段。
rolebinding.subjects.name: 指定要绑定的主体账户的账户名称,必选字段 
rolebinding.subjects.namespace: 指定引用的主体的名称空间,对于非名称空间类的主体,如"User"和"Group",其值必须为空,否则授权插件将返回错误信息。
roleRef 字段 角色绑定字段
rolebinding.roleRef.apiGroup: 引用的资源(Role或ClusterRole)所属的API群组,必选字段 。
rolebinding.roleRef.kind: 引用的资源所属的类别,可用值为Role或ClusterRole,必选字段 。
rolebinding.roleRef.name: 引用的角色资源的名称。

3 配置清单配置

[root@master all]# cat rolebind.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
    name: web-rolebind
    namespace: default
subjects:  #要绑定的用户信息
    - kind: User
      name: web
      apiGroup: rbac.authorization.k8s.io
roleRef:  #定义要绑定的资源信息
    kind: Role
    name: web-role
    apiGroup: rbac.authorization.k8s.io

部署

kubectl apply -f rolebind.yaml 

查看
kubernetes认证、授权、准入控制

切换用户并进行查看

kubernetes认证、授权、准入控制
其不能访问default名称空间外的资源

4 命令行配置

格式

kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME
[--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]

创建绑定web

kubectl create rolebinding web-pod-lsit --role=pod-list  --user=web

查看
kubernetes认证、授权、准入控制

注 :虽然rolebinding不能跨名称空间引用role资源,但主体中的用户账号,用户组合服务账号却不受名称空间限制,因此,管理员可为一个主体通过不同名称空间的rolebinding资源绑定不同名称空间的角色

4 clusterrole和ClusterRoleBinding

1 clusterrole

1 简介

集群级别的角色资源除了能够管理与role资源相同的许可权限外,还可以用于集群级组件的授权,配置方式及其在rules字段中可内嵌的字段和Role类似。

2 配置清单创建方式

[root@master all]# cat clusterrole1.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
    name: web-rolecluster1  #其不属于名称空间级别资源,因此其无namespace
rules:
    - apiGroups: [""] #定义要访问的资源群组为核心群组
      resources: ["nodes"]  #定义要访问的资源,可以是集群级别的资源,也可是名称空间级别的资源
      verbs: ["get","watch","list"] #定义其可执行的操作

部署

kubectl apply -f clusterrole1.yaml

查看

kubernetes认证、授权、准入控制

3 命令行方式创建

格式

kubectl create clusterrole NAME --verb=verb --resource=resource.group
[--resource-name=resourcename] [--dry-run] [options]

创建其可以查询,列出和监控deployment,pods和service资源

kubectl create clusterrole web-cluster --verb=get,list,watch --resource=deployment,pods,service

查看
kubernetes认证、授权、准入控制

注 :rolebindding 也能够将主题绑定到clusterrole资源上,但仅能赋予用户访问rolebinding资源本身所在的名称空间内的由clusterrole赋予的权限,如clusterrole配置了可访问所有POD的查询权限,而rolebinding资源的名称空间是web,则通过rolebinding绑定clusterrole和任何一个用户,其访问的权限范围是web名称空间中的POD资源。


一种常见的做法是集群管理员在集群范围预先定义好一组访问名称空间级别资源全新啊的clusterrole资源,二货普在多个名称空间中多次通过rolebinding引用,从而让用户分别具有不同名称空间上的资源的相应访问权限,而完成了名称空间级别的权限的快速授予。

集群级别的资源nodes、persistentvolumes等资源,以及非资源型的URL不属于名称空间级别,故此不能使用rolebinding来绑定授权,所有非名称空间级别的资源都无法通过rolebinding绑定至用户并赋予用户相关的权限,这写都是属于clusterrolebinding 的功能。


kubernetes 除了名称空间和集群级别的资源外,还有/api、/apis、/healthz、/swaggerapi和/version 等非资源型URL,对这些URL的访问也必须事先获取相关的权限,同级别的资源一样,他们也只能定义在clusterrole中,且需要基于clusterrolebinding进行授权,不过,对资源的读取权限已经由系统默认的名称同为system:discovery的clusterrole 和 clusterrolebinding两个资源自动设定,相关信息如下:

kubernetes认证、授权、准入控制

Non-Resource URLs 字段给出了相关URL列表,允许访问权限仅有一个get,引用了次资源的clusterrolebinding 的相关信息如下

kubernetes认证、授权、准入控制

system:authenticated 和 system:unauthenticated 组包含了所有的用户账号,因此所有的用户默认均有权限读取。

另外,非资源型URL的授权规则和资源权限的授权规则可定义在一个clusterrole中,他们同属于rules字段中的对象。

2 聚合型clusterrole

kubernetes 自1.9版本来时支持rules字段中嵌套aggregationRule字段来整合其他的clusterrole兑现的规则,这种类型的clusterrole 的权限受控于控制器,它们由所有被标签选择器匹配到的用于聚合的clusterrole的授权规则合并生成。

实例

[root@master all]# cat clusterrole2.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
    name: nginx-clusterrole1
    labels:
        web: nginx-clusterrole1
rules:
    - resources: ["pod","service"]
      verbs: ["list","get"]
      apiGroups: [""]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
    name: web-clusterrole3
aggregationRule:  #引用上述配置的clusterrole
    clusterRoleSelectors:
        - matchLabels:
            web: nginx-clusterrole1

部署

kubectl apply -f clusterrole2.yaml

查看
kubernetes认证、授权、准入控制

事实上kubernetes系统上面向用户的內建clusterrole admin 和 edit 也是聚合型clusterrole,因为这可以使默认角色中包含自定义资源的相关规则。

3 面向用户的內建clusterrole

APIserver內建了一组默认的clusterrole和clusterrolebinding已预留系统使用,其中大多数都是以"system: "为前缀 ,另外还有一些非以"system:" 为前缀的默认的role资源,其是为面向用户的需求设定的,包括超级用户角色(cluster-admin)。用于授权集群级别权限的clusterrolebinding(cluster-status)以及授权特定名称空间级别权限的rolebinding (admin、edit 和 view)。

kubernetes认证、授权、准入控制

kubernetes认证、授权、准入控制

內建的clusterrole资源cluster-admin拥有管理集群所有资源的权限,它是基于同名的clusterrolebinding绑定到了"system: master"组上的用户都将具有集群的超级管理权限。kubeadm安装设定集群时自动创建的配置文件admin.conf中的秘钥的组及O是master,其CN 是 kubernetes-admin,因此,其具有管理集群的权限。


因此,为kubernetes集群额外自定义超级管理员的方式有两种:
1 创建用户认证证书,其subjects中的O及组为master。
2 将创建的主体绑定到clusterrolecluster-admin上。


另外,在多租户,多项目或多环境等使用场景中,用户通常应该获取名称空间级别的绝大多数资源的管理,只读或者编辑的权限,这类权限的快速授予可通过在指定的名称空间中创建rolebinding资源引入內建的clusterrole资源admin,view 或edit 来进行。

kubernetes认证、授权、准入控制

若需要授权的是编译或者只读,则仅需要创建rolebinding时引用clusterrole相应的edit和view即可。

4 clusterrolebinding

1 清单文件配置

[root@master all]# cat clusterrolebind.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
    name: web-rolebinding
subjects:
    - kind: User
      name: web
      apiGroup: rbac.authorization.k8s.io
roleRef:
    kind: ClusterRole
    name: web-rolecluster1
    apiGroup: rbac.authorization.k8s.io

部署

kubectl apply -f clusterrolebind.yaml

查看
kubernetes认证、授权、准入控制

2 命令行方式绑定

语法

kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username]
[--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]
[options]

1创建绑定用户和角色

kubectl create clusterrolebinding  web-clusterrolebind  --clusterrole=web-cluster   --user=web

2 切换账户

kubectl config  use-context web@kubernetes  

3 查看其相关资源
kubernetes认证、授权、准入控制

4 准入控制

1 总述

用于在客户端请求经过身份验证和授权检查后,在持久化存储etcd之前拦截请求,用于实现在资源创建、更新和删除操作期间强制执行对象的语义验证等功能,读取资源信息的操作不会经由准入控制器的检查,API 的准入控制器

2 准入控制类型

1 always deny: 总是拒绝,用于测试
2 always allow:总是允许,用于不期望进行授权检查时直接接受检查阶段放行的所有操作,启动api server时,"authorization-mode" 选项用于定义要启用的授权机制,多个选项之间彼此以逗号分隔。
3 alwaysPullmages:总是下载镜像,用于多租户环境中以确保私有镜像能够被拥有权限的用户使用
4 namespacelifecycle:拒绝在不存在的名称空间中创建资源,而删除名称空间会级联其下的所有资源
5 limitRanger:可用资源范围界定,用于监控对设置了limitrange的对象发出的所有请求,以确保其资源请求不会超出限制。
6 serviceaccount: 用于实现service account管控机制的自动化,实现创建POD对象时自动为其附加service account 对象。
7 persistentvolumelabel: 为那些云计算服务商提供的PV自动附加region 或 zone标签,以确保这些存储卷能够正确关联且仅能关联到所属的region 或 zone
8 defaultstorageclass: 监控所有创建PVC对象的请求,以确保没有附加任何专用storageclass的请求会自动设定一个默认值。
9 resourceQuota: 用于对名称空间设置可用资源的上限,并确保在其中创建的任何设置了资源限额的对象都不会超出名称空间的资源配额
10 defaultolerationseconds:如果POD对象上不存在污点宽容期限,则为他们设置默认宽容期。
11 validatingAdmissionWebhook: 并行调用匹配当前请求的所有验证类的webhook,任何一个校验失败,请求及失败。
12 mutatingadmissionwebhook: 串行调用匹配当前请求的所有编译类的webhook,每个调用都可能会更改对象。

猜你喜欢

转载自blog.51cto.com/11233559/2378013