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

Вступление

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

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

Это руководство не охватывает контейнеризацию вашего собственного приложения, а только как создать реестр, в котором вы можете хранить свои развертывания. Если вы хотите узнать, как начать работу с самим Docker (а не с реестром), вы можете прочитать руководствоHow To Install and Use Docker: Getting Started.

Это руководство было протестировано как на сервере реестра, так и на клиенте реестра, на котором запущенUbuntu 14.04, но он может работать с другими дистрибутивами на основе Debian. Он также охватывает версию 2.0 реестра Docker.

Docker Concepts

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

Чтобы узнать, как использовать Docker, взгляните на отличныйDocker Cheat Sheet.

Docker по своей сути - это способ отделить приложение и зависимости, необходимые для его запуска, от самой операционной системы. Чтобы сделать это возможным, Docker используетcontainers иimages. Образ Docker - это в основном шаблон для файловой системы. Когда вы запускаете образ Docker, экземпляр этой файловой системы запускается и запускается в вашей системе внутри контейнера Docker. По умолчанию этот контейнер не может касаться самого исходного образа или файловой системы хоста, на котором работает Docker. Это автономная среда.

Какие бы изменения вы ни делали в контейнере, они сохраняются в самом контейнере и не влияют на исходное изображение. Если вы решили, что хотите сохранить эти изменения, вы можете «зафиксировать» контейнер в образе Docker (с помощью командыdocker commit). Это означает, что вы можете порождать новые контейнеры, которые начинаются с содержимого вашего старого контейнера, не затрагивая оригинальный контейнер (или изображение). Если вы знакомы сgit, то рабочий процесс должен показаться очень похожим: вы можете создавать новые ветви (образы на языке Docker) из любого контейнера. Запуск изображения немного похож на выполнениеgit checkout.

Чтобы продолжить аналогию, запуск частного реестра Docker аналогичен запуску частного Git-репозитория для ваших образов Docker.

Предпосылки

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

  • 2 Ubuntu 14.04 Droplets: один для частного реестра Docker и один для клиента Docker

  • Пользователь без полномочий root с привилегиями sudo для каждой капли (Initial Server Setup with Ubuntu 14.04 объясняет, как это настроить).

  • Docker и Docker Compose установлены с помощью инструкцийHow To Install and Use Docker Compose on Ubuntu 14.04

  • Доменное имя, которое разрешается в Droplet для частного реестра Docker.

[[шаг-1 -—- install-package-for-added-security]] == Шаг 1. Установка пакета для дополнительной безопасности

Для настройки безопасности реестра Docker лучше всего использоватьDocker Compose. Таким образом, мы можем легко запустить Docker Registry в одном контейнере и позволить Nginx управлять безопасностью и связью с внешним миром в другом. Он уже должен быть установлен из раздела «Предварительные условия».

Поскольку мы будем использовать Nginx для обеспечения нашей безопасности, нам также потребуется место для хранения списка комбинаций имени пользователя и пароля, которые мы хотим получить в нашем реестре. Мы установим пакетapache2-utils, который содержит утилитуhtpasswd, которая может легко генерировать хэши паролей, которые Nginx понимает:

sudo apt-get -y install apache2-utils

[[step-2 -—- install-and-configuring-the-docker-registry]] == Шаг 2 - Установка и настройка реестра Docker

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

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

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

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

Сначала создайте папку, в которой будут храниться наши файлы для этого урока, и некоторые из подпапок, которые нам понадобятся:

mkdir ~/docker-registry && cd $_
mkdir data

Используя свой любимый текстовый редактор, создайте файлdocker-compose.yml:

nano docker-compose.yml

Добавьте следующее содержимое в файл:

docker-compose.yml

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

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

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

Давайте начнем, чтобы убедиться, что все в порядке:

cd ~/docker-registry
docker-compose up

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

Output of docker-compose upregistry_1 | time="2015-10-18T23:45:58Z" 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." instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="redis not configured" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="using inmemory blob descriptor cache" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="listening on [::]:5000" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="Starting upload purge in 1m0s" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1

Не беспокойтесь о сообщенииNo HTTP secret provided. Это нормально.

Большой! На этом этапе у вас уже есть полный реестр Docker, работающий и прослушивающий порт 5000 (это было установлено битомports: в файлеdocker-compose.yml). На данный момент реестр пока не очень полезен - он не запустится, если вы не откроете реестр вручную. Кроме того, реестр Docker не имеет встроенного механизма аутентификации, поэтому он небезопасен и полностью открыт для публики прямо сейчас.

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

