Compartir comentarios
Las respuestas se generan en base a la documentación.

Controlador de almacenamiento BTRFS

Important

En la mayoría de los casos deberías usar el controlador de almacenamiento overlay2. No es obligatorio usar el controlador de almacenamiento btrfs solo porque tu sistema utilice Btrfs como su sistema de archivos raíz.

El controlador Btrfs tiene problemas conocidos. Consulta el issue #27653 de Moby para obtener más información.

Btrfs es un sistema de archivos copy-on-write que admite muchas tecnologías de almacenamiento avanzadas, lo que lo hace muy adecuado para Docker. Btrfs está incluido en la línea principal del kernel Linux.

El controlador de almacenamiento btrfs de Docker aprovecha muchas características de Btrfs para la gestión de imágenes y contenedores. Entre estas características se incluyen las operaciones a nivel de bloque, aprovisionamiento dinámico (thin provisioning), snapshots copy-on-write y facilidad de administración. Puedes combinar varios dispositivos de bloque físico en un solo sistema de archivos Btrfs.

Esta página se refiere al controlador de almacenamiento Btrfs de Docker como btrfs y al sistema de archivos Btrfs en general como Btrfs.

Note

El controlador de almacenamiento btrfs solo es compatible con Docker Engine CE en sistemas SLES, Ubuntu y Debian.

Requisitos previos

btrfs es compatible si cumples con los siguientes requisitos previos:

  • btrfs solo se recomienda con Docker CE en sistemas Ubuntu o Debian.

  • Cambiar el controlador de almacenamiento hace que los contenedores que ya hayas creado dejen de estar accesibles en el sistema local. Usa docker save para guardar los contenedores y envía las imágenes existentes a Docker Hub o a un registro privado para que no tengas que volver a crearlas más tarde.

  • btrfs requiere un dispositivo de almacenamiento de bloques dedicado, como un disco físico. Este dispositivo de bloques debe estar formateado para Btrfs y montado en /var/lib/docker/. Las instrucciones de configuración a continuación te guiarán a través de este procedimiento. Por defecto, el sistema de archivos / de SLES está formateado con Btrfs, por lo que en SLES no necesitas usar un dispositivo de bloques separado, aunque puedes optar por hacerlo por razones de rendimiento.

  • El soporte para btrfs debe existir en tu kernel. Para comprobarlo, ejecuta el siguiente comando:

    $ grep btrfs /proc/filesystems
    
    btrfs
    
  • Para gestionar sistemas de archivos Btrfs a nivel del sistema operativo, necesitas el comando btrfs. Si no tienes este comando, instala el paquete btrfsprogs (SLES) o el paquete btrfs-tools (Ubuntu).

Configurar Docker para usar el controlador de almacenamiento btrfs

