x.kubernetes之认证、授权和准入控制

一.认证基本概念

1.1 为何需要认证

1.2 认证的流程

1.3 认证账户的类型

二.基于ServiceAccount认证实践

2.1 使用默认sa认证api

2.2 创建sa并与pod关联

2.3 为sa添加私有仓库认证

三.kubernetes基于user认证实践

3.1 kubeconfig的作用

3.2 kubeconfig文件格式

3.3 自定义kubeconfig实践

四.RBAC授权

4.1 什么是RBAC

4.2 RBAC角色与集群角色

4.3 RBAC场景实践

4.4 内置的ClusterRole

5.认证与授权实践

5.1 Dashboard介绍

5.2 Dashboard安装

5.3 Dashboard认证授权

========================================================================

一.认证基本概念

1.1 为何需要认证

对于kubernetes系统来说,apiserver肯定不是可以轻易访问的,如果轻易可以访问,意味着可以通过命令或者工具访问apiserver,对kubernetes进行操作。在kubernetes随便轻易部署应用程序,还可以删除正在运行的应用程序,这是非常危险的操作。所以需要访问apiserver的用户或者程序进行身份认证,确保身份的合法性。
API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证、操作权限验证以及操作规范验证等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。

1.2 认证流程

任何客户端用户试图通过apiserver操作资源对象时,必须经历多个阶段的访问控制,才会被接受处理,其中包括 认证 授权 准入控制

  • 1.认证: 任何客户端访问,经过api操作之前,需要完成认证操作,也就是身份认证
  • 2.授权: 认证通过后仅代表它是一个合法的用户或者系统用户,它是否拥有资源的增删改查权限需要 授权检查
  • 3.准入控制: 虽然我们有了权限,也可以创建各种资源,但是创建是否成功取决于名称空间的资源限制。假如ops名称空间限制最多创建2个pod,目前已经创建2个pod,无法再进行pod的创建

1.3 认证账户的类型

  • UserAccount: 使用kubernetes创建资源,首先进行客户端身份认证,所以客户端每次请求apiserver时都会携带数字证书,用于认证apiserver,当认证通过后,证书中的subject将被识别为用户标识,其中的CN字段的值为用户名, 字段O的值为组织名称,例如:Subject: O:ops,CN=yangtao 用户名为yangtao 组为 ops
  • ServiceAccount: 有些情况下,我们希望在pod内部能够访问apiserver,获取集群的内部信息,甚至对集群进行改动,针对这个情况,kubernetes提供了特殊的认证方式: ServiceAccout
    默认情况下创建的pod如果没有指定ServiceAccount则系统会默认提供一个serviceaccout,而后通过mount方式挂载到pod的文件系统中,该ServiceAccount能通过DownWardAPI获取该pod相关的一些元数据信息。当然也可以自行创建ServiceAccount来完成APIserver的身份认证,是否能对集群进行改变,则需要看该ServiceAccount是否拥有权限

二.基于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/

2.1 使用默认sa认证api

当创建pod时,如果没有制定serviceaccount,pod会注入对应名称空间中的default服务账户。如果你查看pod的原始yaml(例如: kubectl get pod/podname -o yaml),你可以看到spec.ServiceAccountName字段已经被自动设置了。

]# kubectl get pod tools -o yaml
apiVersion: v1
kind: Pod
metadata:
spec:
   serviceAccountName: default

2.2 创建sa并与pod关联

1.创建ServiceAccount

命令方式创建

kubectl create service accountpod-sa --namespace=default

清单文件写法

apiVersion: v1
kind: ServiceAccount
metadata:
    name: pod-sa
    namespace: default
    automountServiceAccountToken: true  #自动挂在API凭据

2.pod清单文件应用ServiceAccount

]# cat pod-test-sa.yaml
apiVersion: v1
kind: Pod
metadata:
    name: pod-test-sa
spec:
   serviceAccountName: pod-sa              #指定pod运行时使用的serviceaccount
   containers:
   - name: nginx
     image: nginx

3.访问pod,测试sa用户能否认证apiserver

root@pod-test-sa:/# cd /var/run/secrets/kubernetes.io/serviceaccount/
root@pod-test-sa:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)"  https://kubernetes/api/v1/namespaces/default
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "namespaces \"default\" is forbidden: User \"system:serviceaccount:default:pod-sa\" cannot get resource \"namespaces\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "name": "default",
    "kind": "namespaces"
  },
  "code": 403

4.虽然sa账户能通过https方式认证api可以访问,但没有权限访问任何资源(所以先暂时分配一个集群管理员权限,测试效果)

kubectl create rolebinding role-sa-admin --clusterrole=admin --serviceaccount=default:pod-sa

5.再次测试sa是否能访问apiserver

root@pod-test-sa:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)"  https://kubernetes/api/v1/namespaces/default
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "default",
    "uid": "9c2fef52-672e-404d-8627-90356b06fe11",
    "resourceVersion": "36",
    "creationTimestamp": "2023-04-24T10:50:25Z",
    "labels": {
      "kubernetes.io/metadata.name": "default"
    },
    "managedFields": [
      {
        "manager": "kube-apiserver",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2023-04-24T10:50:25Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {
          "f:metadata": {
            "f:labels": {
              ".": {},
              "f:kubernetes.io/metadata.name": {}
            }
          }
        }
      }
    ]
  },
  "spec": {
    "finalizers": [
      "kubernetes"
    ]
  },
  "status": {
    "phase": "Active"
  }
}

2.3 为sa添加私有仓库认证

pod通过ServiceAccountName来完成私有仓库认证,可以不使用imagePullSecret,因为在ServiceAccount中有Image Pull Secrets这个字段,可以将认证仓库信息给附加进去。
1.创建一个ImagePull,所需的Secret资源

kubectl create secret docker-registry myregistry \
--docker-server=xxxxxxx \
--docker-username=xxxxxx \
--docker-password=123456

2.创建serviceaccount,定义名称,然后将镜像拉取secret添加到该账号下;

]# cat pod-imagepull-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
    name: pod-imagepull-sa             #sa账号名称
imaePullSecrets:
   - name: myregistry

3.创建私有pod,测试能否通过sa下载镜像

[root@k8s-240 serviceaccount]# cat pod-imagepull.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-imagepull
spec:
  serviceAccount: pod-imagepull-sa
  containers:
  - name: alpine
    image: harbor.faone.cn:180/test/alpine:3.6

拉取镜像

Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  14s                default-scheduler  Successfully assigned default/pod-imagepull to flyfish82
  Normal   Pulling    13s                kubelet            Pulling image "harbor.faone.cn:180/test/alpine:3.6"
  Normal   Pulled     12s                kubelet            Successfully pulled image "harbor.faone.cn:180/test/alpine:3.6" in 1.067109831s (1.067119144s including waiting)
  Normal   Created    12s (x2 over 12s)  kubelet            Created container alpine
  Normal   Started    12s (x2 over 12s)  kubelet            Started container alpine
  Normal   Pulled     12s                kubelet            Container image "harbor.faone.cn:180/test/alpine:3.6" already present on machine
  Warning  BackOff    10s (x2 over 11s)  kubelet            Back-off restarting failed container alpine in pod pod-imagepull_default(598cda3a-ecf8-4730-87a4-615ccb6840b0)

