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

Как добавить том в существующий контейнер Docker


Хотя Docker — полезный инструмент для упаковки приложений и управления ими, он также создает множество уникальных проблем, таких как работа с хранимыми данными. Обычно вы добавляете тома в контейнеры в скрипте создания, но что, если вам нужно сделать новые?

Добавление тома в работающий контейнер Docker

К сожалению, это не так просто, как просто добавить новый том. Контейнеры должны иметь свои тома, настроенные при запуске, что означает, что для добавления нового тома необходимо перезапустить контейнер. Несмотря на то, что существует хакерское решение (подробнее об этом ниже), настоятельно рекомендуется в любом случае выполнить перезапуск контейнера.

Это по нескольким причинам. Перезапустить контейнер довольно просто, и для большинства обновлений кода в любом случае требуется перезапуск службы. Отслеживание обновлений в Git — еще один важный фактор, особенно если вы используете Docker Compose, и редактирование сценария запуска намного лучше, чем добавление тома в работающий контейнер вручную.

Если ваша служба настолько велика, что вы беспокоитесь о нескольких минутах (максимум) потенциального запланированного простоя для перезапуска контейнера, вам, вероятно, следует запустить масштабируемое развертывание с несколькими экземплярами, которые можно обновлять независимо. Современные системы автоматического масштабирования должны справляться с этим, поскольку развертывание кода происходит часто.

Если вы хотите добавить том, вам нужно остановить запущенный контейнер:

 docker stop my_container

Создайте новый том, если вам нужно:

docker volume create nginx-config

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

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

Если вы используете Docker Compose, вам будет проще автоматизировать и отслеживать этот процесс, поскольку конфигурация тома обрабатывается через файл настроек. вам нужно будет добавить том в файл docker-compose.yml :

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

Затем вы можете перезапустить службы Docker Compose. В Compose есть команда «перезагрузка», но на самом деле она просто обновляет работающую службу без каких-либо изменений конфигурации. Если вы хотите обновить изображения, вам нужно запустить docker-compose up с флагом --build :

docker-compose up -d --build

Вы также можете заранее вручную запустить docker-compose down, чтобы остановить службы, но в большинстве случаев в этом нет необходимости, если только вы не хотите запускать его с флагом -v , чтобы уничтожить существующие тома.

Клонирование из существующего контейнера

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

Этот метод, вероятно, не является хорошей идеей для большинства людей, так как он требует от вас создания нового изображения каждый раз, когда вы хотите это сделать, и по-прежнему требует простоя. Но если вам нужно добавить том в работающий контейнер, вы можете использовать docker commit, чтобы создать новый образ на основе этого контейнера, а затем клонировать его с новым томом.

Возьмите идентификатор контейнера из docker ps:

docker ps

А затем клонируйте его с помощью commit:

docker commit f88f33c918d2 imagename

Затем вы можете запустить новый образ, заменив старый образ клонированным.

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

Хакерское решение

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

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

Вам нужно будет перейти в каталог хранилища Docker:

cd /var/lib/docker/containers

Здесь будет много папок, соответствующих идентификаторам контейнеров Docker, которые вы можете найти с помощью docker ps. Откройте тот, который соответствует контейнеру, который вы хотите изменить.

Файл конфигурации называется config.v2.json, но он имеет компактный формат и его трудно редактировать. Вы можете установить jq для красивого вывода JSON в командной строке и передать его в новый файл для редактирования:

jq . config.v2.json > tmp.json

Вам нужно будет прокрутить вниз, чтобы найти «MountPoints», который содержит конфигурацию для всех томов и привязки монтирования. Вы можете добавить новый здесь, который должен быть в следующем формате:

  "MountPoints": {
    "/home/container": {
      "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933",
      "Destination": "/home/container",
      "RW": true,
      "Name": "",
      "Driver": "",
      "Type": "bind",
      "Propagation": "rprivate",
      "Spec": {
        "Type": "bind",
        "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933",
        "Target": "/home/container"
      },
      "SkipMountpointCreation": true
    }
  },

Затем, как только это будет сделано, вы можете снова минимизировать JSON обратно в файл конфигурации:

jq -c . tmp.json > config.v2.json

jq – мощная утилита, поэтому, если вы хотите полностью автоматизировать этот процесс, вы можете это сделать.

Затем просто перезапустите службу Docker, чтобы применить изменения:

sudo service docker restart