← К программе курса

Модуль 2 / 18

Установка, конфигурация и контексты Docker

DOCKER

Содержание
01

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 как разные модели доступа
02

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 версионируют и обновляют осознанно.

terminal
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.

03

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.

04

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 конфигурации
05

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.

06

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.

07

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 как способ лечения
08

8. Лабораторная работа: inventory, config и contexts

Установка из раздела 2 выполняется только на чистой учебной Ubuntu VM. На текущем хосте начните с inventory. Создайте отдельный context для того же Unix socket, исследуйте его и явно вернитесь к default.

terminal
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-pager
terminal
printf '%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.json
terminal
stat -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 || true
terminal
docker 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.

09

9. Диагностика: client не видит daemon

Создайте context с заведомо закрытым endpoint. Ошибка connection refused ожидаема. Проверьте endpoint и overrides до изменения daemon или firewall.

terminal
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

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 без опасных изменений.