三.kubernetes基于user认证实践

3.1 kubeconfig的作用

由于APIServer是基于无状态 HTTP/HTTPS 协议实现,所以每次与集群进行交互时都需要进行身份认证,通常都是使用证书进行认证,其认证所需要的信息都会存放在kubeconfig文件中

客户端程序可铜鼓默认路径,--kubeconfig选项或KUBECONFIG环境变量定义要加载的kubeconfig文件,从而每次的请求都能通过apiserver

3.2 kubeconfig文件格式

kubeconfig文件主要分为四个部分; cluster,users ,context,current-context

  • cluster: 定义集群的信息 包含ca证书 apiserver的入口 集群的名称
  • users: 定义用户的信息 访问apiserver携带的证书(证书包含组名称 用户名称) 定义用户的名称
  • context: 集群和用户进行绑定 而后定义在context中
  • cuttent-context: 访问集群时使用的默认context,表示当前使用那个用户访问那个集群。

默认使用kubeadm初始化kubernetes集群过程中,在master节点上生成/etc/kubernetes/admin.conf文件就是一个kubeconfig格式的文件,它由kubeadm命令自动生成,可由kubectl加载后接入当前集群的apiserver
默认kubectl加载的kubeconfig文件默认路径为$HOEM/.kube/config,当然也可以通过--kubeconfig选项,或KUBECONFIG环境变量将其修改为其他路径

3.3 自定义kubeconfig实践

创建一个UserAccount的用户,然后加入到kubeconfig文件中,最后通过kubectl加载kubeconfig文件中对应的证书信息,然后尝试认证到apiserver。
UserAccount用户不可以直接创建,需要创建证书we年,在证书申请文件中填写好证书对应的CN,也就是我们的用户名称,而后经由apiserver信任。
CA(/etc/kubernetes/pki/ca.crt)签署证书请求文件。最后与APIServer进行认证时,APIServer会获取整数中的CN信息,判断用户是否合法的。

3.3.1 加入已有集群配置文件

1.创建证书私钥文件

mkdir /root/.certs
(umask 077;openssl genrsa -out /root/.certs/yangtao.key 2048)

2.创建证书签署请求文件,-subj选项中的CN的值将被APIServer识别为用户名,O的值将被识别为用户组

openssl req -new \
-key /root/.certs/yangtao.key \
-out /root/.certs/yangtao.csr \
-subj "/CN=yangtao/O=devops" 

3.使用kubernetes-ca的身份对文件进行签署。

openssl  x509 -req -days 3650 \
-in /root/.certs/yangtao.csr \
-CA /opt/kubernetes/ssl/ca.pem \
-CAkey /opt/kubernetes/ssl/ca-key.pem \
-CAcreateserial -out /root/.certs/yangtao.crt

4.根据x509数字证书及私钥创建身份凭证

kubectl config set-credentials yangtao \
--client-certificate=/root/.certs/yangtao.crt \
--client-key=/root/.certs/yangtao.key \
--embed-certs=true

5.配置context上下文,将yangtao用户与集群进行绑定

kubectl config set-context yangtao@kubernetes \
--cluster=kubernetes \
--user=yangtao

6.将当前上下文切换为yangtao@kubernetes

kubectl config use-context yangtao@kubernetes

7.测试oldxu用户是否能通过APIServer认证

[root@k8s-240 ~]# kubectl get pod 
Error from server (Forbidden): pods is forbidden: User "yangtao" cannot list resource "pods" in API group "" in the namespace "default"
#虽然报错,但是yangtao用户已被APIServer认证成功
3.3.2 创建新的集群配置文件

1.添加集群配置,设定集群名称,设定APIServer地址,以及APIServer信任的CA证书;

kubectl config set-cluster aliyun_k8s \
--kubeconfig=/tmp/config \
--server="https://172.16.10.81:6443" \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true

2.添加身份凭据,使用CA已签署的客户端证书即可

kubectl config set-credentials yangtao \
--kubeconfig=/tmp/config \
--client-certificate=/root/.certs/yangtao.crt \
--client-key=/root/.certs/yangtao.key \
--embed-certs=true

3.将yangtao用户与aliyun_k8s集群建立映射关系

kubectl config set-context yangtao@aliyun_k8s \
--cluster=aliyun_k8s \
--user=yangtao \
--kubeconfig=/tmp/config

4.设定默认上下文为yangtao@aliyun_k8s

kubectl config use-context yangtao@aliyun_k8s  --kubeconfig=/tmp/config

5.yangtao用户未设置任何授权,但它能够被识别为oldxu用户,这表示身份认证是正常,后续就可以授权了

kubectl get nodes --kubeconfig=/tmp/config --context="yangtao@aliyun_k8s"
Error from server (Forbidden): nodes is forbidden: User "yangtao" cannot list resource "nodes" in API group "" at the cluster scopeip a

四.RBAC授权

4.1 什么是RBAC

RBAC (Role Based Access Control) 基于角色的访问控制;其实就是将资源的操作权限授予给指定的角色,而后将用户加入该角色,那么该用户则拥有了对应角色的权限;
举例: 希望yangtao用户能获取所有Pod的列表
1.首先定义角色,然后定义角色权限规则,资源: Pod,操作权限: get,list
2.然后定义角色绑定,将yangtao绑定至该角色,而后yangtao就拥有了该角色的权限,进而就能获取pod信息;

4.2 RBAC角色与集群角色

kubernetes系统的RBAC授权插件将角色分为了Role和ClusterRole两类;

  • role: 仅作用于名称空间级别,用于承载名称空间级别资源的权限集合
  • clusterrole: 作用于集群范围,能够同时承载名称空间和集群级别的资源权限集合
    kubernetes利用role和cousterrole两类角色来赋予对应的权限,同时也需要用到另外两类资源rolebinding和clusterrolebinding来完成用户与角色之间的绑定关系;

    注意: Rolebinding除了可以绑定role以外,还可以绑定clusterrole,但它的权限还是限制在名称空间级别
    这种方式有着特定的应用场景:
    比如希望在三个名称空间中都创建一个管理员身份,那么我们就需要创建三个role和三个rolebinding
    但是我们可以定义一个clusterrole,然后通过rolebinding绑定就完成了,也就不需要重复创建很多的role

4.3 RBAC场景实践

事件场景1
场景说明: 赋予oldxu用户对default名称空间拥有pod的读取权限;

# 命令方式
kubectl create role default-pod-reader --resource=pod --verb=get,list,watch --namespace=default
# yaml方式
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: default-pod-reader
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

2.创建rolebinding角色绑定,将oldxu绑定至对应的role上

