Cómo desplegar nuestra propia Docker Registry
En este artículo, te muestro como desplegar una Docker Registry para que tengas el total control de tus imágenes.
En noviembre, arrancan algunas limitaciones en Docker Hub con respecto al rate pulling de las imágenes. Estas limitaciones no se van a sentir para quien descargue desde Docker Hub para lo básico, pero si, tal vez, para quienes tienen un uso más intensivo de descarga de imágenes constantemente.
Los límites que comienzan a regir a partir de noviembre de 2020 son los siguientes:
- Sin estar autenticado: 100 Pulls cada seis horas.
- Usuario con plan gratuito, autenticado: 200 pulls en el mismo periodo de tiempo.
- Si tienes una cuenta de pago de Docker Hub: No tienes límites.
De nuevo repito, si no sos un consumidor de Docker Hub en el sentido que estás descargando imágenes todo el tiempo, esto no te va a afectar, pero si tal vez tienes plataformas que están buildeando todo el tiempo, puede que si no tienes un plan contratado, la cantidad de pulls te quede chica.
De todos modos no solo tenemos esta excusa para montar una registry, también podemos pensar en privacidad y en el hecho de que tenemos recursos para montarla y nos ahorramos costos de planes en Docker Hub u otra Registry como puede ser Quay.io.
Desplegando una Registry
El despliegue, como veremos, es muy sencillo. Al final del día es un contenedor, que publica determinado puerto, guarda toda la data en un volumen y listo.
En este caso, lo vamos a correr de la siguiente manera:
$ docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /ruta/volumen/registry:/var/lib/registry \
registry:2
Lo que tenemos que tener en cuenta a la hora de desplegarlo de esta manera, es que el directorio que van a bindear, sea uno que esté en nuestro host, también debemos tener en cuenta que estamos publicando el puerto 5000, así que las llamadas que hagamos, cuando queramos operar esta registry, va a tener que incluir ese puerto.
$ docker pull localhost:5000/hello-world:latest
Ahora, este setup tiene un "problema" y es que cualquiera puede subir y descargar imágenes de esta registry. Si esa es la intención, así como esta nos va a servir, pero si no la es o esto va a estar publicado en Internet, debemos añadir un mínimo de seguridad para evitar que cualquiera suba una imagen.
Agregando autenticación básica
Para agregar autenticación a nuestra registry, primero debemos hacer un par de cosas...
Una de esas, es generar un archivo htpasswd con nuestro usuario y contraseña encriptados. Para eso, vamos a correr:
$ docker run --entrypoint htpasswd registry:2.7.0 -Bbn usuario contraseña > /registry/auth/htpasswd
Esto va a generar un archivo donde va a guardar nuestro nombre de usuario y la contraseña.
Ahora bien, supongamos que nuestra registry se va a acceder con el nombre registry.midominio.com, vamos a generar un certificado para eso. Como en este caso, es solamente para pruebas, podemos generar un certificado, auto firmado, usando este servicio:
Una vez que tenemos descargados los certs, los ubicamos a mano, para luego montar un volumen y que el contenedor los pueda ver.
Tiramos el docker run de la siguiente manera:
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /ruta/volumen/registry:/var/lib/registry \
-v /ruta/volumen/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /ruta/volumen/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.midominio.com.cert \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.midominio.com.key \
registry:2
Lo que estamos haciendo acá es, publicando el puerto 5000, montando tres volúmenes, uno para la data de la registry, otro para los certificados y otro para el archivo htpasswd que generamos antes.
Si todo esto sale bien, tiramos un...
$ docker login registry.midominio.com:5000
Nos responderá pidiendo usuario y contraseña y si acertamos, veremos esto:
Login Succeeded
Resolviendo algunos temitas...
Si seguiste al pie de la letra este artículo, seguramente te darás cuenta de dos cosas.
Una de esas cosas es que debemos generar un registro en el /etc/hosts que sea tu propia IP y que se llame registry.midominio.com, caso contrario recibirás este mensaje:
Error response from daemon: Get https://registry.midominio.com:5000/v2/: dial tcp: lookup registry.midominio.com on 192.168.65.1:53: no such host
Con lo otro que probablemente nos encontremos es con este mensaje:
Error response from daemon: Get https://registry.midominio.com:5000/v2/: x509: certificate signed by unknown authority
Para sacarnos de encima este error, debemos permitir el uso de Registries inseguras, para esto, debemos agregar lo siguiente en el archivo daemon.json
{
"insecure-registries" : ["registry.midominio.com:5000"]
}
Luego de eso, debemos reiniciar el daemon de Docker con...
$ systemctl restart docker
Con estas dos cosas, estamos listos para experimentar con la Registry de Docker de manera local.
Para ir cerrando
Espero que este artículo te haya servido, en otros veremos algunas opciones más avanzadas que nos permitirán extender el uso de nuestra registry, incluso de maneras más seguras, atrás de un proxy reverso y más.
Como siempre, cualquier duda o consulta, pueden dejarla en los comentarios.