Виртуализация и контейнеры Docker

Отличие контейнеров от виртуальных машин, образы и слои, Dockerfile и его оптимизация, тома и сети, docker compose для многосервисного приложения.

Развёртывание проекта в контейнерах — сильный аргумент на защите: работа запускается у проверяющего одной командой, независимо от того, что установлено на его машине. Разберём, как это устроено.

Виртуальная машина или контейнер

ПризнакВиртуальная машинаКонтейнер
Что виртуализуетсяОборудованиеПроцессы в рамках ядра хоста
Своё ядро ОСДаНет, ядро общее
РазмерГигабайтыДесятки-сотни мегабайт
ЗапускМинутыСекунды
Накладные расходы5-15 %Практически нулевые
ИзоляцияПолнаяНа уровне пространств имён ядра
Разные ОС на одном хостеДаНет, только совместимые с ядром

Контейнер — это не облегчённая виртуальная машина, а изолированный процесс. Изоляцию обеспечивают механизмы ядра Linux: namespaces разделяют видимость процессов, сети и файловой системы, cgroups ограничивают ресурсы. Отсюда и скорость, и ограничение — ядро одно на всех.

Образы и контейнеры

Образ (image) — неизменяемый шаблон, состоящий из слоёв
Контейнер — запущенный экземпляр образа с записываемым слоем сверху

Аналогия: образ — класс, контейнер — объект.
Из одного образа можно запустить сотню контейнеров,
и они разделяют слои образа, не копируя их.
docker images                       # список образов
docker ps                           # запущенные контейнеры
docker ps -a                        # включая остановленные

docker run -d --name web -p 8080:80 nginx    # запустить в фоне
docker logs -f web                  # смотреть вывод
docker exec -it web bash            # войти внутрь
docker stop web && docker rm web    # остановить и удалить

docker build -t myapp:1.0 .         # собрать образ из Dockerfile
docker system prune -a              # убрать всё неиспользуемое

Dockerfile

# Многоступенчатая сборка: в финальный образ не попадают инструменты сборки
FROM node:20-alpine AS builder
WORKDIR /app

# Сначала только манифесты — слой с зависимостями закешируется
COPY package*.json ./
RUN npm ci --only=production

# Затем исходники: их изменение не заставит переустанавливать пакеты
COPY . .

FROM node:20-alpine
WORKDIR /app

# Не root: процесс в контейнере не должен иметь лишних прав
RUN addgroup -S app && adduser -S app -G app

COPY --from=builder --chown=app:app /app/node_modules ./node_modules
COPY --chown=app:app . .

USER app
EXPOSE 3000
ENV NODE_ENV=production

HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget -qO- http://127.0.0.1:3000/ || exit 1

CMD ["node", "src/server.js"]
Порядок команд определяет скорость пересборки. Каждая инструкция — слой, и при изменении файла все последующие слои пересобираются. Копирование package.json до исходников — стандартный приём: правка кода не вызывает переустановку зависимостей, и сборка занимает секунды вместо минут.

Тома и данные

# Записываемый слой контейнера исчезает вместе с ним
docker run -d --name db postgres:16
docker rm -f db                     # данные потеряны

# Именованный том — данные живут отдельно от контейнера
docker volume create pgdata
docker run -d --name db \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

# Привязка каталога хоста — удобно при разработке
docker run -d -v $(pwd)/src:/app/src -p 3000:3000 myapp:1.0

docker volume ls
docker volume inspect pgdata

Сети

Docker Compose

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/appdb
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      retries: 5

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - app

volumes:
  pgdata:
docker compose up -d                # поднять всё
docker compose logs -f app          # логи одного сервиса
docker compose ps                   # состояние
docker compose exec db psql -U app appdb
docker compose down                 # остановить, тома сохранятся
docker compose down -v              # снести вместе с данными
Файл init.sql, смонтированный в /docker-entrypoint-initdb.d/, выполняется при первом создании базы. Это удобно для курсовой: схема и тестовые данные разворачиваются автоматически, и проверяющему достаточно одной команды.

Частые ошибки

Что показать в курсовой

  1. Обоснование выбора контейнеризации: воспроизводимость среды, изоляция, простота развёртывания.
  2. Схему архитектуры: какие сервисы, как связаны, где хранятся данные.
  3. Dockerfile с комментариями и объяснением порядка слоёв.
  4. docker-compose.yml для всего приложения целиком.
  5. Инструкцию по запуску в две-три команды.
  6. Сравнение размера образа до и после многоступенчатой сборки — обычно разница кратная.
  7. Замер времени развёртывания с нуля.

Частые вопросы

Можно ли запустить Windows-контейнер на Linux?

Нет: ядро у контейнера общее с хостом. Windows-контейнеры работают только на Windows, Linux-контейнеры — на Linux. На Windows и macOS Docker поднимает скрытую Linux-виртуальную машину.

Контейнер безопаснее виртуальной машины?

Нет, изоляция слабее — ядро общее, и уязвимость в нём затрагивает все контейнеры. Для ненадёжного кода надёжнее виртуальная машина. Контейнеры выбирают за скорость и удобство, а не за изоляцию.

Зачем нужен образ на alpine?

Он весит около 5 МБ против 100 МБ у обычного дистрибутива, поэтому итоговый образ в разы меньше и содержит меньше потенциально уязвимых пакетов. Минус — musl вместо glibc, из-за чего отдельные библиотеки требуют пересборки.

Читайте также

Сделаем работу по этой теме

Опишите задачу — ответим в течение 15 минут в личных сообщениях ВКонтакте, назовём срок и цену. Предоплаты за оценку нет.

  • Оценка заявки бесплатно
  • Правки по замечаниям преподавателя
  • Работы по всем техническим и IT-дисциплинам

Нажимая кнопку, вы соглашаетесь на обработку указанных данных для ответа на заявку.

Написать