(十二)Kubernetes 认证、授权与准入控制

访问控制概述

API Server作为Kubernetes集群系统的网关,是访问和管理资源对象的唯一入口;包括kube-controller-managerkube-schedulerkubeletkube-proxy等集群基础组件、CoreDNS等附加组件和kubectl命令等都需要经过网关才能进行正常的访问和管理。每一次的访问请求都需要进行合法性检验,包括用户身份验证、操作权限验证及操作规范验证等,需要通过一系列验证通过之后才能访问或存储数据到etcd中。如下图所示

(十二)Kubernetes 认证、授权与准入控制_第1张图片

通过上图可以看出访问kubernetes集群的资源需要三关:认证、授权、准入控制;API Server处理请求的过程中,认证插件负责鉴定用户身份,授权插件用于操作权限许可鉴别,而准入插件则用于在资源对象的创建、删除、更新或连接(proxy)操作时实现更精细的许可检查。

普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码。

ServiceAccount

Servic Account(服务账号):是指由Kubernetes API管理的账号,用于为Pod之中的服务进程在访问Kubernetes API时提供身份标识。Service Account通常绑定于特定的名称空间,由API Server创建,或者通过API调用手动创建。

User Account(用户账号):独立于Kubernetes之外的其他服务管理用户账号,例如由管理员分发秘钥、Keystone一类的用户存储(账号库)、甚至是保函有用户名和密码列表的文件等。

  • User Account是为人设计的,而Service Account则是为Pod中的进程调用Kubernetes API而设计;

  • User Account是跨namespace的,而Service Account则是仅局限它所在的namespace

  • 每个namespace都会自动创建一个default service account

在创建Pod资源时,如果没有指定一个service account,系统会自动在与该Pod相同的namespace下为其指派一个default service account。而podapiserver之间进行通信的账号,称为serviceAccountName。如下:

[root@k8s-master ~]# kubectl get pods  
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          43h
nginx-statefulset-1   1/1     Running   0          43h
nginx-statefulset-2   1/1     Running   0          43h
nginx-statefulset-3   1/1     Running   0          43h
[root@k8s-master ~]# kubectl get pods/nginx-statefulset-0 -o yaml |grep "serviceAccountName"
  serviceAccountName: default
[root@k8s-master ~]# kubectl describe pods/nginx-statefulset-0
Name:           nginx-statefulset-0
Namespace:      default
......
Volumes:
  default-token-blm9l:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-blm9l
    Optional:    false

通过上面可以看出每个Pod无论定义与否都会有一个存储卷,这个存储卷为default-token-* token令牌,这就是Pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个namespace中都有一个默认的叫做default的service account资源。进行查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。

Service Account创建

[root@k8s-master ~]# kubectl get sa     #查看serviceaccount资源
NAME      SECRETS   AGE
default   1         7d19h
[root@k8s-master ~]# kubectl create serviceaccount admin    #创建一个名为admin的serviceaccount资源
serviceaccount/admin created
[root@k8s-master ~]# kubectl get sa     #查看serviceaccount资源
NAME      SECRETS   AGE
admin     1         7s
default   1         7d19h
[root@k8s-master ~]# kubectl describe sa/admin    #查看serviceaccount资源admin的详细信息,可以看出已经自动生成了一个Tokens:admin-token-lc826
Name:                admin
Namespace:           default
Labels:              
Annotations:         
Image pull secrets:  
Mountable secrets:   admin-token-lc826
Tokens:              admin-token-lc826
Events:              
[root@k8s-master ~]# kubectl get secret    #查看secret,可以查看也生成了一个admin-token-lc826的secret资源
NAME                  TYPE                                  DATA   AGE
admin-token-lc826     kubernetes.io/service-account-token   3      50s
......

Pod中引用service account

每个Pod对象均可附加其所属名称空间中的一个Service Account资源,且只能附加一个。不过,一个Service Account资源可由所属名称空间中的多个Pod对象共享使用。创建Pod时,通过“spec.serviceAccountName”进行定义。示例如下:

[root@k8s-master manfests]# vim pod-sa-demo.yaml    #编辑资源清单文件
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin    #指定serviceAccount资源名称
  
