Compare languages | Модуль user-authz: примеры конфигурации

Пример ClusterAuthorizationRule

An example of ClusterAuthorizationRule

yaml apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: test-rule spec: subjects:

  • kind: User name: some@example.com
  • kind: ServiceAccount name: gitlab-runner-deploy namespace: d8-service-accounts
  • kind: Group name: some-group-name accessLevel: PrivilegedUser portForwarding: true Опция доступна только при включенном режиме enableMultiTenancy (версия Enterprise Edition). allowAccessToSystemNamespaces: false Опция доступна только при включенном режиме enableMultiTenancy (версия Enterprise Edition). namespaceSelector: labelSelector: matchExpressions:
  • key: stage operator: In values:
  • test
  • review matchLabels: team: frontend

yaml apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: test-rule spec: subjects:

  • kind: User name: some@example.com
  • kind: ServiceAccount name: gitlab-runner-deploy namespace: d8-service-accounts
  • kind: Group name: some-group-name accessLevel: PrivilegedUser portForwarding: true This option is only available if the enableMultiTenancy parameter is set (Enterprise Edition version) allowAccessToSystemNamespaces: false This option is only available if the enableMultiTenancy parameter is set (Enterprise Edition version) namespaceSelector: labelSelector: matchExpressions:
  • key: stage operator: In values:
  • test
  • review matchLabels: team: frontend

Создание пользователя

Creating a user

В Kubernetes есть две категории пользователей:

There are two types of users in Kubernetes:

  • ServiceAccount’ы, учет которых ведет сам Kubernetes через API.
  • Остальные пользователи, учет которых ведет не сам Kubernetes, а некоторый внешний софт, который настраивает администратор кластера, — существует множество механизмов аутентификации и, соответственно, множество способов заводить пользователей. В настоящий момент поддерживаются два способа аутентификации:
  • через модуль user-authn;
  • с помощью сертификатов.
  • Service accounts managed by Kubernetes via the API;
  • Regular users managed by some external tool that the cluster administrator configures. There are many authentication mechanisms and, accordingly, many ways to create users. Currently, two authentication methods are supported:
  • Via the user-authn module.
  • Via the certificates.

При выпуске сертификата для аутентификации нужно указать в нем имя (CN=<имя>), необходимое количество групп (O=<группа>) и подписать его с помощью корневого CA-кластера. Именно этим механизмом вы аутентифицируетесь в кластере, когда, например, используете kubectl на bastion-узле.

When issuing the authentication certificate, you need to specify the name (CN=<name>), the required number of groups (O=<group>), and sign it using the root CA of the cluster. It is this mechanism that authenticates you in the cluster when, for example, you use kubectl on a bastion node.

Создание ServiceAccount для сервера и предоставление ему доступа

Creating a ServiceAccount for a machine and granting it access

Создание ServiceAccount с доступом к Kubernetes API может потребоваться, например, при настройке развертывания приложений через CI-системы.

You may need to create a ServiceAccount with access to the Kubernetes API when, for example, an application is deployed using a CI system.

  1. Создайте ServiceAccount, например в namespace d8-service-accounts:
  1. Create a ServiceAccount, e.g., in the d8-service-accounts namespace:

shell kubectl create -f - «EOF apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-runner-deploy namespace: d8-service-accounts — apiVersion: v1 kind: Secret metadata: name: gitlab-runner-deploy-token namespace: d8-service-accounts annotations: kubernetes.io/service-account.name: gitlab-runner-deploy type: kubernetes.io/service-account-token EOF

shell kubectl create -f - «EOF apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-runner-deploy namespace: d8-service-accounts — apiVersion: v1 kind: Secret metadata: name: gitlab-runner-deploy-token namespace: d8-service-accounts annotations: kubernetes.io/service-account.name: gitlab-runner-deploy type: kubernetes.io/service-account-token EOF

  1. Дайте необходимые ServiceAccount права (используя custom resource ClusterAuthorizationRule):
  1. Grant it the necessary privileges (using the ClusterAuthorizationRule custom resource):

shell kubectl create -f - «EOF apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: gitlab-runner-deploy spec: subjects:

  • kind: ServiceAccount name: gitlab-runner-deploy namespace: d8-service-accounts accessLevel: SuperAdmin Опция доступна только при включенном режиме enableMultiTenancy (версия Enterprise Edition). allowAccessToSystemNamespaces: true
    EOF

