Како да поставите приватен докер регистар на Ubuntu 22.04


Авторот ја избра програмата Пишувај за донации.

Вовед

TravisCI, за беспрекорно ажурирање на сликите за време на производството и развојот.

Docker Hub е бесплатен јавен регистар кој може да ги хостира вашите сопствени слики на Docker, но има ситуации кога нема да сакате вашата слика да биде јавно достапна. Сликите обично го содржат целиот код неопходен за извршување на апликацијата, така што користењето на приватен регистар може да се претпочита кога се користи комерцијален софтвер.

Во ова упатство, ќе поставите и обезбедите сопствен приватен Docker Registry. Ќе го користите Docker Compose за да ги дефинирате конфигурациите што ги извршуваат вашите Docker контејнери и Nginx за пренасочување на сообраќајот на серверот од интернет до активниот Docker контејнер. Откако ќе го завршите ова упатство, ќе можете да турнете приспособена слика на Docker во вашиот приватен регистар и безбедно да ја повлечете сликата од оддалечен сервер.

Предуслови

За да го завршите ова упатство, ќе ви треба следново:

  • Два Ubuntu 22.04 сервери поставени со следење на Водичот за првично поставување на серверот Ubuntu 22.04, вклучително и sudo не-root корисник и заштитен ѕид. Еден сервер ќе го домаќини вашиот приватен Docker Registry, а другиот ќе биде вашиот клиент сервер.
  • Докер е инсталиран на двата сервери, кој можете да го поставите следејќи ги чекорите 1 и 2 од Како да го инсталирате и користите Docker на Ubuntu 22.04.