# 命令方式
kubectl create rolebinding oldxu-default-pod-reader \
--role=default-pod-reader \
--user=oldxu \
--namespace=default

#yaml方式
cat default-rolebinding-oldxu.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: oldxu-default-pod-reader
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: default-pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: oldxu

3.使用oldxu用户验证权限

[root@master rbac]# kubectl get pod -n default --context="oldxu@kubernetes"

NAME                                READY   STATUS    RESTARTS   AGE
app-deploy-687dd6f47f-7k6hm3d19h    1/1     Running   0          19h
app-deploy-687dd6f47f-pcq4j3d19h    1/1     Running   0          19h
# 非default名称空间,访问会报错
[root@master rbac]# kubectl get pod -n kube-system --context="oldxu@kubernetes"
Error from server (Forbidden): pods is forbidden: User "oldxu" cannot list resource "pods" in API group "" in the namespace "kube-system"

实践场景2
场景说明: 赋予oldxu用户对所有名称空间拥有Pod的读取权限(clusterrole clusterrolebinding)
1.创建clusterrole

#命令方式
kubectl create clusterrole cluster-pod-reader --resource=pod --verb=get,list,watch

#yaml方式
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

2.创建clusterrolebinding,并绑定oldxu用户至对饮的clusterrole

#命令方式
[root@master ~]# kubectl create clusterrolebinding cluster-pod-reader-oldxu --clusterrole=cluster-pod-reader --user=oldxu

#yaml方式
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-pod-reader-oldxu
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: oldxu

3.使用oldxu用户验证权限

[root@master rbac]# kubectl get pod --context="oldxu@kubernetes"
[root@master rbac]# kubectl get pod -n kube-system --context="oldxu@kubernetes"
[root@master rbac]# kubectl delete pod tools --context="oldxu@kubernetes"
Error from server (Forbidden): pods "tools" is forbidden: User "oldxu" cannot delete resource "pods" in API group "" in the namespace "default"

实践场景3
场景说明: 赋予oldxu用户对default名称空间拥有管理员权限;
系统内置了一个clusterRole: admin的集群管理员,我们可以通过 rolebinding 引用CLusterRole: admin 集群角色,该引用会造成用户仅对 rolebinding 所在的名称空间有管理员权限。(因为rolebinding仅能作用在名称空间。)
1.删除此前的绑定,避免权限收到干扰

[root@master rbac]# kubectl delete clusterrolebindings cluster-pod-reader-oldxu

2.创建rolebinding引用clusterrole

[root@master rbac]# kubectl create rolebinding oldxu --clusterrole=admin --user=oldxu --namespace=default

3.验证Oldxu用户权限

[root@master rbac]# kubectl delete pod mall --context="oldxu@kubernetes"
[root@master rbac]# kubectl get pod --context="oldxu@kubernetes"

# 能对default名称空间进行增删改,对其他名称空间毫无权限

[root@master rbac]# kubectl get pod -n kube-system --context="oldxu@kubernetes"
Error from server (Forbidden): pods is forbidden: User "oldxu" cannot list resource "pods" in API group "" in the namespace "kube-system"

4.4 内置的ClusterRole

kubernetes系统内置了一组默认的clusterrole和clusterrolebinding资源预留给系统使用,其中大多数都以system:为前缀。还有一些不以system:为前缀的clusterrole是面向用户设计的,比如:集群管理员角色 cluster-admin、admin、edit、view,掌握这些默认的内置角色资源有助于按需创建用户并分配相应的权限;

4.4.1 Cluster-admin分析

内置的cluser-admin资源拥有管理集群所有资源的权限,而内置的cluster-admin将改角色分配给了system:master组,这意味着所有加入该组的用户都将自动具有集群的超级管理员权限。
在使用kubeadm安装集群时,它自动创建配置文件/etc/kubernetes/admin.conf中定义的用户为kubernetes-admin,而该用户使用数字证书,Subject属性值为/O=system:master. 所以APIServer会在成功验证该用户的身份后将其识别为system:master
用户组成员

分析过程如下:
1.查看cluster-admin角色的绑定关系,可以看到cluster-admin这个角色绑定的system:masters

[root@k8s-240 ~]# kubectl get clusterrolebinding cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2023-04-24T10:50:26Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters

2.system:masters这个组名称非人为定义,而是证书生成的

[root@k8s-240 ~]# openssl x509 -in /opt/kubernetes/ssl/server.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            75:fe:b7:23:a1:30:71:26:1d:39:72:67:32:78:b5:b2:e5:b7:0a:fe
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = CN, ST = Beijing, L = Beijing, O = k8s, OU = System, CN = kubernetes
        Validity
            Not Before: Apr 24 10:15:00 2023 GMT
            Not After : Apr 21 10:15:00 2033 GMT
        Subject: C = CN, ST = BeiJing, L = BeiJing, O = k8s, OU = System, CN = kubernetes

注意: 在创建证书时,可以将用户绑定到system:masters组;用户会自动继承组的权限;

4.4.2 Cluster-admin实践

创建一个sb用户,然后将该用户加入到system:masters组中,验证是否拥有集群管理员权限;
1.创建证书私钥文件

mkdir /root/.certs  
(umask 077; openssl genrsa -out /root/.certs/sb.key 2048)

2.创建证书签署请求文件,CN为指定的用户名,O为指定的组名称。

openssl req -new -key /root/.certs/sb.key \
                 -out /root/.certs/sb.csr \
                 -subj "/CN=sb/O=system:masters"

3.使用kubernetes-ca的身份对文件进行签署

openssl x509 -req -days 3650 \
-in /root/.certs/sb.csr \
-CA /opt/kubernetes/ssl/ca.pem \
-CAkey /opt/kubernetes/ssl/ca-key.pem \
-CAcreateserial \
-out /root/.certs/sb.crt

4.根据x509数字证书及私钥创建身份凭据

kubectl config set-credentials sb \
--client-certificate=/root/.certs/sb.crt \
--client-key=/root/.certs/sb.key \
--embed-certs=true

5.配置context上下文,sb身份凭据访问已经定义的kubernetes集群,context名称为sb@kubernetes

kubectl config set-context sb@kubernetes \
--cluster=kubernetes \
--user=sb

6.测试oldxu是否具备超级管理员权限

kubectl get nodes --context="sb@kubernetes"
kubectl get pod --context="sb@kubernetes"
kubectl get pod -n kube-system --context="sb@kubernetes"
kubectl delete pod pod-imagepull 

5.认证与授权实践

5.1 Dashboard介绍

kubernetes dashboard项目为kubernetes集群提供了一个基于web的ui,支持集群管理,应用部署及故障排除等功能。dashboard是以pod方式运行在集群上,项目包含了前端和后端两个组件

  • 前端: 运行于客户端浏览器,它使用标准的HTTP/HTTPS方法,将请求发送到后端并从后端获取业务数据。
  • 后端: 负责接收前端的请求,将数据请求发送到远程后端(例如Kubernetes APIServer)来实现业务逻辑

5.2 Dashboard安装

