🔥 Service Discovery в Docker Swarm: Как мы проебали prod в 3 ночи
Вступление для тех, кто ещё не в курсе
Поздравляю, ты дошёл до момента, когда твои 5 контейнеров больше не могут найти друг друга через localhost:3000. Теперь тебе нужен Service Discovery. И ты, нагуглил Docker Swarm.
Спойлер: твоя собака настроит отказоустойчивый кластер быстрее, чем ты разберёшься с overlay networks.
🐕 Что такое Service Discovery
Когда контейнер api-gateway хочет достучаться до user-service, ему нужно знать: IP этого сервиса, порт, и что сервис вообще жив
В Swarm это работает через встроенный DNS на 127.0.0.11:53 и overlay network. Звучит охуенно, правда?
💀 Как это работает (технически)
Overlay Network — твой новый ад
```
Что здесь важно:
--driver overlay — сетка между нодами. Без этого контейнеры на разных хостах НЕ УВИДЯТ друг друга
--attachable — чтобы можно было подключить контейнер руками (для дебага в 3 ночи)
DNS Resolution — магия, которая не работает
Swarm поднимает встроенный DNS внутри каждого контейнера:
```yaml
Обращение внутри контейнера api:
```javascript
🔴 КРИТИЧЕСКИЙ КОСЯК №1: Round-robin DNS — лотерея смерти
Когда у тебя 3 реплики api, Swarm отдаёт IP по очереди:
```bash
Проблема: TTL = 0, но HTTP-клиенты кэшируют соединения. Результат — 30% запросов в труп.
Решение (которое ты не применишь):
```javascript
🔴 КРИТИЧЕСКИЙ КОСЯК №2: Health checks — иллюзия контроля
```yaml
Отмазка CTO Петрова А.С.: "У нас есть health checks!"
Реальность:
Проверка идёт внутри контейнера (localhost)
Сетевые проблемы НЕ ДЕТЕКТЯТСЯ
Между unhealthy и удалением из DNS — 30-60 секунд
За эти 60 секунд ты получишь несколько сотен 503-ошибок. Поздравляю!
🔴 КРИТИЧЕСКИЙ КОСЯК №3: Split-brain при деплое
Когда ты делаешь docker service update:
Поднимается новая реплика (10.0.1.8)
DNS сразу добавляет её в пул
Приложение ещё грузится (20 секунд)
💥 50% запросов в 503
Пруф:
```bash
🐶 Собака vs Твой Service Discovery
Собака: Понимает команды с первого раза
Твой код: 4 дня настройки DNS
Собака: Виляет хвостом при встрече
Твой код: 503 Service Unavailable
Собака: Приносит тапки
Твой код: Приносит алерты в 3 ночи
🔥 Минимально рабочий конфиг
```yaml
```
📊 Что в итоге
✅ Работает из коробки — для pet-проектов
❌ Production — нужен Consul/etcd или хотя бы правильная настройка ❌ Мониторинг — придётся писать руками
❌ Debugging — tcpdump в overlay network (удачи)
Вывод: Docker Swarm Service Discovery — как бесплатный сыр в мышеловке. Работает, пока не нужна надёжность.
Продолжение: В следующей части разберём, как это настроить правильно
Вступление для тех, кто ещё не в курсе
Поздравляю, ты дошёл до момента, когда твои 5 контейнеров больше не могут найти друг друга через localhost:3000. Теперь тебе нужен Service Discovery. И ты, нагуглил Docker Swarm.
Спойлер: твоя собака настроит отказоустойчивый кластер быстрее, чем ты разберёшься с overlay networks.
🐕 Что такое Service Discovery
Когда контейнер api-gateway хочет достучаться до user-service, ему нужно знать: IP этого сервиса, порт, и что сервис вообще жив
В Swarm это работает через встроенный DNS на 127.0.0.11:53 и overlay network. Звучит охуенно, правда?
💀 Как это работает (технически)
Overlay Network — твой новый ад
```
docker network create \
--driver overlay \
--attachable \
my-fucking-network
```Что здесь важно:
--driver overlay — сетка между нодами. Без этого контейнеры на разных хостах НЕ УВИДЯТ друг друга
--attachable — чтобы можно было подключить контейнер руками (для дебага в 3 ночи)
DNS Resolution — магия, которая не работает
Swarm поднимает встроенный DNS внутри каждого контейнера:
```yaml
version: "3.8"
services:
api:
image: api:latest
networks:
- backend
deploy:
replicas: 3
db:
image: postgres:15
networks:
- backend
```Обращение внутри контейнера api:
```javascript
// РАБОТАЕТ (если ты не долбоёб)
fetch('http://db:5432')
// НЕ РАБОТАЕТ (догадайся почему)
fetch('http://localhost:5432') // БЛЯТЬ, ЭТО ЖЕ КОНТЕЙНЕР
```🔴 КРИТИЧЕСКИЙ КОСЯК №1: Round-robin DNS — лотерея смерти
Когда у тебя 3 реплики api, Swarm отдаёт IP по очереди:
```bash
# Запрос 1
dig api # -> 10.0.1.5
# Запрос 2
dig api # -> 10.0.1.6
# Запрос 3
dig api # -> 10.0.1.7 (УЖЕ МЁРТВАЯ РЕПЛИКА)
```Проблема: TTL = 0, но HTTP-клиенты кэшируют соединения. Результат — 30% запросов в труп.
Решение (которое ты не применишь):
```javascript
// Правильно
const agent = new http.Agent({
keepAlive: false // Да, убиваем перформанс
});
// Как у тебя сейчас (НЕПРАВИЛЬНО)
const agent = new http.Agent({
keepAlive: true,
maxSockets: 50 // 50 КОННЕКТОВ В МЁРТВЫЙ КОНТЕЙНЕР, ГЕНИЙ
});
```🔴 КРИТИЧЕСКИЙ КОСЯК №2: Health checks — иллюзия контроля
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 10s
timeout: 3s
retries: 3
```Отмазка CTO Петрова А.С.: "У нас есть health checks!"
Реальность:
Проверка идёт внутри контейнера (localhost)
Сетевые проблемы НЕ ДЕТЕКТЯТСЯ
Между unhealthy и удалением из DNS — 30-60 секунд
За эти 60 секунд ты получишь несколько сотен 503-ошибок. Поздравляю!
🔴 КРИТИЧЕСКИЙ КОСЯК №3: Split-brain при деплое
Когда ты делаешь docker service update:
Поднимается новая реплика (10.0.1.8)
DNS сразу добавляет её в пул
Приложение ещё грузится (20 секунд)
💥 50% запросов в 503
Пруф:
```bash
docker service ps api
# ID IMAGE NODE DESIRED CURRENT STATE
# abc123 api:v2 node1 Running Starting 3 seconds ago ← БЛЯТЬ, НЕ ГОТОВА
# def456 api:v1 node2 Running Running 2 hours ago
```🐶 Собака vs Твой Service Discovery
Собака: Понимает команды с первого раза
Твой код: 4 дня настройки DNS
Собака: Виляет хвостом при встрече
Твой код: 503 Service Unavailable
Собака: Приносит тапки
Твой код: Приносит алерты в 3 ночи
🔥 Минимально рабочий конфиг
```yaml
version: "3.8"
services:
api:
image: api:latest
networks:
- backend
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s # ПОДОЖДИ, ПОКА КОНТЕЙНЕР ПРОГРЕЕТСЯ
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
interval: 5s
timeout: 2s
retries: 3
start_period: 40s # 40 СЕКУНД НА СТАРТ, НЕ 10
networks:
backend:
driver: overlay
driver_opts:
encrypted: "true" # А ТО СНИФФЕРЯТ```
📊 Что в итоге
✅ Работает из коробки — для pet-проектов
❌ Production — нужен Consul/etcd или хотя бы правильная настройка ❌ Мониторинг — придётся писать руками
❌ Debugging — tcpdump в overlay network (удачи)
Вывод: Docker Swarm Service Discovery — как бесплатный сыр в мышеловке. Работает, пока не нужна надёжность.
Продолжение: В следующей части разберём, как это настроить правильно