Kubernetes之(十五)身份认证,授权,准入控制

Kubernetes之(十五)身份认证,授权,准入控制

API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证、操作权限验证以及操作规范验证等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图:

ServiceAccount

Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同:

  • User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计
  • User account是跨namespace的,而service account则是仅局限它所在的namespace
  • 每个namespace都会自动创建一个default service account
  • Token controller检测service account的创建,并为它们创建secret
  • 开启ServiceAccount Admission Controller后
    • 每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
    • 验证Pod引用的service account已经存在,否则拒绝创建
    • 如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
    • 每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/

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

[root@master manifests]# kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
myapp-0   1/1     Running   0          16h
myapp-1   1/1     Running   0          16h
myapp-2   1/1     Running   0          16h
myapp-3   1/1     Running   0          16h
[root@master manifests]# kubectl get pods myapp-0 -o yaml|grep serviceAccountName
  serviceAccountName: default

[root@master manifests]# kubectl describe pods myapp-0
......
  default-token-dqd2f:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-dqd2f
......

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

[root@master manifests]# kubectl get sa
NAME      SECRETS   AGE
default   1         7d21h
[root@master manifests]# kubectl get sa -n ingress-nginx  #所有的名称空间都存在name是default的serviceAccount
NAME                           SECRETS   AGE
default                        1         2d20h
nginx-ingress-serviceaccount   1         2d5h

[root@master manifests]# kubectl get secret
NAME                    TYPE                                  DATA   AGE
default-token-dqd2f     kubernetes.io/service-account-token   3      7d21h
mysql-root-password     Opaque                                1      23h
tomcat-ingress-secret   kubernetes.io/tls                     2      2d3h
[root@master manifests]# kubectl get secret -n ingress-nginx
NAME                                       TYPE                                  DATA   AGE
default-token-fkw6s                        kubernetes.io/service-account-token   3      2d20h
nginx-ingress-serviceaccount-token-jvlq9   kubernetes.io/service-account-token   3      2d5h

默认的service account 仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要扩展Pod,假设有一个Pod需要用于管理其他Pod或者是其他资源对象,是无法通过自身的名称空间的serviceaccount进行获取其他Pod的相关属性信息的,此时就需要进行手动创建一个serviceaccount,并在创建Pod时进行定义。那么serviceaccount该如何进行定义呢???实际上,service accout也属于一个kubernetes资源,如下查看service account的定义方式:

[root@master ~]# kubectl explain sa.
KIND:     ServiceAccount
VERSION:  v1

FIELDS:
   apiVersion   <string>

   imagePullSecrets     <[]Object>

   kind <string>

   metadata     <Object>
   
   secrets      <[]Object>

创建serviceaccount

[root@master manifests]# kubectl create serviceaccount mysa -o yaml --dry-run #干跑模式,类似ansible的-C检查语法
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: mysa

[root@master manifests]# kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml #保存为yaml文件,
[root@master manifests]# cat serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: mysa
  
[root@master manifests]# kubectl get sa mysa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"mysa","namespace":"default"}}
  creationTimestamp: "2019-04-04T06:23:58Z"
  name: mysa
  namespace: default
  resourceVersion: "273220"
  selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
  uid: 3ab9e525-56a2-11e9-80a7-000c295ec349
secrets:
- name: mysa-token-cxlvc

看到有一个 token 已经被自动创建,并被 service account 引用。设置非默认的 service account,只需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。需要注意的是不能更新已创建的 pod 的 service account。

自定义serviceaccount

在default名称空间创建了一个sa为admin

[root@master manifests]# kubectl create sa admin
serviceaccount/admin created
[root@master manifests]# kubectl get sa
NAME      SECRETS   AGE
admin     1         40s
default   1         7d22h
[root@master manifests]# kubectl describe sa admin
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-sswgb
Tokens:              admin-token-sswgb
Events:              <none>

[root@master manifests]# kubectl get secret
NAME                    TYPE                                  DATA   AGE
admin-token-sswgb       kubernetes.io/service-account-token   3      99s
default-token-dqd2f     kubernetes.io/service-account-token   3      7d22h
mysql-root-password     Opaque                                1      23h
tomcat-ingress-secret   kubernetes.io/tls                     2      2d4h

可以看到已经自动生成了一个 Tokens: admin-token-sswgb

[root@master manifests]#  vim pod-sa-demo.yaml #新建pod引用 Tokens: admin-token-sswgb
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    white.com/created-by: "cluster admin"
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin  #引用刚才创建的sa账户

创建并查看

