Пример назначения прав администратору кластера
Пример использует экспериментальную ролевую модель.
Для назначения прав администратору кластера используйте роль d8:manage:all:manager
в ClusterRoleBinding
.
Пример назначения прав администратору кластера (User joe
):
1apiVersion: rbac.authorization.k8s.io/v1
2kind: ClusterRoleBinding
3metadata:
4 name: cluster-admin-joe
5subjects:
6- kind: User
7 name: joe
8 apiGroup: rbac.authorization.k8s.io
9roleRef:
10 kind: ClusterRole
11 name: d8:manage:all:manager
12 apiGroup: rbac.authorization.k8s.io
Пример назначения прав сетевому администратору
Пример использует экспериментальную ролевую модель.
Для назначения прав сетевому администратору на управление сетевой подсистемой кластера используйте роль d8:manage:networking:manager
в ClusterRoleBinding
.
Пример назначения прав сетевому администратору (User joe
):
1apiVersion: rbac.authorization.k8s.io/v1
2kind: ClusterRoleBinding
3metadata:
4 name: network-admin-joe
5subjects:
6- kind: User
7 name: joe
8 apiGroup: rbac.authorization.k8s.io
9roleRef:
10 kind: ClusterRole
11 name: d8:manage:networking:manager
12 apiGroup: rbac.authorization.k8s.io
Пример назначения административных прав пользователю в рамках пространства имён
Пример использует экспериментальную ролевую модель.
Для назначения прав на управление ресурсами приложений в рамках пространства имён, но без возможности настройки модулей DKP, используйте роль d8:use:role:admin
в RoleBinding
в соответствующем пространстве имён.
Пример назначения прав разработчику приложений (User app-developer
) в пространстве имён myapp
:
1apiVersion: rbac.authorization.k8s.io/v1
2kind: RoleBinding
3metadata:
4 name: myapp-developer
5 namespace: myapp
6subjects:
7- kind: User
8 name: app-developer
9 apiGroup: rbac.authorization.k8s.io
10roleRef:
11 kind: ClusterRole
12 name: d8:use:role:admin
13 apiGroup: rbac.authorization.k8s.io
Пример ClusterAuthorizationRule
1apiVersion: deckhouse.io/v1
2kind: ClusterAuthorizationRule
3metadata:
4 name: test-rule
5spec:
6 subjects:
7 - kind: User
8 name: some@example.com
9 - kind: ServiceAccount
10 name: gitlab-runner-deploy
11 namespace: d8-service-accounts
12 - kind: Group
13 name: some-group-name
14 accessLevel: PrivilegedUser
15 portForwarding: true
16 # Опция доступна только при включенном режиме enableMultiTenancy.
17 allowAccessToSystemNamespaces: false
18 # Опция доступна только при включенном режиме enableMultiTenancy.
19 namespaceSelector:
20 labelSelector:
21 matchExpressions:
22 - key: stage
23 operator: In
24 values:
25 - test
26 - review
27 matchLabels:
28 team: frontend
Создание пользователя
В Kubernetes есть две категории пользователей:
- ServiceAccount’ы, учёт которых ведёт сам Kubernetes через API.
- Остальные пользователи, учёт которых ведёт не сам Kubernetes, а некоторый внешний софт, который настраивает администратор кластера, — существует множество механизмов аутентификации и, соответственно, множество способов заводить пользователей. В настоящий момент поддерживаются два способа аутентификации:
- через модуль user-authn;
- с помощью сертификатов.
При выпуске сертификата для аутентификации нужно указать в нём имя (CN=<имя>
), необходимое количество групп (O=<группа>
) и подписать его с помощью корневого CA-кластера. Именно этим механизмом вы аутентифицируетесь в кластере, когда, например, используете kubectl на bastion-узле.
Создание ServiceAccount для сервера и предоставление ему доступа
Создание ServiceAccount с доступом к Kubernetes API может потребоваться, например, при настройке развёртывания приложений через CI-системы.
-
Создайте ServiceAccount, например в пространстве имён
d8-service-accounts
:1kubectl create -f - <<EOF 2apiVersion: v1 3kind: ServiceAccount 4metadata: 5 name: gitlab-runner-deploy 6 namespace: d8-service-accounts 7--- 8apiVersion: v1 9kind: Secret 10metadata: 11 name: gitlab-runner-deploy-token 12 namespace: d8-service-accounts 13 annotations: 14 kubernetes.io/service-account.name: gitlab-runner-deploy 15type: kubernetes.io/service-account-token 16EOF
-
Дайте необходимые ServiceAccount-права (используя custom resource ClusterAuthorizationRule):
1kubectl create -f - <<EOF 2apiVersion: deckhouse.io/v1 3kind: ClusterAuthorizationRule 4metadata: 5 name: gitlab-runner-deploy 6spec: 7 subjects: 8 - kind: ServiceAccount 9 name: gitlab-runner-deploy 10 namespace: d8-service-accounts 11 accessLevel: SuperAdmin 12 # Опция доступна только при включенном режиме enableMultiTenancy. 13 allowAccessToSystemNamespaces: true 14EOF
Если в конфигурации Deckhouse включён режим мультитенантности (в параметре
enableMultiTenancy
), настройте доступные для ServiceAccount пространства имён (в параметреnamespaceSelector
). -
Определите значения переменных (они будут использоваться далее), выполнив следующие команды (подставьте свои значения):
1export CLUSTER_NAME=my-cluster 2export USER_NAME=gitlab-runner-deploy.my-cluster 3export CONTEXT_NAME=${CLUSTER_NAME}-${USER_NAME} 4export FILE_NAME=kube.config
-
Сгенерируйте секцию
cluster
в файле конфигурации kubectl:Используйте один из следующих вариантов доступа к API-серверу кластера:
- Если есть прямой доступ до API-сервера:
-
Получите сертификат CA-кластера Kubernetes:
1kubectl get cm kube-root-ca.crt -o jsonpath='{ .data.ca\.crt }' > /tmp/ca.crt
-
Сгенерируйте секцию
cluster
(используется IP-адрес API-сервера для доступа):1kubectl config set-cluster $CLUSTER_NAME --embed-certs=true \ 2 --server=https://$(kubectl get ep kubernetes -o json | jq -rc '.subsets[0] | "\(.addresses[0].ip):\(.ports[0].port)"') \ 3 --certificate-authority=/tmp/ca.crt \ 4 --kubeconfig=$FILE_NAME
-
- Если прямого доступа до API-сервера нет, используйте один следующих вариантов:
- включите доступ к API-серверу через Ingress-контроллер (параметр publishAPI) и укажите адреса, с которых будут идти запросы (параметр whitelistSourceRanges);
- укажите адреса, с которых будут идти запросы, в отдельном Ingress-контроллере (параметр acceptRequestsFrom).
-
Если используется непубличный CA:
-
Получите сертификат CA из секрета с сертификатом, который используется для домена
api.%s
:1kubectl -n d8-user-authn get secrets -o json \ 2 $(kubectl -n d8-user-authn get ing kubernetes-api -o jsonpath="{.spec.tls[0].secretName}") \ 3 | jq -rc '.data."ca.crt" // .data."tls.crt"' \ 4 | base64 -d > /tmp/ca.crt
-
Сгенерируйте секцию
cluster
(используется внешний домен и CA для доступа):1kubectl config set-cluster $CLUSTER_NAME --embed-certs=true \ 2 --server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq '.spec.rules[].host' -r) \ 3 --certificate-authority=/tmp/ca.crt \ 4 --kubeconfig=$FILE_NAME
-
-
Если используется публичный CA. Сгенерируйте секцию
cluster
(используется внешний домен для доступа):1kubectl config set-cluster $CLUSTER_NAME \ 2 --server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq '.spec.rules[].host' -r) \ 3 --kubeconfig=$FILE_NAME
- Если есть прямой доступ до API-сервера:
-
Сгенерируйте секцию
user
с токеном из секрета ServiceAccount в файле конфигурации kubectl:1kubectl config set-credentials $USER_NAME \ 2 --token=$(kubectl -n d8-service-accounts get secret gitlab-runner-deploy-token -o json |jq -r '.data["token"]' | base64 -d) \ 3 --kubeconfig=$FILE_NAME
-
Сгенерируйте контекст в файле конфигурации kubectl:
1kubectl config set-context $CONTEXT_NAME \ 2 --cluster=$CLUSTER_NAME --user=$USER_NAME \ 3 --kubeconfig=$FILE_NAME
-
Установите сгенерированный контекст как используемый по умолчанию в файле конфигурации kubectl:
1kubectl config use-context $CONTEXT_NAME --kubeconfig=$FILE_NAME
Создание пользователя с помощью клиентского сертификата
Создание пользователя
- Получите корневой сертификат кластера (ca.crt и ca.key).
-
Сгенерируйте ключ пользователя:
1openssl genrsa -out myuser.key 2048
-
Создайте CSR, где укажите, что требуется пользователь
myuser
, который состоит в группахmygroup1
иmygroup2
:1openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser/O=mygroup1/O=mygroup2"
-
Подпишите CSR корневым сертификатом кластера:
1openssl x509 -req -in myuser.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out myuser.crt -days 10
-
Теперь полученный сертификат можно указывать в конфиг-файле:
1cat << EOF 2apiVersion: v1 3clusters: 4- cluster: 5 certificate-authority-data: $(cat ca.crt | base64 -w0) 6 server: https://<хост кластера>:6443 7 name: kubernetes 8contexts: 9- context: 10 cluster: kubernetes 11 user: myuser 12 name: myuser@kubernetes 13current-context: myuser@kubernetes 14kind: Config 15preferences: {} 16users: 17- name: myuser 18 user: 19 client-certificate-data: $(cat myuser.crt | base64 -w0) 20 client-key-data: $(cat myuser.key | base64 -w0) 21EOF
Предоставление доступа созданному пользователю
Для предоставления доступа созданному пользователю создайте ClusterAuthorizationRule
.
Пример ClusterAuthorizationRule
:
1apiVersion: deckhouse.io/v1
2kind: ClusterAuthorizationRule
3metadata:
4 name: myuser
5spec:
6 subjects:
7 - kind: User
8 name: myuser
9 accessLevel: PrivilegedUser
10 portForwarding: true
Настройка kube-apiserver
для работы в режиме multi-tenancy
Режим multi-tenancy, позволяющий ограничивать доступ к пространству имён, включается параметром enableMultiTenancy модуля.
Работа в режиме multi-tenancy требует включения плагина авторизации Webhook и выполнения настройки kube-apiserver
. Все необходимые для работы режима multi-tenancy действия выполняются автоматически модулем control-plane-manager, никаких ручных действий не требуется.
Изменения манифеста kube-apiserver
, которые произойдут после включения режима multi-tenancy:
- исправление аргумента
--authorization-mode
. Перед методом RBAC добавится метод Webhook (например,--authorization-mode=Node,Webhook,RBAC
); - добавление аргумента
--authorization-webhook-config-file=/etc/kubernetes/authorization-webhook-config.yaml
; -
добавление
volumeMounts
:1- name: authorization-webhook-config 2 mountPath: /etc/kubernetes/authorization-webhook-config.yaml 3 readOnly: true
-
добавление
volumes
:1- name: authorization-webhook-config 2 hostPath: 3 path: /etc/kubernetes/authorization-webhook-config.yaml 4 type: FileOrCreate
Как проверить, что у пользователя есть доступ?
Необходимо выполнить следующую команду, в которой будут указаны:
resourceAttributes
(как в RBAC) — к чему мы проверяем доступ;user
— имя пользователя;groups
— группы пользователя.
При совместном использовании с модулем
user-authn
группы и имя пользователя можно посмотреть в логах Dex —kubectl -n d8-user-authn logs -l app=dex
(видны только при авторизации).
1cat <<EOF | 2>&1 kubectl create --raw /apis/authorization.k8s.io/v1/subjectaccessreviews -f - | jq .status
2{
3 "apiVersion": "authorization.k8s.io/v1",
4 "kind": "SubjectAccessReview",
5 "spec": {
6 "resourceAttributes": {
7 "namespace": "",
8 "verb": "watch",
9 "version": "v1",
10 "resource": "pods"
11 },
12 "user": "system:kube-controller-manager",
13 "groups": [
14 "Admins"
15 ]
16 }
17}
18EOF
В результате увидим, есть ли доступ и на основании какой роли:
1{
2 "allowed": true,
3 "reason": "RBAC: allowed by ClusterRoleBinding \"system:kube-controller-manager\" of ClusterRole \"system:kube-controller-manager\" to User \"system:kube-controller-manager\""
4}
Если в кластере включён режим multi-tenancy, нужно выполнить ещё одну проверку, чтобы убедиться, что у пользователя есть доступ в пространство имён:
1cat <<EOF | 2>&1 kubectl --kubeconfig /etc/kubernetes/deckhouse/extra-files/webhook-config.yaml create --raw / -f - | jq .status
2{
3 "apiVersion": "authorization.k8s.io/v1",
4 "kind": "SubjectAccessReview",
5 "spec": {
6 "resourceAttributes": {
7 "namespace": "",
8 "verb": "watch",
9 "version": "v1",
10 "resource": "pods"
11 },
12 "user": "system:kube-controller-manager",
13 "groups": [
14 "Admins"
15 ]
16 }
17}
18EOF
1{
2 "allowed": false
3}
Сообщение allowed: false
значит, что вебхук не блокирует запрос. В случае блокировки запроса вебхуком вы получите, например, следующее сообщение:
1{
2 "allowed": false,
3 "denied": true,
4 "reason": "making cluster scoped requests for namespaced resources are not allowed"
5}
Настройка прав высокоуровневых ролей
Если требуется добавить прав для определённой высокоуровневой роли, достаточно создать ClusterRole с аннотацией user-authz.deckhouse.io/access-level: <AccessLevel>
.
Пример:
1apiVersion: rbac.authorization.k8s.io/v1
2kind: ClusterRole
3metadata:
4 annotations:
5 user-authz.deckhouse.io/access-level: Editor
6 name: user-editor
7rules:
8- apiGroups:
9 - kuma.io
10 resources:
11 - trafficroutes
12 - trafficroutes/finalizers
13 verbs:
14 - get
15 - list
16 - watch
17 - create
18 - update
19 - patch
20 - delete
21- apiGroups:
22 - flagger.app
23 resources:
24 - canaries
25 - canaries/status
26 - metrictemplates
27 - metrictemplates/status
28 - alertproviders
29 - alertproviders/status
30 verbs:
31 - get
32 - list
33 - watch
34 - create
35 - update
36 - patch
37 - delete