Red de conocimiento informático - Material del sitio web - Cómo exportar una imagen desde el registro de Docker

Cómo exportar una imagen desde el registro de Docker

I. Estructura de directorios

El archivo de configuración del registro puede especificar el directorio de tiempo de ejecución del registro (intente utilizar el sistema de archivos local como almacenamiento de fondo) y el registro creará la estructura de directorio correspondiente en este directorio. Inicié el servicio de registro localmente y luego solo envié una imagen de centos. El nombre de la imagen es localhost:5000/library/centos:late y luego el registro creará un directorio localmente, como se muestra en la Figura 1.

Figura 1 Directorio de registro

Para facilitar la visualización, solo intercepté la primera parte del ID de 64 bits. Como puede ver, el directorio se divide aproximadamente en dos: uno para blobs y otro para repositorios. Los blobs almacenan principalmente archivos de datos, que pueden considerarse ID calculados por sha256. El directorio de repositorios contiene información descriptiva sobre la imagen, que registra las capas de la imagen, un archivo de manifiesto correspondiente al marcado y el archivo de enlace es un archivo de texto. El archivo de vínculo es un archivo de texto con un ID de 64 bits, como "sha256:cf34a09a90b54c...", y el archivo correspondiente a este ID en el blob es en realidad el archivo de manifiesto de la imagen.

Archivo de manifiesto

El archivo de manifiesto describe la metainformación de la imagen, incluido el ID de datos de la capa, la configuración de la capa, etc. El formato del archivo es un texto. archivo en forma de json.

Las imágenes de Docker se pueden dividir en dos categorías: V1 y V2. Desde la versión 1.9, el formato de la imagen ha sufrido algunos cambios. Para ser compatible con la versión V1 de Docker, el manifiesto utilizado por docekr

registryV2 también se divide en Schema1 y Schema2 en consecuencia, a los cuales se puede hacer referencia a [1] y [2] mediante la explicación oficial del manifiesto. El experimento se lleva a cabo aquí utilizando el esquema1 como objeto.

El esquema 1 contiene principalmente la siguiente información:

nombre: el nombre del repositorio de la imagen, por ejemplo, localhost:5000/library/centos:latest El nombre del repositorio de esta imagen es biblioteca /centos

etiqueta: La etiqueta de la imagen

Arquitectura: La arquitectura del sistema operativo donde se encuentra la imagen, como "amd64"

fsLayers: Este campo es un Array cuyos elementos especifican el sha256ID del archivo de datos correspondiente a cada capa. El primero de la matriz es el nivel superior de la imagen, el segundo es el siguiente nivel superior, y así sucesivamente. Vale la pena señalar que el fsLayer

ID

de diferentes capas puede ser el mismo, porque algunas capas están vacías y solo tienen cierta información de configuración. Al ejecutar un comando que no involucra operaciones de archivos, se formará un fsLayer vacío y el sha256ID calculado para el fsLayer vacío será el mismo. Una capa de imagen consta del sistema de archivos (como los archivos nuevos agregados) fsLayer y la información de configuración. En el nivel del código de la ventana acoplable, las capas también se denominan imágenes, porque la información de la imagen de la ventana acoplable

puede hacer referencia a cualquier capa como la capa superior, convirtiéndose así en una imagen. Por lo tanto, es necesario distinguir entre fsLayer y las capas.

historial: este campo también es una matriz, configurada para compatibilidad con v1, que especifica la información de configuración de cada capa. El primer elemento de la matriz corresponde al nivel superior de la imagen, que junto con fslayer forma una capa. La clave es "v1Compatibility" y el valor es una cadena. La cadena es la información de configuración de la capa. Puede usar json.Unmrashal directamente para cambiarla a la estructura v1Image (para ver la definición, consulte el código github.com/). docker)/docker/image/image.go

L31)

schemaVersion: versión del manifiesto, tipo int, como 1.

3. Imágenes en forma de paquetes Tar

Docker tiene comandos para guardar y cargar. comando guardar El comando guardar le permite exportar todas las capas de una imagen de la ventana acoplable de arriba a abajo a un archivo tar. Luego puede copiar y enviar este archivo tar a otras máquinas y, finalmente, usar el comando cargar para volver a cargar la imagen en la ventana acoplable.