Este procedimiento es prácticamente idéntico en SLES and Ubuntu.

  1. Detén Docker.

  2. Copia el contenido de /var/lib/docker/ a una ubicación de respaldo y luego vacía el contenido de /var/lib/docker/:

    $ sudo cp -au /var/lib/docker /var/lib/docker.bk
    $ sudo rm -rf /var/lib/docker/*
    
  3. Formatea tu dispositivo o dispositivos de bloque dedicados como un sistema de archivos Btrfs. Este ejemplo asume que estás usando dos dispositivos de bloque llamados /dev/xvdf y /dev/xvdg. Verifica dos veces los nombres de los dispositivos de bloque porque esta es una operación destructiva.

    $ sudo mkfs.btrfs -f /dev/xvdf /dev/xvdg
    

    Hay muchas más opciones para Btrfs, incluyendo striping y RAID. Consulta la documentación de Btrfs.

  4. Monta el nuevo sistema de archivos Btrfs en el punto de montaje /var/lib/docker/. Puedes especificar cualquiera de los dispositivos de bloque utilizados para crear el sistema de archivos Btrfs.

    $ sudo mount -t btrfs /dev/xvdf /var/lib/docker
    
    Note

    Haz que el cambio sea permanente entre reinicios añadiendo una entrada en /etc/fstab.

  5. Copia el contenido de /var/lib/docker.bk a /var/lib/docker/.

    $ sudo cp -au /var/lib/docker.bk/* /var/lib/docker/
    
  6. Configura Docker para usar el controlador de almacenamiento btrfs. Esto es necesario aunque /var/lib/docker/ ahora esté utilizando un sistema de archivos Btrfs. Edita o crea el archivo /etc/docker/daemon.json. Si es un archivo nuevo, añade el siguiente contenido. Si es un archivo existente, añade únicamente la clave y el valor, teniendo cuidado de finalizar la línea con una coma si no es la última línea antes de la llave de cierre (}).

    {
      "storage-driver": "btrfs"
    }

    Consulta todas las opciones de almacenamiento para cada controlador en la documentación de referencia del demonio

  7. Inicia Docker. Cuando esté en ejecución, verifica que se esté utilizando btrfs como controlador de almacenamiento.

    $ docker info
    
    Containers: 0
     Running: 0
     Paused: 0
     Stopped: 0
    Images: 0
    Server Version: 17.03.1-ce
    Storage Driver: btrfs
     Build Version: Btrfs v4.4
     Library Version: 101
    <...>
    
  8. Cuando estés listo, elimina el directorio /var/lib/docker.bk.

Gestionar un volumen Btrfs

Uno de los beneficios de Btrfs es la facilidad para gestionar sistemas de archivos Btrfs sin necesidad de desmontar el sistema de archivos ni reiniciar Docker.

Cuando el espacio disminuye, Btrfs expande automáticamente el volumen en fragmentos de aproximadamente 1 GB.

Para añadir un dispositivo de bloque a un volumen Btrfs, utiliza los comandos btrfs device add y btrfs filesystem balance.

$ sudo btrfs device add /dev/svdh /var/lib/docker

$ sudo btrfs filesystem balance /var/lib/docker
Note

Aunque puedes realizar estas operaciones con Docker en ejecución, el rendimiento se ve afectado. Puede ser conveniente planificar una ventana de mantenimiento para balancear el sistema de archivos Btrfs.

Cómo funciona el controlador de almacenamiento btrfs

El controlador de almacenamiento btrfs funciona de manera diferente a otros controladores en el sentido de que todo el directorio /var/lib/docker/ se almacena en un volumen Btrfs.

Capas de imágenes y contenedores en disco

La información sobre las capas de imágenes y las capas de escritura de los contenedores se almacena en /var/lib/docker/btrfs/subvolumes/. Este subdirectorio contiene un directorio por cada capa de imagen o contenedor, con el sistema de archivos unificado construido a partir de una capa más todas sus capas padres. Los subvolúmenes son nativamente copy-on-write y tienen espacio asignado bajo demanda a partir de un grupo de almacenamiento subyacente. También se pueden anidar y se les pueden realizar snapshots. El siguiente diagrama muestra 4 subvolúmenes. El 'Subvolumen 2' y el 'Subvolumen 3' están anidados, mientras que el 'Subvolumen 4' muestra su propio árbol de directorios interno.

Ejemplo de subvolumen

Solo la capa base de una imagen se almacena como un subvolumen real. Todas las demás capas se almacenan como snapshots (instantáneas), que solo contienen las diferencias introducidas en esa capa. Puedes crear snapshots de snapshots como se muestra en el siguiente diagrama.

Diagrama de snapshots

En el disco, los snapshots se ven y se comportan exactamente como subvolúmenes, pero en realidad son mucho más pequeños y eficientes en términos de espacio. Copy-on-write se utiliza para maximizar la eficiencia del almacenamiento y minimizar el tamaño de las capas, y las escrituras en la capa de escritura del contenedor se gestionan a nivel de bloque. La siguiente imagen muestra un subvolumen y su snapshot compartiendo datos.

Snapshot y subvolumen compartiendo datos

Para obtener la máxima eficiencia, cuando un contenedor necesita más espacio, este se asigna en fragmentos de aproximadamente 1 GB de tamaño.

El controlador de almacenamiento btrfs de Docker almacena cada capa de imagen y contenedor en su propio subvolumen o snapshot de Btrfs. La capa base de una imagen se almacena como un subvolumen, mientras que las capas de imagen secundarias y los contenedores se almacenan como snapshots. Esto se muestra en el siguiente diagrama.

Capas de contenedores Btrfs

El proceso general para crear imágenes y contenedores en hosts Docker que ejecutan el controlador btrfs es el siguiente:

  1. La capa base de la imagen se almacena en un subvolumen de Btrfs bajo /var/lib/docker/btrfs/subvolumes.

  2. Las capas de imagen subsiguientes se almacenan como un snapshot de Btrfs del subvolumen o snapshot de la capa padre, pero incluyendo los cambios introducidos por esa capa. Estas diferencias se almacenan a nivel de bloque.

  3. La capa de escritura del contenedor es un snapshot de Btrfs de la capa final de la imagen, con las diferencias introducidas por el contenedor en ejecución. Estas diferencias se almacenan a nivel de bloque.

Cómo funcionan las lecturas y escrituras de contenedores con btrfs

Lectura de archivos

Un contenedor es un snapshot de una imagen eficiente en espacio. Los metadatos del snapshot apuntan a los bloques de datos reales en el grupo de almacenamiento. Esto es lo mismo que con un subvolumen. Por lo tanto, las lecturas realizadas en un snapshot son esencialmente las mismas que las lecturas realizadas en un subvolumen.

Escritura de archivos

Como precaución general, escribir y actualizar una gran cantidad de archivos pequeños con Btrfs puede provocar un rendimiento lento.

Considera tres escenarios en los que un contenedor abre un archivo para acceso de escritura con Btrfs.

Escritura de archivos nuevos

Escribir un archivo nuevo en un contenedor invoca una operación de asignación bajo demanda para asignar un nuevo bloque de datos al snapshot del contenedor. Luego, el archivo se escribe en este nuevo espacio. La operación de asignación bajo demanda es nativa de todas las escrituras en Btrfs y es lo mismo que escribir nuevos datos en un subvolumen. Como resultado, la escritura de nuevos archivos en el snapshot de un contenedor funciona a velocidades nativas de Btrfs.

Modificación de archivos existentes

Actualizar un archivo existente en un contenedor es una operación copy-on-write (redirect-on-write es la terminología de Btrfs). Los datos originales se leen desde la capa donde existe actualmente el archivo, y solo los bloques modificados se escriben en la capa de escritura del contenedor. A continuación, el controlador Btrfs actualiza los metadatos del sistema de archivos en el snapshot para que apunten a estos nuevos datos. Este comportamiento incurre en una sobrecarga menor.

Eliminación de archivos o directorios

Si un contenedor elimina un archivo o directorio que existe en una capa inferior, Btrfs oculta la existencia del archivo o directorio en la capa inferior. Si un contenedor crea un archivo y luego lo elimina, esta operación se realiza en el propio sistema de archivos Btrfs y el espacio se recupera.

Btrfs y Docker rendimiento

Existen varios factores que influyen en el rendimiento de Docker bajo el controlador de almacenamiento btrfs.

Note

Muchos de estos factores se mitigan utilizando volúmenes de Docker para cargas de trabajo con uso intensivo de escritura, en lugar de depender del almacenamiento de datos en la capa de escritura del contenedor. Sin embargo, en el caso de Btrfs, los volúmenes de Docker siguen sufriendo estos inconvenientes a menos que /var/lib/docker/volumes/ no esté respaldado por Btrfs.

Caché de páginas

Btrfs no admite el uso compartido de la caché de páginas. Esto significa que cada proceso que accede al mismo archivo copia el archivo en la memoria del host de Docker. Como resultado, el controlador btrfs puede no ser la mejor opción para casos de uso de alta densidad como PaaS.

Escrituras pequeñas

Los contenedores que realizan muchas escrituras pequeñas (este patrón de uso también coincide con lo que sucede cuando inicias y detienes muchos contenedores en un corto período de tiempo) pueden provocar un mal uso de los fragmentos (chunks) de Btrfs. Esto puede llenar prematuramente el sistema de archivos Btrfs y provocar condiciones de falta de espacio en tu host Docker. Utiliza btrfs filesys show para supervisar de cerca la cantidad de espacio libre en tu dispositivo Btrfs.

Escrituras secuenciales

Btrfs utiliza una técnica de registro (journaling) al escribir en el disco. Esto puede afectar al rendimiento de las escrituras secuenciales, reduciendo el rendimiento hasta en un 50%.

Fragmentación

La fragmentación es un subproducto natural de los sistemas de archivos copy-on-write como Btrfs. Muchas escrituras aleatorias pequeñas pueden agravar este problema. La fragmentación puede manifestarse como picos de uso de CPU cuando se utilizan SSD o vibración/desplazamiento excesivo del cabezal (head thrashing) cuando se utilizan discos mecánicos. Cualquiera de estos problemas puede perjudicar el rendimiento.

Si la versión de tu kernel Linux es la 3.9 o superior, puedes habilitar la función autodefrag al montar un volumen Btrfs. Prueba esta función en tus propias cargas de trabajo antes de implementarla en producción, ya que algunas pruebas han mostrado un impacto negativo en el rendimiento.

Rendimiento de SSD

Btrfs incluye optimizaciones nativas para medios SSD. Para habilitar estas características, monta el sistema de archivos Btrfs con la opción de montaje -o ssd. Estas optimizaciones incluyen un rendimiento mejorado de escritura en SSD al evitar optimizaciones como las de búsqueda (seek), que no se aplican a los medios de estado sólido.

Balancear los sistemas de archivos Btrfs a menudo

Utiliza utilidades del sistema operativo, como una tarea cron, para balancear el sistema de archivos Btrfs con regularidad, durante las horas de menor actividad. Esto recupera bloques no asignados y ayuda a evitar que el sistema de archivos se llene innecesariamente. No puedes rebalancear un sistema de archivos Btrfs que esté completamente lleno a menos que añadas dispositivos de bloque físico adicionales al sistema de archivos.

Consulta la Btrfs Wiki.

Utilizar almacenamiento rápido

Las unidades de estado sólido (SSD) proporcionan lecturas y escrituras más rápidas que los discos mecánicos.

Utilizar volúmenes para cargas de trabajo con uso intensivo de escritura

Los volúmenes proporcionan el mejor y más predecible rendimiento para cargas de trabajo con uso intensivo de escritura. Esto se debe a que omiten el controlador de almacenamiento y no incurren en ninguna de las posibles sobrecargas introducidas por el aprovisionamiento dinámico y copy-on-write. Los volúmenes tienen otros beneficios, como permitirte compartir datos entre contenedores y persistir incluso cuando ningún contenedor en ejecución los está utilizando.

Información relacionada