[[step-3 -—- setting-up-an-nginx-container]] == Шаг 3. Настройка контейнера Nginx

Давайте приступим к решению этих проблем безопасности. Первый шаг - настроить копию Nginx внутри другого контейнера Docker и связать ее с нашим контейнером реестра Docker.

Начнем с создания каталога для хранения нашей конфигурации Nginx:

mkdir ~/docker-registry/nginx

Теперь снова откройте файлdocker-compose.yml в каталоге~/docker-registry:

nano docker-compose.yml

Вставьте следующее в верхнюю часть файла:

docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro

Это создаст новый контейнер Docker на основе официального образа Nginx. Интересный момент - это разделlinks. Он автоматически устанавливает «связь» с одного контейнера Docker на другой. Когда контейнер Nginx запускается, он сможет достичь контейнераregistry по имени хостаregistry независимо от того, какой фактический IP-адрес окажется у контейнераregistry. (За кулисами Docker фактически вставляет запись в файл/etc/hosts в контейнереnginx, чтобы сообщить ему IP-адрес контейнераregistry).

Разделvolumes: аналогичен тому, что мы сделали для контейнераregistry. В этом случае это дает нам возможность хранить файлы конфигурации, которые мы будем использовать для Nginx, на нашей хост-машине, а не внутри контейнера Docker. :ro в конце просто сообщает Docker, что контейнер Nginx должен иметь доступ только для чтения к файловой системе хоста.

Ваш полный файлdocker-compose.yml теперь должен выглядеть так:

docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

Запускdocker-compose up теперь запускает два контейнера одновременно: один для реестра Docker и один для Nginx.

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

Создайте файлregistry.conf:

nano ~/docker-registry/nginx/registry.conf

Скопируйте следующее в файл:

~/docker-registry/nginx/registry.conf

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # 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;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
    # auth_basic "registry.localhost";
    # auth_basic_user_file /etc/nginx/conf.d/registry.password;
    # add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    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;
  }
}

Сохраните и выйдите из файла.

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

docker-compose up

Nginx не выводит никаких результатов при запуске, но если все прошло хорошо, вы теперь используете копию Nginx, настроенную для прокси-сервера вашего контейнераregistry. Чтобы проверить это, давайте воспользуемсяcurl, чтобы сделать HTTP-запрос напрямую в наш реестр Docker, а затем сделаем еще один запрос к нашему порту Nginx. Если все настроено правильно, вывод будет одинаковым в обоих случаях (на момент написания этой статьи Docker возвращает пустой объект json «{}»), поскольку Nginx будет передавать запрос через прокси в реестр Docker.

Сначала сделайте HTTP-запрос непосредственно в реестр Docker:

curl http://localhost:5000/v2/

На момент написания этой статьи Docker возвращает пустой объект json, поэтому вы должны увидеть:

Output{}

Теперь отправьте HTTP-запрос на порт Nginx:

curl http://localhost:5043/v2/

Вы должны увидеть тот же результат:

Output{}

Если все работает правильно, вы увидите в своем терминалеdocker-compose вывод, который также выглядит следующим образом:

Output of docker-compose    registry_1 | time="2015-08-11T10:24:53.746529894Z" level=debug msg="authorizing request" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | time="2015-08-11T10:24:53.747650205Z" level=info msg="response completed" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" http.response.contenttype="application/json; charset=utf-8" http.response.duration=8.143193ms http.response.status=200 http.response.written=2 instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | 172.17.0.21 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.35.0"
    nginx_1    | 172.17.42.1 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.35.0" "-"

Если вы видите строки с префиксомregistry_ (число после_ может быть другим на вашем компьютере), значит, все в порядке, и Nginx успешно проксировал наш HTTP-запрос в реестр Docker.

Идите вперед и снова нажмитеCTRL-C в терминалеdocker-compose, чтобы закрыть контейнеры Docker.

[[step-4 -—- setting-up-authentication]] == Шаг 4. Настройка аутентификации

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

Создайте первого пользователя следующим образом, заменивUSERNAME на имя пользователя, которое вы хотите использовать:

cd ~/docker-registry/nginx
htpasswd -c registry.password USERNAME

При появлении запроса создайте новый пароль для этого пользователя.