[root@k8s-master manfests]# kubectl apply -f pod-sa-demo.yaml 
pod/pod-sa-demo created
[root@k8s-master manfests]# kubectl get pods -l app=myapp
NAME          READY   STATUS    RESTARTS   AGE
pod-sa-demo   1/1     Running   0          9s
[root@k8s-master manfests]# 
[root@k8s-master manfests]# kubectl describe pods/pod-sa-demo
Name:         pod-sa-demo
Namespace:    default
......
Volumes:
  admin-token-lc826:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-lc826      #这里可以看出挂载token就是上面创建的sa所生成的那个。
    Optional:    false
......

客户端配置文件kubeconfig

包括kubectlkubeletkube-controller-manager等在内的API Server的各类客户端都可以使用kubeconfig配置文件提供接入多个集群的相关配置信息,包括API ServerURL及认证信息等,而且能够设置成不同的上下文环境,并在各环境之间快速切换。

kubernetes集群中,每一个用户对资源的访问都需要通过apiserver进行通信认证才能进行访问的,那么在此机制当中,对资源的访问可以是token,也可以是通过配置文件的方式进行保存和使用认证信息,可以通过kubectl config进行查看和配置。如下:

[root@k8s-master]# kubectl config view
apiVersion: v1
clusters:    #集群列表
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.1.31:6443
  name: kubernetes
contexts:    #上下文列表
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:    #用户列表
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
  • cluster:集群列表,包含访问API ServerURL和所属集群的名称等。

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

  • contexts:kubelet的可用上下文列表,由用户列表中的某特定用户名称和集群列表中的某特定集群名称组合而成。

通过kubeadm部署的kubernetes集群默认提供了拥有集群管理权限的kubeconfig配置文件/etc/kubernetes/admin.conf,它可被复制到任何有着kubectl的主机上以用于管理整个集群。还可以创建基于SSL/TLS认证的自定义账号,以授予非管理员级别的集群资源使用权限。配置过程由两部分组成,一是为用户创建专用私钥及证书文件,而是将其配置与kubeconfig文件中。

自建证书和账号进行访问apiserver示例

1)为目标用户账号kube-user1创建私钥及证书文件,保存于/etc/kubernetes/pki目录中

(1)生成私钥,权限设置为600
[root@k8s-master ~]# cd /etc/kubernetes/pki/
[root@k8s-master pki]# (umask 077; openssl genrsa -out kube-user1.key 2048)
Generating RSA private key, 2048 bit long modulus
...................................................................................................................+++
.+++
e is 65537 (0x10001)
[root@k8s-master pki]# ll kube-user1.key 
-rw------- 1 root root 1679 10月 16 15:01 kube-user1.key

(2)创建证书签署请求,-subj选项中的CN的值将被kubeconfig作为用户名使用,O的值将被识别为用户组
[root@k8s-master pki]# openssl req -new -key kube-user1.key -out kube-user1.csr -subj "/CN=kube-user1/O=kubernetes"

(3)基于kubeadm安装Kubernetes集群时生成的CA签署证书,这里设置其有效时长为3650天
[root@k8s-master pki]# openssl x509 -req -in kube-user1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-user1.crt -days 3650
Signature ok
subject=/CN=kube-user1/O=kubernetes
Getting CA Private Key

(4)验证证书信息
[root@k8s-master pki]# openssl x509 -in kube-user1.crt -text -noout

2)使用默认的管理员kubernetes-admin@kubernetes为新建的kube-user1设定kube-config配置文件。配置结果默认保存于当前系统用户的.kube/config文件中。