[root@master manifests]# kubectl apply -f pod-sa-demo.yaml 
pod/pod-sa-demo created
[root@master manifests]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
myapp-0       1/1     Running   0          21h
myapp-1       1/1     Running   0          21h
myapp-2       1/1     Running   0          21h
myapp-3       1/1     Running   0          21h
pod-sa-demo   1/1     Running   0          2s


[root@master manifests]# kubectl describe pods pod-sa-demo 
......
Volumes:
  admin-token-sswgb:  #已经使用藏才创建的admin账户的token
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-sswgb
    Optional:    false
QoS Class:       BestEffort
......

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

[root@master manifests]# kubectl config view
apiVersion: v1
clusters:    #集群状态
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.10: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

在上面的配置文件当中,定义了集群、上下文以及用户。其中Config也是K8S的标准资源之一,在该配置文件当中定义了一个集群列表,指定的集群可以有多个;用户列表也可以有多个,指明集群中的用户;而在上下文列表当中,是进行定义可以使用哪个用户对哪个集群进行访问,以及当前使用的上下文是什么。如图:定义了用户kubernetes-admin可以对kubernetes该集群的访问,用户kubernetes-user1对Clluster1集群的访问。

(图片来源:https://www.cnblogs.com/linuxk/)

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

生成证书

[root@master manifests]# cd /etc/kubernetes/pki/
[root@master pki]# (umask 077;openssl genrsa -out white.key 2048)
Generating RSA private key, 2048 bit long modulus
..........................................................+++
................................+++
e is 65537 (0x10001)
[root@master pki]# ls -l white.key 
-rw------- 1 root root 1679 4月   4 14:49 white.key

使用ca.crt 签署证书

[root@master pki]# openssl req -new -key white.key -out white.csr -subj "/CN=white" # 证书签署请求

[root@master pki]# openssl x509 -req -in white.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out white.crt  -days 365 #证书签署
Signature ok
subject=/CN=white
Getting CA Private Key

[root@master pki]#  openssl x509 -in white.crt -text -noout
[root@master pki]# kubectl config set-credentials  white --client-certificate=./white.crt --client-key=./white.key --embed-certs=true
User "white" set.

添加到用户认证

[root@master pki]# kubectl config set-context white@kubernetes --cluster=kubernetes --user=white
Context "white@kubernetes" created.

[root@master pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.10:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: white
  name: white@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

切换账号

[root@master pki]# kubectl config use-context white@kubernetes
Switched to context "white@kubernetes".
[root@master pki]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "system:anonymous" cannot list resource "pods" in API group "" in the namespace "default"

当切换成magedu用户进行访问集群时,由于magedu该账户没有管理集群的权限,所以在获取pods资源信息时,会提示Forrbidden。那么下面就再来了解一下怎么对账户进行授权.

RBAC简介

Kubernetes的授权是基于插件形式的,其常用的授权插件有以下几种:

  • Node(节点认证)
  • ABAC(基于属性的访问控制)
  • RBAC(基于角色的访问控制)
  • Webhook(基于http回调机制的访问控制)

让一个用户(Users)扮演一个角色(Role),角色拥有权限,从而让用户拥有这样的权限,随后在授权机制当中,只需要将权限授予某个角色,此时用户将获取对应角色的权限,从而实现角色的访问控制。如图:

基于角色的访问控制(Role-Based Access Control, 即RBAC)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过Kubernetes API动态配置策略。

在k8s的授权机制当中,采用RBAC的方式进行授权,其工作逻辑是  把对对象的操作权限定义到一个角色当中,再将用户绑定到该角色,从而使用户得到对应角色的权限。此种方式仅作用于名称空间当中,这是什么意思呢?当User1绑定到Role角色当中,User1就获取了对该NamespaceA的操作权限,但是对NamespaceB是没有权限进行操作的,如get,list等操作。
另外,k8s为此还有一种集群级别的授权机制,就是定义一个集群角色(ClusterRole),对集群内的所有资源都有可操作的权限,从而将User2,User3通过ClusterRoleBinding到ClusterRole,从而使User2、User3拥有集群的操作权限。Role、RoleBinding、ClusterRole和ClusterRoleBinding的关系如下图:

这里有2种绑定ClusterRoleBinding、RoleBinding。也可以使用RoleBinding去绑定ClusterRole。
当使用这种方式进行绑定时,用户仅能获取当前名称空间的所有权限。为什么这么绕呢??举例有10个名称空间,每个名称空间都需要一个管理员,而该管理员的权限都是一致的。那么此时需要去定义这样的管理员,使用RoleBinding就需要创建10个Role,这样显得更加繁重。为此当使用RoleBinding去绑定一个ClusterRole时,该User仅仅拥有对当前名称空间的集群操作权限,换句话说,此时只需要创建一个ClusterRole就解决了以上的需求。

注意:RoleBinding仅仅对当前名称空间有对应的权限。

在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由命名空间(namespace)内的Role对象定义,而整个Kubernetes集群范围内有效的角色则通过ClusterRole对象实现。

Kubernetes RBAC演示

1、User --> Rolebinding --> Role
创建角色 一个Role对象只能用于授予对某一单一命名空间中资源的访问权限
语法:

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

--verb指定权限,--resource指定资源或者资源组,--dry-run单跑模式并不会创建

[root@master manifests]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml #干跑查看定义格式
apiVersion: rbac.authorization.k8s.io/v1
kind: Role    #资源类型
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:    #目标api群组
  - ""
  resources:   #目标资源
  - pods
  verbs:     #操作权限
  - get
  - list
  - watch
  
[root@master manifests]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml

[root@master manifests]# 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@master manifests]# kubectl apply -f role-demo.yaml 
role.rbac.authorization.k8s.io/pods-reader created
[root@master manifests]# kubectl get role
NAME          AGE
pods-reader   5s
[root@master manifests]# kubectl describe role pods-reader
Name:         pods-reader
Labels:       <none>
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的权限

角色绑定 RoleBinding可以引用在同一命名空间内定义的Role对象。

语法

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

--role|--clusterrole指定绑定哪个角色,--user指定哪个用户

[root@master manifests]# kubectl create rolebinding white-read-pod --role=pods-reader --user=white --dry-run -o yaml>rolebinding-demo.yaml

[root@master manifests]# vim rolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: white-read-pod
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: white


[root@master manifests]# kubectl apply -f rolebinding-demo.yaml    #创建角色绑定
rolebinding.rbac.authorization.k8s.io/white-read-pod created
[root@master manifests]# kubectl describe rolebinding white-read-pod
Name:         white-read-pod
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name":"white-read...
Role:
  Kind:  Role
  Name:  pods-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  white      #查看角色绑定的信息,这里可以看到user:white绑定到了pods-reader这个角色上

[root@master manifests]# kubectl config use-context white@kubernetes #切换white这个用户,并使用get获取pods资源信息
Switched to context "white@kubernetes".
[root@master manifests]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
myapp-0       1/1     Running   0          4d18h
myapp-1       1/1     Running   0          4d18h
myapp-2       1/1     Running   0          4d18h
myapp-3       1/1     Running   0          4d18h
pod-sa-demo   1/1     Running   0          3d21h

从上面的操作,可以总结出,role的定义和绑定,仅作用于当前名称空间,在获取ingress-nginx名称空间时,一样会出现Forbidden!!!

[root@master manifests]# kubectl get pods -n ingress-nginx
Error from server (Forbidden): pods is forbidden: User "white" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
[root@master manifests]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "white" cannot list resource "pods" in API group "" in the namespace "kube-system"

2、User --> Clusterrolebinding --> Clusterrole
clusterrole定义
ClusterRole对象可以授予与Role对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:

  • 集群范围资源(例如节点,即node)
  • 非资源类型endpoint(例如”/healthz”)
  • 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod)
[root@master manifests]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

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

[root@master manifests]# kubectl apply -f clusterrole-demo.yaml 
clusterrole.rbac.authorization.k8s.io/cluster-reader created

这里我们需要切换回kubernetes-admin账户,是由于white账户不具备创建的权限,这也说明普通用户是无法进行创建K8S资源的,除非进行授权。如下,我们另开一个终端,将配置到一个普通用户ik8s上,使其使用white账户进行通信

[root@master manifests]# useradd ik8s
[root@master manifests]# cp -rp ~/.kube/ /home/ik8s/
[root@master manifests]# chown -R ik8s.ik8s /home/ik8s/
[root@master manifests]# su - ik8s
[ik8s@master ~]$ kubectl config view 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.10:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: white
  name: white@kubernetes
- context:
    cluster: ""
    user: ""
  name: xiaomi
current-context: white@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: white
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

clusterrolebinding定义

#清理原有的rolebinding
[root@master manifests]# kubectl get rolebinding
NAME              AGE
white-read-pods   22m
[root@master manifests]# kubectl delete rolebinding white-read-pods 
rolebinding.rbac.authorization.k8s.io "white-read-pods" deleted

#删除后,在ik8s普通用户上进行获取pods资源信息,就立马出现forbidden了

[ik8s@master ~]$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "white" cannot list resource "pods" in API group "" in the namespace "default"

#创建clusterrolebinding
[root@master manifests]# kubectl create clusterrolebinding white-read-all-pods  --clusterrole=cluster-reader --user=white --dry-run -o yaml >clusterrolebinding-demo.yaml
[root@master manifests]# vim clusterrolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: white-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: white
  

[root@master manifests]# kubectl apply -f clusterrolebinding-demo.yaml
clusterrolebinding.rbac.authorization.k8s.io/white-read-all-pods created
[root@master manifests]# kubectl get clusterrolebinding|grep white
white-read-all-pods  
[root@master manifests]# kubectl describe clusterrolebinding white-read-all-pods
Name:         white-read-all-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"white-read-all-pods"},"...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  white  

