Постоянное хранилище в контейнерахPersistent Storage in Containers

В некоторых случаях важно, чтобы приложение могло сохранять данные в контейнере или чтобы в контейнер можно было добавить файлы, которые не были включены во время его сборки.You may have cases where it's important that an app be able to persist data in a container, or you want to show files into a container that were not included at container build-time. Постоянное хранилище можно предоставить контейнерам несколькими способами:Persistent storage can be given to containers in a couple ways:

  • Привязки подключенийBind mounts
  • именованные тома.Named volumes

В документации Docker доступен отличный обзор использования томов, так что сначала лучше прочитать его.Docker has a great overview of how to use volumes so it's best to read that first. Остальная часть этого документа посвящена различиям между Linux и Windows и примерам для Windows.The rest of this page focuses on differences between Linux & Windows and provides examples on Windows.

Привязки подключенийBind Mounts

Привязка подключения позволяет контейнеру использовать каталог совместно с узлом.Bind mounts allow a container to share a directory with the host. Это полезно, если требуется место для хранения файлов на локальном компьютере, которые доступны при перезапуске контейнер, или если необходимо совместно использовать их с несколькими контейнерами.This is useful if you want a place to store files on the local machine that are available if you restart a container, or want to share it with multiple containers. Чтобы запустить контейнер на нескольких компьютерах с доступом к тем же файлам, следует использовать именованный том или SMB-подключение.If you want the container to run on multiple machines with access to the same files, then a named volume or SMB mount should be used instead.

РазрешенияPermissions

Модель разрешений, используемая для привязки подключений зависит от уровня изоляции контейнера.The permission model used for bind mounts varies based on the isolation level for your container.

Для контейнеров, использующих изоляцию Hyper-V, применяется простая модель разрешений только на чтение или на чтение и запись.Containers using Hyper-V isolation use a simple read-only or read-write permission model. Доступ к файлам на узле осуществляется с помощью учетной записи LocalSystem.Files are accessed on the host using the LocalSystem account. Если вам отказано в доступе в контейнере, убедитесь, что у LocalSystem есть доступ к каталогу на узле.If you get access denied in the container, make sure LocalSystem has access to that directory on the host. Если используется флаг только для чтения, изменения, внесенные на томе внутри контейнера, не будут отображаться или сохраняться для каталога на узле.When the read only flag is used, changes made to the volume inside the container will not be visible or persisted to the directory on the host.

Контейнеры Windows, использующие изоляцию процессов, немного отличаются, поскольку они используют идентификатор процесса в контейнере для доступа к данным (списки управления доступом учитываются).Windows containers using process isolation are slightly different because they use the process identity within the container to access data, meaning that file ACLs are honored. Идентификатор процесса, выполняемого в контейнере (по умолчанию «ContainerAdministrator» в Windows Server Core и «ContainerUser» в контейнерах Nano Server) будет использоваться для доступа к файлам и каталогам на подключенном томе вместо LocalSystem, и ему потребуется предоставить доступ для использования данных.The identity of the process running in the container ("ContainerAdministrator" on Windows Server Core and "ContainerUser" on Nano Server containers, by default) will be used to access to the files and directories in the mounted volume instead of LocalSystem, and will need to be granted access to use the data.

Так как эти идентификаторы существуют только в контексте контейнера, а не на узле, где хранятся файлы, вам следует использовать известную группу безопасности, например Authenticated Users, при настройке списков управления доступом для предоставления доступа к контейнерам.Since these identities only exist within the context of the container--not on the host where the files are stored--you should use a well-known security group such as Authenticated Users when configuring the ACLs to grant access to the containers.

Предупреждение

Не используйте привязку подключения конфиденциальных каталогов, таких как C:\, в недоверенных контейнерах.Do not bind-mount sensitive directories such as C:\ into an untrusted container. Это позволит ему изменить файлы на узле, к которым обычно нет доступа, и может создать брешь в системе безопасности.This would allow it to change files on the host that it would not normally have access to and could create a security breach.

Пример использования:Example usage:

  • docker run -v c:\ContainerData:c:\data:RO в случае доступа только для чтения;docker run -v c:\ContainerData:c:\data:RO for read-only access
  • docker run -v c:\ContainerData:c:\data:RW в случае доступа для чтения и записи;docker run -v c:\ContainerData:c:\data:RW for read-write access
  • docker run -v c:\ContainerData:c:\data в случае доступа для чтения и записи (по умолчанию).docker run -v c:\ContainerData:c:\data for read-write access (default)

Символические ссылки разрешаются в контейнере.Symlinks are resolved in the container. При привязке подключения пути узла к контейнеру, который является символической ссылкой или содержит символическую ссылку, у контейнера не будет доступа к этим ресурсам.If you bind-mount a host path to a container that is a symlink, or contains symlinks - the container will not be able to access them.

SMB-подключенияSMB Mounts

В Windows Server версии 1709 и более поздних доступна функция, "Глобальное сопоставление SMB", которая позволяет подключить общую папку SMB на узле, а затем передать каталоги из этой папки в контейнер.On Windows Server version 1709 and later, feature called "SMB Global Mapping" makes it possible to mount a SMB share on the host, then pass directories on that share into a container. Контейнер не требуется настраивать с определенным сервером, общим ресурсом, именем пользователя или паролем — все данные обрабатываются на узле.The container doesn't need to be configured with a specific server, share, username or password - that's all handled on the host instead. Контейнер будет работать так же, как если бы он был локальным хранилищем.The container will work the same as if it had local storage.

