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

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


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

Введение

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

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

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

Предпосылки

Прежде чем приступить к работе с этим руководством, вам потребуется следующее:

  • Два сервера Ubuntu 18.04 настроены в соответствии с руководством по первоначальной настройке сервера Ubuntu 18.04, включая пользователя без полномочий root и брандмауэр. На одном сервере будет размещаться ваш частный реестр Docker, а другой будет вашим клиентским сервером.
  • Docker и Docker-Compose установлены на обоих серверах в соответствии с руководством по установке Docker-Compose в Ubuntu 18.04. Вам нужно только выполнить первый шаг этого руководства, чтобы установить Docker Compose. В этом руководстве объясняется, как установить Docker в рамках его предварительных требований.
  • Nginx, установленный на вашем частном сервере реестра Docker, следуя инструкции по установке Nginx в Ubuntu 18.04.
  • Nginx защищен с помощью Let’s Encrypt на вашем сервере для частного реестра Docker, следуя инструкции «Как защитить 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 Registry сам по себе является приложением с несколькими компонентами, поэтому вы будете использовать 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:

version: '3'

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

Раздел environment устанавливает переменную среды в контейнере Docker Registry с путем /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 Registry из собственного реестра 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

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

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

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

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

У вас уже настроен HTTPS на сервере Docker Registry с 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. Это будет выглядеть так:

...
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;
}
...

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

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

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.

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

Шаг 4 — Запуск Docker Registry как службы

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

  1. nano docker-compose.yml

Добавьте следующую строку содержимого в раздел registration::

...
  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 и добавьте следующую строку:

...
http {
        client_max_body_size 2000M;
        ...
}
...

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

  1. sudo service nginx restart

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

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

Теперь вы готовы опубликовать образ в своем частном реестре Docker, но сначала вам нужно создать образ. В этом руководстве вы создадите простой образ на основе образа ubuntu из Docker Hub. Docker Hub — это общедоступный реестр с множеством предварительно настроенных образов, которые можно использовать для быстрой Dockerize приложений. Используя образ 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

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

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