Kubernetes RBAC

一、简介

RBAC(Role-Based Access Control,基于角色的访问控制),作为Kubernetes安装方式的默认选项,足见其重要程度,相对于其他访问控制方式,RBAC具有以下优势:

  • 对集群中的资源和非资源权限均有完整的覆盖

  • 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubect或API进行操作

  • 可以在运行时进行调整,无须重启启动API Server

RBAC 使用 rbac.authorization.k8s.io API Group来实现授权决策,允许管理员通过kubernetes API动态配置策略,要启用RBAC ,需要在apiserver 中添加参数 --authorization-mode=RBAC

 

二、RBAC API对象

Kubernetes 有一个很基本的特性就是它的所有资源对象都是模型化的API对象,允许执行CRUD(Create、Read、Update、Delete)操作(也就是我们常说的增、删、改、查操作),比如下面的资源:

  • Pods

  • ConfigMaps

  • Deployments

  • Nodes

  • Secrets

  • Namespaces

上面的这些资源对象的可能存在的操作:

  • create

  • get

  • delete

  • list

  • update

  • edit

  • watch

  • exec

 

在更上层,这些资源和API Group进行关联,比如Pods属于Core API Group,而Deployment 属于apps API Group,要在Kubernetes 中进行RBAC 的管理,除了上面的这些资源和操作外,我们还需要另外的一些对象:

  • Rule:规则,规则是一组属于不同API Group资源上的一组操作的集合

  • Role 和 ClusterRole:角色和集群角色,这两个对象都包含上面的Rule元素,二者区别在于,在Role中,定义的规则只适用于单个命名空间,也就是和namespace关联的,而ClusterRole是集群范围内的,因此定义的规则不受命名空间的约束。另外Role和ClusterRole在Kubernetes中都被定义为集群内部的API资源,和Pod、ConfigMap这些类似,都是集群资源的对象,所有同意的可以使用kubectl相关命令来进行操作

  • Subject:主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:

    • User Account:用户,这是由外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用KeyStone或者Google账号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的API进行管理

    • Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如cluster-admin

    • Service Account:服务账号,通过Kubernetes API来管理的一些用户账号,和namespace进行关联,适用于集群内部运行的应用程序,需要通过API来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到Service Account

  • Role Binding和ClusterRoleBinding:角色绑定和集群角色绑定,简单的来说就是把声明的Subject和我们的Role进行绑定的 过程(给某个用户绑定上操作的权限),二者的区别也是作用范围的区别:RoleBinding只会影响到当前namespace下面的资源操作权限,而ClusterRoleBinding会影响到所有的namespace。

 

三、创建一个只能访问某个namespace的用户

3.1 创建一个User Account,只能访问kube-system这个命名空间

  • username: tunan

  • group:jiang

    (1)给用户tunan创建一个私钥,命名为:tunan.key

    # openssl genrsa -out tunan.key 2048

    (2)使用刚刚创建的私钥新建一个证书签名请求文件:tunan.csr,确保参数-subj参数中指定用户名和组(CN表示用户名,O表示组)

    # openssl req -new -key tunan.key -out tunan.csr -subj "/CN=tunan/O=jiang"

    (3)找到kubernetes集群的CA,利用集群的ca.crt和ca.key两个文件来批准上面的证书请求,并设置500天有效期

    # openssl x509 -req -in tunan.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki//ca.key -CAcreateserial -out tunan.crt -days 500

     

    (4)查看证书

    # ls
    tunan.crt  tunan.csr  tunan.key

     

    (5)使用刚创建的证书文件和私钥文件在集群中创建新的凭证和上下文(Context)

    # kubectl config set-credentials tunan --client-certificate=tunan.crt --client-key=tunan.key 
    User "tunan" set.

     

    (6)为这个用户设置新的Context

    # kubectl config set-context tunan-context --cluster=kubernetes --namespace=kube-system --user=tunan
    Context "tunan-context" created.

     

    (7)此时使用这个配置文件来操作kubectl会出错,因为还没有定义任何操作权限

    # kubectl get pods --context=tunan-context
    Error from server (Forbidden): pods is forbidden: User "tunan" cannot list resource "pods" in API group "" in the namespace "kube-system"

     

3.2 创建角色

用户完成后,接下来需要给用户添加操作权限,创建一个允许用户操作Deployment、Pod、ReplicaSets的角色

  1. tunan-role.yaml

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: tunan-role
      namespace: kube-system
    rules:
    - apiGroups: ["","extensions","apps"]
      resources: ["deployments","replicasets","pods"]
      verbs: ["get","list","watch","create","patch","delete"] # 全部权限可以使用["*"]

    apiGroups中[""] 代表核心API Group,ReplicasSets属于extensions这个API Group,而Deployments属于apps这个API Group。上面的verbs就是对这些资源对象执行的操作

  2. 创建这个Role

    # kubectl create -f tunan-role.yaml 
    role.rbac.authorization.k8s.io/tunan-role created

     

3.3 创建角色绑定