(1)添加用户到认证
[root@k8s-master pki]# kubectl config set-credentials kube-user1 --embed-certs=true --client-certificate=/etc/kubernetes/pki/kube-user1.crt --client-key=/etc/kubernetes/pki/kube-user1.key
User "kube-user1" set.
(2)配置context,用来组合cluster和credentials,即访问的集群的上下文
[root@k8s-master pki]# kubectl config set-context kube-user1@kubernetes --cluster=kubernetes --user=kube-user1
Context "kube-user1@kubernetes" created.
(3)查看配置文件信息
[root@k8s-master pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.1.31:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kube-user1
  name: kube-user1@kubernetes
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kube-user1
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
(4)指定要使用的上下文,切换为kube-user1访问集群
[root@k8s-master pki]# kubectl config use-context kube-user1@kubernetes
Switched to context "kube-user1@kubernetes".
(5)测试访问kubernetes的资源
[root@k8s-master pki]# kubectl get pods 
Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "default"

从上面的测试,当切换为kube-user1用户进行访问集群时,由于kube-user1用户没有管理集群的权限,所以在获取pods资源信息时,会提示Forbidden。

RBAC-基于角色的访问控制

介绍RBAC

RBACRole-Based Access Control,基于角色的访问控制)是一种新型、灵活且使用广泛的访问控制机制,它将权限授予“角色”(role)之上,这一点有别于传统访问机制中将权限直接赋予使用者的方式。

RBAC中,用户(User)就是一个可以独立访问计算机系统中的数据或者用数据表示的其他资源的主体(Subject)。角色是指一个组织或任务中的工作或者位置,它代表一种权利、资格和责任。许可(Permission)就是允许对一个或多个客体(Object)执行的操作。一个用户可以经授权而拥有多个角色,一个角色可由多个用户构成;每个角色可拥有多种许可,每个许可也可授权给多个不同的角色。每个操作可施加于多个客体(受控对象),每个客体也可以接受多个操作。

RBAC简单来说就是让一个用户(Users)扮演一个角色(Role),角色拥有权限,让用户绑定该角色;随后在授权机制中,只需要将权限授权给某个角色,此时用户将获取对应角色的权限,从而实现角色的访问控制。

RBAC授权规则

RBAC授权规则是通过四种资源来进行配置的,他们可以分为两个组:

  • Role(角色)和ClusterRole(集群角色),它们指定了在资源上可以执行哪些动作。

  • RoleBinding(角色绑定)和ClusterRoleBinding(集群角色绑定),它们将上述角色绑定到特定的用户、组或ServiceAccounts上。

角色定义了可以做什么操作,而绑定定义了谁可以做这些操作,如下图所示:

(十二)Kubernetes 认证、授权与准入控制_第2张图片

绑定关系:

角色和集群角色,或者角色绑定和集群角色绑定之间的区别在于角色和角色绑定是名称空间级别,而集群角色和集群角色绑定是集群级别的资源。

  • RoleBind--Role:kubernetes授权机制中,采用RBAC的方式进行授权,把对象的操作权限定义到一个角色当中,而将用户绑定到该角色,从而使得用户得到对应角色的权限。比如下图,当用户(User1)绑定到Role角色当中,User1就获取了对应的NamespaceA的操作权限,但是对于NamespaceB是没有权限进行操作的。如getlist等操作。

  • ClusterRoleBind--ClusterRole:集群级别的授权,定义一个集群角色(ClusterRole),对集群内的所有资源都有可操作的权限,如下图(只看蓝色的线连接),当用户(User1)通过ClusterRolebindingClusterRole,从而User1遍拥有了集群的操作权限。

  • RoleBind-ClusterRole:这种方式进行绑定时,用户仅能获取当前名称空间的所有权限。为什么这么绕呢?? 举例有10个名称空间,每个名称空间都需要一个管理员,而每个管理员的权限是一致的。那么此时需要去定义这样的管理员,使用RoleBinding就需要创建10Role,这样显得更加繁重。为了当使用RoleBinding去绑定一个ClusterRole时,该User仅仅拥有对当前名称空间的集群操作权限,也就是此时只需要创建一个ClusterRole就解决了以上的需求。比如下图中的User2User3用户虽然绑定了ClusterRole,但是他们也只有自己的名称空间NamespaceB中权限。

(十二)Kubernetes 认证、授权与准入控制_第3张图片

Kubernetes RBAC示例

这里由于要切换用户,使用root用户同时不停的在kubernetes-admin用户和上面创建的kube-user1用户之间进行测试。故这里创建一个测试用户打开另外一个终端进行测试。