角色绑定后在ik8s终端上进行获取pods信息,已经不会出现forbidden了

[ik8s@master ~]$ kubectl get pods   
NAME          READY   STATUS    RESTARTS   AGE
myapp-0       1/1     Running   0          4d18h
myapp-1       1/1     Running   0          4d18h
myapp-2       1/1     Running   0          4d18h
myapp-3       1/1     Running   0          4d18h
pod-sa-demo   1/1     Running   0          3d21h
[ik8s@master ~]$ kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-78d4cf999f-6cb69         1/1     Running   0          11d
coredns-78d4cf999f-tflpn         1/1     Running   0          11d
etcd-master                      1/1     Running   0          11d
kube-apiserver-master            1/1     Running   0          11d
kube-controller-manager-master   1/1     Running   0          11d
kube-flannel-ds-amd64-gtv85      1/1     Running   0          11d
kube-flannel-ds-amd64-gwbql      1/1     Running   1          11d
kube-flannel-ds-amd64-ml7nf      1/1     Running   0          11d
kube-proxy-ch4vp                 1/1     Running   0          11d
kube-proxy-cz2rf                 1/1     Running   1          11d
kube-proxy-kdp7d                 1/1     Running   0          11d
kube-scheduler-master            1/1     Running   0          11d

但是进行删除pod就无法进行,因为在授权时是没有delete权限的

