# Протокол службы обнаружения

> Обнаружение других участников etcd на этапе начальной инициализации кластера

---

Индекс LLMS: [llms.txt](/ru/llms.txt)

---

Протокол службы обнаружения помогает новому участнику etcd найти остальных участников на этапе начальной инициализации кластера с помощью общего токена обнаружения и списка конечных точек.

Протокол используется _только_ во время начальной инициализации и не подходит для реконфигурации во время выполнения или мониторинга кластера.

Один новый токен обнаружения предназначен для инициализации одного _уникального_ кластера etcd. Один токен может представлять только один кластер. После запуска протокола для токена его нельзя использовать для инициализации другого кластера etcd, даже если первый процесс завершился с ошибкой на полпути.

Далее процесс обнаружения рассматривается на примере самостоятельно размещённого кластера обнаружения.

Этот документ относится только к обнаружению v3. Обнаружение v2 подробнее описано в [предыдущем документе][v2-discovery].

## Рабочий процесс протокола {#protocol-workflow}

Протокол использует внутренний кластер etcd для координации начальной инициализации нового кластера. Сначала все новые участники взаимодействуют со службой обнаружения и совместно формируют ожидаемый список участников. Затем каждый участник запускает свой сервер с этим списком, что выполняет ту же функцию, что и флаг -initial-cluster.

В примере ниже каждый шаг показан с помощью команды `etcdctl`. Предполагается, что на `http://example.com:2379` работает кластер etcd, обслуживающий службу обнаружения.

По соглашению протокол обнаружения etcd использует префикс ключей `/_etcd/registry`.

### Создание нового токена обнаружения {#creating-a-new-discovery-token}

Создайте уникальный токен, идентифицирующий новый кластер. На следующих шагах он будет уникальным префиксом в пространстве ключей обнаружения. Простой способ создать токен — использовать `uuidgen`:

```
UUID=$(uuidgen)
```

### Указание ожидаемого размера кластера {#specifying-the-expected-cluster-size}

Для токена обнаружения необходимо указать размер кластера. Служба использует его, чтобы определить, когда найдены все участники, изначально формирующие кластер.

```
etcdctl --endpoints=http://example.com:2379 put /_etcd/registry/${UUID}/_config/size ${cluster_size}
```

Обычно размер кластера равен 3, 5 или 7. Подробнее см. в разделе [оптимального размера кластера][cluster-size].

### Запуск процессов etcd {#bringing-up-etcd-processes}

Передайте токен обнаружения `${UUID}` флагу `--discovery-token`, а конечные точки кластера etcd, обслуживающего службу обнаружения, — флагу `--discovery-endpoints`. Это включает обнаружение v3 для начальной инициализации кластера etcd.

Если заданы флаги `--discovery-token` и `--discovery-endpoints`, каждый процесс etcd выполняет следующие шаги автоматически.

Если служба обнаружения использует аутентификацию по клиентским сертификатам, настройте следующие флаги. Они применяются так же, как при обращении `etcdctl` к кластеру etcd.
```
--discovery-insecure-transport
--discovery-insecure-skip-tls-verify
--discovery-cert
--discovery-key
--discovery-cacert
```

Если служба обнаружения использует ролевую аутентификацию, настройте следующие флаги. Они применяются так же, как при обращении `etcdctl` к кластеру etcd.
```
--discovery-user
--discovery-password
```

Значения времени и тайм-аутов по умолчанию можно изменить следующими флагами, которые применяются так же, как при обращении `etcdctl` к кластеру etcd.
```
--discovery-dial-timeout
--discovery-request-timeout
--discovery-keepalive-time
--discovery-keepalive-timeout
```

### Саморегистрация {#registering-itself}

Сначала каждый процесс etcd регистрирует себя как участника нового кластера. Для этого ID участника создаётся как ключ в полном ключе реестра.

```
etcdctl --endpoints=http://example.com:2379 put /_etcd/registry/${UUID}/members/${member_id} ${member_name}=${member_peer_url_1}&${member_name}=${member_peer_url_2}
```

### Проверка состояния {#checking-the-status}

Процесс проверяет ожидаемый размер кластера и состояние регистрации, а затем выбирает следующее действие.

```
etcdctl --endpoints=http://example.com:2379 get /_etcd/registry/${UUID}/_config/size
etcdctl --endpoints=http://example.com:2379 get /_etcd/registry/${UUID}/members
```

Если зарегистрированных участников пока недостаточно, процесс ожидает появления остальных.

Если зарегистрированных участников больше ожидаемого размера N, первые N участников принимаются за список кластера. Если текущий участник входит в список, процедура обнаружения завершается успешно и получает из списка всех одноранговых участников. Если его в списке нет, процедура завершается ошибкой, сообщающей, что кластер заполнен.

Участник может проверить состояние кластера ещё до саморегистрации, поэтому при заполненном кластере отказ произойдёт быстро.

### Ожидание всех участников {#waiting-for-all-members}

Процесс продолжает наблюдать за префиксом ключей `/_etcd/registry/${UUID}/members`, пока не найдёт всех участников.

```
etcdctl --endpoints=http://example.com:2379 watch /_etcd/registry/${UUID}/members --prefix
```

[v2-discovery]: https://etcd.io/docs/v3.5/dev-internal/discovery_protocol
[cluster-size]: https://etcd.io/docs/v2.3/admin_guide#optimal-cluster-size
[expected-cluster-size]: #specifying-the-expected-cluster-size
[new-discovery-token]: #creating-a-new-discovery-token
