propia - ¿Cómo se analizan los nombres de las imágenes de Docker?
guardar una imagen en docker (2)
Al hacer un docker push
o al tirar de una imagen, ¿cómo determina Docker si hay un servidor de registro en el nombre de la imagen o si es una ruta / nombre de usuario en el registro predeterminado (p. Ej., Docker Hub)?
Veo lo siguiente de la especificación de imagen 1.1 :
Etiqueta
Una etiqueta sirve para asignar un nombre descriptivo, dado por el usuario, a cualquier ID de imagen individual. Los valores de etiqueta están limitados al conjunto de caracteres [a-zA-Z_0-9].
Repositorio
Una colección de etiquetas agrupadas bajo un prefijo común (el componente de nombre antes de :). Por ejemplo, en una imagen etiquetada con el nombre my-app: 3.1.4, my-app es el componente del repositorio del nombre. Un nombre de repositorio está formado por componentes de nombre separados por barras, opcionalmente con el prefijo de un nombre de host DNS. El nombre de host debe cumplir con las reglas DNS estándar, pero no puede contener _ caracteres. Si hay un nombre de host presente, puede ser seguido opcionalmente por un número de puerto en el formato: 8080. Los componentes de nombre pueden contener caracteres en minúsculas, dígitos y separadores. Un separador se define como un período, uno o dos guiones bajos, o uno o más guiones. Un componente de nombre no puede comenzar o terminar con un separador.
Para el nombre de host DNS, ¿necesita ser totalmente calificado con puntos, o es "my-local-server" un nombre de host de registro válido? Para los componentes de nombre, veo periodos como válidos, lo que implica que "team.user / appserver" es un nombre de imagen válido. Si el servidor de registro se está ejecutando en el puerto 80 y, por lo tanto, no se necesita número de puerto en el nombre de host en el nombre de la imagen, parece que habría ambigüedad entre el nombre de host y la ruta en el servidor de registro. Tengo curiosidad de cómo Docker resuelve esa ambigüedad.
TL; DR: el nombre de host debe contener a .
separador DNS o a :
separador de puerto antes del primero /
, de lo contrario, el código supone que desea el registro predeterminado.
Después de investigar el código, me encontré con distribution / reference / reference.go con lo siguiente:
// Grammar
//
// reference := name [ ":" tag ] [ "@" digest ]
// name := [hostname ''/''] component [''/'' component]*
// hostname := hostcomponent [''.'' hostcomponent]* ['':'' port-number]
// hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
// port-number := /[0-9]+/
// component := alpha-numeric [separator alpha-numeric]*
// alpha-numeric := /[a-z0-9]+/
// separator := /[_.]|__|[-]*/
//
// tag := /[/w][/w.-]{0,127}/
//
// digest := digest-algorithm ":" digest-hex
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
// digest-algorithm-separator := /[+.-_]/
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
La implementación real de eso es a través de una expresión regular en distribution / reference / regexp.go .
Pero con algunas búsquedas y descubrimientos, descubrí que hay otro cheque más allá de esa expresión regular (obtendrás errores con un nombre de host en mayúsculas si no incluyes un .
O :
. Y rastreé la división real del nombre a lo siguiente en docker / reference.go :
func splitHostname(name string) (hostname, remoteName string) {
i := strings.IndexRune(name, ''/'')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
hostname, remoteName = DefaultHostname, name
} else {
hostname, remoteName = name[:i], name[i+1:]
}
if hostname == LegacyDefaultHostname {
hostname = DefaultHostname
}
if hostname == DefaultHostname && !strings.ContainsRune(remoteName, ''/'') {
remoteName = DefaultRepoPrefix + remoteName
}
return
}
La parte importante de eso para mí es el cheque para el .
y :
antes de la primera /
en la primera declaración if. Con él, el nombre de host se divide antes que el primero /
y sin él, el nombre completo se pasa al nombre de host del registro predeterminado.
La especificación de imagen en https://github.com/moby/moby/blob/master/image/spec/v1.1.md ahora se ha actualizado para decir que las etiquetas están limitadas a 128 caracteres.
El hilo de RP está aquí https://github.com/docker/distribution/issues/2248
Algunos códigos de Ruby están aquí https://github.com/cyber-dojo/runner/blob/master/server/src/valid_image_name.rb
Algunas pruebas de Ruby están aquí https://github.com/cyber-dojo/runner/blob/master/server/test/src/valid_image_name_test.rb