Если вы хотите добавить больше пользователей в будущем, просто повторно запустите указанную выше команду без параметра-c (c предназначен для создания):

htpasswd registry.password USERNAME

На данный момент у нас есть файлregistry.password с настроенными пользователями и доступным реестром Docker. Вы можете просмотреть файл в любой момент, если хотите просмотреть своих пользователей (и удалить пользователей, если хотите отозвать доступ).

Далее нам нужно указать Nginx использовать этот файл аутентификации.

Откройте~/docker-registry/nginx/registry.conf в своем любимом текстовом редакторе:

nano ~/docker-registry/nginx/registry.conf

Прокрутите до середины файла, где вы увидите несколько строк, которые выглядят так:

~/docker-registry/nginx/registry.conf

# To add basic authentication to v2 use auth_basic setting plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

Раскомментируйте две строки, начинающиеся сauth_basic, а также строку, начинающуюся сadd_header, удалив символ# в начале
строк. Это должно выглядеть так:

~/docker-registry/nginx/registry.conf

# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

Теперь мы сказали Nginx включить базовую аутентификацию HTTP для всех запросов, которые передаются в реестр Docker, и сказали ему использовать только что созданный файл паролей.

Давайте вернем наши контейнеры, чтобы проверить, работает ли аутентификация:

cd ~/docker-registry
docker-compose up

Повторите предыдущий тест скручивания:

curl http://localhost:5043/v2/

Вы должны получить сообщение с жалобой на несанкционированный доступ:

Output of curl
401 Authorization Required

401 Authorization Required


nginx/1.9.7

Теперь попробуйте добавить созданное вами ранее имя пользователя и пароль к запросуcurl:

curl http://USERNAME:PASSWORD@localhost:5043/v2/

Вы должны получить тот же результат, что и раньше - пустой объект json{}. Вы также должны увидеть тот же выводregistry_ в терминалеdocker-compose.

Продолжайте и используйтеCTRL-C в терминалеdocker-compose, чтобы закрыть контейнеры Docker.

[[step-5 -—- setting-up-ssl]] == Шаг 5. Настройка SSL

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

Давайте позволим им. Сначала откройте файл конфигурации Nginx для редактирования:

nano ~/docker-registry/nginx/registry.conf

Используйте клавиши со стрелками для перемещения и ищите эти строки:

~/docker-registry/nginx/registry.conf

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

Раскомментируйте строки под комментарием SSL, удалив перед ними символы#. Если для вашего сервера настроено доменное имя, измените значениеserver_name на свое доменное имя, пока вы на нем. Когда вы закончите, верхняя часть файла должна выглядеть так:

~/docker-registry/nginx/registry.conf

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  ssl on;
  ssl_certificate /etc/nginx/conf.d/domain.crt;
  ssl_certificate_key /etc/nginx/conf.d/domain.key;

Сохраните файл. Теперь Nginx настроен на использование SSL и будет искать SSL-сертификат и файлы ключей в/etc/nginx/conf.d/domain.crt и/etc/nginx/conf.d/domain.key соответственно. Из-за сопоставлений, которые мы настроили ранее в нашем файлеdocker-compose.yml, путь/etc/nginx/conf.d/ в контейнере Nginx соответствует папке~/docker-registry/nginx/ на нашем хост-компьютере, поэтому мы поместим туда наши файлы сертификатов. .

Если у вас уже настроен сертификат SSL или вы планируете его купить, вы можете просто скопировать файлы сертификата и ключей по путям, указанным вregistry.conf (ssl_certificate иssl_certificate_key).

Вы также можете получитьfree signed SSL certificate.

В противном случае нам придется использовать самозаверяющий сертификат SSL.

Подписание собственного сертификата

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

Для начала перейдем в нашу папку~/docker-registry/nginx и приготовимся к созданию сертификатов:

cd ~/docker-registry/nginx

Создайте новый корневой ключ:

openssl genrsa -out devdockerCA.key 2048

Создайте корневой сертификат (введите все, что вы хотите в запросах):

openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt

Затем сгенерируйте ключ для своего сервера (это файл, на который указываетssl_certificate_key в нашей конфигурации Nginx):

openssl genrsa -out domain.key 2048

Теперь мы должны сделать запрос на подпись сертификата.

