← До програми курсу

Модуль 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 без небезпечних змін.