Ricerca nel sito web

Come impostare un registro Docker privato su Rocky Linux 8


Su questa pagina

  1. Prerequisiti
  2. Passaggio 1: configurazione del firewall
  3. Passaggio 2 - Installa Docker e Docker Compose
  4. Passaggio 3: configurazione del registro Docker
    1. Crea directory utente
    2. Crea un bucket Amazon S3
    3. Crea file di composizione Docker
    4. Imposta l'autenticazione

    1. Copia il file Dhparam nel contenitore

    Se lavori per un'organizzazione e desideri mantenere le tue immagini docker interne per una rapida distribuzione, l'hosting di un repository Docker privato è perfetto. Avere un registro docker privato ti consente di possedere la tua pipeline di distribuzione delle immagini e avere un controllo più stretto sull'archiviazione e la 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: configurare il firewall

    Il primo passo è configurare il firewall. Rocky Linux utilizza Firewalld Firewall. Controlla lo stato dei firewall.

    $ sudo firewall-cmd --state
    running
    

    Il firewall funziona con zone diverse e la zona pubblica è quella predefinita che utilizzeremo. 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: installa 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 utilizzare sudo per eseguire i comandi Docker.

    $ sudo usermod -aG docker $(whoami)
    

    Accedi nuovamente 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
    

    Applicare le autorizzazioni eseguibili al file binario scaricato.

    $ sudo chmod +x /usr/local/bin/docker-compose
    

    Installa lo script Bash Completion di Docker-compose.

    $ 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: configurare il registro Docker

    Crea directory utente

    Creare una directory per la configurazione del registro.

    $ mkdir ~/docker-registry
    

    Passa alla directory docker-registry.

    $ cd ~/docker-registry
    

    Crea una directory per archiviare la password di autenticazione HTTP, i file di configurazione di Nginx e i certificati SSL.

    $ mkdir auth
    

    Crea un'altra directory per archiviare i log Nginx.

    $ mkdir logs
    

    Crea un bucket Amazon S3

    Puoi archiviare i dati anagrafici 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 anche essere definite nel file docker-compose.yml, ma avere un file separato è molto meglio.

    Crea un bucket con le seguenti impostazioni.

    • L'ACL dovrebbe essere disabilitato.
    • L'accesso pubblico al bucket deve essere disabilitato.
    • Il controllo delle versioni del bucket deve essere disabilitato.
    • Abilita la crittografia del bucket utilizzando le chiavi gestite da Amazon S3. (SSE-S3)
    • Il blocco dell'oggetto deve 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 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 file docker-compose.yml 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.

    1. Il primo passaggio consiste nell'acquisire l'immagine più recente 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 consente di acquisire tutti gli aggiornamenti 2.x impedendo l'aggiornamento automatico alla versione principale successiva, che può introdurre modifiche sostanziali.
    2. Il contenitore del registro è impostato per riavviarsi sempre in caso di errore o arresto imprevisto.
    3. Abbiamo impostato varie variabili di ambiente per lo storage Amazon S3. Esaminiamoli rapidamente.
      • REGISTRY_STORAGE imposta il tipo di archiviazione. Abbiamo selezionato s3 poiché utilizziamo 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 del bucket.
      • REGISTRY_STORAGE_S3_CHUNKSIZE imposta la dimensione dei blocchi di caricamento. Dovrebbe essere più grande 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 acquisite dopo aver creato l'utente IAM.
      • REGISTRY_STORAGE_S3_V4AUTH: impostalo su true se utilizzi la v4 dell'autenticazione AWS. Se ricevi errori relativi all'accesso S3, impostalo su false.
      • REGISTRY_STORAGE_S3_ROOTDIRECTORY - imposta la directory root nel bucket in cui verranno archiviati i dati del registro.
      • REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - imposta la posizione per la cache. Nel nostro caso, lo stiamo memorizzando. Puoi anche impostarlo per utilizzare Redis.
      • REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - Impostalo su false per disabilitare il servizio di controllo dello stato di archiviazione di Registrys. C'è un bug con il registro che può causare problemi se non lo si imposta su false.
    4. Il registro Docker comunica tramite la porta 5000, che è ciò che abbiamo esposto nel nostro server alla finestra mobile.
    5. La mappatura ./auth:/etc/nginx/conf.d assicura che tutte le impostazioni di Nginxs siano disponibili nel contenitore.
    6. ./auth/nginx.conf:/etc/nginx/nginx.conf:ro mappa il file delle impostazioni Nginx dal sistema a uno nel contenitore in modalità di sola lettura.
    7. ./logs:/var/log/nginx consente l'accesso ai log Nginxs sul sistema mappando alla directory dei log Nginx nel contenitore.
    8. Le impostazioni dei registri Docker sono memorizzate nel file /etc/docker/registry/config.yml nel contenitore e lo abbiamo mappato al config.yml file nella directory corrente, che creeremo nel passaggio successivo.

    Imposta l'autenticazione

    Per configurare l'autenticazione HTTP, è necessario installare il pacchetto httpd-tools.

    $ sudo dnf install httpd-tools
    

    Crea il file della password nella directory ~/docker-registry/auth.

    $ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1
    New password:
    Re-type new password:
    Adding password for user user1
    

    Il flag -c indica al comando di creare un nuovo file e il flag -B serve per utilizzare l'algoritmo bcrypt supportato da Docker. Sostituisci user1 con un nome utente a tua scelta.

    Se vuoi aggiungere altri utenti, esegui di nuovo il comando, ma senza il flag -c.

    $ htpasswd -B ~/docker-registry/auth/registry.password user2
    

    Ora, il file verrà mappato al contenitore del registro per l'autenticazione.

    Passaggio 4: installa SSL

    Per installare un certificato SSL utilizzando Lets Encrypt, dobbiamo scaricare lo strumento Certbot, disponibile dal repository Epel.

    Installa il 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  -d registry.example.com
    

    Il comando precedente scaricherà un certificato nella directory /etc/letsencrypt/live/registry.example.com sul tuo server.

    Genera un certificato di gruppo Diffie-Hellman.

    $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
    

    Testare il rinnovo del certificato.

    $ sudo certbot renew --dry-run
    

    Se il test ha esito positivo, significa che i certificati verranno rinnovati automaticamente.

    Copia il file Dhparam nel contenitore

    Copia il certificato del gruppo Diffie-Hellman nella directory ~/docker-registry/auth, che verrà mappata al contenitore.

    $ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth
    

    Passaggio 5: configurare 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 registro Docker privato.

    $ sudo setsebool -P httpd_can_network_connect on
    

    Passaggio 6: avvia il registro Docker

    Passa alla directory Docker Registrys.

    $ 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 {} sopra.

    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/ubunt4
    

    Invia l'immagine al registro.

    $ docker push registry.example.com/ubunt4
    

    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":["ubunt4"]}
    

    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/ubunt4       latest    ff0fea8310f3   2 weeks ago   72.8MB
    

    Passaggio 7: accedere e utilizzare il 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/ubunt4
    

    Elenca tutte le immagini sul tuo computer client.

    $ docker images
    REPOSITORY                        TAG        IMAGE ID       CREATED         SIZE
    registry.nspeaks.xyz/ubunt4   latest     ff0fea8310f3   2 weeks ago     72.8MB
    

    Crea e avvia un contenitore utilizzando l'immagine scaricata.

    $ docker run -it registry.example.com/ubunt4 /bin/bash
    

    Verrai connesso alla shell all'interno del contenitore Ubuntu.

    :
    

    Eseguire il seguente comando per verificare la versione di Linux.

    $ 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 tuo registro Docker dai tuoi computer 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.