Как настроить частный реестр 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
со следующими командами. :
- mkdir ~/docker-registry && cd $_
- mkdir data
Используйте текстовый редактор для создания файла конфигурации docker-compose.yml
:
- 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, чтобы проверить настройку:
- docker-compose up
В выводе вы увидите полосы загрузки, которые показывают, что Docker загружает образ Docker Registry из собственного реестра Docker. Через минуту или две вы увидите вывод, похожий на следующий (версии могут различаться):
Output of docker-compose upStarting 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
, содержащий конфигурацию вашего сервера. .
Откройте этот файл в текстовом редакторе:
- 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:
- sudo service nginx restart
Вы можете убедиться, что Nginx перенаправляет трафик на порт 5000
, запустив реестр:
- cd ~/docker-registry
- docker-compose up
В окне браузера откройте следующий URL:
https://example.com/v2
Вы увидите пустой объект JSON или:
{}
В вашем терминале вы увидите вывод, подобный следующему:
Output of docker-compose upregistry_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
, выполнив следующее:
- sudo apt install apache2-utils
Теперь вы создадите каталог, в котором вы будете хранить наши учетные данные для аутентификации, и перейдете в этот каталог. $_
заменяется последним аргументом предыдущей команды, в данном случае ~/docker-registry/auth
:
- mkdir ~/docker-registry/auth && cd $_
Затем вы создадите первого пользователя следующим образом, заменив username
на имя пользователя, которое вы хотите использовать. Флаг -B
указывает шифрование bcrypt
, которое является более безопасным, чем шифрование по умолчанию. Введите пароль при появлении запроса:
- htpasswd -Bc registry.password username
Примечание. Чтобы добавить больше пользователей, повторно запустите предыдущую команду без параметра -c (c
для создания):
- htpasswd registry.password username
Затем вы отредактируете файл docker-compose.yml
, чтобы указать Docker использовать созданный вами файл для аутентификации пользователей.
- cd ~/docker-registry
- 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
.
Теперь вы можете убедиться, что ваша аутентификация работает правильно, запустив реестр и убедившись, что он запрашивает у пользователей имя пользователя и пароль.
- docker-compose up
В окне браузера откройте https://example.com/v2
.
После ввода имя пользователя
и соответствующего пароля вы снова увидите {}
. Вы подтвердили настройку базовой аутентификации: реестр вернул результат только после того, как вы ввели правильное имя пользователя и пароль. Теперь вы защитили свой реестр и можете продолжать использовать реестр.
Шаг 4 — Запуск Docker Registry как службы
Вы хотите убедиться, что ваш реестр будет запускаться всякий раз, когда загружается система. Если происходят какие-либо непредвиденные системные сбои, вы должны убедиться, что реестр перезагружается при перезагрузке сервера. Откройте docker-compose.yml
:
- nano docker-compose.yml
Добавьте следующую строку содержимого в раздел registration:
:
...
registry:
restart: always
...
Вы можете запустить свой реестр как фоновый процесс, что позволит вам выйти из сеанса ssh
и сохранить процесс:
- docker-compose up -d
Теперь, когда ваш реестр работает в фоновом режиме, вы можете подготовить Nginx к загрузке файлов.
Шаг 5 — Увеличение размера загружаемого файла для Nginx
Прежде чем отправлять образ в реестр, необходимо убедиться, что ваш реестр сможет обрабатывать загрузку больших файлов. Хотя Docker разбивает большие загружаемые изображения на отдельные слои, иногда их размер может превышать 1 ГБ
. По умолчанию Nginx имеет ограничение 1 МБ
на загрузку файлов, поэтому вам необходимо отредактировать файл конфигурации для nginx
и установить максимальный размер загружаемого файла 2 ГБ
.
- sudo nano /etc/nginx/nginx.conf
Найдите раздел http
и добавьте следующую строку:
...
http {
client_max_body_size 2000M;
...
}
...
Наконец, перезапустите Nginx, чтобы применить изменения конфигурации:
- sudo service nginx restart
Теперь вы можете загружать большие изображения в свой реестр Docker без ошибок Nginx.
Шаг 6 — Публикация в вашем личном реестре Docker
Теперь вы готовы опубликовать образ в своем частном реестре Docker, но сначала вам нужно создать образ. В этом руководстве вы создадите простой образ на основе образа ubuntu
из Docker Hub. Docker Hub — это общедоступный реестр с множеством предварительно настроенных образов, которые можно использовать для быстрой Dockerize приложений. Используя образ ubuntu
, вы протестируете отправку и извлечение данных в реестр.
На клиентском сервере создайте небольшой пустой образ для отправки в новый реестр, а флаги -i
и -t
предоставят вам интерактивный доступ к оболочке в контейнере:
- docker run -t -i ubuntu /bin/bash
После завершения загрузки вы попадете в приглашение Docker, обратите внимание, что ваш идентификатор контейнера после root@
будет другим. Внесите быстрые изменения в файловую систему, создав файл с именем SUCCESS
. На следующем шаге вы сможете использовать этот файл, чтобы определить, прошел ли процесс публикации успешно:
- touch /SUCCESS
Выйдите из контейнера Docker:
- exit
Следующая команда создает новый образ с именем test-image
на основе уже запущенного образа и любых внесенных вами изменений. В нашем случае добавление файла /SUCCESS
включается в новый образ.
Зафиксируйте изменение:
- docker commit $(docker ps -lq) test-image
На данный момент изображение существует только локально. Теперь вы можете отправить его в новый реестр, который вы создали. Войдите в свой реестр Docker:
- docker login https://example.com
Введите имя пользователя
и соответствующий пароль ранее. Затем вы пометите образ местоположением частного реестра, чтобы отправить его:
- docker tag test-image example.com/test-image
Отправьте образ с новым тегом в реестр:
- docker push example.com/test-image
Ваш вывод будет выглядеть примерно так:
OutputThe push refers to a repository [example.com/test-image]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed
...
Вы убедились, что ваш реестр обрабатывает аутентификацию пользователей и позволяет аутентифицированным пользователям отправлять изображения в реестр. Далее вы подтвердите, что также можете извлекать образы из реестра.
Шаг 7 — Извлечение из вашего частного реестра Docker
Вернитесь на свой сервер реестра, чтобы протестировать загрузку образа с клиентского сервера. Также возможно проверить это с третьего сервера.
Войдите в систему с именем пользователя и паролем, которые вы установили ранее:
- docker login https://example.com
Теперь вы готовы вытащить изображение. Используйте свое доменное имя и имя изображения, которые вы отметили на предыдущем шаге:
- docker pull example.com/test-image
Docker загрузит образ и вернет вас к подсказке. Если вы запустите образ на сервере реестра, вы увидите файл SUCCESS
, который вы создали ранее:
- docker run -it example.com/test-image /bin/bash
Перечислите свои файлы внутри оболочки bash:
- 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, объясняющий процесс.