1.使用官网默认清单文件安装,该清单文件仅提供了项目运行的最小权限,并强制启用了https协议

wget  https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
vi recommended.yaml
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard

2.部署完Dashboard支持多种不同的访问方式,这里采用NodePort方式,通过节点端口进行访问

[root@k8s-240 dashboard]# kubectl get svc -n kubernetes-dashboard 
NAME                        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.0.0.231   <none>        8000/TCP        37m
kubernetes-dashboard        NodePort    10.0.0.197   <none>        443:30001/TCP   37m

3.通过任意节点的IP + 30001端口访问Dashboard,要使用https协议;

5.3 Dashboard认证授权

Dashboard自身并不进行任何形式的身份验证和授权,它仅是把用户提交的身份凭据转发至后端的APIServer完成验证,资源的操作请求及权限检查也会提交至后端的APIServer进行

5.3.1 基于token认证与授权-1

场景: 创建一个ServiceAccount管理员账户,然后通过Dashboard的Token方式进行认证
1.创建ServiceAccount,名称为ui-admin-yang

kubectl create serviceaccount ui-admin-yang -n kubernetes-dashboard

2.将sa账户通过clusterrolebinding绑定到cluster-admin集群角色上,以便用户拥有集群管理员权限

kubectl create clusterrolebinding ui-admin-yang \
--clusterrole=cluster-admin \
--serviceaccount=kubernetes-dashboard:ui-admin-yang

3.创建token

[root@k8s-240 dashboard]# kubectl -n kubernetes-dashboard create token ui-admin-yang
eyJhbGciOiJSUzI1NiIsImtpZCI6IjdTY2kxcjlJX2hOcmoyYkZPczJzR3VaaFRnYUF3Qm1UQV84U2huUVctZXMifQ.eyJhdWQiOlsiYXBpIiwiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5MDY4ODc4LCJpYXQiOjE2ODkwNjUyNzgsImlzcyI6ImFwaSIsImt1YmVybmV0ZXMuaW8iOnsibmFtZXNwYWNlIjoia3ViZXJuZXRlcy1kYXNoYm9hcmQiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoidWktYWRtaW4teWFuZyIsInVpZCI6IjliMjI3MmMyLWQwYmQtNGM1OS05ZjJhLWEwOTE4OGE3MzI5OSJ9fSwibmJmIjoxNjg5MDY1Mjc4LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6dWktYWRtaW4teWFuZyJ9.pksXq_DIrFRuXSAS4fhIWHnUViiFnVPyY6WR6c9Z0NjbecyE1ch7sdr2ZfBCYXG7brxA_WtnOAhXt68veEe_LKPSDL-SPNv_Dq3vx6ZEkPTZAdY0-Jg7Vq5x1LGtwEiXDABQECV4Zaxx-M7jQ2xMcfBzt9_vT6nultF2vJwUr-Aa1K6ib3HZcX1NF2jeV1MsT3vthulL6dxZff95AD3nMbJ701hp4IBriESn7jrCcnlwaD7NcBQAIZ4Xd1zb5YoCCVJjFYZDNTCar3HUOd7fuOAHB_ocXgyKavETOAC90xGAI7X1DhgAeIE6OcnrZMgbzLDl_1CKfRx3cN9qfbv_tA

4.访问UI测试用户权限

5.3.2 基于token认证与授权-2

场景: 创建一个名称空间管理员账号;通过token方式认证
1.创建ServcieAccount,名称为ui-default-yang

kubectl create serviceaccount ui-default-yang -n kubernetes-dashboard

2.将sa账户通过rolebinding绑定到cluster-admin集群角色上,以便用户拥有集群管理员权限

kubectl create rolebinding  ui-default-yang \
--clusterrole=cluster-admin  \
--serviceaccount=kubernetes-dashboard:ui-default-yang \
--namespace=default

3.创建serviceaccount对应的token信息

[root@k8s-240 dashboard]# kubectl create token ui-default-yang -n kubernetes-dashboard 
eyJhbGciOiJSUzI1NiIsImtpZCI6IjdTY2kxcjlJX2hOcmoyYkZPczJzR3VaaFRnYUF3Qm1UQV84U2huUVctZXMifQ.eyJhdWQiOlsiYXBpIiwiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5MDY5ODYyLCJpYXQiOjE2ODkwNjYyNjIsImlzcyI6ImFwaSIsImt1YmVybmV0ZXMuaW8iOnsibmFtZXNwYWNlIjoia3ViZXJuZXRlcy1kYXNoYm9hcmQiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoidWktZGVmYXVsdC15YW5nIiwidWlkIjoiMmVjNTA0NTgtM2FjOC00YTIwLTlmYTMtNTFlOTc0NjhmZWI4In19LCJuYmYiOjE2ODkwNjYyNjIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDp1aS1kZWZhdWx0LXlhbmcifQ.uRZkhX0TYH9AamuPtz_9Avpjfo9OsiawzauU7WRP7I6nV0eHEz5S0g5GHy2oMg3nvhz4dWbXu1VcId9xY3yjEigfBR64SOwV84wY5bNxmB_qBWg9VWUF78Lap-aeZBs0qAwSDFEC7Nk5m0UJFFZMfzJ53awbyMZx9sICOy4jBEgxhkgRQ5epAcHO_pJs9R-sfU4K1eJFCZooatI8P8-ImhrKMKUEovslpmW8FIUeYMZj9XR-s3IhKPbuy473oF6Ltl0E8kKq3-F3YT0FKMEdTj09rB_JIjoA4zFbVuec_-g7t1oCIEk1I7piryA9-N6Bz0dTlccj5rbqkH46SUYSgA

4.访问UI,测试用户是否仅对Default名称空间所有资源有权限

5.3.3 基于kubeconfig认证与授权

每次访问Dashboard之前都要先通过命令获取令牌是相当繁琐的事情,更简单的办法就是根据该身份创建一个专用于kubeconfig为念并存储至客户端,随后登录时在浏览器中通过本地路径加载该文件即可。
但是创建的kubeconfig不可以直接使用/root/.kube/config文件,因为他是useraccount,不是serviceaccount。
1.创建servcieaccount用户,并分配对应的权限(也可以使用之前的sa账户)

kubectl create serviceaccount  ui-cluster-admin -n  kubernetes-dashboard
kubectl create clusterrolebinding ui-cluster-admin \
--clusterrole=cluster-admin  \
--serviceaccount=kubernetes-dashboard:ui-cluster-admin

2.创建kubeconfig配置文件,设定集群信息

kubectl config set-cluster UI \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--server="https://172.16.10.81:6443" \
--kubeconfig=/tmp/ui.config \
--embed-certs=true

3.添加身份凭据

ADMIN_TOKEN=$(kubectl create token ui-cluster-admin -n kubernetes-dashboard)

#基于serviceaccount名称,以及对应的token,创建身份凭据
kubectl config set-credentials ui-cluster-admin \
--token=$ADMIN_TOKEN  \
--kubeconfig=/tmp/ui.config

