Перейти к содержанию

Лабораторная: сеть Docker

В паре со статьёй: Основы сети Docker

Окружение: любой хост с установленным Docker. Ниже приведён эквивалентный docker-compose.yml, если вам удобнее Compose, чем «сырые» команды docker.

docker-compose.yml (необязательно)
services:
  web:
    image: nginx:1.27-alpine
    networks:
      - lab_net

  web2:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"

networks:
  lab_net:
    driver: bridge

Сама лабораторная написана на «сырых» командах docker, чтобы каждый шаг (явное создание сети, явное её отсутствие) был виден; обе формы дают одинаковое сетевое поведение.

Начальные условия

  1. Docker установлен и работает (docker ps выполняется без ошибок).
  2. Никаких контейнеров или сетей из этой лабораторной уже не присутствует (выполните docker network ls, чтобы подтвердить чистое исходное состояние).

Инструкции

Часть 1 — Докажите, что разрешение имён требует членства в сети, а не просто «Docker работает»

docker network create lab_net
docker run -d --name web --network lab_net nginx
docker run -it --rm --name tester --network lab_net alpine sh -c "wget -qO- http://web || echo FAILED"

Затем, без --network lab_net:

docker run -it --rm --name outsider alpine sh -c "wget -qO- http://web || echo FAILED"

Часть 2 — Докажите, что -p это NAT, а не прямая привязка, и что это обходит правила файрвола хоста, которые вы могли бы ожидать применимыми

docker run -d --name web2 -p 8080:80 nginx
sudo ufw deny 8080/tcp 2>/dev/null || echo "(ufw не установлен, пропустите эту конкретную проверку)"
curl -i http://localhost:8080/

Ожидаемые результаты

  • Часть 1: tester (в lab_net) успешен — wget разрешает web по имени и получает страницу nginx по умолчанию. outsider (не в lab_net) проваливается с ошибкой разрешения DNS — имя web ничего не значит за пределами конкретно этой сети со встроенным DNS.
  • Часть 2: даже с правилом ufw deny 8080/tcp на месте, curl к опубликованному порту всё равно успешен — демонстрируя, что собственные правила iptables/nftables Docker для опубликованных портов оцениваются независимо от правил ufw, которые управляют только стандартной цепочкой INPUT, не цепочками DOCKER/DOCKER-USER, которыми управляет сам Docker.

Чек-лист диагностики

  • [ ] Подтвердили ли вы, что сбой outsider — это именно сбой разрешения DNS (имя web не резолвится), а не отказ в соединении или таймаут — это сигнал, что проблема в членстве в сети, а не в доступности на уровне IP?
  • [ ] Проверили ли вы, что правило ufw действительно было на месте (ufw status), прежде чем заключить, что оно не сработало, а не просто предположили это?
  • [ ] Можете ли вы объяснить почему правило ufw не применяется — конкретно, в какую цепочку iptables/nftables Docker вставляет собственные правила NAT, и как это связано с порядком обработки цепочек?

Критерии успеха

Вы можете объяснить кому-то ещё, используя вывод этой лабораторной как доказательство, почему «я поставил правило файрвола, чтобы заблокировать этот порт Docker, и оно не сработало» — часто встречающееся, по-настоящему сбивающее с толку, но полностью объяснимое поведение — а не баг Docker.

Очистка / откат

docker rm -f web web2 2>/dev/null
docker network rm lab_net 2>/dev/null
sudo ufw delete deny 8080/tcp 2>/dev/null || true

Убедитесь через docker network ls и docker ps -a, что никаких лабораторных контейнеров или сетей не осталось, прежде чем считать окружение очищенным.