DOCKER: Como criar e executar um registry privado

Alexandre Rosseto
9 min readSep 14, 2020

Este artigo apresentará uma abordagem para criação de um Docker Registry privado, além de demonstrar, em diferentes distribuições do Linux, como enviar e baixar uma imagem dele.

Após a conclusão das instruções desse artigo, você será capaz de entender como funciona o Docker Registry, executá-lo e enviar suas imagens para esse repositório ao invés do Docker Hub e baixá-las em outras máquinas.

REQUERIMENTO: Ter contato com o Docker, Docker Hub e Linux. A preferência do sistema operacional é para a distribuição Debian com SSL instalado.

Leitura Recomendada:

O QUE EU VOU APRENDER

Não apenas, mas também verá:

  • Introdução ao Docker Registry
  • Uma abordagem de utilização do Docker Registry
  • Como aplicar a abordagem na sua empresa/organização
  • Simular o uso em três máquinas (Ubuntu / Debian / CentOS)
  • Instalar o Docker (Ubuntu / Debian / CentOS)
  • Criar um certificado com OpenSSL
  • Criar um Registry privado
  • Enviar uma imagem para o registry privado
  • Baixar uma imagem do registry privado
  • Tratamento de problemas conhecidos

O QUE É DOCKER REGISTRY?

É possível imaginar o Registry como sendo um repositório de imagens com um aplicativo stateless e altamente escalonável, que roda do lado servidor, para armazenar e distribuir imagens do Docker.

Diferentemente do Docker Hub, a vantagem de se ter um registry privado é, sobretudo, a segurança. Afinal, pode ser acessível somente na intranet corporativa e suas configurações de firewall ficando totalmente isolado da internet.

VERSÕES DO DOCKER REGISTRY

A primeira versão 1 do Docker Registry foi escrito em Python, porém na seu segunda versão foi reescrito em Golang seguindo a mesma linguagem do próprio Docker.

Na v2, suporta imagem v2, JSON Registry API e é mais seguro.

INSTALAÇÃO DO DOCKER

Se você já possui o Docker instalado no seu ambiente, pode ir direto para o próximo tópico.

Ubuntu / Debian

Eleve sua permissão para usuário root com:sudo su. No Debian use su -.
Verifique se sua versão do SO é compatível com o Docker:uname -a. Versões acima da 5.0 sendo 64 bits já será compatível.
Atualize os índices de repositórios de pacotes com:apt-get update.
Instale o docker com o comando:apt-get install -y docker.io.
Você pode verificar se o serviço do Docker está rodando com:service docker status.

CentOS

Eleve sua permissão para usuário root com:su.
Verifique se sua versão do SO é compatível com o Docker:uname -a.
Atualize os índices de repositórios de pacotes com:yum update.
Instale o docker com o comando:yum install -y docker.
Você pode verificar se o serviço do Docker está rodando com:systemctl status docker.service.

Se tudo estiver correto, você pode testar rodar um container de testes.

docker run hello-world
Mensagem que será exibida se tudo estiver funcionando corretamente

PASSO-A-PASSO

Confirme se o SSL está instalado corretamente com o comando openssl version -a. Em seguida, veja se seu docker está atualizado e rodando docker version.

Certificado

Para subir o registry, é necessário ter um certificado de segurança.

Vamos criar um diretório para os certificados.

mkdir -p /docker_data/certs/

Em seguida, vamos criar o certificado com validade de 365 dias no diretório criado. Então use o comando abaixo.

openssl req -newkey rsa:4096 -nodes -sha256 -keyout /docker_data/certs/domain.key -x509 -days 365 -out /docker_data/certs/domain.crt

Ao rodar o comando acima, você será questionado pelo país, estado, localidade, nome da organização e nome da unidade organizacional, sendo que estes itens são opcionais e você pode simplesmente dar enter. Em seguida, será questionado pelo Common Name e endereço de email, sendo que ambos precisam ser informados. No Common Name, você pode informar o endereço do seu blog ou site, por exemplo.

Armazenamento das Imagens

Vamos criar uma pasta para as imagens.

mkdir -p /docker_data/images

Escolhendo o Registry no Docker Hub

Estamos quase lá! Agora, antes de subir nosso registry, vamos escolher o registry apropriadamente no Docker Hub. Então faça:

docker search registry
Após execução do comando

Para dar sequência neste artigo introdutório, vamos usar a versão oficial, mas fique livre para utilizar a que for mais indicada para sua situação. Será necessário pesquisar sobre cada uma delas para entender as vantagens e desvantagens.