После того, как вы введете эту команду, OpenSSL предложит вам ответить на несколько вопросов. Напишите все, что хотите, для первых нескольких, но когда OpenSSL предложит вам ввести“Common Name” make sure to type in the domain or IP of your server.

openssl req -new -key domain.key -out dev-docker-registry.com.csr

Например, если ваш реестр Docker будет работать в доменеwww.ilovedocker.com, то ваш ввод должен выглядеть так:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.ilovedocker.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Не вводите пароль для вызова.

Далее нам нужно подписать запрос сертификата:

openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000

Поскольку сертификаты, которые мы только что сгенерировали, не проверены ни одним известным центром сертификации (например, VeriSign), мы должны сообщить всем клиентам, которые будут использовать этот реестр Docker, что это законный сертификат. Давайте сделаем это локально на хост-машине, чтобы мы могли использовать Docker с самого сервера реестра Docker:

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
sudo update-ca-certificates

Перезапустите демон Docker, чтобы он принял изменения в нашем хранилище сертификатов:

sudo service docker restart

[.warning] #Warning: Вам придется повторить этот шаг для каждой машины, которая подключается к этому реестру Docker! Инструкции по тому, как это сделать для клиентов Ubuntu 14.04, перечислены вStep 9 — Accessing Your Docker Registry from a Client Machine.
#

[[step-6 -—- testing-ssl]] == Шаг 6. Тестирование SSL

Поднимите наши контейнеры Docker с помощью уже знакомогоdocker-compose up:

cd ~/docker-registry
docker-compose up

Выполните еще один тестcurl с другого терминала (только на этот раз с использованием https), чтобы убедиться, что наша настройка SSL работает правильно. Имейте в виду, что для правильной работы SSL вам нужно будет использовать то же доменное имя, которое вы ввели в полеCommon Name ранее при создании сертификата SSL.

curl https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

[.Примечание]##

Note: Если вы используете самозаверяющий сертификат, вы увидите следующую ошибку отcurl:

curl: (60) SSL certificate problem: self signed certificate

Используйте параметр-k, чтобы указатьcurlnot для проверки с партнером:

curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

Например, если пользователь и пароль, которые вы установили, былиsammy иtest, а ваш сертификат SSL предназначен дляwww.example.com, вы должны ввести следующее:

curl https://sammy:[email protected]:5043/v2/

Если все прошло хорошо,curl напечатает пустой объект json{}, а ваш терминалdocker-compose напечатает обычный выводregistry_.

Если нет, перепроверьте шаги SSL и файл конфигурации Nginx, чтобы убедиться, что все правильно.

На данный момент у нас есть функциональный реестр Docker 2.0, работающий за сервером Nginx, который обеспечивает аутентификацию и шифрование через SSL. Если ваш брандмауэр настроен так, чтобы разрешать доступ к порту5043 извне, тогда вы сможете войти в этот реестр Docker с любого компьютераdocker login https://<YOURDOMAIN> и ввести имя пользователя и пароль, которые вы установили в предыдущем разделе. .

[[step-7 -—- setting-ssl-port-to-443]] == Шаг 7. Установка порта SSL на 443

Еще пара шагов, которые нужно сделать, прежде чем мы закончим: измените порт на использование стандартного SSL-порта443 (необязательно) и установитеdocker-compose для запуска этого набора контейнеров при запуске.

Начнем с настройки нашего докеризованного контейнера Nginx для прослушивания порта 443 (стандартный порт для SSL), а не нестандартного порта 5043, который мы использовали до сих пор. Однако порты ниже 1024 являются «привилегированными» портами в Linux, что означает, что нам придется запускать наш контейнерdocker-compose как root.

Сначала откройтеdocker-compose.yml в текстовом редакторе:

nano ~/docker-registry/docker-compose.yml

В разделе Nginx вы увидите разделports:, измените строку- 5043:443 (это отображает порт 5043 на нашем хост-компьютере на порт 443 внутри контейнера Nginx) на- 443:443, чтобы наш Порт 443 контейнера Nginx сопоставляется с портом 443 нашего хост-компьютера. По завершении вашdocker-compose.yml должен выглядеть так:

~/docker-registry/docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 443:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

Завершите сеансdocker-compose черезCTRL-C, если он все еще работает, и перезапустите его на порту 443:

sudo docker-compose up

[.note] #Note: Только пользователи root могут прослушивать порты ниже 1024. Обратите внимание, что на этот раз вам нужно использоватьsudo с командойdocker-compose, чтобы Nginx мог работать на SSL-порту 443 по умолчанию.
#

