Пример назначения прав администратору кластера
Пример использует новую ролевую модель.
Для назначения прав администратору кластера используйте роль d8:manage:all:admin
в ClusterRoleBinding
.
Пример назначения прав администратору кластера (User joe
):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-joe
subjects:
- kind: User
name: joe
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: d8:manage:all:admin
apiGroup: rbac.authorization.k8s.io
Пример назначения прав сетевому администратору
Пример использует новую ролевую модель.
Для назначения прав сетевому администратору на управление сетевой подсистемой кластера используйте роль d8:manage:networking:admin
в ClusterRoleBinding
.
Пример назначения прав сетевому администратору (User joe
):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: network-admin-joe
subjects:
- kind: User
name: joe
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: d8:manage:networking:admin
apiGroup: rbac.authorization.k8s.io
Пример назначения административных прав пользователю в рамках пространства имён
Пример использует новую ролевую модель.
Для назначения прав на управление ресурсами приложений в рамках пространства имён, но без возможности настройки модулей DKP, используйте роль d8:use:role:admin
в RoleBinding
в соответствующем пространстве имён.
Пример назначения прав разработчику приложений (User app-developer
) в пространстве имён myapp
:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp-developer
namespace: myapp
subjects:
- kind: User
name: app-developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: d8:use:role:admin
apiGroup: rbac.authorization.k8s.io
Пример ClusterAuthorizationRule
Пример использует устаревшую ролевую модель.
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
Создание пользователя
Это пример для устаревшей ролевой модели.
В Kubernetes есть две категории пользователей:
- ServiceAccount’ы, учёт которых ведёт сам Kubernetes через API.
- Остальные пользователи, учёт которых ведёт не сам Kubernetes, а некоторый внешний софт, который настраивает администратор кластера, — существует множество механизмов аутентификации и, соответственно, множество способов заводить пользователей. В настоящий момент поддерживаются два способа аутентификации:
- через модуль user-authn;
- с помощью сертификатов.
При выпуске сертификата для аутентификации нужно указать в нём имя (CN=<имя>
), необходимое количество групп (O=<группа>
) и подписать его с помощью корневого CA-кластера. Именно этим механизмом вы аутентифицируетесь в кластере, когда, например, используете kubectl на bastion-узле.
Создание ServiceAccount для сервера и предоставление ему доступа
Создание ServiceAccount с доступом к Kubernetes API может потребоваться, например, при настройке развёртывания приложений через CI-системы.
-
Создайте ServiceAccount, например в пространстве имён
d8-service-accounts
: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
-
Дайте необходимые ServiceAccount-права (используя custom resource ClusterAuthorizationRule):
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
Если в конфигурации Deckhouse включён режим мультитенантности (параметр enableMultiTenancy, доступен только в Enterprise Edition), настройте доступные для ServiceAccount пространства имён (параметр namespaceSelector).
-
Определите значения переменных (они будут использоваться далее), выполнив следующие команды (подставьте свои значения):
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
-
Сгенерируйте секцию
cluster
в файле конфигурации kubectl:Используйте один из следующих вариантов доступа к API-серверу кластера:
- Если есть прямой доступ до API-сервера:
-
Получите сертификат CA-кластера Kubernetes:
kubectl get cm kube-root-ca.crt -o jsonpath='{ .data.ca\.crt }' > /tmp/ca.crt
-
Сгенерируйте секцию
cluster
(используется IP-адрес API-сервера для доступа):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).
-
Если используется непубличный CA:
-
Получите сертификат CA из секрета с сертификатом, который используется для домена
api.%s
: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
-
Сгенерируйте секцию
cluster
(используется внешний домен и CA для доступа):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
(используется внешний домен для доступа):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
- Если есть прямой доступ до API-сервера:
-
Сгенерируйте секцию
user
с токеном из секрета ServiceAccount в файле конфигурации kubectl: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
-
Сгенерируйте контекст в файле конфигурации kubectl:
kubectl config set-context $CONTEXT_NAME \ --cluster=$CLUSTER_NAME --user=$USER_NAME \ --kubeconfig=$FILE_NAME
-
Установите сгенерированный контекст как используемый по умолчанию в файле конфигурации kubectl:
kubectl config use-context $CONTEXT_NAME --kubeconfig=$FILE_NAME
Создание пользователя с помощью клиентского сертификата
Это пример для устаревшей ролевой модели.
Создание пользователя
- Получите корневой сертификат кластера (ca.crt и ca.key).
-
Сгенерируйте ключ пользователя:
openssl genrsa -out myuser.key 2048
-
Создайте CSR, где укажите, что требуется пользователь
myuser
, который состоит в группахmygroup1
иmygroup2
:openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser/O=mygroup1/O=mygroup2"
-
Подпишите CSR корневым сертификатом кластера:
openssl x509 -req -in myuser.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out myuser.crt -days 10
-
Теперь полученный сертификат можно указывать в конфиг-файле:
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
Предоставление доступа созданному пользователю
Для предоставления доступа созданному пользователю создайте ClusterAuthorizationRule
.
Пример ClusterAuthorizationRule
:
apiVersion: deckhouse.io/v1
kind: ClusterAuthorizationRule
metadata:
name: myuser
spec:
subjects:
- kind: User
name: myuser
accessLevel: PrivilegedUser
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
:- name: authorization-webhook-config mountPath: /etc/kubernetes/authorization-webhook-config.yaml readOnly: true
-
добавление
volumes
:- name: authorization-webhook-config hostPath: path: /etc/kubernetes/authorization-webhook-config.yaml type: FileOrCreate
Как проверить, что у пользователя есть доступ?
Необходимо выполнить следующую команду, в которой будут указаны:
resourceAttributes
(как в RBAC) — к чему мы проверяем доступ;user
— имя пользователя;groups
— группы пользователя.
При совместном использовании с модулем
user-authn
группы и имя пользователя можно посмотреть в логах Dex —kubectl -n d8-user-authn logs -l app=dex
(видны только при авторизации).
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
В результате увидим, есть ли доступ и на основании какой роли:
{
"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, нужно выполнить ещё одну проверку, чтобы убедиться, что у пользователя есть доступ в пространство имён:
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
{
"allowed": false
}
Сообщение allowed: false
значит, что вебхук не блокирует запрос. В случае блокировки запроса вебхуком вы получите, например, следующее сообщение:
{
"allowed": false,
"denied": true,
"reason": "making cluster scoped requests for namespaced resources are not allowed"
}
Настройка прав высокоуровневых ролей
Это пример для устаревшей ролевой модели.
Если требуется добавить прав для определённой высокоуровневой роли, достаточно создать ClusterRole с аннотацией user-authz.deckhouse.io/access-level: <AccessLevel>
.
Пример:
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