4.将对应的用户凭据于kubernetes集群建立映射关系

kubectl config set-context ui-cluster-admin@UI \
--cluster=UI \
--user=ui-cluster-admin \
--kubeconfig=/tmp/ui.config

5.设置当前上下文为 ui-cluster-admin@UI

kubectl config use-context ui-cluster-admin@UI --kubeconfig=/tmp/ui.config

6.导出配置文件,登录并测试

===================================================

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

[root@master magedu]# kubectl get ns
NAME                   STATUS   AGE
default                Active   20d
dev-namespace          Active   20d
[root@master magedu]# kubectl get sa -n dev-namespace
NAME      SECRETS   AGE
default   1         20d
[root@master magedu]# kubectl get secret -n dev-namespace 
NAME                  TYPE                                  DATA   AGE
default-token-89wp8   kubernetes.io/service-account-token   3      20d
[root@master magedu]# kubectl describe secrets default-token-89wp8  -n dev-namespace 
Name:         default-token-89wp8
Namespace:    dev-namespace
Type:  kubernetes.io/service-account-token

Data
====
namespace:  13 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImxvTjBGUXNUNVYzUkVBVTlOdFpjZW9aMkszd3NsVjZYbkJEWE1CazlrSVEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXYtbmFtZXNwYWNlIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tODl3cDgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImU4YmQwMTEyLWMwNzYtNDFmMS1hMzFkLTM2ZDc0ZjNmY2UzNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZXYtbmFtZXNwYWNlOmRlZmF1bHQifQ.BM_6tEpc4aIk_cbPY8sw1H5alnSmZXQuro5cpO2rng-rLyNZSVQLNC5enQ0IrqlA6Ei75FAXzm7XjID3uaeEwy4QpPEyFKODvILwb_FfIXhCviS0B-3UQTEjbcvyjRwduhayki6dZlEcvGIaz4EOw0dyNixZ4QcnUVkfAwXPjU--w7Vg-QHntf8xbYEndlWtYAUlmHqeWxf9WzYYJAyLNfisDbTZBq_0_04IBzRATzqYRi1rx-93luXftdetMkpCsV2ditASNatWcIxTiIeruYBv42fVZLHhM27GREEO3RnbdTWYohk0evN-Ua1DMfZs4BLyLrgr1NBQnAR7xFj-aw
ca.crt:     1066 bytes

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

[root@master magedu]# kubectl explain serviceaccount
KIND:     ServiceAccount
VERSION:  v1

DESCRIPTION:
     ServiceAccount binds together: * a name, understood by users, and perhaps
     by peripheral systems, for an identity * a principal that can be
     authenticated and authorized * a set of secrets

FIELDS:
   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   automountServiceAccountToken	<boolean>
     AutomountServiceAccountToken indicates whether pods running as this service
     account should have an API token automatically mounted. Can be overridden
     at the pod level.

   imagePullSecrets	<[]Object>
     ImagePullSecrets is a list of references to secrets in the same namespace
     to use for pulling any images in pods that reference this ServiceAccount.
     ImagePullSecrets are distinct from Secrets because Secrets can be mounted
     in the pod, but ImagePullSecrets are only accessed by the kubelet. More
     info:
     https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   secrets	<[]Object>
     Secrets is the list of secrets allowed to be used by pods running using
     this ServiceAccount. More info:
     https://kubernetes.io/docs/concepts/configuration/secret

service account的创建

