Tutorial

Настройка частного реестра Docker в Ubuntu 18.04

Published on January 7, 2020
Default avatar

By Young Kim

Co-founder, CTO @ Stealth

Русский
Настройка частного реестра Docker в Ubuntu 18.04

Автор выбрал фонд Apache Software Foundation для получения пожертвования в рамках программы Write for DOnations.

Введение

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

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

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

Предварительные требования

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

  • Два сервера Ubuntu 18.04, настроенных в соответствии с руководством по начальной настройке сервера Ubuntu 18.04, включая пользователя sudo без прав root и брандмауэр. На одном сервере будет располагаться ваш частный реестр Docker, а другой будет выступать в качестве сервера-клиента.
  • На обоих серверах должны быть установлены Docker и Docker-Compose в соответствии с указаниями обучающего модуля «Установка Docker-Compose в Ubuntu 18.04». Для установки Docker Compose достаточно выполнить первый шаг этого обучающего модуля. В этом обучающем модуле объясняется, как устанавливать Docker для выполнения предварительных требований.
  • На сервере частного реестра Docker должен быть установлен веб-сервер Nginx в соответствии с указаниями руководства «Установка Nginx в Ubuntu 18.04».
  • Веб-сервер Nginx на сервере частного реестра Docker должен быть защищен Let’s Encrypt в соответствии с указаниями обучающего модуля «Защита Nginx с помощью Let’s Encrypt». Убедитесь, что весь трафик протокола HTTP перенаправляется на протокол HTTPS в соответствии с указаниями шага 4.
  • Доменное имя для сервера, используемого вами для частного реестра Docker. Вы должны были настроить его во время выполнения предварительных требований по защите с помощью Let’s Encrypt.

Шаг 1 — Установка и настройка реестра Docker

Инструмент командной строки Docker подойдет для запуска и управления одним или двумя контейнерами Docker, но для полноценного развертывания большинства приложений, запущенных внутри контейнеров Docker, необходимо, чтобы параллельно работали и другие компоненты. Например, многие приложения включают Nginx или другой веб-сервер, обслуживающий код приложения, а также PHP или другой язык интерпретации скриптов и MySQL или другой сервер СУБД.

С помощью Docker Compose вы можете записать один файл .yml для настройки конфигурации каждого контейнера и информации, необходимой контейнерам для взаимодействия друг с другом. Затем вы можете использовать инструмент командной строки docker-compose для отправки команд всем компонентам, составляющим ваше приложение.

Реестр Docker сам по себе является приложением с несколькими компонентами, и поэтому вы будете использовать Docker Compose для управления его конфигурацией. Чтобы запустить экземпляр реестра, вам нужно задать в файле docker-compose.yml место, где ваш реестр будет хранить свои данные.

На том же сервере, который вы создали для размещения частного реестра Docker, вы можете создать каталог docker-registry, перейти в него, а затем создать подпапку data с помощью следующих команд:

  1. mkdir ~/docker-registry && cd $_
  2. mkdir data

Используйте текстовый редактор для создания файла конфигурации docker-compose.yml:

  1. nano docker-compose.yml

Добавьте в файл следующие строки, описывающие базовую конфигурацию реестра Docker:

docker-compose.yml
version: '3'

services:
  registry:
    image: registry:2
    ports:
    - "5000:5000"
    environment:
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./data:/data

Раздел environment задает в контейнере реестра Docker переменную среды с путем /data. Приложение Docker Registry проверяет эту переменную среды при запуске и в результате сохраняет свои данные в папку /data.

Однако поскольку вы добавили строку volumes: - ./data:/data, Docker начнет сопоставлять каталог /data в этом контейнере с каталогом /data на вашем сервере реестра. В конечном итоге все данные реестра Docker будут храниться в каталоге ~/docker-registry/data на сервере реестра.

Раздел ports с конфигурацией 5000:5000 предписывает Docker сопоставить порт 5000 на сервере с портом 5000 запущенного контейнера. Это позволяет отправить запрос на порт 5000 на сервере так, чтобы этот запрос был перенаправлен в приложение реестра.

Теперь вы можете запустить Docker Compose для проверки настройки:

  1. docker-compose up

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

Output of docker-compose up
Starting docker-registry_registry_1 ... done Attaching to docker-registry_registry_1 registry_1 | time="2018-11-06T18:43:09Z" 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.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="redis not configured" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="Starting upload purge in 20m0s" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="listening on [::]:5000" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2

С предупреждающим сообщением No HTTP secret provided мы разберемся в этом же обучающем модуле, но чуть позднее. Экран результатов показывает, что контейнер запускается. Последняя строка результатов показывает, что прослушивание порта 5000 началось успешно.