Role创建完成后,但是这个Role和用户tunan还没有任何关系,这里就需要创建一个RoleBinding对象,在kube-system这个命名空间下面将上面的tunan-role 角色和用户 tunan进行绑定

  1. tunan-rolebinding.yaml

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: tunan-rolebinding
      namespace: kube-system
    subjects:
    - kind: User
      name: tunan
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: tunan-role
      apiGroup: rbac.authorization.k8s.io

     

  2. 查看

    # kubectl describe role tunan-role -n kube-system 
    Name:         tunan-role
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources               Non-Resource URLs  Resource Names  Verbs
      ---------               -----------------  --------------  -----
      deployments             []                 []              [get list watch create patch delete]
      pods                    []                 []              [get list watch create patch delete]
      replicasets             []                 []              [get list watch create patch delete]
      deployments.apps        []                 []              [get list watch create patch delete]
      pods.apps               []                 []              [get list watch create patch delete]
      replicasets.apps        []                 []              [get list watch create patch delete]
      deployments.extensions  []                 []              [get list watch create patch delete]
      pods.extensions         []                 []              [get list watch create patch delete]
      replicasets.extensions  []                 []              [get list watch create patch delete]
      
    # kubectl describe rolebinding  tunan-rolebinding -n kube-system 
    Name:         tunan-rolebinding
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  Role
      Name:  tunan-role
    Subjects:
      Kind  Name   Namespace
      ----  ----   ---------
      User  tunan  
  3. 验证

    # kubectl get pods --context=tunan-context
    NAME                             READY   STATUS    RESTARTS   AGE
    coredns-66bff467f8-hqqz7         1/1     Running   10         12d
    coredns-66bff467f8-z2hr4         1/1     Running   10         12d
    etcd-master                      1/1     Running   11         12d
    kube-apiserver-master            1/1     Running   11         12d
    kube-controller-manager-master   1/1     Running   13         12d
    ...

     

四、创建一个只能访问某个namespace的ServiceAccount

创建一个集群内部的用户ServiceAccount,只能操作kube-system这个命名空间下面的pods和deployments

  1. sa.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: tunan-sa
      namespace: kube-system

     

  2. 创建sa

    # kubectl create -f sa.yaml
    ​
    # kubectl get sa tunan-sa -n kube-system
    NAME       SECRETS   AGE
    tunan-sa   1         19s

     

  3. 创建一个新的Role对象

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: tunan-sa-role
      namespace: kube-system
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get","watch","list"]
    - apiGroups: ["apps"]
      resources: ["deployments"]
      verbs: ['get','list','watch','create','update','patch','delete']
    # kubectl create -f tunan-sa-role.yaml 
    role.rbac.authorization.k8s.io/tunan-sa-role created
    # kubectl get  role tunan-sa-role -n kube-system
    NAME            CREATED AT
    tunan-sa-role   2020-06-17T03:40:00Z
    ​
    # kubectl describe  role tunan-sa-role -n kube-system
    Name:         tunan-sa-role
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources         Non-Resource URLs  Resource Names  Verbs
      ---------         -----------------  --------------  -----
      deployments.apps  []                 []              [get list watch create update patch delete]
      pods              []                 []              [get watch list]

     

  4. 创建一个Rolebinding,将上面的tunan-sa 和 tunan-sa-role进行绑定

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: tunan-sa-rolebinding
      namespace: kube-system
    subjects:
    - kind: ServiceAccount
      name: tunan-sa
      namespace: kube-system
    roleRef:
      kind: Role
      name: tunan-sa-role
      apiGroup: rbac.authorization.k8s.io
    # kubectl get rolebinding  tunan-sa-rolebinding -n kube-system
    NAME                   ROLE                 AGE
    tunan-sa-rolebinding   Role/tunan-sa-role   30s
    # kubectl describe rolebinding  tunan-sa-rolebinding -n kube-system
    Name:         tunan-sa-rolebinding
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  Role
      Name:  tunan-sa-role
    Subjects:
      Kind            Name      Namespace
      ----            ----      ---------
      ServiceAccount  tunan-sa  kube-system

     

  5. 验证

    每个ServiceAccount会生成一个Srcret对象和它进行映射,这个Secret里面包含一个token,可以利用这个token去登入Dashboard,可以在Dashboard中验证功能是否符合预期

    # kubectl get secret -n kube-system |grep tunan-sa
    # kubectl get secret tunan-sa-token-hn97d -o jsonpath={.data.token} -n kube-system | base64 -d

    会得到一个很长的token,利用这个token去登入Dashboard

    除了命名空间kube-system中的内容,其他都无法查看,结果是符合预期的

 

五、创建一个可以访问所有namespace的ServiceAccount

新创建一个ServiceAccount,具有操作所有namespace的权限,这个时候就需要使用到ClusterRole和ClusterRoleBinding这两种资源对象了。

  1. 创建新的ServiceAccount

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: cluster-tunan-sa
      namespace: kube-system

     

    # kubectl get sa cluster-tunan-sa -n kube-system 
    NAME               SECRETS   AGE
    cluster-tunan-sa   1         64s

     

  2. 创建一个ClusterRoleBinding对象

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: clusterrolebinding-tunan-sa
    subjects:
    - kind: ServiceAccount
      name: cluster-tunan-sa
      namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: cluster-admin
      apiGroup: rbac.authorization.k8s.io

     

    # kubectl create -f cluster-rolebinding-tunan.yaml 
    clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding-tunan-sa created
    # kubectl get clusterrolebinding clusterrolebinding
    -tunan-sa -n kube-system NAME ROLE AGE clusterrolebinding-tunan-sa ClusterRole/cluster-admin 65s

     

  3. 获取token

    # kubectl get secret -n kube-system | grep cluster-tunan-sa
    cluster-tunan-sa-token-zj95w                     kubernetes.io/service-account-token   3      6m51s
    # kubectl get secret cluster
    -tunan-sa-token-zj95w -o jsonpath={.data.token} -n kube-system | base64 -d

    登入Dashboard验证,可以访问所有的namespace资源

posted @ 2020-08-13 09:31  Bigberg  阅读(358)  评论(0编辑  收藏  举报