[root@k8s-master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run #不执行查看定义方式
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: mysa

[root@k8s-master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml  #直接导出为yaml定义文件,可以节省敲键盘的时间
[root@k8s-master mainfests]# kubectl apply -f serviceaccount.yaml 
serviceaccount/mysa created
[root@k8s-master mainfests]# kubectl get serviceaccount/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: 2018-10-11T08:12:25Z
  name: mysa
  namespace: default
  resourceVersion: "432865"
  selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
  uid: 62fc7782-cd2d-11e8-801a-000c2972dc1f
secrets:
- name: mysa-token-h2mgk

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

serviceaccount的自定义使用

这里在default名称空间创建了一个sa为admin,可以看到已经自动生成了一个Tokens:admin-token-7k5nr。

[root@k8s-master mainfests]# kubectl create serviceaccount admin
serviceaccount/admin created
[root@k8s-master mainfests]# kubectl get sa
NAME      SECRETS   AGE
admin     1         3s
default   1         50d
[root@k8s-master mainfests]# kubectl describe sa/admin
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-7k5nr
Tokens:              admin-token-7k5nr
Events:              <none>
[root@k8s-master mainfests]# kubectl get secret
NAME                    TYPE                                  DATA      AGE
admin-token-7k5nr       kubernetes.io/service-account-token   3         31s
default-token-j5pf5     kubernetes.io/service-account-token   3         50d
mysecret                Opaque                                2         1d
tomcat-ingress-secret   kubernetes.io/tls                     2         10d
[root@k8s-master mainfests]# vim pod-sa-demo.yaml  #Pod中引用新建的serviceaccount
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
[root@k8s-master mainfests]# kubectl apply -f pod-sa-demo.yaml 
pod/pod-sa-demo created
[root@k8s-master mainfests]# kubectl describe pods pod-sa-demo
......
Volumes:
  admin-token-7k5nr:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-7k5nr
    Optional:    false
......

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

[root@k8s-master mainfests]# kubectl config view
apiVersion: v1
clusters:  #集群列表
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.56.11: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集群的访问

(1)生成证书
[root@k8s-master pki]# cd /etc/kubernetes/pki/magedu
[root@k8s-master pki]# (umask 077;openssl genrsa -out magedu.key 2048)
Generating RSA private key, 2048 bit long modulus
............................................................................................+++
...................................................................................+++
e is 65537 (0x10001)
[root@k8s-master pki]# ll magedu.key 
-rw------- 1 root root 1675 Oct 12 23:52 magedu.key

(2)使用ca.crt进行签署
[root@k8s-master pki]# openssl req -new -key magedu.key -out magedu.csr -subj "/CN=magedu"  证书签署请求

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

(3)添加到用户认证
[root@k8s-master pki]# kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.1.242:6443  --kubeconfig=/tmp/magedu.conf
[root@k8s-master pki]# kubectl config set-credentials magedu --client-certificate=./magedu.crt --client-key=./magedu.key --embed-certs=true --kubeconfig=/tmp/magedu.conf
User "magedu" set.

[root@k8s-master pki]# kubectl config set-context magedu@kubernetes --cluster=kubernetes --user=magedu --kubeconfig=/tmp/magedu.conf
Context "magedu@kubernetes" created.

[root@k8s-master pki]# kubectl config use-context magedu@kubernetes --kubeconfig=/tmp/magedu.conf

[root@master magedu]# cat /tmp/magedu.conf 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EZ3dNekEyTURBeE9Gb1hEVE14TURnd01UQTJNREF4T0Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTkVwCnNZZ0ZIRG5sejdCRFF5d2JnT2FrZk13YnVhZW1QcEZnbmxhd2ZHOVdUZnU2aHJ0bVNlZVkvckxMRkNac2tmd2kKLzIyVkZjODRtTU1TcDN3UDA0ejl5eEM2anoxclg0SUlvczJvYjlEUWErUWZoRXJpWWNzYzMvMGJ1aEgrUGVSMApIRWI4WitockRwTGdLVnF1eE5Wb010TlB4S2tSTTE3ekQ4Y1pXdmpaWlFXR0xBYXZ6YmwySGRFQmltaWQyMi9CCnE4a2szVmpTNmhsL1hqNTBHS3VxREpKcm1WTFlSL1l0WDR4Zm5QcitnaFJwd3FTY0xaN2w0REJXTUREL1RDbnQKcjhqcU9PTGdCc0xVcFRwdmhpVnNHOGtXckExRXBWWCtsZ3BFOTN6NFdCcjlnMGk2bDZ1MUI5MUZHTElRaG9vRgp2czl1UVdFMzJ2Y2dKYzdpMTY4Q0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZLU1k4aUhYQzRtWDZCSzFpM01ZVDNFdHF6MHNNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFCQ0R4SDNENXlIUHB4b1NJQTNmdHY3cGNDK2Rhd05XZTlsK25kRDhmQ0tSaVJRNkNmNgpPMnpOWXJtYitVa1RqY1JiN3k2bi9GbDdWQmt1L2thS1RETTZEZUlqK2djMVdMTk1wN0FHdEhPdWF1anNPNVRPCkhuVGVEdEIxRzJDOGhlclFJZ0NZSW1UMWVwWmlSU1ZYMVBoc0lqVWV6MWk1WkFrdlZNeGhvQi9FUWpGVmFrRGgKMVN0RWxNNU9IZDBydHFOTnNIU1RRd2lUYmRNRVFrSDgzaEcydmJLejVHZzNPNHFmdWQ5cGQwM24yd1BPL3ZPTgpjeUE0Y2s4eVowVXN1TVY5YkZWZHVPdzY3emtwdUNGYmpGY1RlWVZGb2Z5dVMrZlUxM3lPeG9JYWM5QXQ3b1FLCnU3cjFrUW1mZXhNeC9GbDh3M3dBclV4MEVlZlByTElKaU9tTwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://192.168.1.242:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: magedu
  name: magedu@kubernetes
current-context: magedu@kubernetes
kind: Config
preferences: {}
users:
- name: magedu
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNvakNDQVlvQ0NRREJMOE5XVW9lM2lEQU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHIKZFdKbGNtNWxkR1Z6TUI0WERUSXhNRGd5TkRBeE5Ea3lORm9YRFRNeE1EZ3lNakF4TkRreU5Gb3dFVEVQTUEwRwpBMVVFQXd3R2JXRm5aV1IxTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3cnBiCkJLWlFkNXYzbGtMWWZoa2ZFc00rNGgzcmhIVldGODFJSStuZjZzMEZ1RUViSUJNdHlRN2d6aDhoTGZLOExsd1MKVk5DTXhMNVczbkRuUWF6YUtVbVl6MktvOEMyMVpCcDFNU0l0dWlNY0JBK2F5Z2NzQXhzTHdQMWxha0l4eDNOcgpOV0pkeG9Eci9HN3MzenZkV1hzNXFtM2U0OEJMd29CTkFPM0dpNEplN0FxMjVxVG92aHpxRXpyNnMyaEtiZ1dNCjcxNkovNm1XcENCUndtNlJQQ0NiNDRjb2o4UERHWTE3TzZHanVHMVArdUlkVmRrbmZoUWltSkVteHhUd0U3akMKcFcwS2UwTDQ2M0g1R3BHaURTeXhHWDdqaGVmbklKTElLL0pacDN0UUp5ekxGS1VmOU1yMnV1aTdaUlBjOWo4eApCZDFUcjBEd3B4QUcrdEIwS1FJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFGNk5RK1p6TUkrYjd6CmxLMHRsczd3QzlLTkdUQ3RkVkpRR05ycnNZc2g2NmptMEg1eWNwZzBwZHJCZ04xTklzNEJ0OWdBbjQyVFJYSFAKaWpOOVRBeEVBMVVZZTAwSTVoWWRUeFlZUW9uVTlSZ3RsdHJwVUV1ei8rdWZ0eGhwTFc0bjBENGp6eFFWeWw5NwpiNjFNVjg5WWhqT1F5azVjWFpYSmJqdDY3MUM0ZGZuMVJUMkNoeFBWMFZzN3dEQU5LVDFpbDNJZ0pWSU0rSHhoCkw0V0paTGlkY0F5L2dKcWpUa0VJR2dQSU5FRC9zWFFkREpKZ2MyR0JRMnlNMk44VmUxNGkvQ3dreml5UmZsamkKdklMeFJrcUs1eitya1d2RnQ3K01qbGViL1JTRkQ1MFYzMERMeVF0WURzTkFCbG5WVS9hVDlDMkJZVElJdmhBcwpzT2lLQnFFNAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBd3JwYkJLWlFkNXYzbGtMWWZoa2ZFc00rNGgzcmhIVldGODFJSStuZjZzMEZ1RUViCklCTXR5UTdnemg4aExmSzhMbHdTVk5DTXhMNVczbkRuUWF6YUtVbVl6MktvOEMyMVpCcDFNU0l0dWlNY0JBK2EKeWdjc0F4c0x3UDFsYWtJeHgzTnJOV0pkeG9Eci9HN3MzenZkV1hzNXFtM2U0OEJMd29CTkFPM0dpNEplN0FxMgo1cVRvdmh6cUV6cjZzMmhLYmdXTTcxNkovNm1XcENCUndtNlJQQ0NiNDRjb2o4UERHWTE3TzZHanVHMVArdUlkClZka25maFFpbUpFbXh4VHdFN2pDcFcwS2UwTDQ2M0g1R3BHaURTeXhHWDdqaGVmbklKTElLL0pacDN0UUp5ekwKRktVZjlNcjJ1dWk3WlJQYzlqOHhCZDFUcjBEd3B4QUcrdEIwS1FJREFRQUJBb0lCQVFDTVZUek81d1RLamk0cApyZGJUV1V0WmZEZlBRUHpBSXNkK3M4UXZqWlovWW0yaTBkaTRqdG5LTWR5MDd4NDhQTmg5R0lGbGVqNVljMHVyClZ2WnlFQjNRNzJjZTNkMGQ2ZkwxUjFQNXFzWUZoTlBsNFZFT0U0a1dXK0ZtbmJiK2t1SEkrVmJqekJZRXZsaFQKUGFXYlkwc3I5M0FoY0xqV3JYaHJuWWJoQ25xeGdtcmtRbjUvbmdRa3B0eXVERytkeFRTRHdQWTZuamYzQWgyTQpnVHpDZzFLWGUvVUtSMzZ6Wmc5LzRyVklWZlBIQm0vUE9aNVhWVDJ4STU4OWdnQVJMK0F2QjZ1VzBVMkRFU0ozCmhZdlhhTC9WaDBoK1Z1OHRxR0hJeHk2RkgzZGhJT3V5NDdwNlpnek1nWmtxWjF4RUJLRUNtSVNubHNUdmFZdVkKaVRraG5YY0JBb0dCQU9iWWU3Y1Y0WE1CQkEySXBhVkZ2ZEd4MzhpUmVEVStFRmFKZ2dzVXFIZTRoTm9JeVVDWApkaEk3ZWM4aE1wM2pWdEhTVUM4TzQzTzlLa2I4NU95T3IwaVY4bWFUNGpiMjlPYUxDNExjVzY5NzhaTlo3UmFQCnVlZjRvQy9qSmgvQjJQY0h0bC8yU2U1M2hCZnAxSEM2K3VGaE9DekJ5Uy9aeFRhbzZwM2hjL3Z4QW9HQkFOZnkKVzNXSVdJSVg0YVNzeWtVZmdENytMaVdiNVA2WmY3cUxlYU9TcnN3YnFvVHQzMTJiWDc4VWEyTklFTmJkb1Fxawpxa1VyaGtuQW4rRTNwcVdXOWF5ellkcDNob2dXRFlwWWR3SVBPWG1OYzgwcFhhQ3A4NEVIMVNmYTdiNFNwSUE4Cm1DTFNlQ25sNEJUM0lIWkV3VTg3YnNQVU9wUHAzeTdyTG5tZGxKTzVBb0dBZk1NcnVmdmRhU1ozWmtrZ0hYN2YKNUdGYUxUQlI0NVN6aDlHeHN3TnJPYWxFUkFMVG9sRTV3d2phQUpSVW92aW5oNmMvSnUvSkJsaUtiT3RwWG1DUApZNCtHL3VHV05WYXJiWjVnamsxQ1VFbVFlcTd6Y0dvbGM3WHYvWEdxdlNjcmQvZDNIYzRpanZ1UkxNdDN3YVdNCnlocWRIYk51WktveDZDVExDS0U4NmtFQ2dZRUExRmhoVHdXdjR0MFE2Umx3SE9DSS8yaDZnRWozdU5QQUlmT2MKdlJnMEFra0NPSXlnSkMvd3lyaU5rS2NBeUFoUG4yT2tlemY5YVBDZFJwMnVwUTM0cnNZRjV3bTVwSC9xK0t0YwordzExZXUxNWZiaTdkSTBxQVN0dWt5NVlzWnNyWDE0MlM2ZWl1YkJ0MUsvZG4rNmtHQUZkUGZ1blRtT2ZMMGZiCi80TFE0eUVDZ1lBSFFRdm9hcklZYTVYZytyQjdUanZkN1V0c3hhaXlzNjYrS3NLZ2dPRkJBdjN6R1NhTHJqK0YKNlVreXZtRDBvMldmZjZhWW9KYzBsaVdyb3pXaGdwK091cDNLVmxTOEtpbnFPZ0pKUVRsckh5ZFBkNlJDamNOMwpOQ1ZKd1RYdHJsWlhPRVAxSXFma2hxSjk5T3JUVmpKZXk2Y0xEV1dkZ2lJVk5zNERTNkgwTUE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

[root@k8s-master pki]# kubectl config use-context magedu@kubernetes
Switched to context "magedu@kubernetes".
[root@k8s-master pki]# kubectl get pods
No resources found.
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods 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种绑定ClusterRoleBindingRoleBinding。也可以使用RoleBinding去绑定ClusterRole
当使用这种方式进行绑定时,用户仅能获取当前名称空间的所有权限。为什么这么绕呢??举例有10个名称空间,每个名称空间都需要一个管理员,而该管理员的权限都是一致的。那么此时需要去定义这样的管理员,使用RoleBinding就需要创建10个Role,这样显得更加繁重。为此当使用RoleBinding去绑定一个ClusterRole时,该User仅仅拥有对当前名称空间的集群操作权限,换句话说,此时只需要创建一个ClusterRole就解决了以上的需求。

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

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

三、Kubernetes RBAC的演示

1、User --> Rolebinding --> Role

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

[root@k8s-master ~]# kubectl create role -h   #查看角色创建帮助
Create a role with single rule.

Examples:
  # Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods
  kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
  
  # Create a Role named "pod-reader" with ResourceName specified
  kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
  
  # Create a Role named "foo" with API Group specified
  kubectl create role foo --verb=get,list,watch --resource=rs.extensions
  
  # Create a Role named "foo" with SubResource specified
  kubectl create role foo --verb=get,list,watch --resource=pods,pods/status

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
the template. Only applies to golang and jsonpath output formats.
      --dry-run=false: If true, only print the object that would be sent, without sending it.
  -o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|templatefile|template|jsonpath|jsonpath-file.
      --resource=[]: Resource that the rule applies to
      --resource-name=[]: Resource in the white list that the rule applies to, repeat this flag for multiple items
      --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the
annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
      --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it
      --verb=[]: Verb that applies to the resources contained in the rule

Usage:
  kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]
[options]
使用kubectl create进行创建角色,指定角色名称,--verb指定权限,--resource指定资源或者资源组,--dry-run单跑模式并不会创建

Use "kubectl options" for a list of global command-line options (applies to all commands).

[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 mainfests/
[root@k8s-master mainfests]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml

[root@k8s-master mainfests]# 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 mainfests]# kubectl apply -f role-demo.yaml  #角色创建
role.rbac.authorization.k8s.io/pods-reader created
[root@k8s-master mainfests]# kubectl get role
NAME          AGE
pods-reader   3s
[root@k8s-master mainfests]# 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":[{"apiGroup...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]  #此处已经定义了pods-reader这个角色对pods资源拥有get、list、watch的权限

(2)角色的绑定


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

[root@k8s-master ~]# kubectl create rolebinding -h  #角色绑定创建帮助
Create a RoleBinding for a particular Role or ClusterRole.

Examples:
  # Create a RoleBinding for user1, user2, and group1 using the admin ClusterRole
  kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
the template. Only applies to golang and jsonpath output formats.
      --clusterrole='': ClusterRole this RoleBinding should reference
      --dry-run=false: If true, only print the object that would be sent, without sending it.
      --generator='rolebinding.rbac.authorization.k8s.io/v1alpha1': The name of the API generator to use.
      --group=[]: Groups to bind to the role
  -o, --output='': Output format. One of:
json|yaml|name|templatefile|template|go-template|go-template-file|jsonpath-file|jsonpath.
      --role='': Role this RoleBinding should reference
      --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the
annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
      --serviceaccount=[]: Service accounts to bind to the role, in the format <namespace>:<name>
      --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it

Usage:
  kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]
使用kubectl create进行创建角色绑定,指定角色绑定的名称,--role|--clusterrole指定绑定哪个角色,--user指定哪个用户

Use "kubectl options" for a list of global command-line options (applies to all commands).

[root@k8s-master mainfests]# kubectl create rolebinding magedu-read-pods --role=pods-reader --user=magedu --dry-run -o yaml > rolebinding-demo.yaml
[root@k8s-master mainfests]# cat rolebinding-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: magedu-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: magedu
[root@k8s-master mainfests]# kubectl apply -f rolebinding-demo.yaml  #创建角色绑定
rolebinding.rbac.authorization.k8s.io/magedu-read-pods created

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

 [root@k8s-master ~]# kubectl config use-context magedu@kubernetes #切换magedu这个用户,并使用get获取pods资源信息
Switched to context "magedu@kubernetes".
[root@k8s-master ~]# kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
filebeat-ds-hxgdx        1/1       Running   1          36d
filebeat-ds-s466l        1/1       Running   2          36d
myapp-0                  1/1       Running   0          2d
myapp-1                  1/1       Running   0          2d
myapp-2                  1/1       Running   0          2d
myapp-3                  1/1       Running   0          2d
pod-sa-demo              1/1       Running   0          1d
pod-vol-demo             2/2       Running   0          3d
redis-5b5d6fbbbd-q8ppz   1/1       Running   1          4d
[root@k8s-master ~]# kubectl get pods -n ingress-nginx  #测试获取ingress-nginx这个名称空间的pods信息
No resources found.
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "ingress-nginx"

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

2、User --> Clusterrolebinding --> Clusterrole


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

* 集群范围资源(例如节点,即node)
* 非资源类型endpoint(例如”/healthz”)
* 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod)