Вы должны увидеть, какdocker-compose запускается как обычно.

Давайте попробуем еще один тестcurl, используя наше доменное имя, только на этот раз мы не будем указывать:5043 в URL:

curl https://:@YOUR-DOMAIN/v2/

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

Продолжайте и используйтеCTRL-C в терминалеdocker-compose, чтобы закрыть контейнеры Docker перед переходом к следующему шагу.

[[step-8 -—- start-docker-registry-as-a-service]] == Шаг 8 - Запуск Docker Registry как службы

Если все в порядке, давайте создадим сценарийUpstart, чтобы наш реестр Docker запускался при каждой загрузке системы.

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

cd ~/docker-registry
docker-compose rm   # this removes the existing containers
sudo mv ~/docker-registry /docker-registry
sudo chown -R root: /docker-registry

Затем используйте ваш любимый текстовый редактор для создания сценария Upstart:

sudo nano /etc/init/docker-registry.conf

Добавьте следующее содержимое, чтобы создать скрипт Upstart (заставить Upstart правильно отслеживать контейнеры Docker немного сложно, посмотритеthis blog post, если вам нужна дополнительная информация о том, что делает этот скрипт Upstart):

/etc/init/docker-registry.conf

description "Docker Registry"

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 10 5

chdir /docker-registry

exec /usr/local/bin/docker-compose up

Дополнительные сведения о сценариях Upstart см. Вthis tutorial.

Давайте протестируем наш новый скрипт Upstart, выполнив:

sudo service docker-registry start

Вы должны увидеть что-то вроде этого:

docker-registry start/running, process 25303

Вы можете проверить, что сервер работает, выполнив:

docker ps

