Как синхронизировать доступ к ресурсам между подами в Kubernetes
Что проверяют
Понимаете ли вы, что поды это отдельные процессы на разных узлах, и sync.Mutex между ними ничего не синхронизирует. Хотят услышать, какую внешнюю точку координации вы выберете и что будет, если держатель блокировки завис. Следом часто спрашивают про fencing token.
Как отвечать
Сначала попробуйте убрать необходимость в блокировке, это надёжнее любой блокировки:
- атомарность в базе: условный
UPDATE ... WHERE version = $1(оптимистичная блокировка),SELECT ... FOR UPDATE, уникальный индекс плюсINSERT ... ON CONFLICT. Если ресурс и так в PostgreSQL, есть advisory lock:pg_try_advisory_lock(key); - очередь с одним потребителем на ключ: в Kafka сообщения с одним ключом попадают в одну партицию, её читает один консьюмер группы, и порядок по ключу соблюдается без блокировок.
Если нужен именно единственный исполнитель:
- leader election в Kubernetes: объект
Leaseизcoordination.k8s.io/v1и пакетk8s.io/client-go/tools/leaderelectionс параметрамиLeaseDuration,RenewDeadline,RetryPeriod. Сервис-аккаунту пода нужны права наleases. Задачу выполняет только лидер, остальные ждут; - блокировка в Redis:
SET key token NX PX 30000с уникальным токеном, снимается Lua-скриптом, который удаляет ключ, только если значение совпадает с токеном. В Go этоgithub.com/redis/go-redis/v9; - etcd:
concurrency.NewMutexизgo.etcd.io/etcd/client/v3/concurrency, блокировка привязана к сессии с арендой.
Для периодических задач проще CronJob с concurrencyPolicy: Forbid, чем своя блокировка.
Где спотыкаются
Удаляют ключ блокировки простым DEL. Если TTL истёк и замок уже взял другой под, первый снимет чужую блокировку.
Считают блокировку с TTL абсолютной гарантией. Долгая пауза GC или сети, и два пода уверены, что держат ресурс. Даже документация leaderelection честно пишет, что единственного лидера она не гарантирует, поэтому запись должна проверять монотонный fencing token.
Ставят replicas: 1 и считают вопрос закрытым. Во время rolling update старый и новый под какое-то время работают одновременно.