> For the complete documentation index, see [llms.txt](https://utm-1.gitbook.io/utm-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://utm-1.gitbook.io/utm-docs/dokumentaciya/utm-it/resheniya/kubernetes/nastroika-klastera/podklyuchenie-polzovatelya.md).

# Подключение пользователя

## Ссылки

Как предоставить доступ к кластеру Kubernetes с помощью клиентского сертификата: [habr.com](https://habr.com/ru/companies/vk/articles/539984/?ysclid=mhaln5geky711416865)

## Задача

В кластер Kubernetes необходимо предоставить доступ новому пользователю на основе клиентского сертификат x509.

Участники процесса:

* Пользователь - тот кому необходимо подключиться к кластеру Kubernetes
* Администратор - тот кто будет подключать пользователя к кластеру Kubernetes

Параметры пользователя:

* Логин: andrew
* Группа: utmsoft-developer

## Общее описание

Пользователь запрашивает у администратора доступ к кластеру. Для этого пользователю необходимо передать csr файл (запрос на подпись сертификата) для выпуска сертификата. При этом пользователю нужен закрытый ключ для генерации csr файла.

Администратор на основе csr файла генерирует сертификат, подтверждает его в кластере.

Кроме этого администратор при необходимости создает следующие объекты в кластере: Namespace, Role, ClasterRole, RoleBinding, ClasterRoleBinding для выдачи необходимых прав новому пользователю.

Администратор создает kubeconfig с параметрами доступа к кластеру и передает его пользователю.

Пользователь добавляет свой закрытый ключ в файл kubeconfig и настраивает доступ с помощью этого файла к кластеру через kubectl.

## Этапы работ

### Сформировать запрос на подключение

{% hint style="info" %}
Выполняется пользователем на своем хосте.

Пользователь готовит файл `andrew_k8s.csr`  и передает его администратору.
{% endhint %}

<details>

<summary>Пользователю  необходимо выполнить следующие действия</summary>

#### Закрытый ключ пользователя

Сгенерировать закрытый ключ RSA - файл `andrew_k8s.key`

Необходимо выполнить:

```bash
openssl genrsa -out andrew_k8s.key 4096
```

#### Файл конфигурации для создания CSR

Создать файл конфигурации для создания CSR - файл `andrew_k8s_csr.cnf`

```bash
nano andrew_k8s_csr.cnf
```

Содержание файла:

```
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[ dn ]
CN = andrew
O = utmsoft-developer

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
```

#### Файл запроса на подпись сертификата CSR

Создать файл CSR - файл `andrew_k8s.csr`

Необходимо выполнить:

```bash
openssl req -config ./andrew_k8s_csr.cnf -new -key andrew_k8s.key -nodes -out andrew_k8s.csr
```

Файл `andrew_k8s.csr` необходимо передать администратору для дальнейшей обработки.

</details>

### Зарегистрировать пользователя в кластере

{% hint style="info" %}
Выполняется администратором в кластере.

Администратор получает от пользователя файл `andrew_k8s.csr` , регистрирует пользователя в кластере, готовит файл `kubeconfig_andrew` и передает его пользователю.
{% endhint %}

<details>

<summary>Администратору необходимо выполнить следующие действия</summary>

#### Объект CertificateSigningRequest

Создать файл конфигурации для создания CSR - файл `andrew_k8s_csr.yaml`

```bash
nano andrew_k8s_csr.yaml
```

Содержание файла `andrew_k8s_csr.yaml`:

```yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: andrew-csr
spec:
  groups:
    - system:authenticated
  request: ${BASE64_CSR}
  signerName: "kubernetes.io/kube-apiserver-client"
  
  usages:
    - digital signature
    - key encipherment
    - client auth
```

{% hint style="danger" %}
Если указать

```
  usages:
    - digital signature
    - key encipherment
    - server auth
    - client auth
```

то после принятия статус `Approved,Failed` и сообщение об ошибке "message": "invalid usage for client certificate: server auth"

{% endhint %}

{% hint style="info" %}
На какой срок выпускать сертификат можно указать в spec.expirationSeconds.

Если это значение не указано, то сертификат выпускается сроком на 1 год.
{% endhint %}

Закодировать файл andrew\_k8s.csr в base64

```bash
export BASE64_CSR=$(cat ./andrew_k8s.csr | base64 | tr -d '\n')
```

Подставить закодированное в base64 значение файла  `andrew_k8s.csr` в файл `andrew_k8s_csr.yamls`  и сразу создать объект CertificateSigninRequestat

```bash
cat andrew_k8s_csr.yaml | envsubst | kubectl apply -f -
```

Проверить статус созданного CSR (он находится в состоянии ожидслуфйкания)

```bash
kubectl get csr

# NAME        AGE   REQUESTOR            CONDITION
# andrew-csr  9s    28b93...d73801ee46   Pending
```

Подтвердить CSR

```bash
kubectl certificate approve andrew-csr
```

Проверить статус созданного CSR (CONDITION должен быть `Approved,Issued`)

```bash
kubectl get csr

# NAME        AGE   REQUESTOR            CONDITION
# andrew-csr  9s    28b93...d73801ee46   Approved,Issued
```

{% hint style="danger" %}
Если в CONDITION указано `Approved,Failed`, то нужно разбираться с проблемой. Для этого можно посмотреть:&#x20;

```bash
kubectl get csr andrew-csr --output=jsonpath="{.status}" | jq
```

{% endhint %}

Сертификат создан.

Извлечь сертификат из ресурса CSR и сохранить в файл  `andrew_k8s.crt`

```bash
kubectl get csr andrew-csr -o jsonpath='{.status.certificate}' | base64 --decode > andrew_k8s.crt
```

Посмотреть содержимое сертификата `andrew_k8s.crt`

```
openssl x509 -in ./andrew_k8s.crt -noout -text
```

#### Пространство имен

Опционально

Создать файл `dev-ns.yaml` для создания пространства имен dev

```bash
nano dev-ns.yaml
```

Содержание файла `dev-ns.yaml`:

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dev
```

Выполнить команду

```bash
kubectl apply -f dev-ns.yaml
```

#### Роль

Опционально

Создать файл `developer-role.yaml` для создания роли developer-role

```bash
nano developer-role.yaml
```

Содержание файла `developer-role.yaml`:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: developer-role
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["create", "get", "update", "list", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["create", "get", "update", "list", "delete"]
```

Выполнить команду

```bash
kubectl apply -f developer-role.yaml
```

#### Привязка роли к пользователю

**Опционально**

Создать файл `developer-role-binding-user-andrew.yaml` для привязки пользователя andrew к роли developer-role

```bash
nano developer-role-binding-user-andrew.yaml
```

Содержание файла `developer-role-binding-user-andrew.yaml`:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-role-binding-user-andrew
  namespace: dev
subjects:
- kind: User
  name: andrew
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io
```

Выполнить команду

```bash
kubectl apply -f developer-role-binding-user-andrew.yaml
```

#### Привязка кластерной роли к пользователю

**Опционально**

Создать файл `cluster-admin-binding-user-andrew.yaml` для привязки пользователя andrew к кластерной роли cluster-admin

```bash
nano cluster-admin-binding-user-andrew.yaml
```

Содержание файла `developer-role-binding-user-andrew.yaml`:

```yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cluster-admin-binding-user-andrew
subjects:
  - kind: User
    name: andrew
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
```

Выполнить команду

```bash
kubectl apply -f cluster-admin-binding-user-andrew.yaml
```

#### Привязка роли к группе

Опционально

Создать файл `developer-role-binding-group-utmsoft-developer.yaml` для привязки группы utmsoft-developer к роли developer-role

```bash
nano developer-role-binding-group-utmsoft-developer.yaml
```

Содержание файла `developer-role-binding-group-utmsoft-developer.yaml`:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-role-binding-group-utmsoft-developer
  namespace: dev
subjects:
- kind: Group
  name: utmsoft-developer
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io
```

Выполнить команду

```bash
kubectl apply -f developer-role-binding-group-utmsoft-developer.yaml
```

#### Файл конфигурации kubeconfig

Создать файл шаблон `kubeconfig.tpl`

```bash
nano kubeconfig.tpl
```

Содержание файла `kubeconfig.tpl`:

```yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: ${CLUSTER_CA}
    server: ${CLUSTER_ENDPOINT}
  name: ${CLUSTER_NAME}
users:
- name: ${USER}
  user:
    client-certificate-data: ${CLIENT_CERTIFICATE_DATA}
contexts:
- context:
    cluster: ${CLUSTER_NAME}
    user: ${USER}
  name: ${USER}-${CLUSTER_NAME}
current-context: ${USER}-${CLUSTER_NAME}
```

Установить переменные среды:

```bash
# Имя пользователя
export USER="andrew"

# Имя кластера (полученное из текущего контекста)
export CLUSTER_NAME=$(kubectl config view --raw -o json | jq -r '.contexts[] | select(.name == "'$(kubectl config current-context)'") | .context."cluster"')

# Сертификат клиента
export CLIENT_CERTIFICATE_DATA=$(kubectl get csr andrew-csr -o jsonpath='{.status.certificate}')

# Данные центра сертификации кластера
export CLUSTER_CA=$(kubectl config view --raw -o json | jq -r '.clusters[] | select(.name == "'$CLUSTER_NAME'") | .cluster."certificate-authority-data"')

# Точка входа API
export CLUSTER_ENDPOINT=$(kubectl config view --raw -o json | jq -r '.clusters[] | select(.name == "'$CLUSTER_NAME'") | .cluster."server"')
```

Сформировать файл `kubeconfig_andrew`

```bash
cat kubeconfig.tpl | envsubst > kubeconfig_andrew
```

Файл `kubeconfig` необходимо передать пользователю.

</details>

### Настроить подключение к кластеру

{% hint style="info" %}
Выполняется пользователем на своем хосте.

Пользователь получает от администратора файл `kubeconfig_andrew` и на его основе выполняет подключение к кластеру.
{% endhint %}

<details>

<summary>Пользователю необходимо выполнить следующие действия</summary>

#### Подключить файл kubeconfig (в Linux)

Создать каталог .kube в папке пользователя

```bash
mkdir $HOME/.kube
```

Скопировать в каталог $HOME/.kube файл `kubeconfig_andrew`

Туда же скопировать файл с закрытым ключом `andrew_k8s.key`

Установить переменную среды KUBECONFIG

```bash
export KUBECONFIG=$HOME/.kube/kubeconfig_andrew
```

{% hint style="info" %}
Примечание

Есть разные способы использовать конфигурации Kubernetes.

Можно:

* Установить переменную среду KUBECONFIG
* Добавить новую запись в файл $ HOME/.kube/config по умолчанию
* Использовать флаг --kubeconfig для каждой команды kubectl
  {% endhint %}

В файл `kubeconfig` добавить закрытый ключ `andrew_k8s.key`

```bash
kubectl config set-credentials andrew --client-key=$HOME/.kube/andrew_k8s.key --embed-certs=true
```

{% hint style="info" %}
Примечание

Команда создает ключ client-key-data в записи пользователя файла kubeconfig и устанавливает в качестве значения содержимое файла andrew\_k8s.key сконвертированное в кодировку base64.
{% endhint %}

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

```bash
kubectl version
```

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://utm-1.gitbook.io/utm-docs/dokumentaciya/utm-it/resheniya/kubernetes/nastroika-klastera/podklyuchenie-polzovatelya.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
