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

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


Введение

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

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

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

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

Концепции докера

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

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

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

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

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

Предпосылки

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

  • 2 дроплета Ubuntu 14.04: один для частного реестра Docker и один для клиента Docker
  • Пользователь без полномочий root с привилегиями sudo для каждой капли (начальная настройка сервера с Ubuntu 14.04 объясняет, как это настроить).
  • Docker и Docker Compose, установленные в соответствии с инструкциями из руководства по установке и использованию Docker Compose в Ubuntu 14.04
  • Доменное имя, которое разрешается в дроплет для частного реестра Docker.

Шаг 1 — Установка пакета для дополнительной безопасности

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

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

  1. sudo apt-get -y install apache2-utils

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

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

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

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

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

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

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

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

  1. nano 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 на нашем локальном компьютере.

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

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

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

Output of docker-compose up
registry_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

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

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

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

Шаг 3 — Настройка контейнера Nginx

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

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

  1. mkdir ~/docker-registry/nginx

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

  1. nano 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 теперь должен выглядеть так:

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:

  1. nano ~/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 одной командой:

  1. docker-compose up

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

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

  1. curl http://localhost:5000/v2/

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

Output
{}

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

  1. 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-запрос к Докер реестр.

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

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

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

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

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

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

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

  1. htpasswd registry.password USERNAME

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

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

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

  1. nano ~/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, удалив символ #. в начале

# 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, и сказали ему использовать только что созданный файл паролей.

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

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

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

  1. curl http://localhost:5043/v2/

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

Output of curl
<html> <head><title>401 Authorization Required</title></head> <body bgcolor="white"> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.9.7</center> </body> </html>

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

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

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

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

Шаг 5 — Настройка SSL

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

Включим их. Сначала откройте файл конфигурации Nginx для редактирования:

  1. nano ~/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 на ваше доменное имя, пока вы это делаете. Когда вы закончите, верхняя часть файла должна выглядеть так:

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).

Вы также можете получить бесплатный подписанный SSL-сертификат.

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

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

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

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

  1. cd ~/docker-registry/nginx

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

  1. openssl genrsa -out devdockerCA.key 2048

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

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

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

  1. openssl genrsa -out domain.key 2048

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

После ввода этой команды OpenSSL предложит вам ответить на несколько вопросов. Напишите все, что хотите, для первых нескольких, но когда OpenSSL предложит вам ввести \Общее имя, обязательно введите домен или IP-адрес вашего сервера.

  1. 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 []:

Не вводите контрольный пароль.

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

  1. 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:

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

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

  1. sudo service docker restart

Предупреждение: вам придется повторить этот шаг для каждой машины, которая подключается к этому реестру Docker! Инструкции о том, как это сделать для клиентов Ubuntu 14.04, перечислены в разделе Шаг 9 — Доступ к вашему реестру Docker с клиентского компьютера.

Шаг 6 — Тестирование SSL

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

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

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

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

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

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

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

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

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

  1. curl https://sammy:test@www.example.com:5043/v2/

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

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

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

Шаг 7 — Установка SSL-порта на 443

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

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

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

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

В разделе Nginx вы увидите раздел ports:, измените строку - 5043:443 (это сопоставляет порт 5043 на нашем хост-компьютере с портом 443 внутри контейнера Nginx ) на - 443:443, чтобы порт 443 нашего контейнера Nginx был сопоставлен с портом 443 нашего хост-компьютера. Когда закончите, ваш 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:

  1. sudo docker-compose up

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

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

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

  1. curl https://<YOURUSERNAME>:<YOURPASSWORD>@YOUR-DOMAIN/v2/

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

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

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

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

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

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

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

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

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

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 читайте в этом руководстве.

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

  1. sudo service docker-registry start

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

docker-registry start/running, process 25303

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

  1. 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 необходим, поскольку журналы upstart записываются от имени пользователя root):

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

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

  1. curl https://<YOUR_USERNAME>:<YOURPASSWORD>@[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" "-"

Шаг 9 — Доступ к вашему реестру Docker с клиентского компьютера

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

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

На сервере регистрации просмотрите сертификат:

  1. 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-----

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

На клиентском компьютере создайте каталог сертификатов:

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

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

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

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

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

  1. 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-----

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

  1. sudo update-ca-certificates

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

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

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

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

  1. sudo service docker restart

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

  1. docker login https://YOUR-DOMAIN

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

Output of docker login
Username: 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 login
Login Succeeded

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

Шаг 10 — Опубликуйте в своем личном реестре Docker

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

На клиентском компьютере создайте небольшой пустой образ для отправки в наш новый реестр.

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

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

  1. touch /SUCCESS

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

  1. exit

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

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

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

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

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

  1. 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 есть необычный механизм для указания того, в какой реестр отправлять данные. Вы должны пометить изображение с местоположением частного реестра, чтобы нажать на него. Давайте пометим наш образ в наш частный реестр:

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

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

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

  1. docker push [YOUR-DOMAIN]/test-image

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

Output of docker push
latest: digest: sha256:5ea1cfb425544011a3198757f9c6b283fa209a928caabe56063f85f3402363b4 size: 8008

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

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

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

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

  1. docker login https://[YOUR-DOMAIN]

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

  1. docker pull [YOUR-DOMAIN]/test-image

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

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

Удачного докеринга!