Привет Хабр! Если вам тоже доводилось разбирать незнакомый проект, сопровождать прод или помогать QA, вы знаете, как быстро начинаешь ненавидеть однообразные команды etcdctl: копировать ключ, вбивать get, ловить в терминале многострочные значения, скроллить историю… Особенно если ключей сотни, а половина из них — конфиги или JSON’ы на несколько экранов.
Мне хотелось чего-то попроще: запустил один бинарь в терминале и спокойно ходишь по дереву ключей etcd, как по файловой системе, подобно mc.
Без браузера, без копипаста, с нормальным просмотром и редактированием многострочных значений. Так появился etcd-walker.
Под катом расскажу, как он устроен, почему в etcd v2 внезапно пропадают ключи, которые начинаются с подчеркивания, как их всё-таки увидеть, зачем понадобилась “инъекция” узлов, и как решить боль с большими многострочными ключами, например JSON или yaml. А также покажу, как этот инструмент помогает разбираться с локами, которые создает python библиотека для работы c etcd.
Если вы хоть раз пробовали разгрести чужое хранилище в etcd, то поймёте, почему без подобного инструмента жить уже не хочется.
Что такое etcd-walker
etcd-walker — это консольное TUI-приложение (на базе tview/tcell), которое:
работает прямо в терминале, без web UI;
подключается к etcd v2 и v3 (можно явно выбрать протокол или работать в режиме
auto);-
показывает дерево ключей как каталоги/файлы:
слева — список ключей/“папок”;
справа — панель с деталями (полное имя, Cluster ID, значение);
-
позволяет:
создавать ключи и “каталоги”;
удалять (в том числе рекурсивно);
редактировать значения, в том числе в полноэкранном многстрочном редакторе;
быстро искать и прыгать к нужному ключу.
И самое важное — утилиту можно просто запустить в терминале и забыть про etcdctl для ежедневной рутины. А заодно, если вы так же любите TUI, как автор — это просто приятно эстетически :)
Архитектура вкратце
Утилита разбита на три слоя:
model— работа с etcd (v2 и v3), минимальный API: (Ls, Get, Set, MkDir, Del, DelDir, RenameDir)-
view— TUI на базеtview:список ключей,
панель деталей,
модальные окна,
полноэкранный редактор;
-
controller— склеивает всё вышеперечисленное :)хранит текущее “каталогоподобное” состояние currentDir;
управляет навигацией, поиском, Jump, выделением;
решает “магические” кейсы - например, с ключами, начинающимися с “_”
При запуске в хедере показывается, к какому хосту и порту утилита подключилась и какой протокол реально используется — v2 или v3.
Основная боль: многострочные значения
Одна из причин написать отдельный инструмент — многострочные ключи. В реальных проектах в etcd живут:
большие JSON-конфиги;
шаблоны;
текстовые настройки;
логи/дампы для отладки.
Через etcdctl это читать и править — мучение: терминал ломает форматирование, не видно границы строк, любой промах — снова вбивать команду.
В etcd-walker это решено так:
при выборе “файла” (ключа без
IsDir) в правой панели сразу видно полное значение целиком;есть два режима редактирования:
- обычный (однострочное поле);
- многострочный полноэкранный редактор (горячая клавиша Ctrl+E, если это файл): открывается TextArea и можно спокойно править большие тексты.
После сохранения значение отправляется через model.Set, TUI обновляется, курсор остается на нужном ключе, а детальная панель тут же показывает новое значение. Всё это работает и для обычных ключей, и для “особенных” вроде тех, что начинаются с _.
Проблема ключей, начинающихся с _ в etcd v2
В etcd v2 есть неприятный кейс: ключи, которые находятся на “корне” и начинаются с подчеркивания, не всегда попадают в привычный обзор дерева.
Посмотрим на пример:
curl -s 'http://127.0.0.1:2379/v2/keys/_test' | jq .
Ответ:
{
"action": "get",
"node": {
"key": "/_test",
"value": "test",
"modifiedIndex": 4,
"createdIndex": 4
}
}
То есть ключ / _test существует, значение "test", всё ок.
А теперь попробуем посмотреть весь “корень”:
curl -s 'http://127.0.0.1:2379/v2/keys/?recursive=true' | jq .
Ответ:
{
"action": "get",
"node": {
"dir": true
}
}
То есть etcd сообщает, что это каталог ("dir": true), но детей не показывает — ни /foo, ни /_test, ничего. В итоге TUI, который просто обходит дерево через ls("/"), вообще не видит / _test и подобных ключей.
Как etcd-walker решает проблему ключей с _ через Jump
В контроллере есть механизм “инъекции” узлов — injectNode. И есть отдельная команда Jump (Ctrl+J), которая:
Берет введенный путь (абсолютный или относительный).
-
Через
model.Getделает прямой запрос к etcd:- для v2 — это прямой вызов
KeysAPI.Getпо ключу;- для v3 — запрос через
clientv3.Get. -
Если ключ найден:
- утилита определяет это “директория” (набор ключей с общим префиксом) или файл;
- создаёт
Nodeи подкладывает его в кешinjectedдля родительской “папки”, то есть/ _testпосле Jump реально “вклеивается” в список корня/;- если это директория — переключает текущий “каталог” на неё;
- если это файл — переходит в родительский каталог и ставит курсор на этот ключ.
-
При последующих обновлениях списка (
updateList) контроллер:- сначала берёт real-список от модели (
Ls);- затем поверх него сливает “инъектированные” узлы;
- если ключ уже есть в ответе сервера, отдается приоритет “реальному” варианту.
Таким образом:
даже если etcd v2 не показывает
/ _testв дереве,
один раз прыгнув к нему через Jump — вы “подсветите” его для TUI;в списке такой ключ будет отображаться как обычный файл, который дополнительно подсвечивается жёлтым, т.к.
colorizeспециально крастит всё, что начинается с_.
Практически это выглядит так:
Вы находитесь в корне
/.Нажимаете
Ctrl+J.-
Вводите:
/_test— абсолютный путь, или_test— относительный от текущего каталога. -
Если ключ существует,
etcd-walker:- открывает каталог
/;- отображает
/ _testсреди других ключей (если они есть);- ставит курсор на нём;
- показывает в правой панели полное значение и метаданные.
Дальше можно:
открывать полноэкранный редактор;
удалять ключ;
смотреть значение, не мучаясь с
curl/etcdctl.
Работа с локами на базе EtcdLock
Многие библиотеки поверх etcd используют “скрытые” ключи (часто с _ в имени) для реализации распределённых локов. Типичный пример — Python-клиент:
from etcd import Lock as EtcdLock
Внутри EtcdLock создаёт служебный ключ в etcd (часто с префиксом , типа /locks/...), который:
может жить недолго (TTL);
не предназначен напрямую для человека;
-
но при отладке или расследовании проблем очень хочется видеть:
какие именно ключи создаются;
где они висят;
не “завис” ли где-то лок.
С обычным обходом /v2/keys/?recursive=true такие ключи легко “потерять” — как мы видели на примере /_test.
С etcd-walker подход другой:
вы просто знаете (или подозреваете), где живёт лок,
например/_locks/user-123или/_test_lock;жмёте
Ctrl+J, вписываете путь и попадаете именно туда;ключ инъектируется в дерево и становится видимым в TUI;
дальше можно смотреть значение, при необходимости удалять зависшие локи и наблюдать, как они появляются и исчезают в реальном времени.
Это сильно упрощает анализ и отладку распределённых локов, особенно в QA/стейджинг окружениях, где руками приходится разбирать странные состояния.
Навигация и поиск, когда ключей очень много
На реальных кластерах etcd в одном “уровне” (в одном префиксе) легко может быть сотни ключей. Листать их стрелками — такое себе. В etcd-walker для этого есть несколько фич:
Поиск по имени (/ или Ctrl+S)
Нажимаете / или
Ctrl+S— открывается строка поиска.Вводите префикс имени (поиск регистронезависимый).
Работает автодополнение то есть, показываются только те имена, которые начинаются с введённой строкой.
По
Enterкурсор прыгает на найденный ключ в текущем каталоге.
Это удобно, когда, например, на уровне /services/ куча разных сервисов, и нужно быстро найти /services/payment или /services/auth.
Jump по пути (Ctrl+J)
-
Если вы знаете путь целиком или частично — используете Jump:
абсолютный путь
/foo/bar/baz;относительный от текущего каталога
bar/baz;для “директории” удобно добавить / на конец, чтобы утилита требовала именно папку.
Jump работает поверх
Get, а неLs, поэтому может найти ключи, которых нет в обычном дереве (тот самый кейс с_).
Запоминание позиции
Контроллер хранит position для каждого каталога:
при переходе “вниз” - запоминает позицию в текущем каталоге;
при возвращении “вверх”
[..]или Backspace восстанавливает её.
Это даёт эффект “как в нормальном файловом менеджере”: вернувшись на уровень выше, вы попадаете ровно туда же, а не в начало списка.
Ключи, начинающиеся с _, в списке подсвечиваются жёлтым, чтобы их легко было визуально отделить от остальных — это удобно для тех самых “скрытых” служебных сущностей (локи, системные ключи и т.п.).
Поскольку автор любит TUI, интерфейс сделан максимально “клавиатурным”.
Итог
etcd-walker появился из очень практичной мотивации:
лень и скука постоянно писать команды
etcdctlради банального просмотра и правки значений;боль с многострочными ключами, где обычный терминал не даёт нормального UX;
неудобство работы со скрытыми ключами (особенно теми, что начинаются с _), которых не видно в стандартном дереве etcd v2, но которые критичны для локов и служебной логики.
Теперь всё это закрывается одним TUI-инструментом, который:
запускается как обычная консольная утилита;
даёт привычную “каталожную” навигацию по ключам;
умеет полноэкранный многстрочный редактор;
адекватно работает с etcd v2 и v3;
позволяет видеть и трогать “невидимые” _-ключи через Jump и механизм инъекции.
Если вы много ковыряетесь в конфигурации через etcd, копаетесь в чужих проектах или помогаете QA — такой TUI-проводник очень быстро становится чем-то, что просто всегда хочется иметь под рукой. Ну и это opensource и PR приветствуется ?
Комментарии (3)

baldr
05.12.2025 12:16Любопытно. А для Redis что-нибудь похожее есть? Ну, то есть, существует RedisInsight, но хотелось бы в консоли.
DmitriyEssensci
Приятная статейка