[root@k8s-master ~]# useradd ik8s
[root@k8s-master ~]# cp -rp .kube/ /home/ik8s/
[root@k8s-master ~]# chown -R ik8s.ik8s /home/ik8s/
[root@k8s-master ~]# su - ik8s
[ik8s@k8s-master ~]$ kubectl config use-context kube-user1@kubernetes
Switched to context "kube-user1@kubernetes".
[ik8s@k8s-master ~]$ kubectl config view
......
current-context: kube-user1@kubernetes    #这里可以看到当前已经切换到kube-user1用户了
......
[ik8s@k8s-master ~]$ kubectl get pods     #测试kube-user1用户的权限,可以看出目前它没有任何权限
Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "default"

User --> Rolebinding --> Role

1)角色(Role)创建。(说明:一个Role对象只能用于授予对某一单一名称空间中资源的访问权限)

[root@k8s-master ~]# kubectl create role -h    #查看role创建帮助
......
Usage:
  kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run] [options]
--verb    #指定权限
--resource    #指定资源或者资源组
--dry-run    #干跑模式并不会创建

[root@k8s-master ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml    #干跑模式查看role的定义格式
apiVersion: rbac.authorization.k8s.io/v1
kind: Role    #资源类型
metadata:
  creationTimestamp: null
  name: pods-reader    #资源名称
rules:
- apiGroups:    #定义对哪些api组内的资源可以进行操作
  - ""
  resources:    #定义对哪些资源可以进行操作
  - pods
  verbs:    #定义操作的权限
  - get
  - list
  - watch

[root@k8s-master ~]# cd manfests/
[root@k8s-master manfests]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml

[root@k8s-master manfests]# vim role-demo.yaml    #编写资源清单文件
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pods-reader
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@k8s-master manfests]# kubectl apply -f role-demo.yaml   
role.rbac.authorization.k8s.io/pods-reader created
[root@k8s-master manfests]# kubectl get role
NAME          AGE
pods-reader   4s
[root@k8s-master manfests]# kubectl describe role/pods-reader
Name:         pods-reader
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"default"},"rules...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]    #这里表示当前定义了pods-reader这个角色对pods资源拥有get、list、watch的权限。

2)角色的绑定。(RoleBinding可以引用在同一名称空间定义的Role对象)

[root@k8s-master manfests]# kubectl create rolebinding -h    #查看rolebinding创建帮助
......
Usage:
  kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME
[--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]
--role    #指定role的名字
--user    #指定哪个用户

[root@k8s-master manfests]# kubectl create rolebinding kube-user1-read-pods --role=pods-reader --user=kube-user1 --dry-run -o yaml    #干跑模式查看rolebinding的定义格式
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding    #资源类型
metadata:
  creationTimestamp: null
  name: kube-user1-read-pods    #资源名称
roleRef:    #指定role
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:    #指定user
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1
  
[root@k8s-master manfests]# kubectl create rolebinding kube-user1-read-pods --role=pods-reader --user=kube-user1 --dry-run -o yaml > rolebinding-demo.yaml
[root@k8s-master manfests]# vim rolebinding-demo.yaml    #编辑资源清单文件
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kube-user1-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1

[root@k8s-master manfests]# kubectl apply -f rolebinding-demo.yaml 
rolebinding.rbac.authorization.k8s.io/kube-user1-read-pods created
[root@k8s-master manfests]# kubectl get rolebinding
NAME                   AGE
kube-user1-read-pods   9s
[root@k8s-master manfests]# kubectl describe rolebinding kube-user1-read-pods    #查看角色绑定的信息,这里可以看到user kube-user1绑定到了pods-reader这个角色上。
Name:         kube-user1-read-pods
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"kube-user1-read-pods","namespace":"...
Role:
  Kind:  Role
  Name:  pods-reader
Subjects:
  Kind  Name        Namespace
  ----  ----        ---------
  User  kube-user1 

3)权限测试

这时候我们使用kube-user1用户进行测试
[ik8s@k8s-master ~]$ kubectl config use-context kube-user1@kubernetes   #如果没有切换到该kube-user1用户,通过kubectl config use-context进行切换