Этапы настройкиConfiguration Steps

  1. На узле контейнера глобально сопоставьте удаленную общую папку SMB.On the container host, globally map the remote SMB share:

    $creds = Get-Credential
    New-SmbGlobalMapping -RemotePath \\contosofileserver\share1 -Credential $creds -LocalPath G:
    

    Эта команда будет использовать учетные данные для проверки подлинности на удаленном сервере SMB.This command will use the credentials to authenticate with the remote SMB server. Затем сопоставьте путь к удаленной общей папке с буквой диска G: (или любой другой доступной буквой диска).Then, map the remote share path to G: drive letter (can be any other available drive letter). Контейнеры, созданные на этом узле контейнера, теперь могут сопоставить свои тома данных с путем на диске G:.Containers created on this container host can now have their data volumes mapped to a path on the G: drive.

    Примечание

    При использовании глобального сопоставления SMB для контейнеров всем пользователям на узле контейнера предоставляется доступ к удаленной общей папке.When using SMB global mapping for containers, all users on the container host can access the remote share. Все приложения, работающие на узле контейнера, также получат доступ к сопоставленной удаленной общей папке.Any application running on the container host will also have access to the mapped remote share.

  2. Создайте контейнеры с томами данных, сопоставленными с глобально подключенной общей папкой SMB: docker run -it --name demo -v g:\ContainerData:c:\AppData1 mcr.microsoft.com/windows/servercore:ltsc2019 cmd.exeCreate containers with data volumes mapped to globally mounted SMB share docker run -it --name demo -v g:\ContainerData:c:\AppData1 mcr.microsoft.com/windows/servercore:ltsc2019 cmd.exe

    Внутри контейнера папка c:\AppData1 будет сопоставлена с каталогом "ContainerData" удаленной общей папки.Inside the container, c:\AppData1 will then be mapped to the remote share’s "ContainerData" directory. Все данные, хранящиеся в глобально сопоставленной удаленной общей папке, будут доступны в приложениях внутри контейнера.Any data stored on globally mapped remote share will be available to applications inside the container. Несколько контейнеров могут получить доступ к общим данным для чтения и записи с помощью одной команды.Multiple containers can get read/write access to this shared data with the same command.

Такая поддержка глобального сопоставления SMB является клиентской функцией SMB, которая может работать на любом совместимом SMB-сервере, в том числе:This SMB global mapping support is SMB client-side feature which can work on top of any compatible SMB server including:

  • масштабируемый файловый сервер на базе локальных дисковых пространств (S2D) или традиционного хранилища SAN;Scaleout File Server on top of Storage Spaces Direct (S2D) or a traditional SAN
  • файлы Azure (общий ресурс SMB);Azure Files (SMB share)
  • традиционный файловый сервер;Traditional File Server
  • сторонняя реализация протокола SMB (например, устройств NAS).3rd party implementation of SMB protocol (ex: NAS appliances)

Примечание

Глобальное сопоставление SMB не поддерживает общие папки DFS, DFSN, DFSR в Windows Server версии 1709.SMB global mapping does not support DFS, DFSN, DFSR shares in Windows Server version 1709.

Именованные томаNamed Volumes

Именованные тома позволяют создать том по имени, назначить его контейнеру и повторно использовать его повторно с тем же именем.Named volumes allow you to create a volume by name, assign it to a container, and reuse it later by the same name. Вам не требуется отслеживать фактический путь его создания, а только имя.You don't need to keep track of the actual path of where it was created, just the name. Подсистема Docker в Windows использует встроенный подключаемый модуль именованных томов, который может создавать тома на локальном компьютере.The Docker engine on Windows has a built-in named volume plugin that can create volumes on the local machine. Если вы хотите использовать именованный тома на нескольких компьютерах, дополнительные подключаемый модуль не требуется.An additional plugin is required if you want to use named volumes on multiple machines.

Примеры:Example steps:

  1. docker volume create unwound — создание тома с именем "unwound".docker volume create unwound - Create a volume named 'unwound'
  2. docker run -v unwound:c:\data microsoft/windowsservercore — запуск контейнера с томом, сопоставленным с каталогом c:\data.docker run -v unwound:c:\data microsoft/windowsservercore - Start a container with the volume mapped to c:\data
  3. Запись некоторых файлов в каталог c:\data в контейнере, а затем остановка работы контейнера.Write some files to c:\data in the container, then stop the container
  4. docker run -v unwound:c:\data microsoft/windowsservercore — запуск нового контейнера.docker run -v unwound:c:\data microsoft/windowsservercore - Start a new container
  5. Выполнение dir c:\data в новом контейнере —- файлы по-прежнему там.Run dir c:\data in the new container - the files are still there

Примечание

Windows Server будет преобразовывать целевые пути (пути внутри контейнера) в нижний регистр. Таким образом использование -v unwound:c:\MyData или -v unwound:/app/MyData в контейнерах Linux приведет к созданию внутри сопоставляемых (и созданных в случае отсутствия) контейнеров Linux каталога c:\mydata или /app/mydata.Windows Server will convert target pathnames (the path inside of the container) to lower-case; i. e. -v unwound:c:\MyData, or -v unwound:/app/MyData in Linux containers, will result in a directory inside the container of c:\mydata, or /app/mydata in Linux containers, being mapped (and created, if not existent).