Kubernetes RBAC

Kuber-adm 安装的 k8s 集群默认启用 RBAC,Kubernetes 的授权操作由第三方插件来完成,当有一个插件完成授权后其他插件不再检查,在众多授权插件中常用的有四个

  • Node: 有节点的认证
  • ABAC: 基于属性的访问控制,RBAC 启用前的算法
  • RBAC: Role-based access control,基于角色的访问控制
  • Webhook: 基于 HTTP 的回调机制来实现

RBAC

基于角色分配的访问控制,角色决定权限

  • 角色 (role)
  • 许可 (permission)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7S3jaEhh-1624628602280)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200915224359.png)]

K8s 有三种资源,对象、对象列表和非对象资源或非资源 URL,那么在 k8s 当中所有对对象的 operation 都是一种 action, 在一个对象上可以进行的 operation 的集合就是 permission,而后在 role 之上可以授予 permission,Subject 可以分配权限的有两个账号:human user 和 pod service account

RBAC 工作逻辑

在 namespace 中需要以下方式控制权限

  1. role

    • operation: 许可授权
    • object: 对象
  2. rolbebinding

    • user account OR service account
    • role

在集群中需要以下方式控制权限

  1. cluster role
  2. cluster rolebinding

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5mI88PKN-1624628602282)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200915231835.png)]

可以通过 rolbebinding 绑定 cluster role 这样节省了创建重复 role 和授权 role 的操作,而权限依然根据 rolbebinding 来判定

UserAccount

创建 role

kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename]
[root@master-0 ~]# kubectl create role pod-read --verb=get,list,watch --resource=pods --dry-run -oyaml
W0916 09:24:03.897276    3806 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
role.rbac.authorization.k8s.io/pod-read created (dry run)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pod-read
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master-0 ~]# cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-read
  namespace: default
rules:
- apiGroups:        # 对 apiGroups 里那些资源组做操作
  - ""
  resources:
  - pods
  verbs:            # 值可以用 * 来代表所有权限
  - get
  - list
  - watch
[root@master-0 ~]# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/pod-read created
[root@master-0 ~]# kubectl describe role pod-read
Name:         pod-read
Labels:       <none>
Annotations:  PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  pods        []                 []              [get list watch]
  • Resource Names 指 Resources 下的资源细分
  • Non-Resource URLs 既 非对象资源

创建 rolebinding

kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname]
[root@master-0 ~]# kubectl create rolebinding test-pod-read --role=pod-read --user=testadmin --dry-run -o yaml
W0916 20:26:18.350655   27929 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: test-pod-read
roleRef:            # 引用的 role
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-read
subjects:           # 动作的执行主体,引用谁
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: testadmin
[root@master-0 ~]# kubectl explain rolebinding.subjects
KIND:     RoleBinding
VERSION:  rbac.authorization.k8s.io/v1

RESOURCE: subjects <[]Object>

DESCRIPTION:
     Subjects holds references to the objects the role applies to.

     Subject contains a reference to the object or user identities a role
     binding applies to. This can either hold a direct API object reference, or
     a value for non-objects such as user and group names.

FIELDS:
   apiGroup <string>
     APIGroup holds the API group of the referenced subject. Defaults to "" for
     ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User
     and Group subjects.

   kind <string> -required-         # 指定那个 user 或者 Group 或者 SA
     Kind of object being referenced. Values defined by this API group are
     "User", "Group", and "ServiceAccount". If the Authorizer does not
     recognized the kind value, the Authorizer should report an error.

   name <string> -required-         # kind 资源的名字
     Name of the object being referenced.

   namespace <string>               # 如果是 SA 则必须指定 namespace
     Namespace of the referenced object. If the object kind is non-namespace,
     such as "User" or "Group", and this value is not empty the Authorizer
     should report an error.
[root@master-0 ~]# kubectl create rolebinding test-pod-read --role=pod-read --user=testadmin
rolebinding.rbac.authorization.k8s.io/testadmin-pod-read created
[root@master-0 ~]# kubectl config use-context testadmin@kubernetes
Switched to context "testadmin@kubernetes".
[root@master-0 ~]# kubectl get po
NAME                           READY   STATUS    RESTARTS   AGE
myapp-deploy-5d645d645-2dsjq   1/1     Running   5          17d
myapp-deploy-5d645d645-65ftw   1/1     Running   3          17d
myapp-deploy-5d645d645-hfxqf   1/1     Running   5          17d
pod-cm-3                       1/1     Running   1          5d15h
pod-sa-demo                    1/1     Running   1          5d6h
pod-vol-hostpath               1/1     Running   1          6d2h

创建 clusterrole

Usage:
  kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename]
[--dry-run=server|client|none] [options]
[root@master-0 ~]# kubectl create clusterrole cluster-read  --verb=* --resource=pod -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: "2020-09-17T12:02:21Z"
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:rules: {}
    manager: kubectl
    operation: Update
    time: "2020-09-17T12:02:21Z"
  name: cluster-read
  resourceVersion: "3058226"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-read
  uid: fee331a3-f386-4c0c-a204-82fd50bf0a5c
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - '*'
[root@master-0 ~]# kubectl delete rolebinding test-pod-read
rolebinding.rbac.authorization.k8s.io "test-pod-read" deleted

创建 clusterrolebinding

注意 clusterrolebinding 只能绑定 clusterrole

Usage:
  kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none] [options]
[root@master-0 ~]# kubectl create clusterrolebinding cluster-test-pod-read --clusterrole=cluster-read --user=testadmin
clusterrolebinding.rbac.authorization.k8s.io/cluster-test-pod-read created

