Как Docker Swarm реализует совместное использование томов?

93

Docker Swarm может управлять двумя типами хранилищ:

volume а также bind

Хотя bindэто не предлагается в документации Docker, поскольку она создает привязку между локальным каталогом (на каждом узле роя) к задаче, volumeреализация не упоминается, поэтому я не понимаю, как тома распределяются между задачами?

  • Как Docker Swarm распределяет тома между узлами?
  • Где хранятся тома (на менеджере? А если менеджеров больше одного?)
  • Нет ли проблем между узлами, если они работают на разных машинах в разных сетях?
  • Он создает VPN?
алессандро308
источник
1
Есть ли у Swarm общие тома? Примерно год назад я имел дело с docker swarm, но я думаю, что swarm НЕ отвечает за совместное использование томов между узлами. Если вы хотите, чтобы ваши узлы использовали один и тот же том, вам необходимо использовать плагины томов, такие как azure volumedriver.
Munchkin

Ответы:

66

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

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

Вам нужен плагин стороннего драйвера, который поддерживает Swarm и гарантирует, что том, который вы создали для служебной задачи, будет доступен на нужном узле в нужное время. Варианты включают использование «Docker для AWS / Azure» и включенного в него драйвера CloudStor или популярного решения REX-Ray с открытым исходным кодом .

Есть много сторонних драйверов громкости, которые вы можете найти в Docker Store .

Брет Фишер
источник
может hadoop действовать как такой общий том?
stackit
55

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

Есть несколько программных решений для распределенного хранения данных, таких как GlusterFS, и у Docker есть одно под названием Infinit, которое еще не является GA, и его разработка отошла на задний план по сравнению с интеграцией Kubernetes в EE.

Типичный результат: вам либо нужно управлять репликацией хранилища в вашем приложении (например, etcd и другие алгоритмы на основе raft), либо вы выполняете монтирование на внешней системе хранения (надеюсь, с ее собственной HA). Существует два варианта монтирования внешней системы хранения: блочное или файловое. Блочное хранилище (например, EBS) обычно имеет более высокую производительность, но его можно установить только на одном узле. Для этого вам обычно понадобится сторонний драйвер подключаемого модуля тома, чтобы предоставить вашему докер-узлу доступ к этому блочному хранилищу. Файловое хранилище (например, EFS) имеет более низкую производительность, но более портативно и может быть одновременно установлено на нескольких узлах, что полезно для реплицируемой службы.

Наиболее распространенным сетевым хранилищем на основе файлов является NFS (это тот же протокол, что и EFS). И вы можете смонтировать это без каких-либо сторонних драйверов плагинов. К сожалению, названный драйвер плагина локального тома, который поставляется с докером, дает вам возможность передавать любые значения, которые вы хотите, команде монтирования с параметрами драйвера, и без параметров по умолчанию он хранит тома в каталоге докера / var / lib / докер / тома. С помощью опций вы можете передать ему параметры NFS, и он даже будет выполнять поиск DNS по имени хоста NFS (чего у вас обычно нет с NFS). Вот пример различных способов монтирования файловой системы NFS с использованием драйвера локального тома:

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=192.168.1.1,rw
        device: ":/path/to/dir"
  ...

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

Другая распространенная проблема, с которой я сталкиваюсь в большинстве случаев использования NFS, - это включение на сервере "корневого сквоша". Это приводит к проблемам с разрешениями, когда контейнеры, работающие с правами root, пытаются записать файлы на том. У вас также есть аналогичные проблемы с разрешениями UID / GID, когда UID / GID контейнера - это тот, который требует разрешений для записи на том, что может потребовать настройки владельца каталога и разрешений на сервере NFS.

BMitch
источник
9

Мое решение для AWS EFS, которое работает:

  1. Создайте EFS (не забудьте открыть порт NFS 2049 в группе безопасности)
  2. Установите пакет nfs-common:

    sudo apt-get install -y nfs-common

  3. Проверьте, работает ли ваш efs:

    mkdir efs-test-point
    sudo chmod go + rw efs-test-point
    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point
    коснитесь efs-test-point / 1.txt
    sudo umount efs-test-point /
    ls -la efs-test-point /

    каталог должен быть пустым

    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point

    ls -la efs-test-point/

    файл 1.txt должен существовать

  4. Настройте файл docker-compose.yml:

    Сервисы:
      sidekiq:
        объемы:
          - uploads_tmp_efs: / home / application / public / uploads / tmp
      ...
    объемы:
      uploads_tmp_efs:
        водитель: местный
        driver_opts:
          тип: nfs
          o: addr = [YOUR_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2
          устройство: [YOUR_EFS_DNS]: /

super_p
источник
6

Мое решение для нашего локально размещенного роя: каждый рабочий узел смонтировал общий ресурс nfs, предоставляемый нашим файловым сервером /mnt/docker-data. Когда я определяю тома в своих сервисах для создания файлов, я устанавливаю для устройства некоторый путь /mnt/docker-data, например:

volumes:
  traefik-logs:
    driver: local
    driver_opts:
      o: bind
      device: /mnt/docker-data/services/traefik/logs
      type: none

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

Если вы внимательно посмотрите на файловую систему узлов, вы увидите, что монтирования к моему файловому серверу создаются под /var/lib/docker/volumes , см. Здесь:

root@node-3:~# df -h
Dateisystem                                                                                                   Größe Benutzt Verf. Verw% Eingehängt auf
[...]
fs.mydomain.com:/srv/shares/docker-data/services/traefik/logs                                 194G    141G   53G   73% /var/lib/docker/volumes/traefik_traefik-logs/_data
тигу
источник