Автор выбрал фонд Apache Software Foundation для получения пожертвования в рамках программы Write for DOnations.
Реестр Docker — это приложение, управляющее хранением и доставкой образов контейнеров Docker. Реестры централизуют образы контейнеров и помогают разработчикам сократить время сборки. Образы Docker гарантируют единство среды исполнения за счет виртуализации однако для создания образа может потребоваться много времени. Например, вместо отдельной установки зависимостей и пакетов для использования Docker, разработчики могут загрузить из реестра сжатый образ, содержащий все необходимые компоненты. Более того, разработчики могут автоматизировать отправку образов в реестр с помощью TravisCI или других средств непрерывной интеграции, позволяющих мгновенно обновлять образы во время разработки и использования проекта в производстве.
Бесплатный публичный реестр Docker Hub позволяет храить персонализированные образы Docker, но в некоторых случаях вы можете не захотеть делать свой образ общедоступным. Образы обычно содержат весь необходимый для запуска приложения код, поэтому при работе с коммерческим программным обеспечением предпочтительно использовать частный реестр.
В этом обучающем модуле вы научитесь настраивать и защищать собственный частный реестр Docker. Вы научитесь использовать Docker Compose для определения конфигуарций запуска приложений Docker, а также Nginx для перенаправления серверного трафика с HTTPS в работающий контейнер Docker. После прохождения этого обучающего модуля вы научитесь размещать свои персональные образы Docker в собственном частном реестре и безопасно извлекать образы с удаленного сервера.
Для прохождения этого обучающего модуля вам потребуется следующее:
Инструмент командной строки Docker подойдет для запуска и управления одним или двумя контейнерами Docker, но для полноценного развертывания большинства приложений, запущенных внутри контейнеров Docker, необходимо, чтобы параллельно работали и другие компоненты. Например, многие приложения включают Nginx или другой веб-сервер, обслуживающий код приложения, а также PHP или другой язык интерпретации скриптов и MySQL или другой сервер СУБД.
С помощью Docker Compose вы можете записать один файл .yml
для настройки конфигурации каждого контейнера и информации, необходимой контейнерам для взаимодействия друг с другом. Затем вы можете использовать инструмент командной строки docker-compose
для отправки команд всем компонентам, составляющим ваше приложение.
Реестр Docker сам по себе является приложением с несколькими компонентами, и поэтому вы будете использовать 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 переменную среды с путем /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 из собственного реестра 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
С предупреждающим сообщением No HTTP secret provided
мы разберемся в этом же обучающем модуле, но чуть позднее. Экран результатов показывает, что контейнер запускается. Последняя строка результатов показывает, что прослушивание порта 5000
началось успешно.
Docker Compose по умолчанию будет ожидать от вас команд, так что нажмите CTRL+C
, чтобы закрыть контейнер реестра Docker.
Вы настроили полный реестр Docker, прослушивающий порт 5000
. Сейчас реестр не будет запускаться, если вы не запустите его вручную. Также в реестре Docker отсутствуют встроенные механизмы аутентификации, и это значит, что сейчас он не защищен и полностью открыт для публики. На следующих шагах вы решите эти проблемы безопасности.
Вы уже настроили на сервере реестра Docker протокол HTTPS с 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
в руководстве по Nginx в реестре Docker.
Сохраните и закройте файл. Перезапустите 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
в последней строке на экране результатов означает, что контейнер успешно обработал запрос.
Теперь вы успешно настроили переадресацию портов и можете перейти к дальнейшему повышению безопасности вашего реестра.
Теперь веб-сервер Nginx правильно перенаправляет запросы, и вы можете защитить свой реестр Docker системой аутентификации HTTP, чтобы контролировать доступ к нему. Для этого вам потребуется создать файл аутентификации с помощью 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
.
Введите username
и соответствующий пароль, и вы снова увидите {}
. Вы подтвердили базовую настройку аутентификации. Реестр возвратил результат только после ввода правильного имени пользователя и пароля. Вы защитили свой реестр и теперь можете переходить к его использованию.
Вам нужно, чтобы реестр запускался каждый раз во время загрузки вашей системы. В случае непредвиденного сбоя системы вам нужно сделать так, чтобы реестр перезапускался при перезагрузке сервера. Откройте файл docker-compose.yml
:
- nano docker-compose.yml
Добавьте следующую строку в раздел registry:
:
...
registry:
restart: always
...
Вы можете запускать реестр как фоновый процесс, и тогда вы сможете выходить из сеанса ssh
с сохранением процесса:
- docker-compose up -d
Теперь реестр работает в фоновом режиме, и вы можете подготовить 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.
Теперь вы готовы к публикации образов в частном реестре Docker, но вначале вам потребуется создать образ. Для целей этого обучающего модуля мы создадим простой образ на базе образа ubuntu
из Docker Hub. Docker Hub — это публичный реестр с множеством настроенных образов, которые можно использовать для быстрой контейнеризации приложений с помощью Docker. С помощью образа 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
Введите username
и соответствующий пароль, заданный ранее. Затем поставьте для образа метку расположения частного реестра, чтобы отправить туда образ:
- 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
...
Вы убедились, что ваш реестр успешно выполняет аутентификацию пользователей, и что прошедшие аутентификацию пользователи могут отправлять образы в реестр. Теперь вы должны убедиться, что вы можете извлекать образы из реестра.
Вернитесь на сервер реестра, чтобы вы могли протестировать извлечение образа с клиентского сервера. Также для тестирования можно использовать третий сервер.
Войдите в систему, указав имя пользователя и пароль, которые вы задали ранее:
- 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. Как указывалось во введении, вы также можете использовать TravisCI или другой подобный инструмент CI для автоматизации прямой отправки образов в частный реестр. Используя Docker и реестры в своем рабочем процессе, вы можете убедиться, что образ с кодом будет вести себя одинаково на любом компьютере в производственной среде или в среде разработки. Дополнительную информацию о написании файлов Docker можно найти в следующем обучающем модуле по Docker, где разъясняется данная процедура.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.