Краткое введение в etcd

etcd лого

Такое чувство, будто в последние месяцы я черезчур уж сильно сосредоточился на дебаггинге и .NET Core, и как-то подзабил на топик, ради которого весь этот блог и затевался — DevOps и распределённые приложения. Ошибку осознал, и сегодня мы посмотрим на что-нибудь более релевантное. Например, etcd.

Во время моего романа с распределёнными приложениями etcd всегда был где-то неподалёку. То он был альтернативой Consul, когда я разбирался с сервис-дискавери и управлением конфигурациями. То etcd всплыл как основное хранилище настроек кластера в Kubernetes. В общем, он везде. Так что я думаю, стоит разобраться, на что же это за зверь такой.

Что такое etcd

etcd — это примитивное но при этом высоконадёжное распределённое хранилище для пар ключ-значение. «Примитивное» не значит, что тупое. Это просто значит что etcd фокусируется только на хранении и связанными с этим задачами. Ну и «высоконадёжный» и «распределённый» подразумевает, что если даже одна из кластера машин с etcd упадёт, то данными и кластером всё будет в порядке. По сравнению с тем же Consul фич тут будет поменьше, но в реальных задачах для того, чтобы забить гвоздь, отбойный молоток и не нужен.

Правда, то, что etcd просто хранит пары ключ-значение, не означает, что там всего три команды (get/set/remove) и на этом всё. Данные можно хранить по-разному, и etcd поддерживает и транзакции для работы с данными, и возможность отслеживать изменения, и настраивать пользователей с ролями, и всякие примитивы для синхронизации использовать, и даже даёт возможность установить время жизни значений (TTL).

В общем, будем смотреть.

Установка

Etcd поддерживает лучший из способов для установки — скачай-и-готово, и это прекрасно. Как всегда, я очень ленивый и параноидальный, поэтому вместо того, чтобы запускать временное и непонятно что на своей машине, я лучше напишу Vagrantfile с инструкциями для закачки и развёртывания, и получу готовую к надругиванию виртуальную с etcd внутри в одну команду.

По итогу, вот какой Vagrantfile у меня получился.

Код вполне простой. Первая подсвеченная секция задаёт переменные и адреса, а вторая качает, распаковывает и обновляет PATH для удобства. Как обычно, vagrant up запустит это всё великолепие, vagrant ssh запустит меня внутрь виртуальной машины, а там, например, можно посмотреть, с какой же версией etcd мы имеем дело:

Запускаем маленький etcd кластер

В официальной документации команда для развёртывания даже однохостового кластера выглядит очень уже заморочено. На самом деле для экспериментов на localhost запускать etcd можно вообще без параметров:

Чтобы убедиться, что кластер живой и реагирует на свет, его можно пнуть ещё одной утилиткой — etcdctl, и запросить членов кластера:

Если бы я хотел посмотреть на кластер на другой машине, то пришлось бы подавать дополнительные параметр на вход (вроде -c http://localhost:2379), но опять же, на localhost всё работает и так.

Добавляем, запрашиваем, удаляем данные

Тот же самый etcdctl, что общался с кластером, может манипулировать и данными в нём. Правда, есть больше чем один API, которым можно это сделать, поэтому сразу стоит поставить переменную окружения с версией, которая нам подходит. Например, export ETCDCTL_API=3 переключит etcdctl на самый свежий 3й API .

И это на самом деле меняет много чего. Например, во второй версии была команда set для сохранения данных. А в третьей это уже put. Да и вообще, если вывести список команд, которые поддерживает API 2 и 3, можно очень хорошо удивиться.

Кстати о put, Вот как можно добавить и запросить назад парочку ключей-значений:

Работаем с данными по HTTP

etcdctl, конечно, не самый удобный способ скрестить свою программу с etcd. Хотя под капотом etcd общается по протоколу gRPC, к нему можно подключаться и по старому доброму HTTP при помощи встроенного grpc-gateway. HTTP API, конечно, немного с душком, и определённо застрял где-то у основания Модели Зрелости Ричардсона, но работает. Хотя кодировать и ключ и значение в base64 в каждом запросе, конечно, раздражает.

Вот как можно отправить в кластер пару mykey:myvalue по HTTP:

И забрать назад:

Стрёмно, конечно, но работает ведь.

Другие приятные фичи

Дожидаемся изменений значений

А что если нам хочется, чтобы etcd как-то сообщил нам, когда значение какого-нибудь полезного ключа меняется? Без проблем. Можно даже ждать изменений ключа, которого вообще нет:

В Consul кстати была такая же штука. Так вот, watch запрос будет ждать до тех пор, пока кто-нибудь не обновит значение нашего shutdown-requested ключа.

И всё только для того, чтобы продолжить ждать дальше.

Транзакции

Или вот такой сценарий: нам нужно установить новое значение в ключ только в том случае, если текущее равно чему-то особенному. Ну вроде как есть кластер машин, в etcd хранится имя лидера кластера — ключ leader, и нам нужно установить имя нашей машины только в том случае, если лидера пока нет (none). Интерактивно это можно сделать при помощи команды txn.

Допустим, сначала leader-таки есть.

При таких начальных данных транзакция, разумеется ответила FAILURE, ведь значение ключа отличалось от none. Но если лидера убрать, то всё пройдёт хорошо:

Мораль

Вот такой он etcd. Не весь конечно, но достаточный кусок для того, чтобы сформировать какое-то мнение. Я всё ещё играюсь с его документацией, и практически в восторге от их «Demos» секции. Анимация, конечно, там зря, но короткие куски кода для всех основных фич — это прекрасно, и очень помогает на первых порах. Ну и, как это часто бывает, я уже вижу, где etcd можно было бы засунуть нам в продакшен, как бы двусмысленно эта фраза не звучала.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *