1. Обзор
В этой статье мы рассмотрим, как работать с Docker для управления базами данных.
В первой главе мы рассмотрим установку базы данных на нашей локальной машине. Затем мы узнаем, как сохранение данных работает в разных контейнерах.
В заключение мы обсудим надежность реализации баз данных в производственных средах Docker.
2. Локальный запуск образа Docker
2.1. Начиная со стандартного образа Docker
Во-первых, нам нужно установить Docker Desktop . Затем мы должны найти существующий образ нашей базы данных в Docker Hub . Как только мы найдем его, мы выберем команду docker pull
в правом верхнем углу страницы.
В этом уроке мы будем работать с PostgreSQL, поэтому команда:
$docker pull postgres
Когда загрузка будет завершена, команда запуска docker
создаст работающую базу данных в контейнере Docker . Для PostgreSQL переменная окружения POSTGRES_PASSWORD
должна быть указана с опцией -e :
$docker run -e POSTGRES_PASSWORD=password postgres
Далее мы проверим соединение с контейнером базы данных.
2.2. Подключение Java-проекта к базе данных
Давайте попробуем простой тест. Мы подключим локальный проект Java к базе данных, используя источник данных JDBC. Строка подключения должна использовать порт PostgreSQL 5432
по умолчанию на локальном хосте
:
jdbc:postgresql://localhost:5432/postgres?user=postgres&password=password
Ошибка должна сообщить нам, что порт не открыт. Действительно, база данных прослушивает соединения внутри контейнерной сети, а наш Java-проект выполняется вне ее.
Чтобы исправить это, нам нужно сопоставить порт контейнера с нашим локальным
портом . Мы будем использовать порт 5432 по умолчанию для PostgreSQL:
$docker run -p 5432:5432 -e POSTGRES_PASSWORD=password postgres
Теперь соединение работает, и мы должны иметь возможность использовать наш источник данных JDBC.
2.3. Запуск SQL-скриптов
Теперь мы можем подключиться к нашей базе данных из оболочки, например, для запуска сценария инициализации.
Во-первых, давайте найдем идентификатор нашего работающего контейнера:
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
65d9163eece2 postgres "docker-entrypoint.s…" 27 minutes ago Up 27 minutes 0.0.0.0:5432->5432/tcp optimistic_hellman
Затем мы запустим команду docker exec
с интерактивной опцией -it
, чтобы запустить оболочку внутри контейнера :
$docker exec -it 65d9163eece2 bash
Наконец, мы можем подключиться к экземпляру базы данных с помощью клиента командной строки и вставить наш SQL-скрипт:
root@65d9163eece2:/# psql -U postgres
postgres=#CREATE DATABASE TEST;
CREATE TABLE PERSON(
ID INTEGER PRIMARY KEY,
FIRST_NAME VARCHAR(1000),
LAST_NAME VARCHAR(1000)
);
...
Например, если у нас есть большой файл дампа для загрузки, мы должны избегать копирования и вставки. Вместо этого мы можем запустить команду импорта непосредственно с хоста с помощью команды docker exec
:
$docker exec 65d9163eece2 psql -U postgres < dump.sql
3. Сохраняйте данные с помощью тома Docker
3.1. Зачем нам объемы?
Наша базовая настройка будет работать до тех пор, пока мы используем один и тот же контейнер, с остановкой/запуском контейнера докеров
каждый раз, когда нам нужно перезагрузиться. Если мы снова используем docker run
, будет создан новый пустой контейнер, и мы потеряем наши данные . Действительно, Docker по умолчанию сохраняет данные во временном каталоге.
Теперь мы узнаем, как изменить это сопоставление томов.
3.2. Настройка томов Docker
Первая задача — проверить наш контейнер, чтобы увидеть, какой том используется нашей базой данных:
$docker inspect -f "{{ .Mounts }}" 65d9163eece2
[{volume f1033d3 /var/lib/docker/volumes/f1033d3/_data /var/lib/postgresql/data local true }]
Мы видим, что том f1033d3
сопоставил каталог контейнера /var/lib/postgresql/data
с временным каталогом /var/lib/docker/volumes/f1033d3/_data,
созданным в файловой системе хоста.
Нам нужно изменить это сопоставление, добавив параметр -v
к команде запуска docker,
которую мы использовали в главе 2.1:
$docker run -v C:\docker-db-volume:/var/lib/postgresql/data -e POSTGRES_PASSWORD=password postgres
Теперь мы можем видеть файлы базы данных, созданные в каталоге C:\docker-db-volume
. Мы можем найти расширенную настройку тома в этой специальной статье .
В результате каждый раз, когда мы используем команду запуска docker
,
данные будут сохраняться вместе с различными запусками контейнера.
Кроме того, мы можем захотеть поделиться конфигурацией между членами команды или в разных средах. Мы можем использовать файл Docker Compose, который каждый раз будет создавать новые контейнеры. В этом случае объемы обязательны.
В следующей главе будет рассмотрено конкретное использование базы данных Docker в производственной среде.
4. Работа с Docker в продакшене
Docker Compose отлично подходит для совместного использования конфигурации и управления контейнерами как службами без сохранения состояния. Если служба выходит из строя или не может справиться с рабочей нагрузкой, мы можем настроить Docker Compose для автоматического создания новых контейнеров. Это очень полезно для создания производственного кластера для серверных частей REST, которые по своей конструкции не имеют состояния.
Однако базы данных сохраняют состояние, и управление ими более сложное : давайте рассмотрим различные контексты.
4.1. База данных с одним экземпляром
Предположим, мы создаем некритическую среду для тестирования или производства, которая допускает периоды простоя (во время развертывания, резервного копирования или сбоя).
В этом случае нам не нужен высокодоступный кластер, и мы можем просто использовать Docker Compose для базы данных с одним экземпляром:
- Мы можем использовать простой том для хранения данных, потому что контейнеры будут выполняться на одной машине.
- Мы можем ограничить его запуском одного контейнера за раз, используя глобальный режим .
Давайте посмотрим на минималистичный рабочий пример:
version: '3'
services:
database:
image: 'postgres'
deploy:
mode: global
environment:
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes:
- "C:/docker-db-volume:/var/lib/postgresql/data"
Используя эту конфигурацию, наше производство будет создавать только один контейнер за раз и повторно использовать файлы данных из нашего каталога C:\docker-db-volume .
Однако в этой конфигурации еще более важно делать регулярные резервные копии. В случае ошибки конфигурации этот каталог может быть стерт или поврежден контейнером .
4.2. Реплицированные базы данных
Теперь предположим, что наша производственная среда критична.
В этом случае инструменты оркестрации, такие как Docker Swarm и Kubernetes , полезны для контейнеров без сохранения состояния: они предлагают вертикальную и горизонтальную кластеризацию с возможностями балансировки нагрузки, аварийного переключения и автоматического масштабирования.
К сожалению, поскольку наши контейнеры базы данных сохраняют состояние, эти решения не предоставляют механизм репликации томов.
С другой стороны, создавать самодельные конфигурации опасно, поскольку это может привести к серьезной потере данных. Например:
- Использование общего хранилища, такого как NFS или NAS, для томов не может гарантировать отсутствие потери данных при перезапуске базы данных в другом экземпляре.
- В кластерах master-slave распространенной ошибкой является позволить оркестрации Docker выбрать более одного главного узла , что приведет к повреждению данных.
На данный момент наши различные варианты:
- Не используйте Docker для базы данных и реализуйте специфичный для базы данных или аппаратный механизм репликации.
- Не используйте Docker для базы данных и подпишитесь на решения «платформа как услуга», такие как OpenShift, Amazon AWS или Azure.
- Используйте специфичный для Docker механизм репликации, такой как KubeDB и Portworx.
5. Вывод
В этой статье мы рассмотрели базовую конфигурацию, которая подходила для разработки, тестирования и некритического производства.
Наконец, мы пришли к выводу, что у Docker есть недостатки при использовании в средах с высокой доступностью. Поэтому его следует избегать или сочетать с решениями, специализирующимися на кластерах баз данных.