Se lavori per un'organizzazione e desideri mantenere le tue immagini Docker internamente per una rapida distribuzione, l'hosting di un repository Docker privato è perfetto. Avere un registro docker privato ti consente di possedere la pipeline di distribuzione delle immagini e di avere un controllo più stretto sull'archiviazione e sulla distribuzione delle immagini. Puoi integrare il tuo registro con il tuo sistema CI/CD migliorando il tuo flusso di lavoro.
Questo tutorial ti insegnerà come configurare e utilizzare un registro Docker privato su un server basato su Rocky Linux 8 utilizzando Amazon S3 come posizione di archiviazione.
Prerequisiti
- Due server Linux con Rocky Linux 8. Un server fungerà da host del registro, mentre l'altro verrà utilizzato come client per inviare richieste e ricevere immagini dall'host.
- Un nome di dominio registrato che punta al server host. Useremo
registry.example.com
per il nostro tutorial. - Un utente non root con privilegi sudo su entrambe le macchine.
Passaggio 1:configurazione del firewall
Il primo passo è configurare il firewall. Rocky Linux utilizza Firewalld Firewall. Controlla lo stato del firewall.
$ sudo firewall-cmd --state running
Il firewall funziona con diverse zone e la zona pubblica è quella predefinita che useremo. Elenca tutti i servizi e le porte attive sul firewall.
$ sudo firewall-cmd --permanent --list-services
Dovrebbe mostrare il seguente output.
cockpit dhcpv6-client ssh
Consenti porte HTTP e HTTPS.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
Ricontrolla lo stato del firewall.
$ sudo firewall-cmd --permanent --list-services
Dovresti vedere un output simile.
cockpit dhcpv6-client http https ssh
Ricarica il firewall per abilitare le modifiche.
$ sudo firewall-cmd --reload
Passaggio 2:installazione di Docker e Docker Compose
Questo passaggio è necessario sia sul server che sui computer client.
Installa il repository Docker ufficiale.
$ sudo dnf install yum-utils $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Installa Docker.
$ sudo dnf install docker-ce docker-ce-cli containerd.io
Abilita ed esegui il demone Docker.
$ sudo systemctl enable docker --now
Aggiungi il tuo utente di sistema al gruppo Docker per evitare di usare sudo
per eseguire i comandi Docker.
$ sudo usermod -aG docker $(whoami)
Accedi di nuovo al tuo server dopo esserti disconnesso per abilitare la modifica.
Scarica e installa l'ultima versione stabile di Docker Compose.
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Applica le autorizzazioni eseguibili al file binario scaricato.
$ sudo chmod +x /usr/local/bin/docker-compose
Installa lo script Docker-compose Bash Completion.
$ sudo curl \ -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \ -o /etc/bash_completion.d/docker-compose
Ricarica le impostazioni del tuo profilo per far funzionare il completamento di bash.
$ source ~/.bashrc
Passaggio 3:configurazione del registro Docker
Crea directory utente
Crea una directory per la configurazione del registro.
$ mkdir ~/docker-registry
Passa al docker-registry
directory.
$ cd ~/docker-registry
Crea una directory in cui memorizzare la password di autenticazione HTTP, i file di configurazione Nginx e i certificati SSL.
$ mkdir auth
Crea un'altra directory per memorizzare i log di Nginx.
$ mkdir logs
Crea Amazon S3 Bucket
Puoi archiviare i dati del registro e le immagini sul tuo server o utilizzare un servizio di cloud hosting. Per il nostro tutorial, utilizzeremo il servizio cloud Amazon S3.
Il passaggio successivo consiste nell'impostare il file di configurazione con alcune impostazioni importanti. Queste impostazioni possono essere definite anche in docker-compose.yml
file, ma avere un file separato è molto meglio.
Crea un bucket con le seguenti impostazioni.
- ACL dovrebbe essere disabilitato.
- L'accesso pubblico al bucket deve essere disattivato.
- Il controllo delle versioni del bucket dovrebbe essere disabilitato.
- Abilita la crittografia del bucket utilizzando le chiavi gestite di Amazon S3. (SSE-S3)
- Il blocco degli oggetti dovrebbe essere disabilitato.
Crea un utente IAM con la seguente policy.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*" } ] }
Sostituisci il S3_BUCKET_NAME
con il nome del tuo bucket S3.
Annota la chiave segreta, il valore segreto e la regione del bucket da utilizzare in seguito.
Crea file di composizione Docker
Crea il docker-compose.yml
file e aprilo per la modifica.
$ nano docker-compose.yml
Incolla il seguente codice al suo interno.
version: '3.3' services: registry: image: registry:2 restart: always environment: - REGISTRY_STORAGE=s3 - REGISTRY_STORAGE_S3_REGION=us-west-2 - REGISTRY_STORAGE_S3_BUCKET=hf-docker-registry - REGISTRY_STORAGE_S3_ENCRYPT=true - REGISTRY_STORAGE_S3_CHUNKSIZE=5242880 - REGISTRY_STORAGE_S3_SECURE=true - REGISTRY_STORAGE_S3_ACCESSKEY=AKIA3FIG4NVFCJ6STMUA - REGISTRY_STORAGE_S3_SECRETKEY=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 - REGISTRY_STORAGE_S3_V4AUTH=true - REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry - REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=inmemory - REGISTRY_HEALTH_STORAGEDRIVER_ENABLED=false nginx: image: "nginx:alpine" ports: - 443:443 links: - registry:registry volumes: - ./auth:/etc/nginx/conf.d - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro - ./logs:/var/log/nginx - /etc/letsencrypt:/etc/letsencrypt
Salva il file premendo Ctrl + X e inserendo Y quando richiesto.
Esaminiamo ciò che abbiamo impostato nel nostro file di composizione.
-
Il primo passo è prendere l'ultima immagine della versione 2 del registro Docker dall'hub. Non stiamo utilizzando il tag più recente perché potrebbe causare problemi in caso di aggiornamento di una versione principale. L'impostazione su 2 ti consente di acquisire tutti gli aggiornamenti 2.x impedendo l'aggiornamento automatico alla versione principale successiva, che può introdurre modifiche sostanziali.
-
Il contenitore del registro è impostato per riavviarsi sempre in caso di guasto o arresto imprevisto.
-
Abbiamo impostato varie variabili di ambiente per lo storage Amazon S3. Esaminiamoli rapidamente.
- STORAGE_REGISTRY imposta il tipo di archiviazione. Abbiamo selezionato s3 poiché stiamo utilizzando Amazon S3.
- REGISTRY_STORAGE_S3_REGION imposta la regione del tuo bucket S3.
- REGISTRY_STORAGE_S3_BUCKET imposta il nome del tuo bucket S3.
- REGISTRY_STORAGE_S3_ENCRYPT - impostalo su true se hai abilitato la crittografia Bucket.
- REGISTRY_STORAGE_S3_CHUNKSIZE imposta la dimensione dei blocchi di caricamento. Dovrebbe essere maggiore di 5 MB (5 * 1024 * 1024).
- REGISTRY_STORAGE_S3_SECURE - impostalo su true se intendi utilizzare HTTPS.
- REGISTRY_STORAGE_S3_ACCESSKEY e REGISTRY_STORAGE_S3_SECRETKEY - Credenziali utente che hai acquisito dopo aver creato il tuo utente IAM.
- REGISTRY_STORAGE_S3_V4AUTH - impostalo su true se utilizzi la v4 dell'autenticazione AWS. Se ricevi errori relativi all'accesso a S3, impostalo su false.
- REGISTRY_STORAGE_S3_ROOTDIRECTORY - imposta la directory principale nel tuo bucket in cui verranno archiviati i dati del registro.
- REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - imposta la posizione per la cache. Nel nostro caso, lo stiamo archiviando in memoria. Puoi anche impostarlo per utilizzare Redis.
- REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - Impostalo su false per disabilitare il servizio di controllo dello stato di archiviazione del registro. C'è un bug nel registro che può causare problemi se non lo imposti su false.
-
Il registro Docker comunica tramite la porta 5000, che è ciò che abbiamo esposto nel nostro server alla finestra mobile.
-
./auth:/etc/nginx/conf.d
la mappatura assicura che tutte le impostazioni di Nginx siano disponibili nel contenitore. -
./auth/nginx.conf:/etc/nginx/nginx.conf:ro
mappa il file delle impostazioni di Nginx dal sistema a uno nel contenitore in modalità di sola lettura. -
./logs:/var/log/nginx
consente l'accesso ai registri di Nginx sul sistema mappando la directory dei registri di Nginx nel contenitore. -
Le impostazioni del registro Docker sono archiviate in
/etc/docker/registry/config.yml
nel contenitore e lo abbiamo mappato suconfig.yml
file nella directory corrente, che creeremo nel passaggio successivo.
Configura l'autenticazione
Per impostare l'autenticazione HTTP, devi installare httpd-tools
pacchetto.
$ sudo dnf install httpd-tools
Crea il file della password in ~/docker-registry/auth
directory.
$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1 New password: Re-type new password: Adding password for user user1
Il -c
flag indica al comando di creare un nuovo file e il -B
flag è utilizzare l'algoritmo bcrypt supportato da Docker. Sostituisci user1
con un nome utente a tua scelta.
Se vuoi aggiungere più utenti, esegui di nuovo il comando, ma senza il -c
bandiera.
$ htpasswd -B ~/docker-registry/auth/registry.password user2
Ora, il file verrà mappato al contenitore del registro per l'autenticazione.
Fase 4 - Installa SSL
Per installare un certificato SSL utilizzando Let's Encrypt, dobbiamo scaricare lo strumento Certbot, disponibile dal repository Epel.
Installa repository EPEL e Certbot.
$ sudo dnf install epel-release $ sudo dnf install certbot
Genera un certificato SSL.
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d registry.example.com
Il comando precedente scaricherà un certificato in /etc/letsencrypt/live/registry.example.com
directory sul tuo server.
Genera un gruppo Diffie-Hellman certificato.
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
Testare il rinnovo del certificato.
$ sudo certbot renew --dry-run
Se il ciclo di prova ha esito positivo, significa che i tuoi certificati verranno rinnovati automaticamente.
Copia il file Dhparam nel container
Copia il gruppo Diffie-Hellman certificato al ~/docker-registry/auth
directory, che verrà mappata al contenitore.
$ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth
Passaggio 5 - Configura Nginx
Il passaggio successivo prevede la configurazione del server Nginx come proxy front-end per il server del registro Docker. Il registro Docker viene fornito con un server integrato che opera sulla porta 5000. Lo metteremo dietro Nginx.
Crea e apri il file ~/docker-registry/auth/nginx.conf
per la modifica.
$ sudo nano ~/docker-registry/auth/nginx.conf
Incolla il seguente codice al suo interno.
events { worker_connections 1024; } http { upstream docker-registry { server registry:5000; } ## Set a variable to help us decide if we need to add the ## 'Docker-Distribution-Api-Version' header. ## The registry always sets this header. ## In the case of nginx performing auth, the header is unset ## since nginx is auth-ing before proxying. map $upstream_http_docker_distribution_api_version $docker_distribution_api_version { '' 'registry/2.0'; } server { listen 443 ssl http2; server_name registry.example.com; # SSL ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/registry.example.com/chain.pem; access_log /var/log/nginx/registry.access.log; error_log /var/log/nginx/registry.error.log; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1; ssl_session_cache shared:SSL:10m; ssl_dhparam /etc/nginx.d/conf.d/dhparam.pem; resolver 8.8.8.8; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) chunked_transfer_encoding on; location /v2/ { # Do not allow connections from docker 1.5 and earlier # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } # To add basic authentication to v2 use auth_basic setting. auth_basic "Registry realm"; auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; ## If $docker_distribution_api_version is empty, the header is not added. ## See the map directive above where this variable is defined. add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; proxy_pass http://docker-registry; proxy_set_header Host $http_host; # required for docker client's sake proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 900; } } }
Salva il file premendo Ctrl + X e inserendo Y quando richiesto una volta terminato.
Configura SELinux per consentire le connessioni di rete per il Private Docker Registry.
$ sudo setsebool -P httpd_can_network_connect on
Passaggio 6:avvia il registro Docker
Passa alla directory del registro Docker.
$ cd ~/docker-registry
Avvia il contenitore Docker.
$ docker-compose up -d
Controlla lo stato dei contenitori.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 88d6addc1687 nginx:alpine "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp docker-registry_nginx_1 2b112edc1c72 registry:2 "/entrypoint.sh /etc…" 5 minutes ago Up 5 minutes 5000/tcp docker-registry_registry_1
Accedi al registro Docker.
$ docker login -u=testuser -p=testpassword https://registry.example.com
Puoi anche aprire l'URL https://registry.example.com/v2/
nel tuo browser e ti chiederà un nome utente e una password. Dovresti vedere una pagina vuota con {} su di esso.
Puoi controllare l'URL sul terminale usando curl
.
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/ Enter host password for user 'testuser': {}
Scarica l'ultima immagine della finestra mobile di Ubuntu.
$ docker pull ubuntu:latest
Contrassegna questa immagine per il registro privato.
$ docker tag ubuntu:latest registry.example.com/ubuntu2004
Invia l'immagine al registro.
$ docker push registry.example.com/ubuntu2004
Verifica se il push ha avuto successo.
$ curl -u testuser -X GET https://registry.nspeaks.xyz/v2/_catalog Enter host password for user 'testuser': {"repositories":["ubuntu2004"]}
Inserisci la tua password di autenticazione Nginx quando richiesto e vedrai l'elenco dei repository disponibili tramite il registro.
Controlla l'elenco delle immagini Docker attualmente disponibili per l'uso.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry 2 d3241e050fc9 5 days ago 24.2MB nginx alpine 53722defe627 5 days ago 23.4MB httpd 2 118b6abfbf55 5 days ago 144MB ubuntu latest ff0fea8310f3 2 weeks ago 72.8MB registry.nspeaks.xyz/ubuntu2004 latest ff0fea8310f3 2 weeks ago 72.8MB
Passaggio 7:accesso e utilizzo del registro Docker dal computer client
Accedi al tuo client-server. Nel passaggio 1, abbiamo installato Docker sul computer client.
Accedi al registro Docker privato dal computer client.
$ docker login -u=testuser -p=testpassword https://registry.example.com
Estrai l'immagine di Ubuntu dal registro.
$ docker pull registry.example.com/ubuntu2004
Elenca tutte le immagini sul tuo computer client.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.nspeaks.xyz/ubuntu2004 latest ff0fea8310f3 2 weeks ago 72.8MB
Crea e avvia un contenitore utilizzando l'immagine scaricata.
$ docker run -it registry.example.com/ubuntu2004 /bin/bash
Verrai effettuato l'accesso alla Shell all'interno del contenitore Ubuntu.
[email protected]:
Esegui il comando seguente per verificare la versione di Linux.
[email protected]$ cat /etc/os-release NAME="Ubuntu" VERSION="20.04.4 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.4 LTS" VERSION_ID="20.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=focal UBUNTU_CODENAME=focal
Ora puoi iniziare a utilizzare il registro Docker dalle macchine client.
Conclusione
Questo conclude il nostro tutorial sulla configurazione di un registro Docker privato su un server basato su Rocky Linux 8 che utilizza Amazon S3 come storage. Se hai domande, pubblicale nei commenti qui sotto.