Inside of the Nautical Cave by AshnoAlice
Если вы администрируете кластеры Kubernetes в своей инфраструктуре, а не используете версии, управляемые облачными провайдерами, то, скорее всего, уже управляете кластером etcd. Для тех, кому это внове, команда Kubernetes aaS от Mail.ru перевела статью о том, как обслуживать etcd.
Сначала разберемся с основами и определимся, что же такое etcd.
Итак, etcd — это простое распределенное хранилище вида ключ-значение, которое использует алгоритм консенсуса raft, чтобы обеспечить полную репликацию и высокую степень доступности.
Отличительная черта его стабильности — Kubernetes (сервер API) использует etcd в качестве хранилища ключ-значение для хранения состояния всего кластера. Kubernetes использует функцию etcd watch для мониторинга этих данных и для перенастройки кластера при возникновении изменений. Функция watch сравнивает значения, представляющие фактическое и желаемое состояние кластера, и может инициировать запрос, когда эти состояния различаются.
Что касается сравнения etcd с другими базами данных, такими как Redis, ZooKeeper или Consul, то это сравнение выходит за рамки этого поста. Здесь мы попытаемся перечислить несколько действий по обслуживанию производственных баз данных etcd, позволяющих сохранить их работоспособность.
Первое, что необходимо сделать — добавить в мониторинг оповещения о работе etcd.
Вот конфигурационный файл для Alertmanager для оповещения о базовых событиях etcd:
Здесь мы будем описывать только те оповещения, которых нет в официальной документации etcd, где упоминается большинство важных оповещений. Единственное правило, на которое следует обратить внимание, помимо выбора лидера и процесса, — это размер базы данных. Оно не упоминается в официальном документе, так как настраивается индивидуально.
Хранилище etcd передает метрики в формате Prometheus. Мы добавим к метрикам свои метки, такие как окружение (environment), в котором работает виртуальная машина, как видно в настройках выше. Вы можете убрать эту метку, когда будете пробовать конфиг в Alertmanager.
Чтобы не закончилось место для записи, нужно сжимать историю ключей. Если место закончится, вы поймете это из ошибок, полученных из etcd.
Отслеживайте метрику
Метрику
Поскольку доступное дисковое пространство ограничено, нужно освобождать место, занятое под историю пространства ключей, чего можно добиться с помощью сжатия.
Сжатие урезает журналы изменений для каждого ключа.
Обычно рекомендуется использовать один из следующих режимов автоматического сжатия:
В etcd существует единый счетчик ревизий, который начинается с 0. Каждое изменение, внесенное в ключи и их значения в базе данных, фиксируется в виде новой ревизии. Ревизия представляет собой последнюю версию измененного ключа. C каждой ревизией значение счетчика ревизий увеличивается.
Для режима автоматического сжатия на основе ревизий поведение будет таким же, как когда запускается что-то вроде
Если вам нужно больше свободного дискового пространства, можете передать
Одного сжатия данных недостаточно для высвобождения дискового пространства, так как внутренняя база данных фрагментирована после сжатия. При сжатии устаревшие данные просто удаляются, оставляя пробелы в серверной базе данных, которые по-прежнему приводят к использованию дискового пространства. Для исправления этой ситуации запускается дефрагментация в базе данных etcd.
Дефрагментация удаляет незаполненные места в базе данных.
Сжатие + дефрагментация + правильный мониторинг — основа обслуживания вашего кластера etcd.
Следует отметить, что дефрагментация должна выполняться относительно нечасто, поскольку она всегда вызывает простой. Дефрагментация на работающем инстансе кластера блокирует чтение и запись в кластер, пока состояние кластера не будет перестроено.
Рекомендуется поддерживать небольшой размер базы данных — по умолчанию снова 2 ГБ. Чем больше размер базы данных, тем больше времени потребуется для дефрагментации. В зависимости от того, насколько критична работа etcd для вашего приложения, время выполнения дефрагментации необходимо учитывать.
Настройка HA etcd не поможет уменьшить паузу при дефрагментации, поскольку переизбрание лидера etcd произойдет только тогда, когда дефрагментация займет больше времени, чем тайм-аут выбора лидера. А этого не должно быть, если ваша база данных меньше 2 ГБ и если сжатие производится регулярно.
В кластере дефрагментацию можно запустить для каждого узла или напрямую на всем кластере, выполнив
Лично я предпочитаю использовать systemd.timer для запуска операций дефрагментации, а не традиционный cronjob. При использовании systemd можно получать логи по умолчанию для каждого триггера, передавая информацию о них в journalctl, который гораздо понятнее, чем логи cron.
Пример файла etcd-defrag.service:
Пример файла etcd-defrag.timer:
Используя две вышеупомянутые службы systemd, вы можете запускать операции дефрагментации в зависимости от того, когда вы хотите, чтобы они выполнялись.
Логи сервиса etcd-defrag.service:
Мы используем etcd community cookbook, где описан пример запуска.
Пример etc-default.service:
Пример службы systemd предназначен для базы данных etcd на одном узле. В зависимости от того, требуется ли вам кластер etcd или вы не хотите, чтобы API etcdv2 был доступен — параметры вашего ExecStart изменятся. Это хорошо задокументировано в репозитории etcd community cookbook.
Мы не пробовали запускать etcd на Kubernetes, несмотря на то, что StatefulSets — это вещь, постепенно набирающая обороты. Мы делаем автоматизацию при помощи Proctor в сочетании со сценариями Chef, с несколькими дополнениями для создания связанных с дефрагментацией системных сервисов.
Несколько полезных ссылок:
Что еще почитать по теме:
Если вы администрируете кластеры Kubernetes в своей инфраструктуре, а не используете версии, управляемые облачными провайдерами, то, скорее всего, уже управляете кластером etcd. Для тех, кому это внове, команда Kubernetes aaS от Mail.ru перевела статью о том, как обслуживать etcd.
Что такое etcd
Сначала разберемся с основами и определимся, что же такое etcd.
Итак, etcd — это простое распределенное хранилище вида ключ-значение, которое использует алгоритм консенсуса raft, чтобы обеспечить полную репликацию и высокую степень доступности.
Отличительная черта его стабильности — Kubernetes (сервер API) использует etcd в качестве хранилища ключ-значение для хранения состояния всего кластера. Kubernetes использует функцию etcd watch для мониторинга этих данных и для перенастройки кластера при возникновении изменений. Функция watch сравнивает значения, представляющие фактическое и желаемое состояние кластера, и может инициировать запрос, когда эти состояния различаются.
Что касается сравнения etcd с другими базами данных, такими как Redis, ZooKeeper или Consul, то это сравнение выходит за рамки этого поста. Здесь мы попытаемся перечислить несколько действий по обслуживанию производственных баз данных etcd, позволяющих сохранить их работоспособность.
Мониторинг
Первое, что необходимо сделать — добавить в мониторинг оповещения о работе etcd.
Вот конфигурационный файл для Alertmanager для оповещения о базовых событиях etcd:
groups:
- name: etcd
rules:
- alert: EtcdLeader
expr: |
max(etcd_server_has_leader_gauge{environment="production"}) < 1
for: 3m
labels:
severity: critical
annotations:
summary: "etcd Leader Alert"
description: "Etcd in {{ $labels.environment }} doesnt have leader"
- alert: EtcdDB
expr: |
etcd_mvcc_db_total_size_in_bytes_gauge{environment="production"} >= 1999900000
for: 1m
labels:
severity: critical
annotations:
summary: "etcd db size"
description: "Etcd in {{ $labels.environment }} db has almost exceeded 2GB"
- alert: EtcdProcess
expr: |
procstat_lookup_running{exe="etcd",environment="production"} < 1
for: 1m
labels:
severity: critical
annotations:
summary: "etcd process is down"
description: "Etcd in {{ $labels.environment }} is down"
Здесь мы будем описывать только те оповещения, которых нет в официальной документации etcd, где упоминается большинство важных оповещений. Единственное правило, на которое следует обратить внимание, помимо выбора лидера и процесса, — это размер базы данных. Оно не упоминается в официальном документе, так как настраивается индивидуально.
Хранилище etcd передает метрики в формате Prometheus. Мы добавим к метрикам свои метки, такие как окружение (environment), в котором работает виртуальная машина, как видно в настройках выше. Вы можете убрать эту метку, когда будете пробовать конфиг в Alertmanager.
Чтобы не закончилось место для записи, нужно сжимать историю ключей. Если место закончится, вы поймете это из ошибок, полученных из etcd.
Отслеживайте метрику
etcd_mvcc_db_total_size_in_bytes
, некоторые версии etcd также передают метрику etcd_debugging_mvcc_db_total_size_in_bytes_gauge
. Метрику
etcd_debugging_mvcc_db_total_size_in_bytes_gauge
отслеживать смысла нет, так как ее могут удалить в следующих выпусках etcd. Неплохо вообще не отслеживать метрики с *debugging* в имени метрики.Сжатие
Поскольку доступное дисковое пространство ограничено, нужно освобождать место, занятое под историю пространства ключей, чего можно добиться с помощью сжатия.
Сжатие урезает журналы изменений для каждого ключа.
Обычно рекомендуется использовать один из следующих режимов автоматического сжатия:
- Для периодического сжатия передайте —
auto-compaction-retention
процессу etcd при запуске, например: —auto-compaction-retention = 1
будет запускать сжатие каждый час. Выбранный режим будет периодическим, как будто вы передали параметрauto-compaction-mode = period
. - Режим сжатия на основе ревизий активируется передачей ключа —
auto-compaction-mode = revision
. Мы не используем его, так как в нашем случае используется большое пространство ключей, а не огромное количество ревизий для пары ключ-значение.
В etcd существует единый счетчик ревизий, который начинается с 0. Каждое изменение, внесенное в ключи и их значения в базе данных, фиксируется в виде новой ревизии. Ревизия представляет собой последнюю версию измененного ключа. C каждой ревизией значение счетчика ревизий увеличивается.
Для режима автоматического сжатия на основе ревизий поведение будет таким же, как когда запускается что-то вроде
$ etcdctl compact 4
, после чего ревизии до версии, указанной для сжатия, становятся недоступными. Так что в этом случае, если вы сделаете $ etcdctl get --rev=3 some-key
, то ничего не получите, так как ревизии до 4 удалены.Если вам нужно больше свободного дискового пространства, можете передать
-quota-backend-bytes
с желаемым объемом для установки квоты дискового пространства при запуске процесса etcd. По умолчанию размер квоты 2 ГБ, но вы можете увеличить его до 8 ГБ. Чем меньше этот размер, тем лучше.Дефрагментация
Одного сжатия данных недостаточно для высвобождения дискового пространства, так как внутренняя база данных фрагментирована после сжатия. При сжатии устаревшие данные просто удаляются, оставляя пробелы в серверной базе данных, которые по-прежнему приводят к использованию дискового пространства. Для исправления этой ситуации запускается дефрагментация в базе данных etcd.
Дефрагментация удаляет незаполненные места в базе данных.
Сжатие + дефрагментация + правильный мониторинг — основа обслуживания вашего кластера etcd.
Следует отметить, что дефрагментация должна выполняться относительно нечасто, поскольку она всегда вызывает простой. Дефрагментация на работающем инстансе кластера блокирует чтение и запись в кластер, пока состояние кластера не будет перестроено.
Рекомендуется поддерживать небольшой размер базы данных — по умолчанию снова 2 ГБ. Чем больше размер базы данных, тем больше времени потребуется для дефрагментации. В зависимости от того, насколько критична работа etcd для вашего приложения, время выполнения дефрагментации необходимо учитывать.
Поможет ли настройка HA (High Availability, то есть высокой доступности)
Настройка HA etcd не поможет уменьшить паузу при дефрагментации, поскольку переизбрание лидера etcd произойдет только тогда, когда дефрагментация займет больше времени, чем тайм-аут выбора лидера. А этого не должно быть, если ваша база данных меньше 2 ГБ и если сжатие производится регулярно.
В кластере дефрагментацию можно запустить для каждого узла или напрямую на всем кластере, выполнив
etcdctl defrag-cluster
. Эта команда выполнит дефрагментацию на всех членах кластера.Запуск операций дефрагментации
Лично я предпочитаю использовать systemd.timer для запуска операций дефрагментации, а не традиционный cronjob. При использовании systemd можно получать логи по умолчанию для каждого триггера, передавая информацию о них в journalctl, который гораздо понятнее, чем логи cron.
Пример файла etcd-defrag.service:
[Unit]
Description=Run etcdctl defrag
Documentation=https://etcd.io/docs/v3.3.12/op-guide/maintenance/#defragmentation
After=network.target
[Service]
Type=oneshot
Environment="LOG_DIR=/var/log"
Environment="ETCDCTL_API=3"
ExecStart=/usr/bin/etcdctl defrag
[Install]
WantedBy=multi-user.target
Пример файла etcd-defrag.timer:
[Unit]
Description=Run etcd-defrag.service every day
After=network.target
[Timer]
OnCalendar=*-*-* 01:00:0
[Install]
WantedBy=multi-user.target
Используя две вышеупомянутые службы systemd, вы можете запускать операции дефрагментации в зависимости от того, когда вы хотите, чтобы они выполнялись.
Логи сервиса etcd-defrag.service:
root@foo-bar-etcd:/# journalctl -f -u etcd-defrag.service --since=-48h
-- Logs begin at Thu 2020-04-16 21:31:40 --
Apr 21 01:00:12 foo-bar-etcd systemd[1]: Starting Run etcdctl defrag...
Apr 21 01:00:13 foo-bar-etcd etcdctl[4265]: Finished defragmenting etcd member[127.0.0.1:2379]
Apr 21 01:00:13 foo-bar-etcd systemd[1]: Started Run etcdctl defrag.
Apr 22 01:00:12 foo-bar-etcd systemd[1]: Starting Run etcdctl defrag...
Apr 22 01:00:13 foo-bar-etcd etcdctl[3403]: Finished defragmenting etcd member[127.0.0.1:2379]
Apr 22 01:00:13 foo-bar-etcd systemd[1]: Started Run etcdctl defrag.
....
Запуск Etcd
Мы используем etcd community cookbook, где описан пример запуска.
Пример etc-default.service:
[Unit]
Description = Etcd Application Container Engine
Documentation = https://coreos.com/etcd
After = network.target
[Service]
Type = notify
ExecStart = /usr/bin/etcd -name=default -advertise-client-urls=http://<NODE_IP>:2379 -data-dir=/default.etcd -debug=false -auto-compaction-retention=6 -enable-v2=true -force-
new-cluster=false -initial-advertise-peer-urls=http://<NODE_IP>:2380 -initial-cluster=default=http://<NODE_IP>:2380 -listen-client-urls=http://0.0.0.0:2379 -listen-peer-
urls=http://0.0.0.0:2380 -auto-tls=false -peer-auto-tls=false -enable-pprof=false -metrics=basic -auth-token=simple
Restart = always
RestartSec = 10s
LimitNOFILE = 1048576
LimitNPROC = 1048576
LimitCORE = infinity
TimeoutStartSec = 120
User = etcd
[Install]
WantedBy = multi-user.target
Пример службы systemd предназначен для базы данных etcd на одном узле. В зависимости от того, требуется ли вам кластер etcd или вы не хотите, чтобы API etcdv2 был доступен — параметры вашего ExecStart изменятся. Это хорошо задокументировано в репозитории etcd community cookbook.
Мы не пробовали запускать etcd на Kubernetes, несмотря на то, что StatefulSets — это вещь, постепенно набирающая обороты. Мы делаем автоматизацию при помощи Proctor в сочетании со сценариями Chef, с несколькими дополнениями для создания связанных с дефрагментацией системных сервисов.
Несколько оптимизаций
- Предпочтительно, чтобы устройство хранения данных было подключено к виртуальной машине etcd и находилось с ней в одной сети, поскольку etcd чрезвычайно зависима от задержек сохранения, некоторые операции блокируются до тех пор, пока большинство узлов не примут изменения. Если задержка превысит определенные критические значения, это может привести к шторму перевыборов лидера, когда ни один лидер не удерживает главенствующую роль достаточно долго, чтобы изменения внеслись.
- Поскольку etcd сильно зависит от задержек ввода-вывода, целесообразно использовать SSD-диски в качестве хранилища.
- Выбирайте производительность виртуальной машины в зависимости от рабочей нагрузки, чтобы не иметь проблем с производительностью (более подробное обсуждение здесь).
Несколько полезных ссылок:
- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/maintenance.md
- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/etcd3_alert.rules.yml
- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/hardware.md
- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/etcd3_alert.rules.yml
- https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/grafana.json
- https://freedesktop.org/software/systemd/man/systemd.timer.html
Что еще почитать по теме:
chemtech
Скажите, зачем запускать etcd на Kubernetes?