itmo_conspects

Лекция 6. Контейнеризация

Контейнеризация - абстракция вокруг группы процессов, позволяющая их изолировать и предоставляющая виртуализацию на уровне операционной системы. В отличии от полной виртуализации операционной системы, контейнеризация не загружают все ядро ОС целиком, а лишь использует механизмы ядра Linux - в частности для этого используются две фичи Linux: контрольные группы (cgroups) и пространства имен (namespaces)

Пространства имен - набор инструментов (функции ядра) для контроля того, что видит отдельный процесс и какие действия может выполнять как процесс, так и пользователь внутри пространства имен

Раньше процесс можно было ограничивать только по процессорному времени. С появлением контрольных групп стало возможным ограничивать использование ресурсов сетевых, памяти и так далее. Контрольные группы включают в себя контроллеры для учета и управления ресурсами

Самая популярная утилита для управления контейнерами - Docker.
Docker, помимо реализации пространства имен и контрольных групп, включает в себя управление образами, CLI для работы с контейнером и прочее

Образ (Image) - это по сути архив с предустановленными заранее программами и библиотеками для работы приложения. Образ может определяться специальным файлом с названием Dockerfile, например:

# Делаем форк на основе готового образа с установленным Python
FROM python:3.12
WORKDIR /usr/local/app

# Устанавливаем зависимости приложения
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Копируем исходники
COPY src ./src
EXPOSE 5000

# Создает нового пользователя, чтобы не запускать приложение от лица root
RUN useradd app
USER app

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]

Каждая строчка в файле Dockerfile называется слоем (layer). Чтобы собрать из Dockerfile полноценный образ, воспользуемся командой

docker build -t my-python-app .

В Docker Desktop можно посмотреть на слои образа:

alt text

Также можно посмотреть публичные образы в Docker Hub.

Собранный образ теперь можно запустить в контейнере.
В файле docker-compose.yml можно указать конфигурацию контейнера

# Версия параметров Compose
version: "2"

services:
  postgres:
    # Имя образа (в данном случае с готовым PostgreSQL 14)
    image: postgres:14

    # Имя контейнера
    container_name: postgres_db

    # Переназначение портов между контейнером и хостом
    ports:
      - "5432:5432"

    # Привязка файловой системы контейнера с файловой системой хоста
    volumes:
      - ./scripts:/docker-entrypoint-initdb.d
      - ./pgdata:/var/lib/postgresql/data

    # Переменные среды: имя, пароль и название БД в PostgreSQL
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypass
      POSTGRES_DB: mydb

Чтобы запустить контейнер, воспользуемся командой

docker compose up

в каталоге с docker-compose.yml. Флаг -d запустит контейнер в фоновом режиме. Команда

docker compose down

прервет выполнение в контейнере, а команда

docker compose stop

остановит контейнер с возможностью возобновления. При помощи

docker ps

можно посмотреть все запущенные контейнеры.

В примере выше мы связали локальную папку ./scripts с /docker-entrypoint-initdb.d. При запуске PostgreSQL выполнит все .sql и .sh-скрипты, находящиеся в ней, таким образом, можно задать начальную схему базы данных