Docker Compose по умолчанию будет ожидать от вас команд, так что нажмите CTRL+C, чтобы закрыть контейнер реестра Docker.

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

Шаг 2 — Настройка перенаправления портов Nginx

Вы уже настроили на сервере реестра Docker протокол HTTPS с Nginx, и это значит, что теперь вы можете настроить переадресацию портов с Nginx на порт 5000. После выполнения этого шага вы сможете получать доступ к своему реестру непосредственно по адресу example.com.

На предварительном этапе «Защита Nginx с помощью Let’s Encrypt» вы уже создали и настроили файл /etc/nginx/sites-available/example.com с конфигурацией вашего сервера.

Откройте этот файл в предпочитаемом текстовом редакторе:

  1. sudo nano /etc/nginx/sites-available/example.com

Найдите существующую строку location. Он будет выглядеть примерно так:

/etc/nginx/sites-available/example.com
...
location / {
  ...
}
...

Вам нужно перенаправить трафик на порт 5000, где будет работать ваш реестр. Также вам следует добавить в запрос реестра заголовки, которые будут предоставлять дополнительную информацию сервера в каждом запросе и ответе. Удалите содержимое раздела location и добавьте в него следующее:

/etc/nginx/sites-available/example.com
...
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;
}
...

Раздел $http_user_agent подтверждает, что версия клиента Docker выше 1.5 и что UserAgent не является приложением Go. Поскольку вы используете версию реестра 2.0, старые клиенты не поддерживаются. Дополнительную информацию можно найти в конфигурации заголовка nginx в руководстве по Nginx в реестре Docker.

Сохраните и закройте файл. Перезапустите Nginx для активации изменений:

  1. sudo service nginx restart

Для подтверждения перенаправления трафика Nginx на порт 5000 запустите реестр:

  1. cd ~/docker-registry
  2. docker-compose up

Откройте в окне браузера следующий url:

https://example.com/v2

Вы увидите пустой объект JSON или:

{}

Вы увидите на терминале следующий экран результатов:

Output of docker-compose up
registry_1 | time="2018-11-07T17:57:42Z" level=info msg="response completed" go.version=go1.7.6 http.request.host=cornellappdev.com http.request.id=a8f5984e-15e3-4946-9c40-d71f8557652f http.request.method=GET http.request.remoteaddr=128.84.125.58 http.request.uri="/v2/" http.request.useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" http.response.contenttype="application/json; charset=utf-8" http.response.duration=2.125995ms http.response.status=200 http.response.written=2 instance.id=3093e5ab-5715-42bc-808e-73f310848860 version=v2.6.2 registry_1 | 172.18.0.1 - - [07/Nov/2018:17:57:42 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7"

Из последней строки видно, что запрос GET был направлен по адресу /v2/, который представляет собой конечную точку отправки запроса из браузера. Контейнер получил отправленный запрос посредством перенаправления портов и возвратил ответ {}. Код 200 в последней строке на экране результатов означает, что контейнер успешно обработал запрос.

Теперь вы успешно настроили переадресацию портов и можете перейти к дальнейшему повышению безопасности вашего реестра.

Шаг 3 — Настройка аутентификации

Теперь веб-сервер Nginx правильно перенаправляет запросы, и вы можете защитить свой реестр Docker системой аутентификации HTTP, чтобы контролировать доступ к нему. Для этого вам потребуется создать файл аутентификации с помощью htpasswd и добавить в него пользователей. Аутентификация HTTP быстро настраивается и обеспечивает безопасность, если использовать соединение HTTPS, как в случае нашего реестра.

Для установки пакета htpasswd запустите следующую команду:

  1. sudo apt install apache2-utils

Теперь вы создадите каталог, где будут храниться учетные данные аутентификации, и перейдете в этот каталог. $_ раскрывается в последний аргумент предыдущей команды, в данном случае ~/docker-registry/auth:

  1. mkdir ~/docker-registry/auth && cd $_

Теперь вы создадите первого пользователя, заменив username желаемым именем пользователя. Флаг -B указывает, что нужно использовать шифрование bcrypt, которое более безопасно, чем шифрование по умолчанию. Введите пароль в диалоговом окне:

  1. htpasswd -Bc registry.password username

Примечание. Для добавления дополнительных пользователей запустите предыдущую команду еще раз с опцией -c («c» означает создание):

  1. htpasswd registry.password username

Теперь вам нужно отредактировать файл docker-compose.yml, чтобы предписать Docker использовать созданный файл для аутентификации пользователей.

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