Si sacamos una imagen del registro, podemos usar el comando guardar para enviarla a un tarball, y luego podemos usar el comando cargar para volver a cargarla en la ventana acoplable. Si tomamos una imagen del registro, la organizamos en un formato que se guarda como tarball y luego la cargamos usando el comando de carga, entonces podemos descargar la imagen sin usar el comando docker pull. Un principio es crear una tercera. -Herramienta de descarga de imágenes de fiesta.

Entonces, echemos un vistazo al formato del paquete tar del archivo de imagen. Utilicé el comando guardar para exportar la imagen centos. La estructura del directorio descomprimido se muestra en la Figura 2:

Figura 2 El directorio descomprimido del paquete tar de la imagen

El siguiente es un resumen. de varios Explicación del archivo:

El archivo de repositorios en el directorio raíz

El archivo de repositorios en el directorio raíz describe el nombre, el número de capas y la identificación de nivel superior de la imagen

Diferentes Las carpetas representan diferentes capas.

json: Información de configuración de capas, como hora de creación, comandos ejecutados, etc.

layer: Información de configuración de capas.

Layer.tar: El archivo incluido en la capa. Si es una capa vacía, Layer.tar estará vacío después de la descompresión.

VERSIÓN: información de la versión.

4. Exportar la imagen del registro

Comparamos los archivos del paquete comprimido con los archivos del registro. No es difícil encontrar la correspondencia entre json, VERSIÓN y. Los archivos de los repositorios se pueden exportar desde el manifiesto.

El archivo json es en realidad el campo de historial en v1Compatibilitiy mencionado anteriormente. La diferencia es que este campo en la lista tiene muchos caracteres de escape. Necesitamos eliminar estos caracteres de escape cambiando primero Unmarshal a la estructura V1Image y luego. en json. Simplemente conviértalo nuevamente en una cadena.

layer.tar es en realidad el archivo de datos correspondiente en blobs, simplemente cópielo y cámbiele el nombre.

VERSIÓN es la versión del esquema en el manifiesto.

El contenido del archivo de repositorios es muy simple. El formato es {"imageName":{"tag": "topLayerID"}}, por lo que está bien buscar los datos correspondientes del manifiesto y completarlos. según este formato.

Estos archivos están listos y luego puede prepararse para empaquetarlos en archivos tar. Una cosa a tener en cuenta aquí es que debe usar la opción "solo paquete, sin compresión" si usa directamente el que viene. con linux. Después de generar el paquete tar, puede usar el comando de carga de Docker para importarlo directamente.

Hice esto e importé una imagen con éxito. Sin embargo, hay un problema: la imagen importada usando el método anterior y la imagen que descargué directamente usando el comando pull de la ventana acoplable

tienen ID diferentes en cada capa, y la imagen importada a través de la ventana acoplable

pull La ID obtenida nunca aparece en ninguna parte del manifiesto o registro. Y, ya sea que use una máquina nueva o vuelva a tirar, la identificación que obtengo es la misma. Después de leer el código de la ventana acoplable, me di cuenta de que la ID de la capa no se genera aleatoriamente ni la identificación se escribe en el manifiesto, sino que se calcula. El siguiente es el proceso de cálculo.

El LayerID que finalmente necesitamos se llama StrongID en el código fuente de Docker. StrongID es un hash de una matriz de bytes. Se necesitan tres objetos para generar esta matriz de bytes: v1Compatibility, blobSum (manifest) fsLayerID), padre. (StrongID de la capa principal), el método de generación de matriz se refiere al método MakeImageConfig en image.go (docker

1.9). La operación básica es convertir un objeto json en una matriz de bytes. Dado que hay un campo principal, debe iterar paso a paso desde abajo para obtener el ID de la capa superior. Lo último que debe hacer es reemplazar el campo de identificación y el principal en el archivo json con el ID recién calculado. campo nivelado. Asimismo, el nombre de la carpeta debe cambiarse en consecuencia.

Importación incremental: si algunas capas ya existen localmente, podemos empaquetar directamente las nuevas capas, porque Docker verificará si estas capas existen durante la importación y hay información principal para garantizar la relación entre las capas.