shell kubectl create -f - «EOF apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: gitlab-runner-deploy spec: subjects:

  • kind: ServiceAccount name: gitlab-runner-deploy namespace: d8-service-accounts accessLevel: SuperAdmin This option is only available if the enableMultiTenancy parameter is set (Enterprise Edition version) allowAccessToSystemNamespaces: true
    EOF

Если в конфигурации Deckhouse включен режим мультитенантности (параметр enableMultiTenancy, доступен только в Enterprise Edition), настройте доступные для ServiceAccount пространства имен (параметр namespaceSelector).

If multitenancy is enabled in the Deckhouse configuration (the enableMultiTenancy paameter; it is only available in Enterprise Edition), configure the namespaces the ServiceAccount has access to (the namespaceSelector parameter).

  1. Определите значения переменных (они будут использоваться далее), выполнив следующие команды (подставьте свои значения):
  1. Set the variable values (they will be used later) by running the following commands (insert your own values):

shell export CLUSTER_NAME=my-cluster export USER_NAME=gitlab-runner-deploy.my-cluster export CONTEXT_NAME=${CLUSTER_NAME}-${USER_NAME} export FILE_NAME=kube.config

shell export CLUSTER_NAME=my-cluster export USER_NAME=gitlab-runner-deploy.my-cluster export CONTEXT_NAME=${CLUSTER_NAME}-${USER_NAME} export FILE_NAME=kube.config

  1. Сгенерируйте секцию cluster в файле конфигурации kubectl:
  1. Generate the cluster section in the kubectl configuration file:

Используйте один из следующих вариантов доступа к API-серверу кластера:

Use one of the following options to access the cluster API server:

  • Если есть прямой доступ до API-сервера:
    1. Получите сертификат CA кластера Kubernetes:
  • If there is direct access to the API server:
    1. Get a Kubernetes cluster CA certificate:

shell kubectl get cm kube-root-ca.crt -o jsonpath=’{ .data.ca.crt }’ > /tmp/ca.crt

shell kubectl get cm kube-root-ca.crt -o jsonpath=’{ .data.ca.crt }’ > /tmp/ca.crt

  1. Сгенерируйте секцию cluster (используется IP-адрес API-сервера для доступа):
  1. Generate the cluster section (the API server’s IP address is used for access):

shell kubectl config set-cluster $CLUSTER_NAME –embed-certs=true
–server=https://$(kubectl get ep kubernetes -o json | jq -rc ‘.subsets[0] | “(.addresses[0].ip):(.ports[0].port)”’)
–certificate-authority=/tmp/ca.crt
–kubeconfig=$FILE_NAME

shell kubectl config set-cluster $CLUSTER_NAME –embed-certs=true
–server=https://$(kubectl get ep kubernetes -o json | jq -rc ‘.subsets[0] | “(.addresses[0].ip):(.ports[0].port)”’)
–certificate-authority=/tmp/ca.crt
–kubeconfig=$FILE_NAME

  • Если прямого доступа до API-сервера нет, то используйте один следующих вариантов:
  • включите доступ к API-серверу через Ingress-контроллер (параметр publishAPI), и укажите адреса с которых будут идти запросы (параметр whitelistSourceRanges);
  • укажите адреса с которых будут идти запросы в отдельном Ingress-контроллере (параметр acceptRequestsFrom).
  • If there is no direct access to the API server, use one of the following options:
  • enable access to the API-server over the Ingress controller (the publishAPI parameter) and specify the addresses from which requests originate (the whitelistSourceRanges parameter);
  • specify addresses from which requests will originate in a separate Ingress controller (the acceptRequestsFrom parameter).
  • Если используется непубличный CA:
  • If a non-public CA is used:
  1. Получите сертификат CA из Secret’а с сертификатом, который используется для домена api.%s:
  1. Get the CA certificate from the Secret with the certificate that is used for the api.%s domain:

shell kubectl -n d8-user-authn get secrets -o json
$(kubectl -n d8-user-authn get ing kubernetes-api -o jsonpath=”{.spec.tls[0].secretName}”)
| jq -rc ‘.data.”ca.crt” // .data.”tls.crt”’
| base64 -d > /tmp/ca.crt

shell kubectl -n d8-user-authn get secrets -o json
$(kubectl -n d8-user-authn get ing kubernetes-api -o jsonpath=”{.spec.tls[0].secretName}”)
| jq -rc ‘.data.”ca.crt” // .data.”tls.crt”’
| base64 -d > /tmp/ca.crt

  1. Сгенерируйте секцию cluster (используется внешний домен и CA для доступа):
  1. Generate the cluster section (an external domain and a CA for access are used):

