Модуль 2 / 18
Установка, конфигурация и контексты Docker
Содержание
1. Цели и границы модуля
После модуля вы сможете выбрать поддерживаемый способ установки Docker Engine, доказать совместимость клиента и daemon, читать effective configuration, безопасно проверять daemon.json и управлять несколькими endpoint через Docker contexts.
- официальный repository и зафиксированная версия для production
- разделение client, API и server
- systemd unit, socket activation и daemon logs
- приоритет context, environment и CLI flags
- Unix socket, SSH и mutual TLS как разные модели доступа
2. Теория: установка и жизненный цикл пакетов
Для production используйте официальный repository поддерживаемой ОС или согласованный vendor package. Convenience script предназначен для development и не даёт достаточного контроля версий. Перед установкой выявляют конфликтующие docker.io, podman-docker, containerd и runc: официальный пакет containerd.io приносит согласованные зависимости.
Latest удобен для лаборатории, но production upgrade должен начинаться с release notes, совместимости API/plugins, backup и canary. Пакеты docker-ce, docker-ce-cli, containerd.io, buildx и compose plugin версионируют и обновляют осознанно.
sudo apt update
sudo apt install ca-certificates curl jq
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
. /etc/os-release
printf 'Types: deb\nURIs: https://download.docker.com/linux/ubuntu\nSuites: %s\nComponents: stable\nArchitectures: %s\nSigned-By: /etc/apt/keyrings/docker.asc\n' "${UBUNTU_CODENAME:-$VERSION_CODENAME}" "$(dpkg --print-architecture)" | sudo tee /etc/apt/sources.list.d/docker.sources
sudo apt update
apt list --all-versions docker-ce
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker "$USER"После usermod завершите SSH/login-сессию и войдите снова: дополнительная группа применяется только к новому процессу входа. Проверьте id и docker version. Членство в группе docker эквивалентно root-доступу и допустимо только для доверенного пользователя учебной VM.
3. Теория: client, daemon и API compatibility
Команда docker запускает client. Он выбирает endpoint, согласует API version и отправляет запрос daemon. Версия CLI не доказывает версию Engine: docker version показывает обе стороны, а при недоступном server выводит только client и transport error.
Новый client обычно умеет понижать API version до поддерживаемой daemon, но новые flags и поля могут быть недоступны. DOCKER_API_VERSION принудительно отключает negotiation и нужен преимущественно для диагностики совместимости, а не как постоянный workaround.
4. Теория: systemd и daemon.json
На обычном Linux daemon читает /etc/docker/daemon.json, в rootless mode — ~/.config/docker/daemon.json с учётом XDG_CONFIG_HOME. JSON-конфигурация предпочтительнее набора flags. Один параметр нельзя одновременно задать в daemon.json и ExecStart: dockerd завершится с конфликтом.
Сначала выполняйте dockerd --validate, затем планируйте restart и проверку. Restart может остановить containers; live-restore уменьшает влияние планового restart daemon, но не заменяет тест upgrade и не сохраняет управление сетью или изменениями workload во время недоступности daemon.
- systemctl status показывает состояние unit
- journalctl -u docker.service содержит daemon diagnostics
- systemctl cat docker раскрывает vendor unit и drop-ins
- systemctl daemon-reload нужен после изменения unit/drop-in
- перезапуск допустим только с rollback конфигурации
5. Теория: данные и доступ к socket
Классическая установка хранит daemon data в /var/lib/docker. На свежем Engine 29+ containerd image store используется по умолчанию: image content и snapshots находятся в /var/lib/containerd, тогда как volumes и другие данные остаются в /var/lib/docker. data-root Docker не переносит containerd storage автоматически.
Unix socket обычно принадлежит root:docker. Членство в группе docker фактически даёт root-level control над хостом: пользователь может монтировать host filesystem или запускать privileged workload. Альтернатива — rootless mode с известными ограничениями. Нельзя публиковать незашифрованный TCP 2375.
6. Теория: Docker contexts и удалённый доступ
Context хранит имя, Docker endpoint, TLS material и metadata. default обычно указывает на unix:///var/run/docker.sock. Активный context отмечен звёздочкой, но DOCKER_CONTEXT, DOCKER_HOST и глобальные --context/--host могут изменить фактическую цель.
Для удалённого Engine предпочтителен ssh://user@host: он использует существующую SSH authentication и не требует открывать Docker TCP API. TCP 2376 допустим с проверкой CA, server certificate и client certificate. Обладатель client key получает полномочия Docker daemon, поэтому ключ защищают как root credential.
7. Методические указания
- Не устанавливайте пакеты поверх рабочего production host без maintenance plan
- До изменений сохраните docker version, docker info, systemctl cat docker и daemon.json
- Не добавляйте пользователя в docker group без threat-model и approval
- Не копируйте TLS private keys в Git и context exports без защиты
- Перед каждой командой называйте фактический context
- Сначала validate, затем restart, затем smoke и daemon logs
- Не удаляйте /var/lib/docker или /var/lib/containerd как способ лечения
8. Лабораторная работа: inventory, config и contexts
Установка из раздела 2 выполняется только на чистой учебной Ubuntu VM. На текущем хосте начните с inventory. Создайте отдельный context для того же Unix socket, исследуйте его и явно вернитесь к default.
docker version --format '{{json .}}' | jq
docker info --format '{{json .}}' | jq '{ServerVersion,Driver,CgroupVersion,LoggingDriver,DockerRootDir,SecurityOptions}'
docker context ls
docker context inspect default
sudo systemctl is-enabled docker.service docker.socket
sudo systemctl is-active docker.service docker.socket
sudo journalctl -u docker.service --since '15 minutes ago' --no-pagerprintf '%s\n' '{' ' "log-driver": "local",' ' "log-opts": {"max-size": "100m", "max-file": "3"},' ' "live-restore": true' '}' > /tmp/docker-m2-daemon.json
sudo dockerd --validate --config-file=/tmp/docker-m2-daemon.json
jq . /tmp/docker-m2-daemon.json
rm /tmp/docker-m2-daemon.jsonstat -c 'mode=%A owner=%U group=%G path=%n' /var/run/docker.sock
id
getent group docker
docker info --format 'root={{.DockerRootDir}} driver={{.Driver}} cgroup={{.CgroupVersion}}'
sudo du -sh /var/lib/docker /var/lib/containerd 2>/dev/null || truedocker context create docker-m2-local --description 'Module 2 local socket' --docker host=unix:///var/run/docker.sock
docker context inspect docker-m2-local
docker --context docker-m2-local version
docker context use docker-m2-local
docker context show
DOCKER_CONTEXT=default docker context show
docker context use default
docker context rm docker-m2-localКритерий: client и server доступны, конфигурация проходит validate, вы определили storage/cgroup/logging driver, доказали права socket и после упражнения активен исходный default context.
9. Диагностика: client не видит daemon
Создайте context с заведомо закрытым endpoint. Ошибка connection refused ожидаема. Проверьте endpoint и overrides до изменения daemon или firewall.
docker context create docker-m2-broken --docker host=tcp://127.0.0.1:1
docker --context docker-m2-broken version
docker context inspect docker-m2-broken
env | grep '^DOCKER_' || true
docker context use default
docker context rm docker-m2-broken- docker context show и inspect — куда направлен запрос
- env — не переопределяют ли context переменные DOCKER_CONTEXT или DOCKER_HOST
- docker version — доступна ли server-часть ответа
- systemctl status и journalctl — запущен ли локальный daemon
- stat socket — существует ли endpoint и разрешён ли доступ
- SSH/TLS — отдельно проверить transport, identity, certificate SAN и срок действия
Диагностический порядок: target → transport → authentication → API compatibility → daemon health → object. Restart daemon без установленной причины расширяет blast radius.
10. Контроль и шпаргалка
- Почему convenience script не подходит для управляемого production upgrade?
- Чем версия CLI отличается от API version daemon?
- Почему повтор одного параметра в flags и daemon.json останавливает dockerd?
- Почему docker group считается root-equivalent?
- Как DOCKER_CONTEXT влияет на активную цель?
- Когда выбирать SSH, а когда mutual TLS?
- Где Engine 29 fresh install может хранить image snapshots?
Модуль освоен, если вы воспроизводимо описываете установку, читаете effective endpoint, валидируете конфигурацию до restart и диагностируете недоступный daemon без опасных изменений.