На серверот домаќин, ќе треба да поставите:

  • Docker Compose е инсталиран на серверот домаќин, кој можете да го поставите следејќи го чекор 1 од Како да инсталирате и користите Docker Compose на Ubuntu 22.04.
  • Nginx е инсталиран на вашиот сервер домаќин, кој можете да го поставите следејќи ги чекорите во Како да инсталирате Nginx на Ubuntu 22.04.
  • Nginx е обезбеден со Let’s Encrypt на вашиот сервер домаќин за приватниот Docker Registry, кој можете да го поставите следејќи го упатството Како да се обезбеди Nginx со Let’s Encrypt на Ubuntu 22.04. Погрижете се да го пренасочите целиот сообраќај од HTTP на HTTPS во чекор 4.
    • Регистрирано име на домен што се решава на серверот што го користите за хостирање на приватниот Docker Registry. Ќе го поставите ова како дел од предусловот Let’s Encrypt. Во ова упатство, ќе го нарекуваме вашиот_домен.

    Чекор 1 - Инсталирање и конфигурирање на регистарот Docker

    Работењето на Docker на командната линија е корисно при стартување и тестирање на контејнерите, но може да стане незгодно со поголеми распоредувања кои вклучуваат повеќе контејнери кои работат паралелно.

    Со Docker Compose, пишувате една датотека .yml за да ја поставите конфигурацијата на секој контејнер и информациите што им се потребни на контејнерите за да комуницираат едни со други. Можете да ја користите алатката docker compose за да издавате команди на сите компоненти што ја сочинуваат вашата апликација и да ги контролирате како група.

    Docker Registry сам по себе е апликација со повеќе компоненти, така што ќе го користите Docker Compose за да управувате со него. За да започнете примерок од регистарот, ќе поставите датотека docker-compose.yml за да ја дефинирате и локацијата на дискот каде што вашиот регистар ќе ги складира своите податоци.

    Ќе ја зачувате конфигурацијата во директориум наречен docker-registry на серверот домаќин. Создадете го со извршување:

    1. mkdir ~/docker-registry

    Одете до него:

    1. cd ~/docker-registry

    Потоа, креирајте поддиректориум наречен податоци, каде што вашиот регистар ќе ги складира неговите слики:

    1. mkdir data

    Креирајте и отворете датотека наречена docker-compose.yml со извршување:

    1. nano docker-compose.yml

    Додадете ги следните линии, кои дефинираат основен примерок на Docker Registry:

    version: '3'
    
    services:
      registry:
        image: registry:latest
        ports:
        - "5000:5000"
        environment:
          REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
        volumes:
          - ./data:/data
    

    Прво, ја именувате првата услуга регистар и ја поставувате нејзината слика во регистар, користејќи ја најновата верзија. Потоа, под ports, ја мапирате портата 5000 на домаќинот до портата 5000 на контејнерот, што ќе ви овозможи да испратите барање до приклучете 5000 на серверот и побарајте да го проследите до регистарот.

    Во делот околина, ја поставивте променливата REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY на /data, одредувајќи во кој волумен треба да ги складира своите податоци. Потоа, во делот volumes, го мапирате директориумот /data на датотечниот систем на домаќинот на /data во контејнерот, кој делува како премин. Податоците всушност ќе бидат зачувани на датотечниот систем на домаќинот.

    Зачувајте ја и затворете ја датотеката.

    Сега можете да ја стартувате конфигурацијата со извршување:

    1. docker compose up

    Контејнерот со регистарот и неговите зависности ќе се преземат и стартуваат.

    Output
    [+] Running 2/2 ⠿ Network docker-registry_default Created 0.1s ⠿ Container docker-registry-registry-1 Created 0.1s Attaching to docker-registry-registry-1 docker-registry-registry-1 | time="2022-11-19T14:31:20.40444638Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." go.version=go1.16.15 instance.id=4fb8d420-eaf8-4a69-b740-bdc94fa52d91 service=registry version="v2.8.1+unknown" docker-registry-registry-1 | time="2022-11-19T14:31:20.404960549Z" level=info msg="redis not configured" go.version=go1.16.15 instance.id=4fb8d420-eaf8-4a69-b740-bdc94fa52d91 service=registry version="v2.8.1+unknown" docker-registry-registry-1 | time="2022-11-19T14:31:20.412312462Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.16.15 instance.id=4fb8d420-eaf8-4a69-b740-bdc94fa52d91 service=registry version="v2.8.1+unknown" docker-registry-registry-1 | time="2022-11-19T14:31:20.412803878Z" level=info msg="Starting upload purge in 52m0s" go.version=go1.16.15 instance.id=4fb8d420-eaf8-4a69-b740-bdc94fa52d91 service=registry version="v2.8.1+unknown" docker-registry-registry-1 | time="2022-11-19T14:31:20.41296431Z" level=info msg="listening on [::]:5000" go.version=go1.16.15 instance.id=4fb8d420-eaf8-4a69-b740-bdc94fa52d91 service=registry version="v2.8.1+unknown" ...

    Ќе се обратите на предупредувачката порака Не е обезбедена HTTP тајна подоцна во ова упатство.

    Последната линија на излезот покажува дека успешно започнала, слушајќи на порта 5000.

    Можете да притиснете CTRL+C за да го запрете неговото извршување.

    Во овој чекор, создадовте конфигурација на Docker Compose што започнува да слуша Docker Registry на портата 5000. Во следните чекори, ќе го изложите на вашиот домен и ќе поставите автентикација.

    Чекор 2 - Поставување Nginx Port Forwarding

    Како дел од предусловите, овозможивте HTTPS на вашиот домен. За да го откриете вашиот заштитен регистар на Docker таму, ќе треба да го конфигурирате Nginx да го проследува сообраќајот од вашиот домен до контејнерот на регистарот.

    Веќе ја поставивте датотеката /etc/nginx/sites-available/your_domain, која ја содржи конфигурацијата на вашиот сервер. Отворете го за уредување со извршување:

    1. sudo nano /etc/nginx/sites-available/your_domain

    Најдете го постојниот блок локација:

    ...
            location / {
      ...
            }
    ...
    

    Треба да го пренасочите сообраќајот до портата 5000, каде што вашиот регистар ќе го слуша сообраќајот. Исто така, сакате да додадете заглавија на барањето проследено до регистарот, кој обезбедува дополнителни информации од серверот за самото барање. Заменете ја постоечката содржина на блокот location со следните редови:

    ...
    location / {
        # 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;
        }
    
        proxy_pass                          http://localhost:5000;
        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;
    }
    ...
    

    Блокот if го проверува корисничкиот агент на барањето и потврдува дека верзијата на клиентот Docker е над 1,5 и дека не е апликација Go што се обидува да пристапи. За повеќе објаснувања за ова, можете да ја најдете конфигурацијата на заглавието nginx во водичот Nginx на регистарот на Docker.

    Зачувајте ја и затворете ја датотеката кога ќе завршите. Применете ги промените со рестартирање на Nginx:

    1. sudo systemctl restart nginx

    Ако примите порака за грешка, проверете ја повторно конфигурацијата што сте ја додале.

    За да потврдите дека Nginx правилно го препраќа сообраќајот до вашиот контејнер за регистар на портата 5000, стартувајте го:

    1. docker compose up

    Потоа, во прозорецот на прелистувачот, одете до вашиот домен и пристапете до крајната точка v2, вака:

    https://your_domain/v2
    

    Прелистувачот ќе вчита празен JSON објект:

    {}
    

    Во вашиот терминал, ќе добиете излез сличен на следново:

    Output
    docker-registry-registry-1 | time="2022-11-19T14:32:50.082396361Z" level=info msg="response completed" go.version=go1.16.15 http.request.host=your_domain http.request.id=779fe265-1a7c-4a15-8ae4-eeb5fc35de98 http.request.method=GET http.request.remoteaddr=87.116.166.89 http.request.uri="/v2" http.request.useragent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" http.response.contenttype="text/html; charset=utf-8" http.response.duration="162.546µs" http.response.status=301 http.response.written=39 docker-registry-registry-1 | 172.19.0.1 - - [19/Nov/2022:14:32:50 +0000] "GET /v2 HTTP/1.0" 301 39 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" docker-registry-registry-1 | 172.19.0.1 - - [19/Nov/2022:14:32:50 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" docker-registry-registry-1 | time="2022-11-19T14:32:50.132472674Z" level=info msg="response completed" go.version=go1.16.15 http.request.host=your_domain http.request.id=0ffb17f0-c2a0-49d6-94f3-af046cfb96e5 http.request.method=GET http.request.remoteaddr=87.116.166.89 http.request.uri="/v2/" http.request.useragent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" http.response.contenttype="application/json; charset=utf-8" http.response.duration=2.429608ms http.response.status=200 http.response.written=2 docker-registry-registry-1 | 172.19.0.1 - - [19/Nov/2022:14:32:50 +0000] "GET /favicon.ico HTTP/1.0" 404 19 "your_domain/v2/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"

    Од последната линија, знаете дека е поднесено барање GET до /v2/, што е крајната точка до која испративте барање. Контејнерот го прими барањето што го направивте поради препраќање на портата и врати одговор од {}. Кодот 200 значи дека контејнерот успешно се справи со барањето.

    Притиснете CTRL+C за да го запрете неговото извршување.

    Сега кога поставивте препраќање порти, ќе ја подобрите безбедноста на вашиот регистар.

    Чекор 3 - Поставување автентикација

    Nginx ви овозможува да поставите HTTP автентикација за сајтовите што ги управува, што можете да ги користите за да го ограничите пристапот до вашиот Docker Registry. За да го постигнете ова, ќе создадете датотека за автентикација со htpasswd и ќе додадете комбинации на корисничко име и лозинка во неа што ќе бидат прифатени. Тој процес ќе овозможи автентикација на вашиот регистар.

    Можете да ја добиете алатката htpasswd со инсталирање на пакетот apache2-utils. Направете го тоа со трчање:

    1. sudo apt install apache2-utils -y

    Ќе ја зачувате датотеката за автентикација со ингеренциите под ~/docker-registry/auth. Создадете го со извршување:

    1. mkdir ~/docker-registry/auth

    Одете до него:

    1. cd ~/docker-registry/auth

    Направете го првиот корисник, заменете го корисничко име со корисничкото име што сакате да го користите. Знамето -B наредува користење на алгоритмот bcrypt, што го бара Докер:

    1. htpasswd -Bc registry.password username

    Внесете лозинка кога ќе биде побарано. Комбинацијата на ингеренциите ќе биде додадена на registry.password.

    Забелешка: за да додадете повеќе корисници, повторно извршете ја претходната команда без -c:

    1. htpasswd -B registry.password username

    -c создава нова датотека, па со нејзино отстранување ќе се ажурира постоечката датотека.

    Сега кога е направен списокот со акредитиви, ќе го уредите docker-compose.yml за да му наредите на Docker да ја користи датотеката што сте ја создале за автентикација на корисниците. Отворете го за уредување:

    1. nano ~/docker-registry/docker-compose.yml

    Додадете ги означените линии:

    version: '3'
    
    services:
      registry:
        image: registry:latest
        ports:
        - "5000:5000"
        environment:
          REGISTRY_AUTH: htpasswd
          REGISTRY_AUTH_HTPASSWD_REALM: Registry
          REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
          REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
        volumes:
          - ./auth:/auth
          - ./data:/data
    

    Додадовте променливи на околината кои ја одредуваат употребата на HTTP автентикација и ја обезбедуваат патеката до креираната датотека htpasswd. За REGISTRY_AUTH, наведовте htpasswd како негова вредност, што е шемата за автентикација што ја користите и го поставивте REGISTRY_AUTH_HTPASSWD_PATH на патеката на датотеката за автентикација . REGISTRY_AUTH_HTPASSWD_REALM го означува името на областа htpasswd.

    Го монтиравте и директориумот ./auth за да ја направите датотеката достапна во контејнерот на регистарот. Зачувајте ја и затворете ја датотеката.

    Сега можете да потврдите дека вашата автентикација работи правилно. Прво, одете до главниот директориум:

    1. cd ~/docker-registry

    Потоа, стартувајте го регистарот со извршување:

    1. docker compose up

    Во вашиот прелистувач, освежете ја страницата на вашиот домен. Ќе ви биде побарано корисничко име и лозинка.

    Откако ќе обезбедите валидна комбинација на ингеренциите, ќе пристапите на страницата со празниот JSON објект:

    {}
    

    Успешно ја потврдивте автентичноста и добивте пристап до регистарот. Излезете со притискање на CTRL+C во вашиот терминал.

    Вашиот регистар сега е заштитен и може да се пристапи само по автентикација. Следно ќе го конфигурирате да работи како процес во заднина, а истовремено да биде отпорен на рестартирање со автоматско стартување.

    Чекор 4 - Започнување на Docker Registry како услуга

    Може да се осигурате дека контејнерот на регистарот се стартува секогаш кога системот ќе се подигне или откако ќе се урне, со инструкции на Docker Compose секогаш да работи.

    Отворете го docker-compose.yml за уредување:

    1. nano docker-compose.yml

    Додајте ја следнава линија во блокот регистар:

    ...
      registry:
        restart: always
    ...
    

    Поставувањето рестартирај на секогаш осигурува дека контејнерот ќе ги преживее рестартирањето. Кога ќе завршите, зачувајте ја и затворете ја датотеката.

    Сега можете да го стартувате вашиот регистар како процес во заднина со префрлање во -d:

    1. docker compose up -d

    Кога вашиот регистар работи во заднина, можете слободно да ја затворите оваа SSH сесија, терминалот и регистарот нема да биде засегнат.

    Бидејќи сликите на Docker може да бидат многу големи по големина, следно ќе ја зголемите максималната големина на датотеката што Nginx ќе ја прифати за прикачувања.

    Чекор 5 - Зголемување на големината на поставување датотека за Nginx

    Пред да можете да туркате слика во регистарот, треба да се осигурате дека вашиот регистар ќе може да се справи со прикачувања на големи датотеки. Стандардното ограничување на големината на прикачуваните датотеки во Nginx е 1 m, што не е ни приближно доволно за сликите на Docker. За да го подигнете, ќе ја измените главната конфигурациска датотека Nginx, која се наоѓа на /etc/nginx/nginx.conf.

    Отворете го за уредување:

    1. sudo nano /etc/nginx/nginx.conf

    Додајте ја означената линија во делот http:

    ...
    http {
            client_max_body_size 16384m;
            ...
    }
    ...
    

    Параметарот client_max_body_size сега е поставен на 16384m, со што максималната големина на прикачување е еднаква на 16 GB.

    Зачувајте ја и затворете ја датотеката.

    Рестартирајте го Nginx за да ги примените промените во конфигурацијата:

    1. sudo systemctl restart nginx

    Во овој чекор, ја ажуриравте големината на датотеката дозволена од Nginx. Сега можете да прикачувате големи слики во вашиот Docker Registry без Nginx да го блокира преносот или да направи грешка.

    Чекор 6 - Објавување во вашиот приватен докер регистар

    Сега кога вашиот Docker Registry сервер работи и прифаќа големи димензии на датотеки, можете да се обидете да туркате слика на неа. Бидејќи немате никакви слики лесно достапни, ќе ја користите сликата ubuntu од Docker Hub, јавен Docker регистар, за да го тестирате ова.

    Во нова терминална сесија за вашиот клиентски сервер, извршете ја следнава команда за да ја преземете сликата ubuntu, да ја извршите и да добиете пристап до нејзината школка:

    1. docker run -t -i ubuntu /bin/bash

    Знамените -i и -t ви даваат интерактивен пристап на школка во контејнерот.

    Откако ќе влезете, креирајте датотека наречена SUCCESS со извршување:

    1. touch /SUCCESS

    Со креирање на оваа датотека, го приспособивте вашиот контејнер. Подоцна ќе го користите за да проверите дали го користите токму истиот контејнер.

    Излезете од лушпата на контејнерот трчајќи:

    1. exit

    Сега креирајте нова слика од контејнерот што штотуку го приспособивте:

    1. docker commit $(docker ps -lq) test-image

    Новата слика сега е достапна локално и ќе ја турнете во регистарот на контејнер. Прво, треба да се најавите:

    1. docker login https://your_domain

    Кога ќе биде побарано, внесете ги ингеренциите за корисничко име и лозинка што ги дефиниравте во Чекор 3.

    Излезот ќе биде:

    Output
    ... Login Succeeded

    Откако ќе се најавите, преименувајте ја креираната слика:

    1. docker tag test-image your_domain/test-image

    Конечно, турнете ја новоозначената слика во вашиот регистар:

    1. docker push your_domain/test-image

    Ќе добиете излез сличен на следново:

    Output
    Using default tag: latest The push refers to a repository [your_domain/test-image] 1cf9c9034825: Pushed f4a670ac65b6: Pushed latest: digest: sha256:95112d0af51e5470d74ead77932954baca3053e04d201ac4639bdf46d5cd515b size: 736

    Потврдивте дека вашиот регистар се справува со автентикација на корисникот со најавување и дека им овозможува на автентицираните корисници да туркаат слики во регистарот. Сега ќе се обидете да ја повлечете сликата од вашиот регистар.

    Чекор 7 - Повлекување од вашиот приватен докер регистар

    Сега, кога сте ставиле слика во вашиот приватен регистар, ќе се обидете да повлечете од неа.

    На главниот сервер, најавете се со корисничкото име и лозинката што ги поставивте претходно:

    1. docker login https://your_domain

    Обидете се да ја повлечете тест-слика со извршување:

    1. docker pull your_domain/test-image

    Докер ќе ја преземе сликата. Стартувај го контејнерот со следнава команда:

    1. docker run -it your_domain/test-image /bin/bash

    Ќе ја вчита лушпата за контејнерот.

    Наведете ги присутните датотеки со извршување:

    1. ls

    Списокот на датотеки ќе ја вклучи датотеката SUCCESS што сте ја создале порано, потврдувајќи дека овој контејнер ја користи истата слика што сте ја создале:

    1. SUCCESS bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

    Излезете од лушпата на контејнерот:

    1. exit

    Тестиравте туркање и влечење слики и завршивте со поставување безбеден регистар што можете да го користите за складирање на сопствени слики.

    Заклучок

    Во ова упатство, поставивте сопствен приватен Docker Registry и објавивте слика на Docker на него. Како што беше споменато во воведот, можете исто така да користите TravisCI или слична CI алатка за да го автоматизирате директното притискање до приватен регистар.

    Со користење на Docker контејнерите во вашиот работен тек, можете да се осигурате дека сликата што го содржи кодот ќе резултира со исто однесување на која било машина, без разлика дали е во производство или во развој. За повеќе информации за пишување датотеки на Docker, можете да ги посетите официјалните документи за најдобри практики.