Поиск по сайту:

Как справиться с персистентностью и хранением контейнеров Docker


Используйте внешнюю базу данных или хранилище объектов

Это метод, который порекомендует большинство людей. Хранение состояния в виде файла на диске не соответствует модели Docker, и хотя это можно сделать, всегда лучше подумать — действительно ли вам это нужно?

Например, предположим, что вы запускаете веб-приложение в Docker, которому необходимо хранить данные в базе данных. Нет особого смысла запускать MySQL в контейнере Docker, поэтому вместо этого вам следует развернуть MySQL на RDS или EC2, а контейнер Docker подключиться к нему напрямую. Контейнер Docker полностью не имеет состояния, как и должно быть; его можно остановить, запустить или ударить кувалдой, а на его место можно раскрутить новый, и все это без потери данных. Используя разрешения IAM, это можно сделать безопасно, полностью в вашем VPC.

Если вам действительно нужно хранить файлы, такие как фотографии и видео, загруженные пользователями, вам действительно следует использовать сервис AWS Simple Storage Service (S3). Это намного дешевле, чем хранилище на основе EBS, и гораздо дешевле, чем хранилище EFS, которое является вашим основным выбором для общей файловой системы для контейнеров ECS. Вместо того, чтобы хранить файл на диске, вы загружаете его непосредственно в S3. Этот метод также позволяет выполнять дополнительную обработку загруженного содержимого с помощью функций Lambda, например сжатие изображений или видео, что может значительно сэкономить на затратах на пропускную способность.

Простое решение: смонтировать диск в контейнер

У Docker есть два способа добиться постоянства: монтирование тома и монтирование с привязкой. Связывание позволяет вам монтировать определенное место в файловой системе вашего сервера в место внутри контейнера Docker. Эта ссылка может быть доступна только для чтения, но также и для чтения/записи, когда файлы, записанные контейнером Docker, будут сохраняться на диске.

Вы можете привязать отдельные каталоги хоста к целевым каталогам в контейнере Docker, что полезно, но рекомендуемый метод — создать новый «том», управляемый Docker. Это упрощает резервное копирование, передачу и совместное использование томов между разными экземплярами контейнеров.

Предупреждение. Если у вас нет прямого доступа к серверу, на котором вы используете Docker, как в случае с управляемыми развертываниями, такими как Elastic Container Service (ECS) AWS и Kubernetes, вы Я хочу быть осторожным с этим. Он привязан к собственному дисковому пространству сервера, которое обычно является эфемерным. Вы захотите использовать внешнее хранилище файлов, такое как EFS, чтобы добиться реального сохранения с помощью ECS (подробнее об этом позже).

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

Вы можете создать новый том из командной строки с помощью:

docker volume create nginx-config

А затем, когда вы собираетесь запускать контейнер Docker, свяжите его с целью в контейнере с помощью флага --mount :

docker run -d 
--name devtest 
--mount source=nginx-config,target=/etc/nginx 
nginx:latest

Если вы запустите docker inspect , вы увидите том, указанный в разделе Mounts .

Если вы используете Docker Compose, настройка также проста. Просто добавьте запись volumes для каждой имеющейся у вас службы контейнеров, а затем сопоставьте имя тома с местоположением в гостевой системе. Вам также потребуется предоставить список томов в ключе верхнего уровня volumes для предоставления Compose.

version: "3.0"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - nginx-config:/etc/nginx/
volumes:
  nginx-config:

Это автоматически создаст том для этого Compose. Если вы хотите использовать готовый том вне Compose, укажите external: true в конфигурации тома:

volumes:
  cms-content:
    external: true

Если вы хотите вместо этого просто выполнить монтирование с привязкой и не возиться с томами, просто введите путь вместо имени тома и не определяйте имена томов.

version: "3.0"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - /docker/nginx-config/:/etc/nginx/

Вы можете прочитать полную документацию Docker по использованию томов с Compose, если ваш вариант использования требует чего-то более конкретного, чем это.

Для управляемых развертываний используйте общую файловую систему (AWS EFS)

Если вы развертываете на AWS ECS, вы не сможете использовать обычную привязку или монтирование тома, потому что после закрытия контейнера вы, вероятно, не будете работать на той же машине при следующем запуске. , победив цель настойчивости.

Однако постоянства по-прежнему можно добиться с помощью другого сервиса AWS — эластичной файловой системы (EFS). EFS — это общая сетевая файловая система. Вы можете подключить его к нескольким серверам EC2, и данные, к которым осуществляется доступ, будут синхронизироваться между ними. Например, вы можете использовать это для размещения статического контента и кода для своего веб-сайта, а затем запустить все свои рабочие узлы на ECS для обработки фактического обслуживания вашего контента. Это позволяет обойти запрет на хранение данных на диске, поскольку монтирование тома привязано к внешнему диску, который сохраняется во всех развертываниях ECS.

Чтобы настроить это, вам нужно создать файловую систему EFS. Это довольно просто, и это можно сделать из консоли управления EFS, но вы должны записать идентификатор тома, так как он понадобится вам для работы с томом.

Если вам нужно вручную добавить или изменить файлы в томе EFS, вы можете подключить его к любому инстансу EC2. Вам потребуется установить amazon-efs-utils:

sudo yum install -y amazon-efs-utils

А затем смонтируйте его с помощью следующей команды, используя идентификатор:

sudo mount -t efs fs-12345678:/ /mnt/efs

Таким образом, вы можете напрямую просматривать и редактировать содержимое тома EFS, как если бы это был другой жесткий диск на вашем сервере. Вы должны убедиться, что у вас установлены nfs-utils, чтобы все это работало правильно.

Далее вам нужно будет подключить ECS к этому тому. Создайте новое определение задачи в консоли управления ECS. Прокрутите вниз и выберите «Настроить через JSON». Затем замените пустой ключ «volumes» следующим JSON, добавив в конце ключ «family»:

"volumes": [
        {
            "name": "efs-demo",
            "host": null,
            "dockerVolumeConfiguration": {
                "autoprovision": true,
                "labels": null,
                "scope": "shared",
                "driver": "local",
                "driverOpts": {
                    "type": "nfs",
                    "device": ":/",
                    "o": "addr=fs-XXXXXX.efs.us-east-1.amazonaws.com,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport"
                }
            }
        }
    ],
"family":"nginx",

Замените fs-XXXXXX.efs.us-east-1.amazonaws.com на реальный адрес тома EFS. Вы должны увидеть новый том:

Вы можете использовать это в своем определении контейнера в качестве точки монтирования. Выберите «Добавить контейнер» (или отредактируйте существующий) и в разделе «Хранилище и ведение журнала» выберите вновь созданный том и укажите путь к контейнеру.

Сохраните определение задачи, и когда вы запустите кластер с этим новым определением, все контейнеры смогут получить доступ к вашей общей файловой системе.