Результат должен выглядеть примерно так (обратите внимание, что все имена начинаются сdockerregistry_

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                          NAMES
d4b6fef0b4d1        nginx:1.9           "nginx -g 'daemon of   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:443->443/tcp   dockerregistry_nginx_1
77668352bd39        registry:2          "registry cmd/regist   2 minutes ago       Up 2 minutes        127.0.0.1:5000->5000/tcp       dockerregistry_registry_1

Upstart будет записывать вывод командыdocker-compose в/var/log/upstart/docker-registry.log. Для нашего последнего теста давайте «вживую» просмотрим файл журнала сtail (sudo необходим, поскольку журналы выскочки записываются от имени пользователя root):

sudo tail -f /var/log/upstart/docker-registry.log

Вы должны увидеть обычный выводregistry_. С другого терминала или машины запустите наш теперь уже знакомый тестcurl:

curl https://:@[YOUR-DOMAIN]/v2/

Если все работает правильно, curl напечатает{} на вашем терминале, и вы должны увидеть как обычно:

registry_1 | time="2015-08-12T08:01:12.241887501Z" level=debug msg="authorizing request" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | time="2015-08-12T08:01:12.242206499Z" level=info msg="response completed" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" http.response.contenttype="application/json; charset=utf-8" http.response.duration=3.359883ms http.response.status=200 http.response.written=2 instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | 172.17.0.4 - - [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.37.1"
nginx_1    | 106.1.247.4 - nik [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.37.1" "-"

[[step-9 -—- accessing-your-docker-registry-from-a-client-machine]] == Шаг 9. Доступ к вашему реестру Docker с клиентского компьютера

Чтобы получить доступ к реестру Docker с другого компьютера, сначала добавьте сертификат SSL, созданный ранее, на новый клиентский компьютер. Нужный файл находится в~/docker-registry/nginx/devdockerCA.crt.

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

Наregistry server просмотрите сертификат:

sudo cat /docker-registry/nginx/devdockerCA.crt

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

Output of sudo cat /docker-registry/nginx/devdockerCA.crt-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTQwOTIxMDYwODE2WhcNNDIwMjA2MDYwODE2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuK4kNFaY3k/0RdKRK1XLj9+IrpR7WW5lrNaFB0OIiItHV9FjyuSWK2mj
ObR1IWJNrVSqWvfZ/CLGay6Lp9DJvBbpT68dhuS5xbVw3bs3ghB24TntDYhHMAc8
GWor/ZQTzjccHUd1SJxt5mGXalNHUharkLd8mv4fAb7Mh/7AFP32W4X+scPE2bVH
OJ1qH8ACo7pSVl1Ohcri6sMp01GoELyykpXu5azhuCnfXLRyuOvQb7llV5WyKhq+
SjcE3c2C+hCCC5g6IzRcMEg336Ktn5su+kK6c0hoD0PR/W0PtwgH4XlNdpVFqMST
vthEG+Hv6xVGGH+nTszN7F9ugVMxewIDAQABo1AwTjAdBgNVHQ4EFgQULek+WVyK
dJk3JIHoI4iVi0FPtdwwHwYDVR0jBBgwFoAULek+WVyKdJk3JIHoI4iVi0FPtdww
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkignESZcgr4dBmVZqDwh
YsrKeWSkj+5p9eW5hCHJ5Eg2X8oGTgItuLaLfyFWPS3MYWWMzggxgKMOQM+9o3+k
oH5sUmraNzI3TmAtkqd/8isXzBUV661BbSV0obAgF/ul5v3Tl5uBbCXObC+NUikM
O0C3fDmmeK799AM/hP5CTDehNaFXABGoVRMSlGYe8hZqap/Jm6AaKThV4g6n4F7M
u5wYtI9YDMsxeVW6OP9ZfvpGZW/n/88MSFjMlBjFfFsorfRd6P5WADhdfA6CBECG
LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H
6g==
-----END CERTIFICATE-----

Скопируйте этот вывод в буфер обмена и подключитесь к клиентскому компьютеру.

Наclient machine создайте каталог сертификатов:

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert

Откройте файл сертификата для редактирования:

sudo nano /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

Вставьте содержимое сертификата.

Убедитесь, что файл сохранен на клиентском компьютере правильно, просмотрев файл:

cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

Если все работает правильно, вы увидите тот же текст из ранее:

Output of cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
...
...
LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H
6g==
-----END CERTIFICATE-----

Теперь обновите сертификаты:

sudo update-ca-certificates

Вы должны получить следующий результат (обратите внимание на «1 добавлено»):

Output of sudo update-ca-certificatesUpdating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

Если на клиенте еще не установлен Docker, сделайте это сейчас (см. Раздел «Предварительные требования»).

Перезапустите Docker, чтобы убедиться, что он перезагружает сертификаты CA системы.

sudo service docker restart

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

docker login https://YOUR-DOMAIN

Обратите внимание, что вы используетеhttps://. Введите имя пользователя и пароль, которые вы установили ранее (введите все, что вы хотите для электронной почты, если будет предложено).

Output of docker loginUsername: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

Вы должны увидеть следующее сообщение:

Output of docker loginLogin Succeeded

На данный момент ваш реестр Docker запущен и работает! Давайте создадим тестовое изображение для отправки в реестр.

[[step-10 -—- publish-to-your-private-docker-registry]] == Шаг 10. Опубликуйте в личном реестре Docker

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

Из вашегоclient machine создайте небольшой пустой образ, который нужно отправить в наш новый реестр.

docker run -t -i ubuntu /bin/bash

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

touch /SUCCESS

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

exit

Зафиксируйте изменения:

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

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

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

На предыдущем шаге вы вошли в свой личный реестр Docker. Если вы все еще не вошли в систему, давайте войдем снова (обратите внимание, что вы хотите использоватьhttps://):

docker login https://YOUR-DOMAIN

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

Username: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

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

docker tag test-image [YOUR-DOMAIN]/test-image

Обратите внимание, что вы сначала используете локальное имя изображения, а затем тег, который хотите добавить к нему. Тегnot используетhttps://, только домен, порт и имя изображения.

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

docker push [YOUR-DOMAIN]/test-image

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

Output of docker pushlatest: digest: sha256:5ea1cfb425544011a3198757f9c6b283fa209a928caabe56063f85f3402363b4 size: 8008

[[step-11 -—- pull-from-your-docker-registry]] == Шаг 11. Извлечь из вашего реестра Docker

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

Если Docker не установлен на тестовом сервере Pull, вернитесь и следуйте инструкциям по установке (а если это третий сервер, инструкции SSL), начиная с шага 6.

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

docker login https://[YOUR-DOMAIN]

А теперь потяните изображение. Вам нужно только «теговое» имя изображения, которое включает имя домена, порт и имя изображения (но неhttps://):

docker pull [YOUR-DOMAIN]/test-image

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

docker run -t -i [YOUR-DOMAIN]/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!

Счастливого Докеринга!

Related