Поиск по сайту:

Как настроить частный реестр Docker в Ubuntu 22.04


Автор выбрал программу Write for DOnations.

Введение

TravisCI для беспрепятственного обновления изображений во время производства и разработки.

Docker Hub — это бесплатный общедоступный реестр, в котором могут размещаться ваши собственные образы Docker, но бывают ситуации, когда вы не хотите, чтобы ваш образ был общедоступным. Образы обычно содержат весь код, необходимый для запуска приложения, поэтому использование частного реестра может быть предпочтительнее при использовании проприетарного программного обеспечения.

В этом руководстве вы настроите и защитите свой собственный реестр Docker. Вы будете использовать Docker Compose для определения конфигураций, запускающих ваши контейнеры Docker, и Nginx для перенаправления трафика сервера из Интернета в работающий контейнер Docker. После того, как вы закончите это руководство, вы сможете отправить пользовательский образ Docker в свой частный реестр и безопасно извлечь образ с удаленного сервера.

Предпосылки

Для выполнения этого урока вам потребуется следующее:

  • Два сервера Ubuntu 22.04 настроены в соответствии с Руководством по первоначальной настройке сервера Ubuntu 22.04, включая пользователя без полномочий root sudo и брандмауэр. На одном сервере будет размещаться ваш частный реестр Docker, а другой будет вашим клиентским сервером.
  • На обоих серверах установлен Docker, который можно настроить, выполнив шаги 1 и 2 раздела Установка и использование Docker в Ubuntu 22.04.

На хост-сервере вам нужно будет настроить:

  • Docker Compose установлен на хост-сервере, который можно настроить, выполнив шаг 1 инструкции по установке и использованию Docker Compose в Ubuntu 22.04.
  • Nginx установлен на вашем хост-сервере, который вы можете настроить, выполнив действия, описанные в разделе Как установить Nginx в Ubuntu 22.04.
  • Nginx защищен с помощью Let’s Encrypt на вашем хост-сервере для частного реестра Docker, который вы можете настроить, следуя руководству Как защитить Nginx с помощью Let’s Encrypt в Ubuntu 22.04. Обязательно перенаправьте весь трафик с HTTP на HTTPS на шаге 4.
    • Зарегистрированное доменное имя, которое разрешается в сервер, который вы используете для размещения частного реестра Docker. Вы настроите это как часть предварительного условия Let’s Encrypt. В этом руководстве мы будем называть его your_domain.

    Шаг 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

    Затем создайте подкаталог с именем data, где ваш реестр будет хранить свои изображения:

    1. mkdir data

    Создайте и откройте файл с именем docker-compose.yml, выполнив:

    1. nano docker-compose.yml

    Добавьте следующие строки, которые определяют базовый экземпляр реестра Docker:

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

    Сначала вы назначаете имя первой службы registry и устанавливаете ее образ в registry, используя последнюю версию. Затем в разделе ports вы сопоставляете порт 5000 на хосте с портом 5000 контейнера, что позволит вам отправить запрос на порт 5000 на сервере и перенаправьте запрос в реестр.

    В разделе environment вы устанавливаете для переменной 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, прослушивающий порт 5000. На следующих шагах вы откроете его в своем домене и настроите аутентификацию.

    Шаг 2 — Настройка переадресации портов Nginx

    В рамках предварительных условий вы включили HTTPS в своем домене. Чтобы открыть доступ к вашему защищенному реестру Docker, вам нужно настроить Nginx для перенаправления трафика из вашего домена в контейнер реестра.

    Вы уже настроили файл /etc/nginx/sites-available/your_domain, содержащий конфигурацию вашего сервера. Откройте его для редактирования, запустив:

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

    Найдите существующий блок location:

    ...
            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 в руководстве Docker по реестру Nginx.

    Сохраните и закройте файл, когда закончите. Примените изменения, перезапустив 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. Для этого вы создадите файл аутентификации с помощью htpasswd и добавите в него комбинации имени пользователя и пароля, которые будут приняты. Этот процесс включит аутентификацию в вашем реестре.

    Вы можете получить утилиту htpasswd, установив пакет apache2-utils. Сделайте это, запустив:

    1. sudo apt install apache2-utils -y

    Вы сохраните файл аутентификации с учетными данными в папке ~/docker-registry/auth. Создайте его, запустив:

    1. mkdir ~/docker-registry/auth

    Перейдите к нему:

    1. cd ~/docker-registry/auth

    Создайте первого пользователя, заменив username на имя пользователя, которое вы хотите использовать. Флаг -B указывает на использование алгоритма bcrypt, который требуется Docker:

    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:

    ...
      registry:
        restart: always
    ...
    

    Установка для restart значения always гарантирует, что контейнер выдержит перезагрузку. Когда вы закончите, сохраните и закройте файл.

    Теперь вы можете запустить свой реестр как фоновый процесс, передав -d:

    1. docker compose up -d

    Когда ваш реестр работает в фоновом режиме, вы можете свободно закрыть этот сеанс SSH, терминал и реестр не будут затронуты.

    Поскольку образы Docker могут быть очень большими, вы затем увеличите максимальный размер файла, который Nginx будет принимать для загрузки.

    Шаг 5 — Увеличение размера загружаемого файла для Nginx

    Прежде чем отправлять образ в реестр, необходимо убедиться, что ваш реестр сможет обрабатывать загрузку больших файлов. Ограничение размера загружаемых файлов по умолчанию в Nginx составляет 1m, чего недостаточно для образов 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 ГБ.

    Сохраните и закройте файл.

    Перезапустите Nginx, чтобы применить изменения конфигурации:

    1. sudo systemctl restart nginx

    На этом шаге вы обновили размер файла, разрешенный Nginx. Теперь вы можете загружать большие образы в свой реестр Docker, при этом Nginx не блокирует передачу или не выдает ошибку.

    Шаг 6 — Публикация в вашем личном реестре Docker

    Теперь, когда ваш сервер 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 — Извлечение из вашего частного реестра Docker

    Теперь, когда вы отправили образ в свой частный реестр, вы попытаетесь извлечь из него данные.

    На главном сервере войдите в систему с именем пользователя и паролем, которые вы установили ранее:

    1. docker login https://your_domain

    Попробуйте получить test-image, запустив:

    1. docker pull your_domain/test-image

    Docker загрузит образ. Запустите контейнер с помощью следующей команды:

    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 и опубликовали в нем образ Docker. Как упоминалось во введении, вы также можете использовать TravisCI или аналогичный инструмент CI для автоматизации прямой отправки в частный реестр.

    Используя контейнеры Docker в своем рабочем процессе, вы можете быть уверены, что образ, содержащий код, будет вести себя одинаково на любой машине, будь то рабочая или разрабатываемая. Для получения дополнительной информации о написании файлов Docker вы можете посетить официальную документацию по лучшим практикам.