[ik8s@k8s-master ~]$ kubectl get pods     #在default名称空间获取pods信息
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          3d
nginx-statefulset-1   1/1     Running   0          3d
nginx-statefulset-2   1/1     Running   0          3d
nginx-statefulset-3   1/1     Running   0          3d
pod-sa-demo           1/1     Running   0          27h

[ik8s@k8s-master ~]$ kubectl get pods -n kube-system    #测试获取kube-system名称空间中的pods
Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "kube-system"

从上面的操作可以看出,role的定义和绑定,仅作用于当前名称空间,在获取别的名称空间比如kube-system名称空间时,一样会出现Forbidden

User --> ClusterRolebinding --> ClusterRole

1)ClusterRole定义

ClusterRole资源对象可以授予与Role资源对象相同的权限,但由于它们属于集群范围的对象,也可以使用它们授予对以下几种资源的访问权限:

  • 集群范围资源(例如节点,即Node

  • 非资源类型endpoint(例如/api/healthz等。)

  • 跨所有名称空间的名称空间资源(例如pod,运行kubectl get pods --all-namespaces来查询集群中所有的pod

[root@k8s-master manfests]# kubectl create clusterrole -h    #查看clusterrole创建帮助
......
Usage:
  kubectl create clusterrole NAME --verb=verb --resource=resource.group
[--resource-name=resourcename] [--dry-run] [options]
--verb    #指定权限
--resource    #指定资源或者资源组

[root@k8s-master manfests]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml    #干跑模式查看clusterrole的定义格式
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

[root@k8s-master manfests]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > clusterrole-demo.yaml
[root@k8s-master manfests]# vim clusterrole-demo.yaml    #编辑资源清单
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

[root@k8s-master manfests]# kubectl apply -f clusterrole-demo.yaml    #创建clusterrole
clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@k8s-master manfests]# kubectl get clusterrole |grep "cluster-reader"
cluster-reader                                                         19s
[root@k8s-master manfests]# kubectl describe clusterrole/cluster-reader
Name:         cluster-reader
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"cluster-reader"},"rules":[{"apiGrou...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

2)ClusterRoleBinding定义

#这里还是使用kube-user1用户,所以先将上面的角色绑定信息删除
[root@k8s-master manfests]# kubectl get rolebinding     #查看角色绑定信息
NAME                   AGE
kube-user1-read-pods   27m
[root@k8s-master manfests]# kubectl delete rolebinding kube-user1-read-pods     #删除前面的绑定
rolebinding.rbac.authorization.k8s.io "kube-user1-read-pods" delete
[ik8s@k8s-master ~]$ kubectl get pods     #删除后再用kube-user1用户获取pods资源信息,就立马出现Forbidden了
Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "default"


[root@k8s-master manfests]# kubectl create clusterrolebinding -h
Usage:
  kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username]
[--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]
[options]
--clusterrole    #指定clusterrole
--user    #指定用户

[root@k8s-master manfests]# kubectl create clusterrolebinding kube-user1-read-all-pods --clusterrole=cluster-reader --user=kube-user1 --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: kube-user1-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1
  
[root@k8s-master manfests]# kubectl create clusterrolebinding kube-user1-read-all-pods --clusterrole=cluster-reader --user=kube-user1 --dry-run -o yaml > clusterrolebinding-demo.yaml
[root@k8s-master manfests]# vim clusterrolebinding-demo.yaml    #编辑资源清单文件
cat clusterrolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kube-user1-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1

[root@k8s-master manfests]# kubectl apply -f clusterrolebinding-demo.yaml     #创建clusterrolebinding
clusterrolebinding.rbac.authorization.k8s.io/kube-user1-read-all-pods created
[root@k8s-master manfests]# kubectl get clusterrolebinding/kube-user1-read-all-pods
NAME                       AGE
kube-user1-read-all-pods   25s
[root@k8s-master manfests]# kubectl describe clusterrolebinding/kube-user1-read-all-pods    #查看clusterrolebinding资源kube-user1-read-all-pods详细信息,可以看到kube-user1用户已经绑定到clusterrole资源cluster-reader上了。
Name:         kube-user1-read-all-pods
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"kube-user1-read-all-pod...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name        Namespace
  ----  ----        ---------
  User  kube-user1

