> 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/nastroika-razreshennykh-khostov-dlya-dostupa-k-apiserver.md).

# Настройка разрешенных хостов для доступа к apiserver

## Ссылки

Обеспечение безопасности Kubernetes: добавление нового имени хоста или IP-адреса на сервер API Kubernetes: [dev.to](https://dev.to/aws-builders/securing-kubernetes-api-server-adding-a-new-hostname-or-ip-address-to-kubernetes-api-server-1aej)

## Проблема

### Ошибка при подключении через Internet

После развертывания кластера Kubernetes при попытке обратиться к нему через Internet при помощи kubectl возникает ошибка

{% hint style="danger" %}
failed to verify certificate: x509: certificate is valid for 10.96.0.1, 192.168.4.1, 192.168.1.100, not 88.25.186.5
{% endhint %}

Клиентский сертификат Kubernates не позволяет подключаться к кластеру с хоста 88.25.186.5, т.к. этот хост не входит в список разрешенных.

Проблему можно решить, если в команде kubectl добавить параметр --insecure-skip-tls-verify

Например

```
kubectl get pods --insecure-skip-tls-verify
```

Но это отключает проверку сертификатов и не безопасно.

Поэтому необходимо добавить хост 88.25.186.5 в список разрешенных в сертефикатах, размещенных в master узлах кластера.

### Решение проблемы

{% hint style="warning" %}
Указанные ниже действия необходимо выполнить на каждому master узле кластера!
{% endhint %}

В папке пользователя:

```bash
sudo su
mkdir tmp
cd tmp/
```

Получить файл конфигурации `kubeadm.yaml`:

```bash
kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' --insecure-skip-tls-verify > kubeadm.yaml
```

Внести изменения в файл `kubeadm.yaml`:

```bash
nano kubeadm.yaml
```

Изменить секцию apiServer.certSANs. Если certSANs нет, то добавить. Прописать в этой секции все IP и DNS адреса с которых будет разрешено обращение:

```
apiServer:
  certSANs:
  - "88.25.186.5"
  - "server.your-domain.com"
```

Дальше необходимо пересоздать сертификаты.

Сначала старые сертификаты нужно переместить в папку с бэкапом:

```bash
mkdir backup_apiserver_crt_20251029
mv /etc/kubernetes/pki/apiserver.{crt,key} ./backup_apiserver_crt_20251029/
```

Сгенерировать новые сертификаты на основе подготовленного файла конфигурации:

```bash
kubeadm init phase certs apiserver --config kubeadm.yaml
```

В отдельную папку можно сделать бэкап новых сертификатов:

```bash
mkdir new_apiserver_crt_20251029
cp /etc/kubernetes/pki/apiserver.{crt,key} ./new_apiserver_crt_20251029/
```

Далее необходимо перезапустите контейнер kubeapiserver.

При использовании Containerd или Cri-o в качестве среды выполнения:

* Запустите `crictl pods | grep kube-apiserver | cut -d' ' -f1`, чтобы получить идентификатор Pod для Pod сервера Kubernetes API.
* Выполнить `crictl stop <pod-id>`, чтобы остановить Под.
* Выполнить, `crictl rm <pod-id>`чтобы удалить Pod.

После выполнения этих шагов Kubelet автоматически инициирует перезапуск контейнера, обеспечивая принятие обновлённого сертификата. После перезапуска API-сервера будет немедленно установлено соединение, позволяющее получить доступ по любому из недавно добавленных IP-адресов или имён хостов.

{% hint style="info" %}
Если при остановке или удалении контейнера возникает ошибка,  то можно просто перезагрузить сервер.
{% endhint %}

### Проверка

Посмотреть выпущенный сертификат

```bash
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
```

Проверьте строку «X509v3 Subject Alternative Name», в которой перечислены DNS-имена и IP-адреса, включённые в сертификат в качестве альтернативных имён субъектов (SAN). Выполнение этой процедуры должно отобразить вновь добавленные имена и IP-адреса, указанные в изменённом `kubeadm`файле конфигурации.&#x20;

### Обновление конфигурации кластера

При условии бесперебойного выполнения всех изменений, последний шаг включает обновление карты конфигурации kubeadm, хранящейся в кластере. Это гарантирует, что при последующем использовании kubeadm для обновления кластера обновлённая информация будет беспрепятственно интегрирована в кластер.

Задача. Изменения внесенные в локальный файл `kubeadm.yaml` сохранить в конфигурации кластера с помочью kubeadm, чтобы они не потерялись.

```bash
kubeadm config upload from-file --config kubeadm.yaml
```

{% hint style="danger" %}
Данная команда выдает ошибку в кластере 1.31.1

Это команда в 1.34.1 уже не работает. Убрали начиная с 1.31.

Альтернативу загрузить измененную конфигурацию kubeadm пока не найдена.

Один из возможных вариантов:

```bash
kubeadm init phase \
	upload-config kubeadm \
	--config kubeadm.yaml 
```

Но это приводит к следующей ошибке

`error: found multiple CRI endpoints on the host.`\
`Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/crio/crio.sock`\
`To see the stack trace of this error execute with --v=5 or higher`

Контейнерным движком кластера является clio, но на master узлах также был установлен docker, поэтому присутствуют 2 cri endpoint. В других случаях это не является проблемой. Для указания с каким cni необходимо работать утилите kubeadm в вызов добавляется дополнительный параметр для указания с каким сокетом  работать:

```
kubeadm init phase \
	--cri-socket unix:///var/run/crio/crio.sock	\
	upload-config kubeadm \
	--config kubeadm.yaml
```

Но в данном варианте вызова команды возникает ошибка:

`error: can not mix '--config' with arguments [cri-socket]`\
`To see the stack trace of this error execute with --v=5 or higher`

Нельзя одновременно указывать параметры --cri-socket и --config. Таким образом если обязательно нужно указывать cri сокет, то нет возможности применить конфиг из файла.

Удаление docker с очисткой его системных каталогов сокет `/var/run/containerd/containerd.sock` в системе оставил.

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

* Утилита kubeadm позволяет передавать параметры не только в виде конфига, но и виде специально подготовленной строки с этими параметрами. Возможно удастся внести изменения в конфиг kubeadm таким образом
* Можно настроить сокет по умолчанию, который kubeadm будет использовать если не указан параметр  --cri-socket, а в системе есть несколько сокетов. Это настраивается через параметр criSocket в том же конфиге kubeadm, аналогичным образом как и apiServer.certSANs. Но тут та же проблема, чтобы этот параметр заработал, его нужно сначала применить. Нужно найти способ его применить.
* <mark style="color:$success;">Рабочий вариант!</mark> Через прямое редактирование ConfigMap. Этот конфиг это ConfigMap объект с именем `kubeadm-config` в кластере, который можно получить командой\
  `kubectl -n kube-system get configmap kubeadm-config -o yaml`\
  Этот ConfigMap нужно отредактировать командой\
  `kubectl edit configmap kubeadm-config -n kube-system`\
  После выполнения этой команды откроется текстовый редактор назначенный по умолчанию, в котором необходимо скорректировать yaml и сохранить файл. После этого изменения автоматически сохранятся в кластере. Этот вариант сработал! Вручную в конфиг добавлены строки с IP и DNS адресами.
  {% endhint %}
