hub - dockers container download
¿Cómo eliminar imágenes de un registro de acoplador privado? (7)
Ejecuto un registro de acoplador privado, y quiero eliminar todas las imágenes, pero las latest
de un repositorio. No quiero eliminar todo el repositorio, solo algunas de las imágenes que contiene. Los documentos API no mencionan una forma de hacerlo, pero seguramente es posible.
Actualmente no puede usar la API de registro para esa tarea. Solo le permite eliminar un repositorio o una etiqueta específica.
En general, eliminar un repositorio significa que todas las etiquetas asociadas a este repositorio se eliminan.
Eliminar una etiqueta significa que la asociación entre una imagen y una etiqueta se elimina.
Ninguno de los anteriores eliminará una sola imagen. Se quedan en tu disco.
Solución
Para esta solución, debe tener sus imágenes acoplables almacenadas localmente.
Una solución alternativa para su solución sería eliminar todas las etiquetas menos las últimas y, por lo tanto, eliminar potencialmente la referencia a las imágenes asociadas. Luego puede ejecutar esta secuencia de comandos para eliminar todas las imágenes, a las que no hace referencia ninguna etiqueta ni la ascendencia de ninguna imagen utilizada.
Terminología (imágenes y etiquetas)
Considere un gráfico de imagen como este donde las letras mayúsculas ( A
, B
, ...) representan identificaciones cortas de imágenes y <-
significa que una imagen se basa en otra imagen:
A <- B <- C <- D
Ahora agregamos etiquetas a la imagen:
A <- B <- C <- D
| |
| <version2>
<version1>
Aquí, la etiqueta <version1>
referencia a la imagen C
y la etiqueta <version2>
referencia a la imagen D
Refinando tu pregunta
En su pregunta, dijo que quería eliminar
todas las imágenes pero la
latest
. Ahora, esta terminología no es del todo correcta. Has mezclado imágenes y etiquetas. Al mirar el gráfico, creo que estaría de acuerdo en que la etiqueta <version2>
representa la última versión. De hecho, según esta pregunta , puede tener una etiqueta que represente la última versión:
A <- B <- C <- D
| |
| <version2>
| <latest>
<version1>
Como la <latest>
etiqueta hace referencia a la imagen D
le pregunto: ¿realmente quiere eliminar todas las imágenes menos D
? ¡Probablemente no!
¿Qué sucede si borras una etiqueta?
Si elimina la etiqueta <version1>
utilizando la API REST de Docker, obtendrá esto:
A <- B <- C <- D
|
<version2>
<latest>
Recuerde: Docker nunca eliminará una imagen. Incluso si lo hizo, en este caso no puede eliminar una imagen, ya que la imagen C
es parte de la ascendencia de la imagen D
que está etiquetada.
Incluso si usa este script , no se eliminará ninguna imagen.
Cuando una imagen puede ser eliminada
Con la condición de que pueda controlar cuándo alguien puede tirar o empujar a su registro (por ejemplo, deshabilitando la interfaz REST). Puede eliminar una imagen de un gráfico de imagen si no hay otra imagen basada en ella y ninguna etiqueta se refiere a ella.
Observe que en el siguiente gráfico, la imagen D
no se basa en C
sino en B
Por lo tanto, D
no depende de C
Si elimina la etiqueta <version1>
en este gráfico, la imagen C
no será utilizada por ninguna imagen y esta secuencia de comandos puede eliminarla.
A <- B <--------- D
/ |
/ <version2>
/ <latest>
/ <- C
|
<version1>
Después de la limpieza, su gráfico de imagen se ve así:
A <- B <- D
|
<version2>
<latest>
¿Es esto lo que quieres?
El registro v2
actual ahora admite eliminar mediante DELETE /v2/<name>/manifests/<reference>
Ver: https://github.com/docker/distribution/blob/master/docs/spec/api.md#deleting-an-image
Uso de trabajo: https://github.com/byrnedo/docker-reg-tool
Esta imagen de la ventana acoplable incluye una secuencia de comandos bash que se puede utilizar para eliminar imágenes de un registro v2 remoto: https://hub.docker.com/r/vidarl/remove_image_from_registry/
Esto es realmente feo pero funciona, el texto se prueba en el registro: 2.5.1. No logré que la eliminación funcionara sin problemas incluso después de actualizar la configuración para habilitar la eliminación. La identificación fue realmente difícil de recuperar, tuvo que iniciar sesión para obtenerla, tal vez algún malentendido. De todos modos, los siguientes trabajos:
Ingresar al contenedor
docker exec -it registry sh
Defina variables que coincidan con su contenedor y versión del contenedor:
export NAME="google/cadvisor" export VERSION="v0.24.1"
Mover al directorio de registro:
cd /var/lib/registry/docker/registry/v2
Eliminar archivos relacionados con su hash:
find . | grep `ls ./repositories/$NAME/_manifests/tags/$VERSION/index/sha256`| xargs rm -rf $1
Eliminar manifiestos:
rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
Cerrar sesión
exit
Ejecute el GC:
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
Si todo se hizo correctamente, se muestra cierta información sobre blobs eliminados.
Hay algunos clientes (en Python, Ruby, etc.) que hacen exactamente eso. Para mi gusto, no es sostenible instalar un tiempo de ejecución (por ejemplo, Python) en mi servidor de registro, ¡solo para mantener mi registro!
Así que deckschrubber
es mi solución:
go get github.com/fraunhoferfokus/deckschrubber
$GOPATH/bin/deckschrubber
las imágenes anteriores a una determinada edad se eliminan automáticamente. La edad se puede especificar utilizando-año, -month
, -day
o una combinación de ellos:
$GOPATH/bin/deckschrubber -month 2 -day 13 -registry http://registry:5000
ACTUALIZACIÓN : aquí hay una breve introducción sobre deckschrubber.
He enfrentado el mismo problema con mi registro y luego probé la solución que se detalla a continuación en una página de blog. Funciona.
Paso 1: catalogación de catálogos
Puede enumerar sus catálogos llamando a esta url:
http://YourPrivateRegistyIP:5000/v2/_catalog
La respuesta será en el siguiente formato:
{
"repositories": [
<name>,
...
]
}
Paso 2: etiquetas de listado para el catálogo relacionado
Puede enumerar las etiquetas de su catálogo llamando a esta url:
http://YourPrivateRegistyIP:5000/v2/<name>/tags/list
La respuesta será en el siguiente formato:
{
"name": <name>,
"tags": [
<tag>,
...
]
}
Paso 3: valor del manifiesto de la lista para la etiqueta relacionada
Puede ejecutar este comando en el contenedor de registro de Docker:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://localhost:5000/v2/<name>/manifests/<tag> 2>&1 | grep Docker-Content-Digest | awk ''{print ($3)}''
La respuesta será en el siguiente formato:
sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Ejecute el siguiente comando con valor de manifiesto:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://127.0.0.1:5000/v2/<name>/manifests/sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Paso 4: borrar los manifiestos marcados
Ejecute este comando en su contenedor de registro docker:
bin/registry garbage-collect /etc/docker/registry/config.yml
Aquí está mi config.yml
root@c695814325f4:/etc# cat /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
Problema 1
Usted mencionó que era su registro de acoplador privado, por lo que probablemente deba verificar la API de registro en lugar del documento de API de registro de Hub , que es el enlace que proporcionó.
Problema 2
La API de registro de Docker es un protocolo de cliente / servidor, depende de la implementación del servidor si se eliminan las imágenes en el back-end. (Supongo)
DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*)
Explicación detallada
Debajo, demuestro cómo funciona ahora desde su descripción a mi entender por sus preguntas.
Ejecutas, ejecutas el registro privado del acoplador, yo uso el predeterminado y escucho en el puerto 5000
docker run -d -p 5000:5000 registry
Luego etiqueto la imagen local y la inserto.
$ docker tag ubuntu localhost:5000/ubuntu
$ docker push localhost:5000/ubuntu
The push refers to a repository [localhost:5000/ubuntu] (len: 1)
Sending image list
Pushing repository localhost:5000/ubuntu (1 tags)
511136ea3c5a: Image successfully pushed
d7ac5e4f1812: Image successfully pushed
2f4b4d6a4a06: Image successfully pushed
83ff768040a0: Image successfully pushed
6c37f792ddac: Image successfully pushed
e54ca5efa2e9: Image successfully pushed
Pushing tag for rev [e54ca5efa2e9] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
Después de eso, puede usar Registry API para verificar que exista en su registro privado de acopladores
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags
{"latest": "e54ca5efa2e962582a223ca9810f7f1b62ea9b5c3975d14a5da79d3bf6020f37"}
¡Ahora puedo eliminar la etiqueta usando esa API!
$ curl -X DELETE localhost:5000/v1/repositories/ubuntu/tags/latest
true
Verifique nuevamente, la etiqueta no existe en su servidor de registro privado
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags/latest
{"error": "Tag not found"}