[root@k8s-master mainfests]# kubectl config use-context kubernetes-admin@kubernetes  #切换会kubernetes-admin用户
Switched to context "kubernetes-admin@kubernetes".
[root@k8s-master mainfests]# kubectl create clusterrole cluster-read --verb=get,list,watch --resource=pods -o yaml > clusterrole-demo.yaml

[root@k8s-master mainfests]# vim clusterrole-demo.yaml #定义clusterrole和权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-read
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@k8s-master mainfests]# kubectl apply -f clusterrole-demo.yaml  #创建clusterrole
clusterrole.rbac.authorization.k8s.io/cluster-read configured

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

[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 magedu@kubernetes
Switched to context "magedu@kubernetes".
[ik8s@k8s-master ~]$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.56.11:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: magedu
  name: magedu@kubernetes
current-context: magedu@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: magedu
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

(2)clusterrolebinding定义

[root@k8s-master mainfests]# kubectl get rolebinding  #获取角色绑定信息
NAME               AGE
magedu-read-pods   1h
[root@k8s-master mainfests]# kubectl delete rolebinding magedu-read-pods #删除前面的绑定
rolebinding.rbac.authorization.k8s.io "magedu-read-pods" deleted

[ik8s@k8s-master ~]$ kubectl get pods  #删除后,在ik8s普通用户上进行获取pods资源信息,就立马出现forbidden了
No resources found.
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default"

[root@k8s-master mainfests]# kubectl create clusterrolebinding magedu-read-all-pods --clusterrole=cluster-read --user=magedu --dry-run -o yaml > clusterrolebinding-demo.yaml
[root@k8s-master mainfests]# vim clusterrolebinding-demo.yaml  #创建角色绑定,将magedu绑定到clusterrole:magedu-read-all-pods上
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: magedu-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-read
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: magedu
  
[root@k8s-master mainfests]# kubectl get clusterrole
NAME                                                                   AGE
admin                                                                  52d
cluster-admin                                                          52d
cluster-read                                                           13m
......

[root@k8s-master mainfests]# kubectl apply -f clusterrolebinding-demo.yaml 
clusterrolebinding.rbac.authorization.k8s.io/magedu-read-all-pods created
[root@k8s-master mainfests]# kubectl get clusterrolebinding
NAME                                                   AGE
......
magedu-read-all-pods                                   10s

[root@k8s-master mainfests]# kubectl describe clusterrolebinding magedu-read-all-pods
Name:         magedu-read-all-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"magedu-read-all-pods","namespace":""...
Role:
  Kind:  ClusterRole
  Name:  cluster-read
Subjects:
  Kind  Name    Namespace
  ----  ----    ---------
  User  magedu  

[ik8s@k8s-master ~]$ kubectl get pods  #角色绑定后在ik8s终端上进行获取pods信息,已经不会出现forbidden了
NAME                     READY     STATUS    RESTARTS   AGE
filebeat-ds-hxgdx        1/1       Running   1          36d
filebeat-ds-s466l        1/1       Running   2          36d
myapp-0                  1/1       Running   0          2d
myapp-1                  1/1       Running   0          2d
myapp-2                  1/1       Running   0          2d
myapp-3                  1/1       Running   0          2d
pod-sa-demo              1/1       Running   0          1d
pod-vol-demo             2/2       Running   0          4d
redis-5b5d6fbbbd-q8ppz   1/1       Running   1          4d
[ik8s@k8s-master ~]$ kubectl get pods -n ingress-nginx #更换名称空间进行查看也是可行的
NAME                                        READY     STATUS    RESTARTS   AGE
default-http-backend-7db7c45b69-nqxw9       1/1       Running   1          4d
nginx-ingress-controller-6bd7c597cb-9fzbw   1/1       Running   0          4d

[ik8s@k8s-master ~]$ kubectl delete pods pod-sa-demo  #但是进行删除pod就无法进行,因为在授权时是没有delete权限的
Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "magedu" cannot delete pods in the namespace "default"

从上面的实验,我们可以知道对用户magedu进行集群角色绑定,用户magedu将会获取对集群内所有资源的对应权限。

3、User --> Rolebinding --> Clusterrole

将maedu通过rolebinding到集群角色magedu-read-pods当中,此时,magedu仅作用于当前名称空间的所有pods资源的权限

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

[root@k8s-master mainfests]# kubectl create rolebinding magedu-read-pods --clusterrole=cluster-read --user=magedu --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
[root@k8s-master mainfests]# vim rolebinding-clusterrole-demo.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: magedu-read-pods
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-read
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: magedu

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

[ik8s@k8s-master ~]$ kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
filebeat-ds-hxgdx        1/1       Running   1          36d
filebeat-ds-s466l        1/1       Running   2          36d
myapp-0                  1/1       Running   0          2d
myapp-1                  1/1       Running   0          2d
myapp-2                  1/1       Running   0          2d
myapp-3                  1/1       Running   0          2d
pod-sa-demo              1/1       Running   0          1d
pod-vol-demo             2/2       Running   0          4d
redis-5b5d6fbbbd-q8ppz   1/1       Running   1          4d
[ik8s@k8s-master ~]$ kubectl get pods -n ingress-nginx
No resources found.
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "ingress-nginx"
posted @ 2021-08-24 11:35  老夫聊发少年狂88  阅读(1368)  评论(0编辑  收藏  举报