shell kubectl config set-cluster $CLUSTER_NAME –embed-certs=true
–server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq ‘.spec.rules[].host’ -r)
–certificate-authority=/tmp/ca.crt
–kubeconfig=$FILE_NAME

shell kubectl config set-cluster $CLUSTER_NAME –embed-certs=true
–server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq ‘.spec.rules[].host’ -r)
–certificate-authority=/tmp/ca.crt
–kubeconfig=$FILE_NAME

  • Если используется публичный CA. Сгенерируйте секцию cluster (используется внешний домен для доступа):
  • If a public CA is used. Generate the cluster section (an external domain is used for access):

shell kubectl config set-cluster $CLUSTER_NAME
–server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq ‘.spec.rules[].host’ -r)
–kubeconfig=$FILE_NAME

shell kubectl config set-cluster $CLUSTER_NAME
–server=https://$(kubectl -n d8-user-authn get ing kubernetes-api -ojson | jq ‘.spec.rules[].host’ -r)
–kubeconfig=$FILE_NAME

  1. Сгенерируйте секцию user с токеном из Secret’а ServiceAccount в файле конфигурации kubectl:
  1. Generate the user section using the token from the Secret’s ServiceAccount in the kubectl configuration file:

shell kubectl config set-credentials $USER_NAME
–token=$(kubectl -n d8-service-accounts get secret gitlab-runner-deploy-token -o json |jq -r ‘.data[“token”]’ | base64 -d)
–kubeconfig=$FILE_NAME

shell kubectl config set-credentials $USER_NAME
–token=$(kubectl -n d8-service-accounts get secret gitlab-runner-deploy-token -o json |jq -r ‘.data[“token”]’ | base64 -d)
–kubeconfig=$FILE_NAME

  1. Сгенерируйте контекст в файле конфигурации kubectl:
  1. Generate the context in the kubectl configuration file:

shell kubectl config set-context $CONTEXT_NAME
–cluster=$CLUSTER_NAME –user=$USER_NAME
–kubeconfig=$FILE_NAME

shell kubectl config set-context $CONTEXT_NAME
–cluster=$CLUSTER_NAME –user=$USER_NAME
–kubeconfig=$FILE_NAME

  1. Установите сгенерированный контекст как используемый по умолчанию в файле конфигурации kubectl:
  1. Set the generated context as the default one in the kubectl configuration file:

shell kubectl config use-context $CONTEXT_NAME –kubeconfig=$FILE_NAME

shell kubectl config use-context $CONTEXT_NAME –kubeconfig=$FILE_NAME

Создание пользователя с помощью клиентского сертификата

How to create a user using a client certificate

Создание пользователя

Creating a user

  • Получите корневой сертификат кластера (ca.crt и ca.key).
  • Сгенерируйте ключ пользователя:
  • Get the cluster’s root certificate (ca.crt and ca.key).
  • Generate the user key:

shell openssl genrsa -out myuser.key 2048

shell openssl genrsa -out myuser.key 2048

  • Создайте CSR, где укажите, что требуется пользователь myuser, который состоит в группах mygroup1 и mygroup2:
  • Create a CSR file and specify in it the username (myuser) and groups to which this user belongs (mygroup1 & mygroup2):

shell openssl req -new -key myuser.key -out myuser.csr -subj “/CN=myuser/O=mygroup1/O=mygroup2”

shell openssl req -new -key myuser.key -out myuser.csr -subj “/CN=myuser/O=mygroup1/O=mygroup2”

  • Подпишите CSR корневым сертификатом кластера:
  • Sign the CSR using the cluster root certificate:

shell openssl x509 -req -in myuser.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out myuser.crt -days 10

shell openssl x509 -req -in myuser.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out myuser.crt -days 10

  • Теперь полученный сертификат можно указывать в конфиг-файле:
  • Now you can use the certificate issued in the config file:

shell cat « EOF apiVersion: v1 clusters:

  • cluster: certificate-authority-data: $(cat ca.crt | base64 -w0) server: https://<хост кластера="">:6443 name: kubernetes contexts:
  • context: cluster: kubernetes user: myuser name: myuser@kubernetes current-context: myuser@kubernetes kind: Config preferences: {} users:
  • name: myuser user: client-certificate-data: $(cat myuser.crt | base64 -w0) client-key-data: $(cat myuser.key | base64 -w0) EOF

shell cat « EOF apiVersion: v1 clusters:

  • cluster: certificate-authority-data: $(cat ca.crt | base64 -w0) server: https://:6443 name: kubernetes contexts:
  • context: cluster: kubernetes user: myuser name: myuser@kubernetes current-context: myuser@kubernetes kind: Config preferences: {} users:
  • name: myuser user: client-certificate-data: $(cat myuser.crt | base64 -w0) client-key-data: $(cat myuser.key | base64 -w0) EOF

Предоставление доступа созданному пользователю

Granting access to the created user

Для предоставления доступа созданному пользователю создайте ClusterAuthorizationRule.

To grant access to the created user, create a `ClusterAuthorizationRule’.

Пример ClusterAuthorizationRule:

Example of a ClusterAuthorizationRule:

yaml apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: myuser spec: subjects:

  • kind: User name: myuser accessLevel: PrivilegedUser portForwarding: true

yaml apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: myuser spec: subjects:

  • kind: User name: myuser accessLevel: PrivilegedUser portForwarding: true

Настройка kube-apiserver для работы в режиме multi-tenancy

Configuring kube-apiserver for multi-tenancy mode

Режим multi-tenancy, позволяющий ограничивать доступ к namespace, включается параметром enableMultiTenancy модуля.

The multi-tenancy mode, which allows you to restrict access to namespaces, is enabled by the enableMultiTenancy module’s parameter.

Работа в режиме multi-tenancy требует включения плагина авторизации Webhook и выполнения настройки kube-apiserver. Все необходимые для работы режима multi-tenancy действия выполняются автоматически модулем control-plane-manager, никаких ручных действий не требуется.

Working in multi-tenancy mode requires enabling the Webhook authorization plugin and configuring a kube-apiserver. All actions necessary for the multi-tenancy mode are performed automatically by the control-plane-manager module; no additional steps are required.

Изменения манифеста kube-apiserver, которые произойдут после включения режима multi-tenancy:

Changes to the kube-apiserver manifest that will occur after enabling multi-tenancy mode:

  • исправление аргумента --authorization-mode. Перед методом RBAC добавится метод Webhook (например — --authorization-mode=Node,Webhook,RBAC);
  • добавление аргумента --authorization-webhook-config-file=/etc/kubernetes/authorization-webhook-config.yaml;
  • добавление volumeMounts:
  • The --authorization-mode argument will be modified: the Webhook method will be added in front of the RBAC method (e.g., --authorization-mode=Node,Webhook,RBAC);
  • The --authorization-webhook-config-file=/etc/kubernetes/authorization-webhook-config.yaml will be added;
  • The volumeMounts parameter will be added:

yaml

  • name: authorization-webhook-config mountPath: /etc/kubernetes/authorization-webhook-config.yaml readOnly: true

yaml

  • name: authorization-webhook-config mountPath: /etc/kubernetes/authorization-webhook-config.yaml readOnly: true
  • добавление volumes:
  • The volumes parameter will be added:

yaml

  • name: authorization-webhook-config hostPath: path: /etc/kubernetes/authorization-webhook-config.yaml type: FileOrCreate

yaml

  • name: authorization-webhook-config hostPath: path: /etc/kubernetes/authorization-webhook-config.yaml type: FileOrCreate

Как проверить, что у пользователя есть доступ?

How do I check that a user has access?

Необходимо выполнить следующую команду, в которой будут указаны:

Execute the command below with the following parameters:

  • resourceAttributes (как в RBAC) — к чему мы проверяем доступ;
  • user — имя пользователя;
  • groups — группы пользователя.
  • resourceAttributes (the same as in RBAC) - target resources;
  • user - the name of the user;
  • groups - user groups;

При совместном использовании с модулем user-authn группы и имя пользователя можно посмотреть в логах Dex — kubectl -n d8-user-authn logs -l app=dex (видны только при авторизации).

You can use Dex logs to find out groups and a username if this module is used together with the user-authn module (kubectl -n d8-user-authn logs -l app=dex); logs available only if the user is authorized).

shell cat «EOF | 2>&1 kubectl create –raw /apis/authorization.k8s.io/v1/subjectaccessreviews -f - | jq .status { “apiVersion”: “authorization.k8s.io/v1”, “kind”: “SubjectAccessReview”, “spec”: { “resourceAttributes”: { “namespace”: “”, “verb”: “watch”, “version”: “v1”, “resource”: “pods” }, “user”: “system:kube-controller-manager”, “groups”: [ “Admins” ] } } EOF

shell cat «EOF | 2>&1 kubectl create –raw /apis/authorization.k8s.io/v1/subjectaccessreviews -f - | jq .status { “apiVersion”: “authorization.k8s.io/v1”, “kind”: “SubjectAccessReview”, “spec”: { “resourceAttributes”: { “namespace”: “”, “verb”: “watch”, “version”: “v1”, “resource”: “pods” }, “user”: “system:kube-controller-manager”, “groups”: [ “Admins” ] } } EOF

В результате увидим, есть ли доступ и на основании какой роли:

You will see if access is allowed and what role is used:

json { “allowed”: true, “reason”: “RBAC: allowed by ClusterRoleBinding "system:kube-controller-manager" of ClusterRole "system:kube-controller-manager" to User "system:kube-controller-manager"” }

json { “allowed”: true, “reason”: “RBAC: allowed by ClusterRoleBinding "system:kube-controller-manager" of ClusterRole "system:kube-controller-manager" to User "system:kube-controller-manager"” }

Если в кластере включен режим multi-tenancy, нужно выполнить еще одну проверку, чтобы убедиться, что у пользователя есть доступ в namespace:

If the multitenancy mode is enabled in your cluster, you need to perform another check to be sure that the user has access to the namespace:

shell cat «EOF | 2>&1 kubectl –kubeconfig /etc/kubernetes/deckhouse/extra-files/webhook-config.yaml create –raw / -f - | jq .status { “apiVersion”: “authorization.k8s.io/v1”, “kind”: “SubjectAccessReview”, “spec”: { “resourceAttributes”: { “namespace”: “”, “verb”: “watch”, “version”: “v1”, “resource”: “pods” }, “user”: “system:kube-controller-manager”, “groups”: [ “Admins” ] } } EOF

shell cat «EOF | 2>&1 kubectl –kubeconfig /etc/kubernetes/deckhouse/extra-files/webhook-config.yaml create –raw / -f - | jq .status { “apiVersion”: “authorization.k8s.io/v1”, “kind”: “SubjectAccessReview”, “spec”: { “resourceAttributes”: { “namespace”: “”, “verb”: “watch”, “version”: “v1”, “resource”: “pods” }, “user”: “system:kube-controller-manager”, “groups”: [ “Admins” ] } } EOF

json { “allowed”: false }

json { “allowed”: false }

Сообщение allowed: false значит, что webhook не блокирует запрос. В случае блокировки запроса webhook’ом вы получите, например, следующее сообщение:

The allowed: false message means that the webhook doesn’t block access. In case of webhook denying the request, you will see, e.g., the following message:

json { “allowed”: false, “denied”: true, “reason”: “making cluster scoped requests for namespaced resources are not allowed” }

json { “allowed”: false, “denied”: true, “reason”: “making cluster scoped requests for namespaced resources are not allowed” }

Настройка прав высокоуровневых ролей

Customizing rights of high-level roles

Если требуется добавить прав для определенной высокоуровневой роли, достаточно создать ClusterRole с аннотацией user-authz.deckhouse.io/access-level: <AccessLevel>.

If you want to grant more privileges to a specific high-level role, you only need to create a ClusterRole with the user-authz.deckhouse.io/access-level: <AccessLevel> annotation.

Пример:

An example:

yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: user-authz.deckhouse.io/access-level: Editor name: user-editor rules:

  • apiGroups:
  • kuma.io resources:
  • trafficroutes
  • trafficroutes/finalizers verbs:
  • get
  • list
  • watch
  • create
  • update
  • patch
  • delete
  • apiGroups:
  • flagger.app resources:
  • canaries
  • canaries/status
  • metrictemplates
  • metrictemplates/status
  • alertproviders
  • alertproviders/status verbs:
  • get
  • list
  • watch
  • create
  • update
  • patch
  • delete

yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: user-authz.deckhouse.io/access-level: Editor name: user-editor rules:

  • apiGroups:
  • kuma.io resources:
  • trafficroutes
  • trafficroutes/finalizers verbs:
  • get
  • list
  • watch
  • create
  • update
  • patch
  • delete
  • apiGroups:
  • flagger.app resources:
  • canaries
  • canaries/status
  • metrictemplates
  • metrictemplates/status
  • alertproviders
  • alertproviders/status verbs:
  • get
  • list
  • watch
  • create
  • update
  • patch
  • delete