Пример назначения прав администратору кластера

Для назначения прав администратору кластера используйте роль 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- или kube-.

Пользователю будут доступны следующие права:

  • Просмотр, изменение, удаление и создание ресурсов Kubernetes и модулей DKP.
  • Изменение конфигурации модулей (просмотр, изменение, удаление и создание ресурсов moduleConfig).
  • Выполнение следующих команд к подам и сервисам:
    • kubectl attach;
    • kubectl exec;
    • kubectl port-forward;
    • kubectl proxy.

Пример назначения прав сетевому администратору

Для назначения прав сетевому администратору на управление сетевой подсистемой кластера используйте роль 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 из подсистемы networking (фактический список зависит от списка включённых в кластере модулей):

  • d8-cni-cilium;
  • d8-cni-flannel;
  • d8-cni-simple-bridge;
  • d8-ingress-nginx;
  • d8-istio;
  • d8-metallb;
  • d8-network-gateway;
  • d8-openvpn;
  • d8-static-routing-manager;
  • d8-system;
  • kube-system.

Пользователю будут доступны следующие права:

  • Просмотр, изменение, удаление и создание стандартных ресурсов Kubernetes в пространстве имён модулей из подсистемы networking.

    Пример ресурсов, которыми сможет управлять пользователь (список не полный):

    • Certificate;
    • CertificateRequest;
    • ConfigMap;
    • ControllerRevision;
    • CronJob;
    • DaemonSet;
    • Deployment;
    • Event;
    • HorizontalPodAutoscaler;
    • Ingress;
    • Issuer;
    • Job;
    • Lease;
    • LimitRange;
    • NetworkPolicy;
    • PersistentVolumeClaim;
    • Pod;
    • PodDisruptionBudget;
    • ReplicaSet;
    • ReplicationController;
    • ResourceQuota;
    • Role;
    • RoleBinding;
    • Secret;
    • Service;
    • ServiceAccount;
    • StatefulSet;
    • VerticalPodAutoscaler;
    • VolumeSnapshot.
  • Просмотр, изменение, удаление и создание ресурсов в пространстве имён модулей из подсистемы networking.

    Список ресурсов, которыми сможет управлять пользователь:

    • EgressGateway;
    • EgressGatewayPolicy;
    • FlowSchema;
    • IngressClass;
    • IngressIstioController;
    • IngressNginxController;
    • IPRuleSet;
    • IstioFederation;
    • IstioMulticluster;
    • RoutingTable.
  • Изменение конфигурации модулей (просмотр, изменение, удаление и создание ресурсов moduleConfig) из подсистемы networking.

    Список модулей, которыми сможет управлять пользователь:

    • cilium-hubble;
    • cni-cilium;
    • cni-flannel;
    • cni-simple-bridge;
    • flow-schema;
    • ingress-nginx;
    • istio;
    • kube-dns;
    • kube-proxy;
    • metallb;
    • network-gateway;
    • network-policy-engine;
    • node-local-dns;
    • openvpn;
    • static-routing-manager.
  • Выполнение следующих команд к подам и сервисам в пространстве имён модулей из подсистемы networking:

    • kubectl attach;
    • kubectl exec;
    • kubectl port-forward;
    • kubectl proxy.

Пример назначения административных прав пользователю в рамках пространства имён

Для назначения прав на управление ресурсами приложений в рамках пространства имён, но без возможности настройки модулей 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

Список прав, которые получит пользователь

В рамках пространства имён myapp пользователю будут доступны следующие права:

  • Просмотр, изменение, удаление и создание ресурсов Kubernetes. Например, следующих ресурсов (список не полный):
    • Certificate;
    • CertificateRequest;
    • ConfigMap;
    • ControllerRevision;
    • CronJob;
    • DaemonSet;
    • Deployment;
    • Event;
    • HorizontalPodAutoscaler;
    • Ingress;
    • Issuer;
    • Job;
    • Lease;
    • LimitRange;
    • NetworkPolicy;
    • PersistentVolumeClaim;
    • Pod;
    • PodDisruptionBudget;
    • ReplicaSet;
    • ReplicationController;
    • ResourceQuota;
    • Role;
    • RoleBinding;
    • Secret;
    • Service;
    • ServiceAccount;
    • StatefulSet;
    • VerticalPodAutoscaler;
    • VolumeSnapshot.
  • Просмотр, изменение, удаление и создание следующих ресурсов модулей DKP:
    • DexAuthenticator;
    • DexClient;
    • PodLogginConfig.
  • Выполнение следующих команд к подам и сервисам:
    • kubectl attach;
    • kubectl exec;
    • kubectl port-forward;
    • kubectl proxy.

Пример 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-системы.

  1. Создайте 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
    
  2. Дайте необходимые 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).

  3. Определите значения переменных (они будут использоваться далее), выполнив следующие команды (подставьте свои значения):

    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
    
  4. Сгенерируйте секцию cluster в файле конфигурации kubectl:

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

    • Если есть прямой доступ до API-сервера:
      1. Получите сертификат CA-кластера Kubernetes:

        1kubectl get cm kube-root-ca.crt -o jsonpath='{ .data.ca\.crt }' > /tmp/ca.crt
        
      2. Сгенерируйте секцию 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:

      1. Получите сертификат 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
        
      2. Сгенерируйте секцию 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
      
  5. Сгенерируйте секцию 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
    
  6. Сгенерируйте контекст в файле конфигурации kubectl:

    1kubectl config set-context $CONTEXT_NAME \
    2  --cluster=$CLUSTER_NAME --user=$USER_NAME \
    3  --kubeconfig=$FILE_NAME
    
  7. Установите сгенерированный контекст как используемый по умолчанию в файле конфигурации 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