Una organización externa con la que trabajo me ha dado acceso a un registro docker privado (protegido por token de autenticación) y, eventualmente, me gustaría poder consultar este registro, utilizando la API HTTP V2 de docker, para obtener una lista de todos los repositorios y/o imágenes disponibles en el registro.
Pero antes de hacer eso, primero me gustaría obtener algo de práctica básica con la construcción de este tipo de consultas API en un registro público como Docker Hub . Así que seguí adelante y me registré con un nombre de usuario y contraseña en Docker Hub, y también consulté la documentación de API V2, que establece que uno puede solicitar una verificación de versión de API como:
GET /v2/
o solicitar una lista de repositorios como:
GET /v2/_catalog
Usando curl, junto con el nombre de usuario y la contraseña que usé para registrar mi cuenta de Docker Hub, intento construir una solicitud GET en la línea de comando:
stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/ {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]} stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/_catalog {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}
donde, por supuesto, en lugar de <my_password>
, sustituí la contraseña de mi cuenta real.
La respuesta que esperaba de esta consulta era un mensaje json gigante, que enumeraba miles de nombres de repositorios, pero en cambio, parece que la API está rechazando mis credenciales de Docker Hub.
Pregunta 1: ¿Tengo la URL correcta ( index.docker.io
) para el registro del concentrador docker? (Hice esta suposición en primer lugar en función de la información de estado devuelta por la información de la docker info
de la herramienta de línea de comandos, por lo que tengo buenas razones para pensar que es correcta).
Pregunta 2: suponiendo que tengo la URL correcta para el servicio de registro, ¿por qué mi consulta devuelve un código de error "NO AUTORIZADO"? Las credenciales de mi cuenta funcionan bien cuando intento iniciar sesión a través de la web en hub.docker.com, entonces, ¿cuál es la diferencia entre los dos casos?
Aquí hay un programa de ejemplo para leer repositorios desde un registro. Lo usé como una ayuda de aprendizaje con Docker Hub.
#!/bin/bash set -e # set username and password UNAME="username" UPASS="password" # get token to be able to talk to Docker Hub TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token) # get list of repos for that user account REPO_LIST=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${UNAME}/?page_size=10000 | jq -r '.results|.[]|.name') # build a list of all images & tags for i in ${REPO_LIST} do # get tags for repo IMAGE_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${UNAME}/${i}/tags/?page_size=10000 | jq -r '.results|.[]|.name') # build a list of images from tags for j in ${IMAGE_TAGS} do # add each tag to list FULL_IMAGE_LIST="${FULL_IMAGE_LIST} ${UNAME}/${i}:${j}" done done # output list of all docker images for i in ${FULL_IMAGE_LIST} do echo ${i} done
(Esto proviene de un artículo en el sitio de Docker que describe cómo usar la API).
En esencia...
Authorization: JWT <token>
con cualquier llamada a la API que realicehttps://hub.docker.com/v2/repositories/<username>/
Lo primero es lo primero, Docker es un protocolo, DockerHub es un producto que implementa el protocolo Docker pero no se limita a él.
hub.docker.com
tiene las ricas API específicas de DockerHub.
index.docker.io
es la implementación genérica de Docker API V2 para DockerHub que se usa en la mayoría de los clientes que admiten varios registros de docker.
DockerHub implementa la API HTTP V2 genérica de Docker, pero no implementa la API _catalog
delconjunto de API genéricas .
Para usar la API de Docker V2, se debe generar un token de autenticación JWT y ese token se debe usar como token de portador en las llamadas de DockerHub en index.docker.io
Cuando presiona las API de DockerHub de esta manera:
https://index.docker.io/v2/library/alpine/tags/list
y devuelve 401,
Busque el encabezado de respuesta
www-authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/alpine:pull",error="invalid_token"
Esto significa que debe llamar explícitamente
https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull
Lo que le dará el token de portador que puede usar en la solicitud index.docker.io
original.
El https://auth.docker.io/token
funciona sin ningún token de autenticación, pero solo para repositorios públicos.
En caso de que desee acceder a un repositorio privado, debe agregar un encabezado de autenticación básico a la solicitud.
curl -u username:password https://auth.docker.io/token?service=registry.docker.io&scope=repository:<repo>:pull
NOTA: auth.docker.io
generará un token de todos modos, incluso si la solicitud no es válida (créditos o alcance o cualquier cosa). Para validar el token, si coloca el token en jwt.io, debería ver el campo de access
en la carga útil que contiene las referencias de alcance solicitadas.
Este sitio dice que no podemos :(
Dockerhub aloja una combinación de repositorios públicos y privados, pero no expone un punto final de catálogo para enumerarlos mediante programación.