Вы можете добавить переменные среды и том для созданного вами каталога auth/, отредактировав файл docker-compose.yml, чтобы указать Docker желаемый способ аутентификации пользователей. Добавьте в файл следующий выделенный код:

docker-compose.yml
version: '3'

services:
  registry:
    image: registry:2
    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

Для REGISTRY_AUTH вы задали htpasswd как используемую схему аутентификации, а для REGISTRY_AUTH_HTPASSWD_PATH вы задали путь к файлу аутентификации. Наконец, REGISTRY_AUTH_HTPASSWD_REALM означает имя области htpasswd.

Теперь вы можете убедиться в нормальной работе аутентификации, попробовав запустить реестр и проверив, запрашивает ли система имя пользователя и пароль.

  1. docker-compose up

Откройте в окне браузера адрес https://example.com/v2.

Введите username и соответствующий пароль, и вы снова увидите {}. Вы подтвердили базовую настройку аутентификации. Реестр возвратил результат только после ввода правильного имени пользователя и пароля. Вы защитили свой реестр и теперь можете переходить к его использованию.

Шаг 4 — Запуск реестра Docker как службы

Вам нужно, чтобы реестр запускался каждый раз во время загрузки вашей системы. В случае непредвиденного сбоя системы вам нужно сделать так, чтобы реестр перезапускался при перезагрузке сервера. Откройте файл docker-compose.yml:

  1. nano docker-compose.yml

Добавьте следующую строку в раздел registry::

docker-compose.yml
...
  registry:
    restart: always
...

Вы можете запускать реестр как фоновый процесс, и тогда вы сможете выходить из сеанса ssh с сохранением процесса:

  1. docker-compose up -d

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

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

Прежде чем вы сможете отправить образ в реестр, нужно убедиться, что реестр может принимать большие файлы. Хотя Docker разделяет выгружаемые большие образы на несколько слоев, их размер иногда может превышать 1 ГБ. По умолчанию в Nginx установлен лимит выгрузки файлов 1 МБ, так что вам нужно отредактировать файл конфигурации nginx и задать максимальный размер выгрузки файла 2 ГБ.

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

Найдите раздел http и добавьте в него следующую строку:

/etc/nginx/nginx.conf
...
http {
        client_max_body_size 2000M;
        ...
}
...

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

  1. sudo service nginx restart

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

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

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

Создайте на своем клиентском сервере небольшой пустой образ для отправки в новый реестр. Флаги -i и -t обеспечивают доступ к контейнеру через интерактивную оболочку:

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

После завершения выгрузки вы попадете в диалог Docker. Обратите внимание, что идентификатор контейнера после root@ может отличаться. Внесите быстрые изменения в файловую систему, создав файл с именем SUCCESS. На следующем шаге вы сможете использовать данный файл, чтобы определить, была ли публикация успешной:

  1. touch /SUCCESS

Выход из контейнера Docker:

  1. exit

Следующая команда создает новый образ под названием test-image на основе уже запущенного образа и всех внесенных изменений. В нашем случае добавление файла /SUCCESS включается в новый образ.

Сохраните изменение:

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

Сейчас образ существует только на локальном компьютере. Теперь вы можете отправить его в новый реестр, который вы создали. Войдите в свой реестр Docker:

  1. docker login https://example.com

Введите username и соответствующий пароль, заданный ранее. Затем поставьте для образа метку расположения частного реестра, чтобы отправить туда образ:

  1. docker tag test-image example.com/test-image

Отправьте образ с меткой в реестр:

  1. docker push example.com/test-image

Экран результатов должен выглядеть примерно следующим образом:

Output
The push refers to a repository [example.com/test-image] e3fbbfb44187: Pushed 5f70bf18a086: Pushed a3b5c80a4eba: Pushed 7f18b442972b: Pushed 3ce512daaf78: Pushed 7aae4540b42d: Pushed ...

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

Шаг 7 — Извлечение образов из частного реестра Docker

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

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

  1. docker login https://example.com

Теперь вы готовы к извлечению образа. Используйте доменное имя и имя образа, к которому вы добавили метку на предыдущем шаге:

  1. docker pull example.com/test-image

Docker загрузит образ и вернется в командную строку. Если вы запустите образ на сервере реестра, вы увидите, что ранее созданный файл SUCCESS находится в этом образе:

  1. docker run -it example.com/test-image /bin/bash

Выведите список файлов в оболочке bash:

  1. ls

Вы увидите файл SUCCESS, который вы создали для этого образа:

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

Вы завершили настройку защищенного реестра для отправки и получения образов.

Заключение

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

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Young Kim

author

Co-founder, CTO @ Stealth



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel