Almacenamiento persistente en contenedores

Puede haber casos en los que sea importante que una aplicación pueda conservar los datos en un contenedor o en los que quieras mostrar los archivos en un contenedor que no se incluyeron en el tiempo de compilación del contenedor. El almacenamiento persistente se puede proporcionar a los contenedores de un par de maneras:

  • Enlazar montajes
  • Volúmenes con nombre

Docker tiene una excelente introducción de cómo usar volúmenes por lo que es mejor leerla primero. El resto de esta página se centra en las diferencias entre Linux y Windows y proporciona ejemplos en Windows.

Enlazar montajes

Enlazar montajes permite que un contenedor comparta un directorio con el host. Esto es útil si quieres un lugar para almacenar archivos en la máquina local que están disponibles si reinicias un contenedor o quieres compartirlos con varios contenedores. Si quieres que el contenedor se ejecute en varias máquinas con acceso a los mismos archivos, debe usarse en su lugar un volumen con nombre o el montaje SMB.

Nota:

No se admite el montaje de enlace directamente en volúmenes compartidos de clúster (CSV), las máquinas virtuales que funcionan como host de contenedores se pueden ejecutar en un volumen CSV.

Permisos

El modelo de permiso utilizado para enlazar montajes varía según el nivel de aislamiento de tu contenedor.

Los contenedores que usan el aislamiento de Hyper-V utilizan un modelo simple de permisos de solo lectura o de lectura y escritura. Se acceden a los archivos en el host mediante la cuenta LocalSystem. Si obtienes acceso denegado en el contenedor, asegúrate de que LocalSystem tenga acceso a ese directorio en el host. Cuando se usa la marca de solo lectura, los cambios realizados en el volumen dentro del contenedor no se mostrarán ni permanecerán en el directorio del host.

Los contenedores de Windows con aislamiento de procesos son ligeramente diferentes, ya que usan la identidad del proceso dentro del contenedor para acceder a datos, lo que significa que se aceptan las ACL de archivos. La identidad del proceso que se ejecuta en el contenedor ("ContainerAdministrator" en Windows Server Core y "ContainerUser" en contenedores de Nano Server, de manera predeterminada) se utilizará para tener acceso a los archivos y directorios en el volumen montado en lugar de LocalSystemy necesitará tener acceso para usar los datos.

Dado que estas identidades solo existen en el contexto del contenedor, no en el host donde se almacenan los archivos, debes usar un grupo de seguridad conocido, como Authenticated Users al configurar las ACL para tener acceso a los contenedores.

Advertencia

No unas mediante enlace directorios confidenciales, como por ejemplo, C:\ en un contenedor que no es de confianza. Esto le permitiría cambiar archivos en el host al que normalmente no tendría acceso y podría crear una infracción de seguridad.

Ejemplo de uso:

  • docker run -v c:\ContainerData:c:\data:RO para acceso de solo lectura
  • docker run -v c:\ContainerData:c:\data:RW para acceso de lectura y escritura
  • docker run -v c:\ContainerData:c:\data para acceso de lectura y escritura (opción predeterminada)

Symlinks se resuelven en el contenedor. Si unes mediante enlace una ruta de acceso de host a un contenedor que es un symlink o incluye symlinks: el contenedor no podrá tener acceso a ellos.

Montajes de SMB

En Windows Server, versión 1709 y posteriores, una característica denominada "Asignación global de SMB" hace posible montar un recurso compartido de SMB en el host y luego pasar los directorios del recurso compartido a un contenedor. El contenedor no debe configurarse con un servidor, recurso compartido, nombre de usuario o contraseña en concreto: todo se administra en el host en su lugar. El contenedor funcionará de la misma forma que si tuviera el almacenamiento local.

Pasos de configuración

  1. En el host de contenedor, asigna globalmente el recurso compartido SMB remoto:

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

    Este comando usará las credenciales para autenticarse en el servidor SMB remoto. Después asigna la ruta de acceso de recurso compartido remoto a la letra de unidad G: (puede ser cualquier otra letra de unidad disponible). Los contenedores creados en este host del contenedor ahora pueden tener sus volúmenes de datos asignados a una ruta de acceso en la unidad G:.

    Nota

    Al usar la asignación global de SMB para contenedores, todos los usuarios en el host del contenedor pueden acceder al recurso compartido remoto. Cualquier aplicación que se ejecuta en el host del contenedor también tendrá acceso al recurso compartido remoto asignado.

  2. Cree contenedores con volúmenes de datos asignados a Docker de recurso compartido de SMB montado globalmente. Ejecute -it --name demo -v g:\ContainerData:c:\AppData1 mcr.microsoft.com/windows/servercore:ltsc2019 cmd.exe.

    Dentro del contenedor, c:\AppData1 se asignará al directorio "ContainerData" del recurso compartido remoto. Todos los datos almacenados en el recurso compartido remoto asignado globalmente estarán disponibles para aplicaciones dentro del contenedor. Varios contenedores pueden obtener acceso de lectura y escritura a estos datos compartidos con el mismo comando.

Esta compatibilidad de asignación global de SMB es una característica de cliente de SMB que puede funcionar en la parte superior de cualquier servidor SMB compatible, entre los que se incluyen:

  • Servidor de archivos de escalabilidad horizontal en la parte superior de Storage Spaces Direct (S2D) o una SAN tradicional
  • Azure Files (recurso compartido de SMB)
  • Servidor de archivos tradicional
  • Implementación de terceros del protocolo SMB (ejemplo: dispositivos NAS)

Nota

La asignación global de SMB no admite carpetas de espacios de nombres DFS (DFSN). Por ejemplo, si asigna un recurso compartido raíz DFSN con New-SmbGlobalMapping -LocalPath Z: -RemotePath \\contoso.com\share1', al leer los destinos de carpeta de la raíz se devolverá el error "No se puede acceder a la ubicación de red".

Volúmenes con nombre

Los volúmenes con nombre te permiten crear un volumen según el nombre, asignarle a un contenedor y reutilizarlo más adelante con el mismo nombre. No tienes que realizar un seguimiento de la ruta de acceso real de dónde se creó, solo el nombre. Docker Engine en Windows tiene un complemento de volumen con nombre integrado que puede crear volúmenes en la máquina local. Un complemento adicional es necesario si quieres usar volúmenes con nombre en varias máquinas.

Pasos de ejemplo:

  1. docker volume create unwound: Crear un volumen denominado "unwound"
  2. docker run -v unwound:c:\data microsoft/windowsservercore: Iniciar un contenedor con el volumen asignado a c:\data.
  3. Escribir algunos archivos en c:\data en el contenedor y luego detener el contenedor
  4. docker run -v unwound:c:\data microsoft/windowsservercore: Iniciar un nuevo contenedor
  5. Ejecutar dir c:\data en el contenedor nuevo: los archivos siguen estando ahí

Nota

Windows Server convertirá los nombres de las rutas de acceso de destino (la ruta de acceso dentro del contenedor) en minúsculas; es decir, -v unwound:c:\MyData, o -v unwound:/app/MyData en contenedores de Linux, hará que se asigne (y se cree si no existe) un directorio dentro del contenedor de c:\mydata, o /app/mydata en contenedores de Linux.