Finalmente, vamos subir nosso Docker Registry com o comando abaixo.

docker run -d -p 5000:5000 -v /docker_data/images:/var/lib/registry -v /docker_data/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key --restart on-failure --name myregistry registry

Explicando:
* docker run: Executar um container.
* -d: Executar o container sem entrar nele.
* -p 5000:5000: Especifica a porta 5000 de execução do container e expõe na máquina hospedeira a porta 5000.
* -v: Expõe um volume. Basicamente funcionará como um mapa onde o registry de utilizar/salvar as imagens e o certificado.
*-e: Define as variáveis de ambiente informando o certificado e a chave do certificado.
* restart on-failure: Caso haja alguma falha ao inicializar o container, será reinicializado automaticamente.
* name: Define o nome do registry o qual você poderá usar qualquer nome que desejar.
* O último argumento é o nome do registry o qual foi informado “registry” por ser o oficial, conforme figura acima.

Verificando o Registry

Após rodar o comando anterior, você poderá conferir que o container está rodando usando o comando docker ps.

Container rodando conforme especificação

Vamos testar nosso registry criando uma imagem marcada com a tag do nosso repositório. Desse modo, primeiro vamos fazer um push e depois um pull para ver se tudo funcionou. Nesse exemplo, vamos utilizar uma imagem do nginx por ser pequena e baixar bem rápido.

docker pull nginx

Você poderá confirmar as imagens abaixadas comdocker images.

Imagens baixadas

Criando uma Tag e Enviando para o Host Local

O objetivo de criar uma tag é para ser identificado no nosso registry privado. A estrutura do comando que vamos usar segue abaixo.

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

Como nosso objetivo é gerar uma tag do nginx que baixamos, sendo que o docker irá buscar localmente primeiro, e determinar uma referência a uma imagem local ouvindo na porta 5000, então devemo usar:

docker tag docker.io/nginx localhost:5000/my-nginx

Após isso, vamos listar as imagens baixadas usando o comando docker images.

Note que agora existe um repositório chamado localhost:5000/my-nginx

Agora vamos enviar a tag criada para o host local que criamos usando o comando que segue:

docker push localhost:5000/my-nginx

Para confirmar que funcionou, vamos listar o diretório que criamos para verificar se nossa imagem estará devidamente armazenada.

ls -lia /docker_data/images/docker/registry/v2/repositories/
Note que agora existe a imagem local my-nginx

Agora vamos fazer uma cópia segura do nosso certificado (domain.crt) para nossa pasta compartilhada de rede com a máquina local e que também será usada para enviar para outra VM Linux, porém agora uma imagem Ubuntu. Você pode usar qualquer meio de transferência que preferir, mas se quiser fazer do mesmo modo deste artigo, é recomendável ler o artigo disponibilizado no topo deste documento na seção Leitura Recomendada.

scp -r /docker_data/certs/domain.crt /mnt/hgfs/shared/

Configurando Outra VM para Testar

Rodando uma VM Ubuntu, vamos apenas registrar que não existe uma imagem nginx.

$ docker images
VM Ubuntu

Então vamos criar uma pasta para receber a imagem. Você pode nomeá-la como preferir.

mkdir -p /etc/docker/certs.d/debianregistry:5000/

Agora vamos copiar o certificado da pasta compartilhada para dentro da nova pasta criada.

cp -rf /mnt/hgfs/shared/domain.crt /etc/docker/certs.d/debianregistry.com.br:5000/

Em seguida, você pode conferir se o arquivo foi realmente copiada usando o comando abaixo.

ls -lia /etc/docker/certs.d/debianregistry:5000/

Caso você não tenha um serviço de DNS, poderá incluir no arquivo de hosts o IP da máquina que está hospedando o registry. Neste exemplo, para ser didático, vou utilizar isto.

echo {IP DA MÁQUINA DO REGISTRY} debianregistry.com.br >> /etc/hosts

Caso tenha dificuldade em saber, basta executar o comando abaixo e procurar pelo IP público começando por 192, por exemplo.

ip addr show

Para confirmar se foi corretamente incluído, use o comando abaixo na VM Ubuntu ou outra qualquer que esteja usando.

cat /etc/hosts
Arquivos de Hosts da VM Ubuntu

Agora vamos baixar a imagem do servidor remoto que criamos usando tag que informamos nos passos anteriores.

docker pull debianregistry.com.br:5000/my-nginx:latest
Download do Registry — Sucesso!