clusterrole 绑定 rolebinding

[root@master-0 ~]# kubectl create clusterrole cluster-rolebinding-read  --verb=get,list --resource=pod
[root@master-0 ~]# kubectl create rolebinding clusterrole-rolebinding --clusterrole=cluster-rolebinding-read --user=testadmin
  • 系统默认的 clusterrole 拥有一个 admin,用户可以直接用 rolebinding 绑定这个 clusterrole 来生成特定名称空间的管理员
[root@master-0 ~]# kubectl get clusterrole admin -oyaml
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.authorization.k8s.io/aggregate-to-admin: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2020-03-30T07:32:03Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:aggregationRule:
        .: {}
        f:clusterRoleSelectors: {}
      f:metadata:
        f:annotations:
          .: {}
          f:rbac.authorization.kubernetes.io/autoupdate: {}
        f:labels:
          .: {}
          f:kubernetes.io/bootstrapping: {}
    manager: kube-apiserver
    operation: Update
    time: "2020-03-30T07:32:03Z"
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:rules: {}
    manager: kube-controller-manager
    operation: Update
    time: "2020-03-30T07:32:24Z"
  name: admin
  resourceVersion: "353"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/admin
  uid: a9254f8a-4914-4c63-8945-d66d4a679d23
rules:
- apiGroups:
  - ""
  resources:
  - pods/attach
  - pods/exec
  - pods/portforward
  - pods/proxy
  - secrets
  - services/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - serviceaccounts
  verbs:
  - impersonate
- apiGroups:
  - ""
  resources:
  - pods
  - pods/attach
  - pods/exec
  - pods/portforward
  - pods/proxy
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - replicationcontrollers
  - replicationcontrollers/scale
  - secrets
  - serviceaccounts
  - services
  - services/proxy
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - apps
  resources:
  - daemonsets
  - deployments
  - deployments/rollback
  - deployments/scale
  - replicasets
  - replicasets/scale
  - statefulsets
  - statefulsets/scale
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - batch
  resources:
  - cronjobs
  - jobs
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - extensions
  resources:
  - daemonsets
  - deployments
  - deployments/rollback
  - deployments/scale
  - ingresses
  - networkpolicies
  - replicasets
  - replicasets/scale
  - replicationcontrollers/scale
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - policy
  resources:
  - poddisruptionbudgets
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  - networkpolicies
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - persistentvolumeclaims/status
  - pods
  - replicationcontrollers
  - replicationcontrollers/scale
  - serviceaccounts
  - services
  - services/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - bindings
  - events
  - limitranges
  - namespaces/status
  - pods/log
  - pods/status
  - replicationcontrollers/status
  - resourcequotas
  - resourcequotas/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - controllerrevisions
  - daemonsets
  - daemonsets/status
  - deployments
  - deployments/scale
  - deployments/status
  - replicasets
  - replicasets/scale
  - replicasets/status
  - statefulsets
  - statefulsets/scale
  - statefulsets/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  - horizontalpodautoscalers/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - batch
  resources:
  - cronjobs
  - cronjobs/status
  - jobs
  - jobs/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  resources:
  - daemonsets
  - daemonsets/status
  - deployments
  - deployments/scale
  - deployments/status
  - ingresses
  - ingresses/status
  - networkpolicies
  - replicasets
  - replicasets/scale
  - replicasets/status
  - replicationcontrollers/scale
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - policy
  resources:
  - poddisruptionbudgets
  - poddisruptionbudgets/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  - ingresses/status
  - networkpolicies
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - authorization.k8s.io
  resources:
  - localsubjectaccessreviews
  verbs:
  - create
- apiGroups:
  - rbac.authorization.k8s.io
  resources:
  - rolebindings
  - roles
  verbs:
  - create
  - delete
  - deletecollection
  - get
  - list
  - patch
  - update
  - watch

cluster-admin

系统默认定义的 cluster-admin 中包含定义了一个 masters 组,在创建账号时 O 指定这个组,则默认归类到 cluster-admin 中,并拥有最高管理权限,在授权多个用户时也可以以这种组方式授权

[root@master-0 ~]# cd /etc/kubernetes/pki/
[root@master-0 pki]# openssl x509 -in apiserver-kubelet-client.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7592427137245817586 (0x695db8414292aaf2)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Mar 30 07:31:42 2020 GMT
            Not After : Mar 30 07:31:42 2021 GMT
        Subject: O=system:masters, CN=kube-apiserver-kubelet-client         # O 代表隶属于什么组织
        ... ...
[root@master-0 pki]# kubectl get clusterrolebinding cluster-admin -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2020-03-30T07:32:04Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:rbac.authorization.kubernetes.io/autoupdate: {}
        f:labels:
          .: {}
          f:kubernetes.io/bootstrapping: {}
      f:roleRef:
        f:apiGroup: {}
        f:kind: {}
        f:name : {}
      f:subjects: {}
    manager: kube-apiserver
    operation: Update
    time: "2020-03-30T07:32:04Z"
  name: cluster-admin
  resourceVersion: "101"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin
  uid: 8ff1eba1-2543-445c-be36-4a4d9cc31102
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters                          # 代表这个组都拥有这种权限,即在创建用户是 O 指定的组

ServiceAccount

一个 pod 以指定的 spec.serviceAccountName 身份运行时, serviceAccountName 授予特定权限以后,这个 pod 就拥有了 serviceAccountName 之上对 apiserver 的访问权限

https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/
https://kubernetes.io/zh/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod

上一篇:javascript-Angular js / ui-router /限制用户手动导航到url(查看)


下一篇:容器集群k8s从入门到精通之安全认证(第九章)