Controlador de almacenamiento BTRFS
ImportantEn la mayoría de los casos deberías usar el controlador de almacenamiento
overlay2. No es obligatorio usar el controlador de almacenamientobtrfssolo 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.
NoteEl controlador de almacenamiento
btrfssolo es compatible con Docker Engine CE en sistemas SLES, Ubuntu y Debian.
Requisitos previos
btrfs es compatible si cumples con los siguientes requisitos previos:
btrfssolo 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 savepara 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.btrfsrequiere 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
btrfsdebe existir en tu kernel. Para comprobarlo, ejecuta el siguiente comando:$ grep btrfs /proc/filesystems btrfsPara gestionar sistemas de archivos Btrfs a nivel del sistema operativo, necesitas el comando
btrfs. Si no tienes este comando, instala el paquetebtrfsprogs(SLES) o el paquetebtrfs-tools(Ubuntu).
Configurar Docker para usar el controlador de almacenamiento btrfs
Este procedimiento es prácticamente idéntico en SLES and Ubuntu.
Detén Docker.
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/*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/xvdfy/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/xvdgHay muchas más opciones para Btrfs, incluyendo striping y RAID. Consulta la documentación de Btrfs.
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/dockerNoteHaz que el cambio sea permanente entre reinicios añadiendo una entrada en
/etc/fstab.Copia el contenido de
/var/lib/docker.bka/var/lib/docker/.$ sudo cp -au /var/lib/docker.bk/* /var/lib/docker/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
Inicia Docker. Cuando esté en ejecución, verifica que se esté utilizando
btrfscomo 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 <...>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
NoteAunque 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.

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.

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.

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.

El proceso general para crear imágenes y contenedores en hosts Docker que ejecutan el controlador btrfs es el siguiente:
La capa base de la imagen se almacena en un subvolumen de Btrfs bajo
/var/lib/docker/btrfs/subvolumes.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.
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.
NoteMuchos 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.