理解kubernetes的角色控制

RBAC

Posted by Zeusro on January 17, 2019
👈🏻 Select language

kubernetes内部容器通讯都需要通过api-server进行通讯。外部通过kubectl访问管理集群,本质上也是访问api-server,api-server就是整个集群的指挥中枢。

但是人在江湖漂,哪能不挨刀呢?要怎么防止集群内外瞎搞事的破坏分子呢?RBAC(Role-based access control )顺势而生。

一句话总结ServiceAccount,Role,RoleBinding,ClusterRole,ClusterRoleBinding的关系就是,

ClusterRoleBinding,RoleBinding是一种任命,认命被授权的对象(users, groups, or service accounts)能够有什么样的权限(Role,ClusterRole)

ServiceAccount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"flannel","namespace":"kube-system"}}
  creationTimestamp: 2018-07-24T06:44:45Z
  name: flannel
  namespace: kube-system
  resourceVersion: "382"
  selfLink: /api/v1/namespaces/kube-system/serviceaccounts/flannel
  uid: 0d4064e6-8f0d-11e8-b4b4-00163e08cd06
secrets:
- name: flannel-token-f7d4d

上面说了,ServiceAccount只是一个虚名,本身没有任何的权限说明。

service-account-token

service-account-token的API type是kubernetes.io/service-account-token

变动ServiceAccount时,Token Controller(controller-manager的一部分) 会自动维护service-account-token,根据实际情况增加/修改/删除,service-account-token的本质类型是secret.所以service-account-token是1对1跟ServiceAccount随生随死的。

而定义的资源如果指定了ServiceAccount,Admission Controllers(api-server的一部分)就会把这个ServiceAccount相应的service-account-token以文件的形式挂载到容器内部的/var/run/secrets/kubernetes.io/serviceaccount目录下。

该目录一般会有3个文件

  1. ca.crt
  2. namespace
  3. token

参考链接:

  1. 管理Service Accounts
  2. Configure Service Accounts for Pods

Role

1
2
3
4
5
6
7
8
9
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Role 只能用于授予对单个命名空间中的资源访问权限

定义了具体的url

RoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding 适用于某个命名空间内授权,RoloBinding 可以将角色中定义的权限授予用户或用户组

ClusterRole

1
2
3
4
5
6
7
8
9
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
  1. 集群级别的资源控制(例如 node 访问权限)
  2. 非资源型 endpoints(例如 /healthz 访问)
  3. 所有命名空间资源控制(例如 pods)

ClusterRoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-operator
subjects:
- kind: ServiceAccount
  name: prometheus-operator
  namespace: monitoring

ClusterRoleBinding 适用于集群范围内的授权。

最后用一个表格整理一下

资源类型 说明
ServiceAccount 一个虚名
service-account-token ServiceAccount的身份象征
Role 授予对单个命名空间中的资源访问权限
RoleBinding 将赋予被授权对象和Role
ClusterRole 可视为Role的超集,是从集群角度做的一种授权
ClusterRoleBinding 将赋予被授权对象和ClusterRole

理解kubernetesRBAC的最简单办法,就是进入kube-system内部,看看各类集群资源是怎么定义的。

参考链接:

  1. Kubernetes TLS bootstrapping 那点事
  2. 使用 RBAC 控制 kubectl 权限
  3. Kubernetes RBAC
  4. Using RBAC Authorization
  5. Authenticating with Bootstrap Tokens

All communication between containers in kubernetes needs to go through the api-server. External access to manage the cluster through kubectl is essentially also accessing the api-server. The api-server is the command center of the entire cluster.

But when you’re in the world, you can’t avoid getting hurt. How to prevent troublemakers inside and outside the cluster from causing damage? RBAC (Role-based access control) was born.

In one sentence, the relationship between ServiceAccount, Role, RoleBinding, ClusterRole, and ClusterRoleBinding is:

ClusterRoleBinding and RoleBinding are appointments, authorizing what permissions (Role, ClusterRole) the authorized objects (users, groups, or service accounts) can have.

ServiceAccount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"flannel","namespace":"kube-system"}}
  creationTimestamp: 2018-07-24T06:44:45Z
  name: flannel
  namespace: kube-system
  resourceVersion: "382"
  selfLink: /api/v1/namespaces/kube-system/serviceaccounts/flannel
  uid: 0d4064e6-8f0d-11e8-b4b4-00163e08cd06
secrets:
- name: flannel-token-f7d4d

As mentioned above, ServiceAccount is just a name, with no permission description itself.

service-account-token

The API type of service-account-token is kubernetes.io/service-account-token

When ServiceAccount changes, the Token Controller (part of controller-manager) automatically maintains service-account-token, adding/modifying/deleting as needed. The essence type of service-account-token is secret. So service-account-token is 1-to-1 with ServiceAccount, living and dying together.

If a defined resource specifies a ServiceAccount, Admission Controllers (part of api-server) will mount the corresponding service-account-token of this ServiceAccount as files into the container at the /var/run/secrets/kubernetes.io/serviceaccount directory.

This directory generally has 3 files:

  1. ca.crt
  2. namespace
  3. token

Reference Links:

  1. Managing Service Accounts
  2. Configure Service Accounts for Pods

Role

1
2
3
4
5
6
7
8
9
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Role can only be used to grant access permissions to resources in a single namespace.

Defines specific URLs.

RoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding is used for authorization within a namespace. RoleBinding can grant permissions defined in a role to users or user groups.

ClusterRole

1
2
3
4
5
6
7
8
9
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
  1. Cluster-level resource control (e.g., node access permissions)
  2. Non-resource endpoints (e.g., /healthz access)
  3. All namespace resource control (e.g., pods)

ClusterRoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-operator
subjects:
- kind: ServiceAccount
  name: prometheus-operator
  namespace: monitoring

ClusterRoleBinding is used for cluster-wide authorization.

Finally, let’s organize it in a table:

Resource Type Description
ServiceAccount Just a name
service-account-token Identity symbol of ServiceAccount
Role Grants access permissions to resources in a single namespace
RoleBinding Grants authorized objects and Role
ClusterRole Can be considered a superset of Role, authorization from a cluster perspective
ClusterRoleBinding Grants authorized objects and ClusterRole

The simplest way to understand kubernetes RBAC is to go inside kube-system and see how various cluster resources are defined.

Reference Links:

  1. Kubernetes TLS bootstrapping Notes
  2. Using RBAC to Control kubectl Permissions
  3. Kubernetes RBAC
  4. Using RBAC Authorization
  5. Authenticating with Bootstrap Tokens

Вся связь между контейнерами внутри kubernetes должна проходить через api-server. Внешний доступ к управлению кластером через kubectl по сути также является доступом к api-server. api-server — это командный центр всего кластера.

Но когда вы в мире, вы не можете избежать травм. Как предотвратить вредителей внутри и снаружи кластера? RBAC (Role-based access control) был создан.

В одном предложении, отношения между ServiceAccount, Role, RoleBinding, ClusterRole и ClusterRoleBinding:

ClusterRoleBinding и RoleBinding — это назначения, авторизующие, какие разрешения (Role, ClusterRole) могут иметь авторизованные объекты (пользователи, группы или сервисные аккаунты).

ServiceAccount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"flannel","namespace":"kube-system"}}
  creationTimestamp: 2018-07-24T06:44:45Z
  name: flannel
  namespace: kube-system
  resourceVersion: "382"
  selfLink: /api/v1/namespaces/kube-system/serviceaccounts/flannel
  uid: 0d4064e6-8f0d-11e8-b4b4-00163e08cd06
secrets:
- name: flannel-token-f7d4d

Как упоминалось выше, ServiceAccount — это просто имя, без описания разрешений.

service-account-token

API тип service-account-token — kubernetes.io/service-account-token

При изменении ServiceAccount Token Controller (часть controller-manager) автоматически поддерживает service-account-token, добавляя/изменяя/удаляя по мере необходимости. Сущностный тип service-account-tokensecret. Поэтому service-account-token находится в соотношении 1 к 1 с ServiceAccount, живя и умирая вместе.

Если определенный ресурс указывает ServiceAccount, Admission Controllers (часть api-server) смонтируют соответствующий service-account-token этого ServiceAccount в виде файлов в контейнер в директорию /var/run/secrets/kubernetes.io/serviceaccount.

Эта директория обычно имеет 3 файла:

  1. ca.crt
  2. namespace
  3. token

Ссылки:

  1. Управление Service Accounts
  2. Настройка Service Accounts для Pods

Role

1
2
3
4
5
6
7
8
9
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" указывает на основную API группу
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Role может использоваться только для предоставления прав доступа к ресурсам в одном пространстве имен.

Определяет конкретные URL.

RoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Это привязка роли позволяет "jane" читать pods в пространстве имен "default".
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding применяется для авторизации в пространстве имен. RoleBinding может предоставить разрешения, определенные в роли, пользователям или группам пользователей.

ClusterRole

1
2
3
4
5
6
7
8
9
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" опущен, так как ClusterRoles не имеют пространства имен
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
  1. Контроль ресурсов на уровне кластера (например, права доступа к узлу)
  2. Нересурсные конечные точки (например, доступ к /healthz)
  3. Контроль ресурсов всех пространств имен (например, pods)

ClusterRoleBinding

1
2
3
4
5
6
7
8
9
10
11
12
13
# Это привязка роли кластера позволяет любому в группе "manager" читать секреты в любом пространстве имен.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-operator
subjects:
- kind: ServiceAccount
  name: prometheus-operator
  namespace: monitoring

ClusterRoleBinding применяется для авторизации в масштабе кластера.

Наконец, давайте организуем это в таблице:

Тип ресурса Описание
ServiceAccount Просто имя
service-account-token Символ идентичности ServiceAccount
Role Предоставляет права доступа к ресурсам в одном пространстве имен
RoleBinding Предоставляет авторизованным объектам и Role
ClusterRole Можно рассматривать как надмножество Role, авторизация с точки зрения кластера
ClusterRoleBinding Предоставляет авторизованным объектам и ClusterRole

Самый простой способ понять RBAC kubernetes — войти внутрь kube-system и посмотреть, как определены различные ресурсы кластера.

Ссылки:

  1. Заметки о Kubernetes TLS bootstrapping
  2. Использование RBAC для управления разрешениями kubectl
  3. Kubernetes RBAC
  4. Использование авторизации RBAC
  5. Аутентификация с Bootstrap Tokens


💬 讨论 / Discussion

对这篇文章有想法?欢迎在 GitHub 上发起讨论。
Have thoughts on this post? Start a discussion on GitHub.

在 GitHub 参与讨论 / Discuss on GitHub