[ik8s@master ~]$ kubectl delete pods myapp-0
Error from server (Forbidden): pods "myapp-0" is forbidden: User "white" cannot delete resource "pods" in API group "" in the namespace "default"

从上面的实验,我们可以知道对用户white进行集群角色绑定,用户white将会获取对集群内所有资源的对应权限。
3、User --> Rolebinding --> Clusterrole
将white通过rolebinding到集群角色white-read-pods当中,此时,white仅作用于当前名称空间的所有pods资源的权限

[root@master manifests]# kubectl delete clusterrolebinding white-read-all-pods
clusterrolebinding.rbac.authorization.k8s.io "white-read-all-pods" deleted

[root@master manifests]# kubectl create rolebinding white-read-pods --clusterrole=cluster-reader --user=white --dry-run -oyaml >rolebinding-clusterrole-demo.yaml

[root@master manifests]# vim rolebinding-clusterrole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: white-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: white


[root@master manifests]# kubectl apply -f rolebinding-clusterrole-demo.yaml 
rolebinding.rbac.authorization.k8s.io/white-read-pods created

[ik8s@master ~]$  kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
myapp-0       1/1     Running   0          4d18h
myapp-1       1/1     Running   0          4d18h
myapp-2       1/1     Running   0          4d18h
myapp-3       1/1     Running   0          4d18h
pod-sa-demo   1/1     Running   0          3d21h
[ik8s@master ~]$  kubectl get pods -n ingress-nginx
Error from server (Forbidden): pods is forbidden: User "white" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
[ik8s@master ~]$  kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "white" cannot list resource "pods" in API group "" in the namespace "kube-system"
[ik8s@master ~]$ 

RBAC的三种授权访问

BAC不仅仅可以对user进行访问权限的控制,还可以通过group和serviceaccount进行访问权限控制。当我们想对一组用户进行权限分配时,即可将这一组用户归并到一个组内,从而通过对group进行访问权限的分配,达到访问权限控制的效果。

从前面serviceaccount我们可以了解到,Pod可以通过 spec.serviceAccountName来定义其是以某个serviceaccount的身份进行运行,当我们通过RBAC对serviceaccount进行访问授权时,即可以实现Pod对其他资源的访问权限进行控制。也就是说,当我们对serviceaccount进行rolebinding或clusterrolebinding,会使创建Pod拥有对应角色的权限和apiserver进行通信。如图:

参考资料

https://www.cnblogs.com/linuxk
马永亮. Kubernetes进阶实战 (云计算与虚拟化技术丛书)
Kubernetes-handbook-jimmysong-20181218

posted @ 2019-04-12 10:16  微落不落  阅读(8017)  评论(0编辑  收藏  举报