• Kubernetes(k8s)访问控制:权限管理之RBAC鉴权


    一.系统环境

    本文主要基于Kubernetes1.21.9和Linux操作系统CentOS7.4。

    服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构
    CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64

    Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点。

    服务器 操作系统版本 CPU架构 进程 功能描述
    k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
    k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
    k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

    二.前言

    Kubernetes作为目前最流行的容器编排平台之一,提供了强大的安全性能。在Kubernetes集群中,访问控制是保障集群安全的重要组成部分。其中,权限管理是访问控制的核心。本篇博客将介绍Kubernetes中的权限管理机制之RBAC鉴权。

    使用RBAC鉴权的前提是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html。

    三.Kubernetes访问控制

    用户使用 kubectl、客户端库或构造 REST 请求来访问 Kubernetes API。 用户账户和 Kubernetes 服务账号都可以被鉴权访问 API。 当请求到达 API 时,它会经历多个阶段,如下图所示:

    image-20230620112925208

    整体过程简述:请求发起方进行K8s API请求,建立 TLS 后,经过Authentication(认证)、Authorization(鉴权)、AdmissionControl(准入控制)三个阶段的校验,最后把请求转化为对K8s对象的变更操作持久化至etcd中。

    关于Authentication(认证)详细内容请查看博客《Kubernetes(k8s)访问控制:身份认证》。

    四.鉴权简介

    在Kubernetes中,鉴权(Authorization)是指检查用户是否有权限执行请求所需的操作的过程。鉴权机制由Kubernetes API server实现,并可以支持RBAC(基于角色的访问控制)、ABAC(基于属性的访问控制)和Node鉴权等多种方式。

    RBAC/ABAC/Node鉴权区别:

    • RBAC(Role-Based Access Control):基于角色的访问控制。RBAC允许管理员定义一系列角色,每个角色包含一组权限和资源。然后,将用户或者服务账户与相应的角色绑定起来。这样,用户或者服务账户就可以访问其相应的角色包含的资源和权限了。RBAC是Kubernetes推荐的鉴权方式。
    • ABAC(Attribute-Based Access Control):基于属性的访问控制。ABAC允许管理员定义一系列策略,每个策略包含多个属性,例如用户身份、资源类型、操作类型等。当一个请求被发送到API server时,API server会检查该请求是否满足所有匹配的策略。
    • Node鉴权:在Kubernetes中,每个节点都有主机名和IP地址。Node鉴权是指Kubernetes API server根据节点信息对请求进行授权的过程。可以使用Node鉴权来限制哪些节点可以访问某些资源。

    在本篇博客中,我们将重点介绍RBAC鉴权。

    五.配置客户端机器

    如下是我们的kubernetes集群。

    [root@k8scloude1 ~]# kubectl get nodes -o wide
    NAME         STATUS   ROLES                  AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME
    k8scloude1   Ready    control-plane,master   67d   v1.21.0   192.168.110.130   <none>        CentOS Linux 7 (Core)   3.10.0-693.el7.x86_64   docker://20.10.12
    k8scloude2   Ready    <none>                 67d   v1.21.0   192.168.110.129   <none>        CentOS Linux 7 (Core)   3.10.0-693.el7.x86_64   docker://20.10.12
    k8scloude3   Ready    <none>                 67d   v1.21.0   192.168.110.128   <none>        CentOS Linux 7 (Core)   3.10.0-693.el7.x86_64   docker://20.10.12
    

    先准备一台机器作为访问k8s集群的客户端,机器etcd1作为客户端,不是k8s集群的一部分。

    访问k8s集群需要客户端工具kubectl,下面安装kubectl,--disableexcludes=kubernetes 表示禁掉除了这个之外的别的仓库。

    [root@etcd1 ~]# yum -y install kubectl-1.21.0-0 --disableexcludes=kubernetes
    

    配置kubectl命令自动补全。

    [root@etcd1 ~]# vim /etc/profile
    
    [root@etcd1 ~]# grep source /etc/profile
    source <(kubectl completion bash)
    

    使配置生效。

    [root@etcd1 ~]# source /etc/profile
    
    [root@etcd1 ~]# kubectl get node
    The connection to the server localhost:8080 was refused - did you specify the right host or port?
    

    六.设置k8s集群允许所有请求访问

    kubernetes默认的授权模式为:authorization-mode=Node,RBAC。

    [root@k8scloude1 ~]# ls /etc/kubernetes/manifests/kube-apiserver.yaml 
    /etc/kubernetes/manifests/kube-apiserver.yaml
    
    [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml
        - --authorization-mode=Node,RBAC
    

    设置k8s允许所有请求访问。

    [root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml 
    
    [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml
        #- --authorization-mode=Node,RBAC
        - --authorization-mode=AlwaysAllow
    

    重启kubelet使配置生效。

    [root@k8scloude1 ~]# systemctl restart kubelet
    
    [root@k8scloude1 ~]# systemctl status kubelet
    ● kubelet.service - kubelet: The Kubernetes Node Agent
       Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
      Drop-In: /usr/lib/systemd/system/kubelet.service.d
               └─10-kubeadm.conf
       Active: active (running) since 五 2022-03-18 18:36:24 CST; 11s ago
         Docs: https://kubernetes.io/docs/
     Main PID: 28054 (kubelet)
       Memory: 42.4M
       CGroup: /system.slice/kubelet.service
               └─28054 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-in...
    

    当- --authorization-mode=AlwaysAllow 设置为允许所有请求之后,客户端机器可以随意访问所有资源。

    kctest这个自定义的kubeconfig文件博客《Kubernetes(k8s)访问控制:身份认证》已经详细讲解过了,这里就不赘述了。

    在etcd1机器上可以访问任何资源。

    [root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest 
    NAME         STATUS   ROLES                  AGE   VERSION
    k8scloude1   Ready    control-plane,master   68d   v1.21.0
    k8scloude2   Ready    <none>                 68d   v1.21.0
    k8scloude3   Ready    <none>                 68d   v1.21.0
    
    [root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest 
    NAMESPACE        NAME                                        READY   STATUS      RESTARTS   AGE
    ingress-nginx    ingress-nginx-admission-create-2lg57        0/1     Completed   0          31d
    ingress-nginx    ingress-nginx-admission-patch-hd7p4         0/1     Completed   1          31d
    ingress-nginx    ingress-nginx-controller-59b8bf5fdc-t2f7z   1/1     Running     14         31d
    kube-system      calico-kube-controllers-6b9fbfff44-4jzkj    1/1     Running     78         68d
    kube-system      calico-node-bdlgm                           1/1     Running     38         68d
    kube-system      calico-node-hx8bk                           1/1     Running     38         68d
    kube-system      calico-node-nsbfs                           1/1     Running     38         68d
    kube-system      coredns-545d6fc579-7wm95                    1/1     Running     38         68d
    kube-system      coredns-545d6fc579-87q8j                    1/1     Running     38         68d
    kube-system      etcd-k8scloude1                             1/1     Running     38         68d
    kube-system      kube-apiserver-k8scloude1                   0/1     Running     1          8m36s
    kube-system      kube-controller-manager-k8scloude1          1/1     Running     45         68d
    kube-system      kube-proxy-599xh                            1/1     Running     38         68d
    kube-system      kube-proxy-lpj8z                            1/1     Running     38         68d
    kube-system      kube-proxy-zxlk9                            1/1     Running     38         68d
    kube-system      kube-scheduler-k8scloude1                   1/1     Running     45         68d
    kube-system      metrics-server-bcfb98c76-n4fnb              1/1     Running     42         60d
    metallb-system   controller-7dcc8764f4-qdwl2                 1/1     Running     24         34d
    metallb-system   speaker-892pm                               1/1     Running     16         34d
    metallb-system   speaker-jfccb                               1/1     Running     16         34d
    metallb-system   speaker-nkrgk                               1/1     Running     16         34d
    volume           nfs-client-provisioner-76c576954d-5x7t2     1/1     Running     16         57d
    

    七.设置k8s集群拒绝所有请求访问

    设置k8s拒绝所有请求访问。

    [root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml 
    
    #设置为拒绝所有请求
    [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml
        #- --authorization-mode=Node,RBAC
        - --authorization-mode=AlwaysDeny
    

    重启kubelet使配置生效。

    [root@k8scloude1 ~]# systemctl restart kubelet
    

    设置为拒绝所有请求 - --authorization-mode=AlwaysDeny之后,客户端机器访问不了了。

    [root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest 
    error: the server doesn't have a resource type "pod"
    
    [root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest 
    error: the server doesn't have a resource type "nodes"
    
    [root@etcd1 ~]# kubectl get node --kubeconfig=kctest 
    error: the server doesn't have a resource type "node"
    

    设置为拒绝所有请求 - --authorization-mode=AlwaysDeny之后,admin管理员用户无影响,其他用户访问不了。

    [root@k8scloude1 ~]# kubectl get node
    NAME         STATUS   ROLES                  AGE   VERSION
    k8scloude1   Ready    control-plane,master   68d   v1.21.0
    k8scloude2   Ready    <none>                 68d   v1.21.0
    k8scloude3   Ready    <none>                 68d   v1.21.0
    

    八.RBAC授权

    RBAC支持基于角色的授权,即将一组权限分配给一个角色,再将该角色分配给一个或多个用户或服务账户。在Kubernetes中,RBAC鉴权由以下三个部分组成:

    1. Role:针对特定命名空间(Namespace)内的资源定义一组操作权限。
    2. RoleBinding:将Role和Subject(User或ServiceAccount)关联起来,以便Subject能够执行Role所定义的操作。
    3. ClusterRole和ClusterRoleBinding:类似于上述两个对象,但作用于整个集群。

    8.1 role,rolebinding

    想要使用RBAC授权,需要恢复- --authorization-mode=Node,RBAC,想要查看什么,都是我们敲命令获取,其实有很多我们看不到的操作(比如master和worker之间交互查询,审计等等),- --authorization-mode=Node 表示允许worker向master查询相应信息,想要--authorization-mode=Node生效,--enable-admission-plugins=NodeRestriction准入控制器要开启。

    [root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml 
    
    [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml
        - --authorization-mode=Node,RBAC
        #- --authorization-mode=AlwaysDeny
    

    重启kubelet使配置生效。

    [root@k8scloude1 ~]# systemctl restart kubelet
    

    管理员拥有所有权限,查看管理员的权限就可以知道k8s有哪些权限。

    [root@k8scloude1 ~]# kubectl describe clusterrole cluster-admin
    Name:         cluster-admin
    Labels:       kubernetes.io/bootstrapping=rbac-defaults
    Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      *.*        []                 []              [*]
                 [*]                []              [*]
    

    可以看到admin角色对各种资源Resources的权限Verbs。

    [root@k8scloude1 ~]# kubectl describe clusterrole admin
    Name:         admin
    Labels:       kubernetes.io/bootstrapping=rbac-defaults
    Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
    PolicyRule:
      Resources                                       Non-Resource URLs  Resource Names  Verbs
      ---------                                       -----------------  --------------  -----
      rolebindings.rbac.authorization.k8s.io          []                 []              [create delete deletecollection get list patch update watch]
      roles.rbac.authorization.k8s.io                 []                 []              [create delete deletecollection get list patch update watch]
      ......
      services/proxy                                  []                 []              [get list watch create delete deletecollection patch update]
      bindings                                        []                 []              [get list watch]
      events                                          []                 []              [get list watch]
      limitranges                                     []                 []              [get list watch]
      namespaces/status                               []                 []              [get list watch]
      namespaces                                      []                 []              [get list watch]
      persistentvolumeclaims/status                   []                 []              [get list watch]
      pods/log                                        []                 []              [get list watch]
      pods/status                                     []                 []              [get list watch]
      replicationcontrollers/status                   []                 []              [get list watch]
     ......
      pods.metrics.k8s.io                             []                 []              [get list watch]
      ingresses.networking.k8s.io/status              []                 []              [get list watch]
      poddisruptionbudgets.policy/status              []                 []              [get list watch]
      serviceaccounts                                 []                 []              [impersonate create delete deletecollection patch update get list watch]
    

    8.1.1 给test用户授予对pod的get和list权限

    注意:RBAC不是直接把权限授予用户,而是把权限都放在角色role里,再把角色role绑定rolebinding到用户,这样用户就具有了相应的权限,注意对于命名空间ns1里的角色role1,命名空间ns2不能使用。

    除了role,还有clusterrole,role是归属于某一个namespace,clusterrole是全局生效的,clusterrole除了可以使用rolebinding绑定之外,还可以使用clusterrolebingding绑定,rolebinding归属于某一个命名空间,clusterrolebingding全局生效。

    查看角色role。

    [root@k8scloude1 ~]# kubectl get role
    No resources found in safe namespace.
    
    [root@k8scloude1 ~]# cd safe/
    

    我们使用yaml文件的方式创建角色role :kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml。

    --verb=get,list指定权限为get和list,--resource=pods表示权限作用在pod上。

    [root@k8scloude1 safe]# kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml
    

    查看yaml文件,功能为:在 Kubernetes 集群中创建一个叫做 "role1" 的角色(Role),该角色具有操作(Kubernetes Pod)的权限。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      #name: role1: 该角色的名称为 "role1"。
      name: role1
    #rules: 角色的规则部分定义了角色能够执行的操作列表。  
    rules:
    #- apiGroups: [""]: apiGroups 字段指定资源所属的 API 组(或者不属于任何组)。在本例中,Pod 不属于任何 API 组,所以值为空字符串。
    - apiGroups:
      - ""
      #resources: ["pods"]: resources 字段指定角色能够访问的资源列表。在本例中,只有 Pod 是被授权的资源。
      resources:
      - pods
      #verbs: ["get", "list"]: verbs 字段列出了角色可用的动词列表。在本例中,角色可以执行 "get" 和 "list" 操作。这意味着此角色可以查看 Pod 的详细信息和列表信息。
      verbs:
      - get
      - list
    

    生成role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 created
    

    查看role。

    [root@k8scloude1 safe]# kubectl get role
    NAME    CREATED AT
    role1   2022-03-19T09:52:13Z
    

    查看role的权限:对pod具有get list权限。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list]
    

    把角色role1绑定到test用户上,test用户不属于任何命名空间。

    [root@k8scloude1 safe]# kubectl create rolebinding rolebind1 --role=role1 --user=test
    rolebinding.rbac.authorization.k8s.io/rolebind1 created
    

    查看rolebinding。

    [root@k8scloude1 safe]# kubectl get rolebinding
    NAME        ROLE         AGE
    rolebind1   Role/role1   110s
    

    查看rolebind1的描述信息。

    [root@k8scloude1 safe]# kubectl describe rolebinding rolebind1 
    Name:         rolebind1
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  Role
      Name:  role1
    Subjects:
      Kind  Name  Namespace
      ----  ----  ---------
      User  test  
    

    在客户端进行权限测试,把角色role1绑定给test用户之后,客户端具有了safe命名空间里pod的查询权限。

    [root@etcd1 ~]# kubectl get pods --kubeconfig=kctest -n safe
    No resources found in safe namespace.
    

    客户端不具有default命名空间里pod的查询权限。

    [root@etcd1 ~]# kubectl get pods --kubeconfig=kctest 
    Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"
    

    8.1.2 增加对pod的创建权限

    如下是使用nginx镜像创建pod的配置文件。

    [root@etcd1 ~]# cat pod.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: podtest
      name: podtest
    spec:
      #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
      terminationGracePeriodSeconds: 0
      containers:
      - name: nginx
        image: nginx
        #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
        imagePullPolicy: IfNotPresent
    

    现在想在客户端创建一个pod,用户test只对pod有get ,list权限,没有创建pod权限,创建失败。

    [root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest 
    Error from server (Forbidden): error when creating "pod.yaml": pods is forbidden: User "test" cannot create resource "pods" in API group "" in the namespace "safe"
    

    修改yaml文件,添加pod的create权限。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      #添加了创建权限create
      verbs:
      - get
      - list
      - create
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    现在role1具有了对pod的get list create权限。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list create]
    

    role1添加pod的create权限之后,成功在客户端创建pod。

    [root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest 
    pod/podtest created
    
    [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest 
    NAME      READY   STATUS    RESTARTS   AGE
    podtest   1/1     Running   0          22s
    

    8.1.3 增加对pod的删除权限

    用户test没有pod删除权限。

    [root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest 
    Error from server (Forbidden): pods "podtest" is forbidden: User "test" cannot delete resource "pods" in API group "" in the namespace "safe"
    

    给角色role1增加删除pod的权限。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      #增加删除权限delete
      verbs:
      - get
      - list
      - create
      - delete
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    现在role1具有了对pod的get list create delete权限。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list create delete]
    

    给角色role1增加删除pod的权限之后,客户端成功删除了pod。

    [root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest 
    pod "podtest" deleted
    
    [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest 
    No resources found in safe namespace.
    

    8.1.4 增加对svc的get list create delete权限

    test用户没有对services的list权限。

    [root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest 
    Error from server (Forbidden): services is forbidden: User "test" cannot list resource "services" in API group "" in the namespace "safe"
    

    修改yaml文件,对role1添加service的get list create delete权限,注意:services不能简写。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      #资源里增加services
      resources:
      - pods
      - services
      verbs:
      - get
      - list
      - create
      - delete
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    查看角色的描述信息,角色role1增加了services的get list create delete权限。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list create delete]
      services   []                 []              [get list create delete]
    

    给角色role1增加了services的get list create delete权限之后,客户端可以查询svc了。

    [root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest 
    No resources found in safe namespace.
    

    8.1.5 增加对deployments的get list create delete权限

    客户端没有对deployments的list权限。

    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
    

    修改yaml文件,给role1添加deployments的get list create delete权限。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - services
      - deployments
      verbs:
      - get
      - list
      - create
      - delete
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    查看角色的描述信息,角色role1增加了deployments的get list create delete权限。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources    Non-Resource URLs  Resource Names  Verbs
      ---------    -----------------  --------------  -----
      deployments  []                 []              [get list create delete]
      pods         []                 []              [get list create delete]
      services     []                 []              [get list create delete]
    

    给角色role1增加了deployments的get list create delete权限之后,客户端还是没有对deployments的list权限。

    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
    

    给角色role1增加了deployments的get list create delete权限之后,客户端还是没有对deployments的list权限,原因为:pod,service对应的apiVersion为v1,deploy对应的apiVersion为apps/v1

    apiVersion的结构有 xx ,yy/zz ,对于xx结构,apiGroups写为:apiGroups:"",对于yy/zz结构,apiGroups写为:apiGroups:"yy"。

    如果apiGroups只写为“”,不写"apps"则pods,services生效,deployments不生效,因为没有父级,如果apiGroups只写为"apps",不写""则pods,services不生效,deployments生效,因为pods,services没有父级。

    下面才是正确的写法,修改yaml文件。

    [root@k8scloude1 safe]# vi  role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    #- apiGroups: ["apps"]: apiGroups 字段指定资源所属的 API 组(或者不属于任何组)。在本例中,deployments 属于 apps/v1 组,所以值为apps。
    - apiGroups:
      - ""
      - "apps"
      resources:
      - pods
      - services
      - deployments
      verbs:
      - get
      - list
      - create
      - delete
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    查看role1的描述信息。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources         Non-Resource URLs  Resource Names  Verbs
      ---------         -----------------  --------------  -----
      deployments       []                 []              [get list create delete]
      pods              []                 []              [get list create delete]
      services          []                 []              [get list create delete]
      deployments.apps  []                 []              [get list create delete]
      pods.apps         []                 []              [get list create delete]
      services.apps     []                 []              [get list create delete]
    

    给role1添加deployment的get list create delete权限之后,客户端可以查询deploy了。

    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    No resources found in safe namespace.
    

    如下是使用Nginx镜像创建deploy的yaml文件。

    [root@etcd1 ~]# cat nginx.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
      name: nginx
    spec:
      #5个副本
      replicas: 5
      selector:
        matchLabels:
          app: nginx
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: nginx
        spec:
          #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
          terminationGracePeriodSeconds: 0
          containers:
          - image: nginx
            name: nginx
            #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
            imagePullPolicy: IfNotPresent
            resources: {}
    status: {}
    

    在客户端创建deploy,由于被授权了,deploy创建成功。

    [root@etcd1 ~]# kubectl apply -f nginx.yaml -n safe --kubeconfig=kctest 
    deployment.apps/nginx created
    
    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    NAME    READY   UP-TO-DATE   AVAILABLE   AGE
    nginx   5/5     5            5           23s
    
    [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest 
    NAME                     READY   STATUS    RESTARTS   AGE
    nginx-6cf858f6cf-62m8t   1/1     Running   0          72s
    nginx-6cf858f6cf-74nzb   1/1     Running   0          72s
    nginx-6cf858f6cf-bw84g   1/1     Running   0          72s
    nginx-6cf858f6cf-cmj95   1/1     Running   0          72s
    nginx-6cf858f6cf-fzs4l   1/1     Running   0          72s
    

    刚才给role1添加deployments权限写的不好,如下为优化后的写法:

    [root@k8scloude1 safe]# vim role1.yaml 
    
    #对于给role1添加权限还可以有另一种写法(这种方法更好),如下
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - services
      verbs:
      - get
      - list
      - create
      - delete
    - apiGroups:
      - "apps"
      resources:
      - deployments
      verbs:
      - get
      - list
      - create
      - delete
    

    8.1.6 增加对deployments的patch权限

    把nginx的deploy的副本数变为2,发现用户test没有deployments/scale的patch权限。

    [root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest 
    Error from server (Forbidden): deployments.apps "nginx" is forbidden: User "test" cannot patch resource "deployments/scale" in API group "apps" in the namespace "safe"
    

    修改yaml文件,添加deployments/scale的patch权限。

    [root@k8scloude1 safe]# vim role1.yaml 
    
    [root@k8scloude1 safe]# cat role1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: role1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - services
      - deployments
      verbs:
      - get
      - list
      - create
      - delete
    - apiGroups:
      - "apps"
      resources:
      - deployments
      - deployments/scale
      verbs:
      - get
      - list
      - create
      - delete
      - patch
    

    应用role。

    [root@k8scloude1 safe]# kubectl apply -f role1.yaml 
    role.rbac.authorization.k8s.io/role1 configured
    

    查看role1的描述信息。

    [root@k8scloude1 safe]# kubectl describe role role1 
    Name:         role1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources               Non-Resource URLs  Resource Names  Verbs
      ---------               -----------------  --------------  -----
      deployments.apps/scale  []                 []              [get list create delete patch]
      deployments.apps        []                 []              [get list create delete patch]
      deployments             []                 []              [get list create delete]
      pods                    []                 []              [get list create delete]
      services                []                 []              [get list create delete]
    

    添加deployments/scale的patch权限之后,客户端可以修改副本数了。

    [root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest 
    deployment.apps/nginx scaled
    
    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    NAME    READY   UP-TO-DATE   AVAILABLE   AGE
    nginx   2/2     2            2           7m19s
    

    删除deploy。

    [root@etcd1 ~]# kubectl delete -f nginx.yaml -n safe --kubeconfig=kctest 
    deployment.apps "nginx" deleted
    
    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    No resources found in safe namespace.
    

    8.2 clusterrole,clusterrolebinding

    上面做的权限都是role,rolebinding,下面开始clusterrole,clusterrolebinding。

    删除role。

    [root@k8scloude1 safe]# kubectl get role
    NAME    CREATED AT
    role1   2022-03-19T09:52:13Z
    
    [root@k8scloude1 safe]# kubectl delete -f role1.yaml 
    role.rbac.authorization.k8s.io "role1" deleted
    
    [root@k8scloude1 safe]# kubectl get role
    No resources found in safe namespace.
    

    删除rolebinding。

    [root@k8scloude1 safe]# kubectl get rolebinding
    NAME        ROLE         AGE
    rolebind1   Role/role1   25h
    
    [root@k8scloude1 safe]# kubectl delete rolebinding rolebind1 
    rolebinding.rbac.authorization.k8s.io "rolebind1" deleted
    
    [root@k8scloude1 safe]# kubectl get rolebinding
    No resources found in safe namespace.
    

    8.2.1 test用户授予对Pod、Service 、Deployment 的get 和 create 权限

    生成创建clusterrole的yaml文件,--verb指定权限,--resource指定作用的资源。

    [root@k8scloude1 safe]# kubectl create clusterrole clusterrole1 --verb=get,create --resource=pod,svc,deploy --dry-run=client -o yaml >clusterrole1.yaml
    

    查看ClusterRole的yaml文件,功能为:在 Kubernetes 集群中创建一个叫做 "clusterrole1" 的集群角色(ClusterRole),该角色具有对 Pod、Service 和 Deployment 资源的操作权限。

    使用这个 YAML 文件在 Kubernetes 中创建 "clusterrole1" 集群角色后,该角色将能够访问 Pod、Service 和 Deployment 资源,并且具有 get 和 create 操作权限。

    [root@k8scloude1 safe]# vim clusterrole1.yaml 
    
    [root@k8scloude1 safe]# cat clusterrole1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    #kind: ClusterRole: ClusterRole 是 Kubernetes 集群级别的角色授权机制,与 Role 类似,但是它可以跨命名空间使用。
    kind: ClusterRole
    metadata:
      creationTimestamp: null
      name: clusterrole1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - services
      verbs:
      - get
      - create
    - apiGroups:
      - apps
      resources:
      - deployments
      verbs:
      - get
      - create
    

    应用clusterrole。

    [root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml 
    clusterrole.rbac.authorization.k8s.io/clusterrole1 created
    

    查看clusterrole。

    [root@k8scloude1 safe]# kubectl get clusterrole | grep clusterrole1
    clusterrole1                                                           2022-03-20T11:24:36Z
    

    kubernetes集群自带的clusterrole有很多。

    [root@k8scloude1 safe]# kubectl get clusterrole | wc -l
    75
    

    把集群角色clusterrole1使用clusterrolebinding绑定给用户test。

    [root@k8scloude1 safe]# kubectl create clusterrolebinding clusterrolebinding1 --clusterrole=clusterrole1 --user=test
    clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding1 created
    

    查看clusterrolebinding。

    [root@k8scloude1 safe]# kubectl get clusterrolebinding | grep clusterrolebinding1
    clusterrolebinding1                                    ClusterRole/clusterrole1                                                           25s
    
    [root@k8scloude1 safe]# kubectl get clusterrolebinding | wc -l
    60
    

    查看集群绑定的描述信息。

    [root@k8scloude1 safe]# kubectl describe clusterrolebinding clusterrolebinding1
    Name:         clusterrolebinding1
    Labels:       >
    Annotations:  >
    Role:
      Kind:  ClusterRole
      Name:  clusterrole1
    Subjects:
      Kind  Name  Namespace
      ----  ----  ---------
      User  test  
    

    查看集群角色的描述信息。

    [root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 
    Name:         clusterrole1
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources         Non-Resource URLs  Resource Names  Verbs
      ---------         -----------------  --------------  -----
      pods              []                 []              [get create]
      services          []                 []              [get create]
      deployments.apps  []                 []              [get create]
    

    8.2.2 增加list权限

    在客户端进行测试,设置了clusterrole,clusterrolebinding之后,发现用户test没有对deploy的list权限。

    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
    

    修改yaml文件,增加list权限。

    [root@k8scloude1 safe]# vim clusterrole1.yaml 
    
    #添加list权限
    [root@k8scloude1 safe]# cat clusterrole1.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      creationTimestamp: null
      name: clusterrole1
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - services
      verbs:
      - get
      - create
      - list
    - apiGroups:
      - apps
      resources:
      - deployments
      verbs:
      - get
      - create
      - list
    

    应用clusterrole。

    [root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml 
    clusterrole.rbac.authorization.k8s.io/clusterrole1 configured
    

    查看clusterrole1的描述信息。

    [root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 
    Name:         clusterrole1
    Labels:       >
    Annotations:  >
    PolicyRule:
      Resources         Non-Resource URLs  Resource Names  Verbs
      ---------         -----------------  --------------  -----
      pods              []                 []              [get create list]
      services          []                 []              [get create list]
      deployments.apps  []                 []              [get create list]
    

    clusterrole1添加了list权限之后,客户端可以get信息了。

    [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest 
    No resources found in safe namespace.
    
    [root@etcd1 ~]# kubectl get deploy -n default --kubeconfig=kctest 
    No resources found in default namespace.
    

    可以发现,clusterrolebinding全局生效,在所有namespace里都生效。

    [root@etcd1 ~]# kubectl get deploy -n kube-system --kubeconfig=kctest 
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    calico-kube-controllers   1/1     1            1           70d
    coredns                   2/2     2            2           70d
    metrics-server            1/1     1            1           69d
    

    九.总结

    在本篇博客中,我们介绍了Kubernetes中的权限管理机制之RBAC鉴权。通过创建Role、RoleBinding、ClusterRole和ClusterRoleBinding等对象,管理员可以有效地控制用户和服务账户的访问权限,保障集群的安全性。

    除了RBAC、ABAC和Node鉴权外,Kubernetes还支持Webhook鉴权、Service Account Token Volume Projection等多种鉴权方式。同时,在进行权限管理时,管理员还需注意以下事项:

    1. 避免为用户授予过多的权限。
    2. 确保所有操作都可以被审计和跟踪。
    3. 定期审核访问权限,确保其符合组织政策和最佳实践。
  • 相关阅读:
    PS进阶篇——如何PS软件给图片部分位置打马赛克(四)
    数据分析 第三周 (numpy数组的处理 , numpy数组的运用与画图的结合)笔记
    java中如何将嵌套循环性能提高500倍
    认识RocketMQ4.x架构设计
    智慧工业+数字孪生,打造智慧设备运维最优解
    算法和数据结构解析-9 : 排序相关问题讲解
    ERROR: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    关于C++的隐藏 (hidden),重载(overload),重写(override)小结。
    Sentinel底层原理(下)
    网易游戏如何基于 Apache Doris 构建全新湖仓一体架构
  • 原文地址:https://www.cnblogs.com/renshengdezheli/p/17504354.html