Проверить актуальную версию DockerAdded
Убедитесь, что у вас установлена последняя версия Docker, так как некоторые команды могут изменяться с обновлениями.
docker --versionПонять, что управляется Swarm, а что нетMoved
Сначала смотрим сервисы кластера:
1docker stack ls
2docker service ls
3docker node ls
Потом — все контейнеры на машине:
У контейнеров Swarm имена вида стек_сервис.1.длинныйидентификатор. У обычных — простые, из compose-файла. Это самый быстрый способ их различить.
docker service lsОстановить дублирующие контейнерыMoved
Когда сервис уже живёт в Swarm, старый контейнер надо гасить тем же инструментом, которым поднимали:
1
2docker compose -f путь/к/docker-compose.yml down
3
4
5docker stop имя && docker rm имя
Не пытайся гасить через docker stop контейнер Swarm-сервиса — кластер тут же создаст новый. Нужно docker service scale имя=0 или docker stack rm.
docker ps --format "{{.Names}}"Проверить состояние сервисов после остановкиAdded
После остановки дублирующих контейнеров убедитесь, что все сервисы работают корректно.
docker service lsРазвернуть стекMoved
1docker stack deploy -c docker-compose.yml имя-стека
Тот же файл, что и для compose, но часть полей работает иначе:
- раздел
deploy читается только в Swarm, compose его игнорирует;
build в Swarm не работает — образ должен быть уже собран и доступен всем узлам;
depends_on игнорируется — порядок запуска не гарантируется.
docker stack deploy -c docker-compose.yml myappПонять, почему сервис не поднимаетсяMoved
Если docker service ls показывает 0/1, смотри историю задач:
1docker service ps имя-сервиса --no-trunc
Колонка CURRENT STATE и ERROR обычно говорят всё. Типичные состояния:
- Rejected — узел отказался: нет образа, не сошлись ограничения размещения, нет ресурсов
- Failed — контейнер запустился и упал с ненулевым кодом
- Complete — контейнер вышел с кодом 0. При
restart_policy: on-failure кластер его НЕ поднимет, и сервис так и останется 0/1
Логи сервиса целиком: docker service logs имя --tail 50
docker service ps имя-сервиса --no-trunc# С чего начинается путаницаRemoved
# С чего начинается путаница
Типичный вопрос после перехода на Swarm: «место на диске не освободилось, контейнеры появились на втором сервере, docker-compose теперь не нужен?»
Короткий ответ: **всё запущено дважды**. Старые контейнеры от `docker-compose` никуда не делись, а рядом появились сервисы Swarm. Они не видят друг друга и едят ресурсы одновременно.
Список непоследовательный — читай то, что нужно.
## Два разных мираRemoved
## Два разных мира
| | `docker compose up` | `docker stack deploy` |
|---|---|---|
| Что создаёт | контейнеры | сервисы |
| Где запускает | только на этой машине | на любом узле кластера |
| Чем смотреть | `docker ps` | `docker service ls` |
| При падении | лежит, пока не поднимешь | перезапускается сам |
| Масштабирование | вручную | `replicas: N` |
**Главное:** `docker ps` показывает **и** контейнеры Swarm, **и** обычные. Поэтому по одному `docker ps` нельзя понять, что чем управляется — и именно отсюда ощущение, что «всё как-то странно».
## Распределение между manager и workerRemoved
## Распределение между manager и worker
В кластере есть узлы двух ролей. Manager держит состояние кластера и принимает решения, worker — просто запускает задачи.
Рабочее правило распределения:
| Что | Куда | Почему |
|---|---|---|
| Инфраструктура кластера, панель управления, прокси | **Manager** | без них кластером не поуправляешь |
| Базы данных | **Manager** | стабильность важнее гибкости, данные привязаны к тому узла |
| Кэш (Redis и подобные) | **Worker** | лёгкие, перезапуск безболезненен |
| Бэкенды | **Worker** | тяжёлые по CPU, их много |
| Фронтенды, статика | **Worker** | лёгкие, легко масштабируются |
Закрепляется в compose через ограничения размещения:
```yaml
services:
api:
deploy:
replicas: 2
placement:
constraints:
- node.role == worker
postgres:
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
```
**Критично для баз данных:** если сервис с томом переедет на другой узел, том за ним не поедет — он привязан к машине. Получишь пустую базу и очень неприятный вечер.
## Шпаргалка по командамRemoved
## Шпаргалка по командам
```bash
# обзор
docker node ls # узлы кластера и их роли
docker stack ls # стеки
docker service ls # сервисы и реплики
# конкретный сервис
docker service ps имя --no-trunc # где запущен и что с ним было
docker service logs имя --tail 50 # логи
docker service inspect имя # полная конфигурация
# изменения
docker service scale имя=3 # число реплик
docker service update --force имя # перезапустить задачи
docker stack deploy -c file.yml стек # развернуть или обновить
docker stack rm стек # снести стек целиком
```
Заметь: `docker stack deploy` с тем же именем стека не создаёт второй стек, а обновляет существующий. Это и есть штатный способ выкатки.
## О безопасности кластераRemoved
## О безопасности кластера
Чтобы узел вошёл в кластер, нужен **join-токен**. Их два вида, и разница между ними огромная:
```bash
docker swarm join-token worker # может только выполнять задачи
docker swarm join-token manager # может УПРАВЛЯТЬ кластером
```
**Manager-токен — это полный контроль над кластером.** Кто его получил, тот может запускать что угодно на любом узле и читать все секреты Swarm. По последствиям это хуже утечки пароля от одной базы.
Отсюда три правила:
1. **Токены не коммитятся.** Ни в скрипты автоматизации, ни в документацию, ни «временно, чтобы не забыть».
2. **Если токен где-то засветился — ротируй:** `docker swarm join-token --rotate manager`. Старый сразу перестаёт работать, уже вошедшие узлы не вылетают.
3. **Новые узлы — всегда worker**, если нет явной причины делать их manager.
Проверь прямо сейчас: `grep -r "SWMTKN" .` по своим репозиториям и скриптам.