3)权限测试

[ik8s@k8s-master ~]$ kubectl get pods     #角色绑定后再次获取pods信息,已经可以正常查看
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          3d1h
nginx-statefulset-1   1/1     Running   0          3d1h
nginx-statefulset-2   1/1     Running   0          3d1h
nginx-statefulset-3   1/1     Running   0          3d1h
pod-sa-demo           1/1     Running   0          28h

[ik8s@k8s-master ~]$ kubectl get pods -n kube-system    #切换名称空间也是可以查看的
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-bccdc95cf-9gsn8              1/1     Running   0          8d
coredns-bccdc95cf-x7m8g              1/1     Running   0          8d
etcd-k8s-master                      1/1     Running   0          8d
kube-apiserver-k8s-master            1/1     Running   0          8d
kube-controller-manager-k8s-master   1/1     Running   0          8d
kube-flannel-ds-amd64-gg55s          1/1     Running   0          8d
kube-flannel-ds-amd64-ssr7j          1/1     Running   5          8d
kube-flannel-ds-amd64-w6f9h          1/1     Running   4          8d
kube-proxy-77pbc                     1/1     Running   3          8d
kube-proxy-qs655                     1/1     Running   3          8d
kube-proxy-xffq4                     1/1     Running   0          8d
kube-scheduler-k8s-master            1/1     Running   0          8d

[ik8s@k8s-master ~]$ kubectl delete pods/pod-sa-demo    #在进行删除pod测试时,还是会报Forbidden,这是因为在授权时就没授予delete权限的。
Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "kube-user1" cannot delete resource "pods" in API group "" in the namespace "default"

从上面的操作可以看出,clusterrole的定义和clusterrolebinding的绑定,可以获取到集群内所有资源的对应权限。

User --> Rolebinding --> Clusterrole

将用户kube-user1通过角色绑定(RoleBinding)到集群角色cluster-reader当中,此时kube-user1仅作用于当前名称空间的所有pods资源的权限。

1)绑定

#首先删除上面的clusterrolebinding
[root@k8s-master manfests]# kubectl delete clusterrolebinding kube-user1-read-all-pods
clusterrolebinding.rbac.authorization.k8s.io "kube-user1-read-all-pods" deleted

[root@k8s-master manfests]# kubectl create rolebinding kube-user1-read-pods --clusterrole=cluster-reader --user=kube-user1 --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: kube-user1-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1
  
[root@k8s-master manfests]# kubectl create rolebinding kube-user1-read-pods --clusterrole=cluster-reader --user=kube-user1 --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
[root@k8s-master manfests]# vim rolebinding-clusterrole-demo.yaml    #编辑资源清单文件
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kube-user1-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kube-user1
  
[root@k8s-master manfests]# kubectl apply -f rolebinding-clusterrole-demo.yaml 
rolebinding.rbac.authorization.k8s.io/kube-user1-read-pods created
[root@k8s-master manfests]# kubectl get rolebinding kube-user1-read-pods 
NAME                   AGE
kube-user1-read-pods   32s
[root@k8s-master manfests]# kubectl describe rolebinding kube-user1-read-pods
Name:         kube-user1-read-pods
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"kube-user1-read-pods","namespace":"...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name        Namespace
  ----  ----        ---------
  User  kube-user1 

2)权限测试

[ik8s@k8s-master ~]$ kubectl get pods 
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          3d1h
nginx-statefulset-1   1/1     Running   0          3d1h
nginx-statefulset-2   1/1     Running   0          3d1h
nginx-statefulset-3   1/1     Running   0          3d1h
pod-sa-demo           1/1     Running   0          28h

[ik8s@k8s-master ~]$ kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "kube-system"

从上面的操作可以看出,角色绑定(Rolebinding)和集群角色(ClusterRole)绑定后,用户只拥有自己当前名称空间的对应的权限。

 

 

你可能感兴趣的:((十二)Kubernetes 认证、授权与准入控制)