Conforme imagem acima, pode-se notar que o download da máquina virtual remota (Debian) foi feita com sucesso para a máquina virtual Ubuntu.

Verificando as imagens locais na máquina Ubuntu

Repetindo na Máquina Local

Como vimos que nosso experimento foi um sucesso e, caso você deseje, pode fazer o mesmo na máquina local (debian ou qualquer outra que esteja fazendo).

### Crie o diretório para armazenar o certificado ###
$ mkdir -p /etc/docker/certs.d/debianregistry.com.br:5000/
### Copie o certificado ###
$ cp -rf /mnt/hgfs/shared/domain.crt /etc/docker/certs.d/debianregistry.com.br:5000/
### Atualize o arquivo de hosts ###
$ echo {IP DA MÁQUINA DO REGISTRY} debianregistry.com.br >> /etc/hosts
### Sobe a imagem no Registry Privado ###
$ docker pull debianregistry.com.br:5000/my-nginx:latest
Imagem disponibilizada com êxito na máquina Debian — Onde está o Registry

Sumarizando

Em resumo, vimos como criar um certificado, criar um repositório de imagens local, escolher uma imagem do registry para trabalhar e escolhemos a imagem oficial, criar uma tag de uma imagem pública, baixá-la e enviá-la para o host local e verificar que o registry está funcionando localmente.

USANDO O REGISTRY PRIVADO

Após toda a validação da ideia na seção anterior, vou demonstrar como usar o Docker Registry na prática, onde iremos enviar uma imagem da VM Ubuntu para o nosso Registry no Debian e depois baixá-la para uma nova VM com o sistema operacional CentOS.

Ilustra o objetivo dessa seção

Criando uma TAG para Imagem a ser Enviada

Neste artigo, será utilizada uma imagem de demonstração, sendo a “Hello World”, porém você poderá enviar qualquer imagem que desejar.

VM Ubuntu — Lista de Imagens e Seleção de um Image ID
docker tag f07ffa23aa92 debianregistry.com.br:5000/hello-private-registry:1.1
VM Ubuntu —Tag da imagem gerado

Note que o hash da imagem (IMAGE ID) com a nova tag gerada é exatamente igual ao da imagem original.

Enviando a Imagem para o Docker Registry Privado

Utilizando o comando que já apresentado, porém agora com a tag da imagem “Hello World”.

docker push debianregistry.com.br:5000/hello-private-registry:1.1
VM Ubuntu — Imagem com tag enviada com sucesso para o Registry Privado

Essa é uma ação que um desenvolvedor poderia estar fazendo dentro da organização após identificar ou criar uma imagem personalizada.

Se desejar conferir se a imagem realmente foi disponibilizada no Registry Privado da máquina Debian, basta executar o comando abaixo.

ls -lia /docker_data/images/docker/registry/v2/repositories/
VM Debian — Listagem do diretório criado nesse artigo

Baixando a Imagem do Docker Registry Privado

Com a máquina virtual CentOS montada e com o Docker instalado, vamos agora listar as imagens e containers.

VM CentOS — Listagem de imagens e containers

Apenas para demonstrar que realmente não tem nada baixado ou rodando.

Agora vamos baixar a imagem “Hello World” com a tag criada na seção anterior para essa VM. Será necessário fazer as configurações do /etc/host como demonstrado nas seções anteriores. Repita os passos antes de prosseguir.

docker pull debianregistry.com.br:5000/hello-private-registry:1.1
VM CentOS — Imagem baixada com sucesso

Parabéns para quem chegou até aqui!

Espero que esse artigo tenha te ajudado a começar a entender como funciona o Docker Registry e como a implementá-lo na sua empresa.

PROBLEMA CONHECIDO

Quando você for fazer o docker pull, pode ser que receba a mensagem:
“x509: certificate signed by unknown authority”

Se isso acontecer, a solução é bem simples. Provavelmente você nomeou a pasta com o CA (Certificate Authority) que nomeamos de Domain.crt incorretamente. O nome da pasta precisa ser exatamente o mesmo que você informou no comando echo.

Se for esse o caso, apenas use:

mv {caminho completo da pasta errada} {caminho inteiro da pasta correta}### Exemplo ###
mv /etc/docker/certs.d/debianregistry:5000/ /etc/docker/certs.d/debianregistry.com.br:5000

Em seguida, pode executar o docker pull que o problema não existirá mais.

--

--

Alexandre Rosseto

Senior Tech Manager specialized in Java with experience in software factories and consultancies. LinkedIn: https://www.linkedin.com/in/alexandrerosseto