Развертывание сервера реестра

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

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

В этом разделе представлены основные сведения о развертывании и настройке реестра. Полный список параметров конфигурации см. в справочнике на конфигурацию.

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

Запуск локального реестра

Используйте следующую команду, чтобы запустить контейнер реестра:

$ docker run -d -p 5000:5000 --restart=always --name registry registry:2

Теперь реестр готов к использованию.

Предупреждение

В данных первых нескольких примерах показаны конфигурации реестра, которые подходят только для тестирования. Готовый к работе реестр должен быть защищен TLS и в идеале должен использовать механизм контроля доступа. Продолжайте читать, а затем перейдите к руководство по настройке, чтобы развернуть готовый к работе реестр.

Копирует образ из Docker Hub в свой реестр

Вы можете получает образ из Docker Hub и отправить его в свой реестр. В следующем примере образ ubuntu:16.04 извлекается из Docker Hub и повторно помечается как my-ubuntu, а затем отправляется в локальный реестр. Наконец, образы ubuntu:16.04 и my-ubuntu удаляются локально, а образ my-ubuntu извлекается из локального реестра.

  1. Загружает образ ubuntu:16.04 из Docker Hub.

    $ docker pull ubuntu:16.04
    
  2. Пометьте образ как localhost:5000/my-ubuntu. Это создаёт дополнительный тег для существующего образа. Когда первая часть тега представляет собой имя хоста и порт, Docker интерпретирует это как расположение реестра при отправке.

    $ docker tag ubuntu:16.04 localhost:5000/my-ubuntu
    
  3. Отправить образ в локальный реестр с адресом localhost:5000:

    $ docker push localhost:5000/my-ubuntu
    
  4. Удаляет локально кэшированные образы ubuntu:16.04 и localhost:5000/my-ubuntu, чтобы вы могли протестировать извлечение образа из реестра. При этом образ localhost:5000/my-ubuntu не удаляется из реестра.

    $ docker image remove ubuntu:16.04
    $ docker image remove localhost:5000/my-ubuntu
    
  5. Извлечь образ localhost:5000/my-ubuntu из локального реестра.

    $ docker pull localhost:5000/my-ubuntu
    

Останавливает локальный реестр

Чтобы останавливает реестр, используйте ту же команду docker container stop, что и для любого другого контейнера.

$ docker container stop registry

Чтобы удаляет контейнер, используйте docker container rm.

$ docker container stop registry && docker container rm -v registry

Базовая конфигурация

Чтобы настроить контейнер, вы можете передать дополнительные или измененные параметры команде docker run.

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

Автоматический запуск реестра

Если вы хотите использовать реестр как часть своей постоянной инфраструктуры, вы должны настроить его на автоматический перезапуск при перезапуске Docker или при выходе из него. В этом примере используется флаг --restart always, чтобы задать политику перезапуска для реестра.

$ docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  registry:2

Настраивает опубликованный порт

Если вы уже используете порт 5000 или хотите запустить несколько локальных реестров для разделения проблемных областей, вы можете настроить параметры порта реестра. В этом примере реестр запускается через порт 5001 и также называется registry-test. Помните, что первая часть значения -p — это порт хоста, а вторая часть — это порт внутри контейнера. В контейнере реестр по умолчанию прослушивает порт 5000.

$ docker run -d \
  -p 5001:5000 \
  --name registry-test \
  registry:2

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

$ docker run -d \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
  -p 5001:5001 \
  --name registry-test \
  registry:2

Настройка хранилища

Настраивает место хранения

По умолчанию данные вашего реестра сохраняются как объём Docker в файловой системе хоста. Если вы хотите хранить содержимое реестра в определенном месте файловой системы вашего хоста, например, если у вас есть SSD или SAN, смонтированные в определённый каталог, вы можете вместо этого использовать монтирование с привязкой. Связное монтирование больше зависит от структуры файловой системы хоста Docker, но во многих ситуациях более производительно. В следующем примере каталог узлов /mnt/registry подключается к контейнеру реестра по адресу /var/lib/registry/.

$ docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -v /mnt/registry:/var/lib/registry \
  registry:2

Настраивает серверную часть хранилища

По умолчанию реестр хранит свои данные в локальной файловой системе, независимо от того, используете ли вы монтирование с привязкой или том. Вы можете хранить данные реестра в бакете Amazon S3, Google Cloud Platform или другом внутреннем хранилище с помощью драйверы хранилища. Для получения дополнительной информации см. параметры конфигурации хранилища.

Запуск доступного извне реестра

Запуск реестра, доступного только в localhost, имеет ограниченную полезность. Чтобы сделать ваш реестр доступным для внешних хостов, вы должны сначала защитить его с помощью TLS.

Данный пример расширен в Запуск реестра как службы далее.

Получает сертификат

Данные примеры предполагают следующее:

  • URL-адрес вашего реестра — https://myregistry.domain.com/.

  • Ваши настройки DNS, маршрутизации и брандмауэра разрешают доступ к узлу реестра через порт 443.

  • Вы уже получили сертификат от центра сертификации (CA).

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

  1. Создаёт каталог certs.

    $ mkdir -p certs
    

    Копирует файлы .crt и .key из каталога CA в каталог certs. Следующие шаги предполагают, что файлы имеют имена domain.crt и domain.key.

  2. Останавливает реестр, если он в данный момент запущен.

    $ docker container stop registry
    
  3. Перезапустите реестр, направив его на использование сертификата TLS. Эта команда монтирует каталог certs/ в контейнер по адресу /certs/ и устанавливает переменные среды, которые сообщают контейнеру, где найти файлы domain.crt и domain.key. Реестр работает через порт 443, порт HTTPS по умолчанию.

    $ docker run -d \
      --restart=always \
      --name registry \
      -v "$(pwd)"/certs:/certs \
      -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
      -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
      -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
      -p 443:443 \
      registry:2
    
  4. Клиенты Docker теперь могут извлекать данные из вашего реестра и отправлять их в него, используя его внешний адрес. Следующие команды демонстрируют это:

    $ docker pull ubuntu:16.04
    $ docker tag ubuntu:16.04 myregistry.domain.com/my-ubuntu
    $ docker push myregistry.domain.com/my-ubuntu
    $ docker pull myregistry.domain.com/my-ubuntu
    

Используйте промежуточный сертификат

Эмитент сертификата может предоставить вам промежуточный сертификат. В этом случае вы должны объединить свой сертификат с промежуточным сертификатом, чтобы сформировать пакет сертификатов. Вы можете сделать это с помощью команды cat:

cat domain.crt intermediate-certificates.pem > certs/domain.crt

Пакет сертификатов можно использовать так же, как файл domain.crt в предыдущем примере.

Поддержка Let’s Encrypt

Реестр поддерживает использование Let’s Encrypt для автоматического получения доверенного браузером сертификата. Для получения дополнительной информации о Let’s Encrypt см. https://letsencrypt.org/how-it-works/ и соответствующий раздел конфигурация реестра.

Используйте небезопасный реестр (только для тестирования)

Можно использовать самозаверяющий сертификат или небезопасно использовать наш реестр. Если вы не настроили проверку для своего самозаверяющего сертификата, это только для тестирования. См. запуск небезопасного реестра.

Запуск реестра как службу

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

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

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

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

В следующем примере реестр запускается как служба с одной репликой, которая доступна на любом узле swarm через порт 80. Предполагается, что вы используете те же сертификаты TLS, что и в предыдущих примерах.

Сначала сохраняет сертификат TLS и ключ как секреты:

$ docker secret create domain.crt certs/domain.crt

$ docker secret create domain.key certs/domain.key

Затем добавляет метку к узлу, на котором вы хотите запустить реестр. Чтобы получает имя узла, используйте docker node ls. Заменяет имя вашего узла на node1 далее.

$ docker node update --label-add registry=true node1

Затем создаёт службу, предоставив ей доступ к двум секретам и ограничив её работу только на узлах с меткой registry=true. Помимо ограничения, вы также указываете, что одновременно должна выполняться только одна реплика. В примере привязка монтирует /mnt/registry на узле swarm в /var/lib/registry/ внутри контейнера. Монтирование Bind зависит от уже существующего исходного каталога, поэтому убедиться, что /mnt/registry существует на node1. Возможно, вам потребуется создать его перед выполнением следующей команды docker service create.

По умолчанию секреты монтируются в службу по адресу /run/secrets/<secret-name>.

$ docker service create \
  --name registry \
  --secret domain.crt \
  --secret domain.key \
  --constraint 'node.labels.registry==true' \
  --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \
  --publish published=443,target=443 \
  --replicas 1 \
  registry:2

Вы можете получает доступ к сервису через порт 443 любого узла swarm. Docker отправляет запросы на узел, на котором работает служба.

Соображения по балансировке нагрузки

Можно использовать балансировщик нагрузки для распределения нагрузки, завершения TLS или обеспечения высокой доступности. Хотя настройка полной балансировки нагрузки выходит за рамки этого документа, есть несколько соображений, которые могут сделать процесс более плавным.

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

  • Драйвер хранилища

  • HTTP-секрет

  • Кэш Redis (если настроен)

Различия в любом из вышеперечисленных причин вызывают проблемы с обслуживанием запросов. Например, если вы используете драйвер файловой системы, все экземпляры реестра должны иметь доступ к одному и тому же корню файловой системы на одном компьютере. Для других драйверов, таких как S3 или Azure, они должны иметь доступ к одному и тому же ресурсу и использовать идентичную конфигурацию. Секрет HTTP координирует загрузку, поэтому он также должен быть одинаковым для всех экземпляров. Настройка разных экземпляров Redis работает (на момент написания), но не оптимальна, если экземпляры не являются общими, поскольку больше запросов направляется на серверную часть.

Важные/обязательные HTTP-заголовки

Правильные заголовки очень важны. Для всех ответов на любой запрос в пространстве URL «/v2/» в заголовке Docker-Distribution-API-Version должно быть установлено значение «registry/2.0», даже для ответа 4xx. Данный заголовок позволяет движку Docker быстро разрешать области аутентификации и при необходимости отступать к реестрам версии 1. Подтверждение правильности настройки может помочь избежать проблем с откатом.

В том же духе вы должны убедиться, что вы правильно отправляете заголовки X-Forwarded-Proto, X-Forwarded-For и Host в их значения «на стороне клиента». Если этого не сделать, проблема с реестром обычно приводит к перенаправлению на внутренние имена хостов или переходу с https на http.

Надлежащим образом защищенный реестр должен возвращать 401 при попадании в конечную точку «/v2/» без учетных данных. Ответ должен включать вызов WWW-Authenticate, предоставляющий рекомендации по аутентификации, например, с помощью базовой аутентификации или службы токенов. Если у балансировщика нагрузки есть проверки работоспособности, рекомендуется настроить его таким образом, чтобы ответ 401 считался работоспособным, а любой другой — нерабочим. Это защищает ваш реестр, гарантируя, что проблемы конфигурации с проверкой подлинности не откроют случайно незащищенный реестр. Если вы используете менее сложный балансировщик нагрузки, такой как Elastic Load Balancer от Amazon, который не позволяет изменяет код работоспособного ответа, проверки работоспособности можно направить на «/», который всегда возвращает ответ 200 OK.

Ограничение доступа

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

Нативная базовая авторизация

Самый простой способ добиться ограничения доступа — использовать базовую аутентификацию (это очень похоже на базовый механизм аутентификации других веб-серверов). В этом примере используется собственная базовая проверка подлинности с использованием htpasswd для хранения секретов.

Предупреждение

Вы не можете использовать аутентификацию со схемами аутентификации, которые отправляют учетные данные в виде открытого текста. Для работы аутентификации необходимо сначала настраивает TLS.

  1. Создаёт файл паролей с одной записью для пользователя testuser с паролем testpassword:

    $ mkdir auth
    $ docker run \
      --entrypoint htpasswd \
      httpd:2 -Bbn testuser testpassword > auth/htpasswd
    

    В Windows убедиться, что выходной файл правильно закодирован:

    docker run --rm --entrypoint htpasswd httpd:2 -Bbn testuser testpassword | Set-Content -Encoding ASCII auth/htpasswd
    
  2. Останавливает реестр.

    $ docker container stop registry
    
  3. Запуск реестра с базовой аутентификацией.

    $ docker run -d \   -p 5000:5000 \   --restart=always \   --name registry \   -v "$(pwd)"/auth:/auth \   -e "REGISTRY_AUTH=htpasswd" \   -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \   -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \   -v "$(pwd)"/certs:/certs \   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \   -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \   registry:2
    
  4. Пытается вытащить образ из реестра или отправить образ в реестр. Данные команды не работают.

  5. Войти в реестр.

    $ docker login myregistrydomain.com:5000
    

    Входит имя пользователя и пароль из первого шага.

    Проверяет, что теперь вы можете извлечь образ из реестра или отправить образ в реестр.

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

Более продвинутая аутентификация

Возможно, вы захотите использовать более продвинутые базовые реализации аутентификации, используя прокси-сервер перед реестром. См. список рецептов.

Реестр также поддерживает делегированную аутентификацию, которая перенаправляет пользователей на определённый доверенный сервер токенов. Данный подход более сложен в настройке и имеет смысл только в том случае, если вам необходимо полностью настроить списки управления доступом и требуется больший контроль над интеграцией реестра в ваши глобальные системы авторизации и аутентификации. См. следующие исходная информация и информация о конфигурации здесь.

Данный подход требует от вас реализации собственной системы аутентификации или использования сторонней реализации.

Разверните реестр, используя файл Compose

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

registry:
  restart: always
  image: registry:2
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
    REGISTRY_HTTP_TLS_KEY: /certs/domain.key
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
    - /path/data:/var/lib/registry
    - /path/certs:/certs
    - /path/auth:/auth

Заменяет /path на каталог, содержащий каталоги certs/ и auth/.

Запуск реестра, введя следующую команду в каталоге, содержащем файл docker-compose.yml:

$ docker-compose up -d

Соображения по поводу закрытых реестров

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

  • Вам может потребоваться создать том данных вашего локального реестра на подключенном узле, где вы можете выполнить docker pull, чтобы получить любые доступные удаленно образы, а затем перенести том данных реестра в изолированную сеть.

  • Некоторые образы, например официальные базовые образы Microsoft Windows, распространять нельзя. Это означает, что когда вы отправляете образ, основанный на одном из данных образов, в свой частный реестр, нераспространяемые слои не передаются, а всегда извлекаются из их авторизованного местоположения. Это нормально для хостов, подключенных к Интернету, но не в системе с воздушным зазором.

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

  1. Отредактируйте файл daemon.json, который находится в /etc/docker/ на хостах Linux и C:\ProgramData\docker\config\daemon.json на Windows Server. Предполагая, что файл ранее был пуст, добавляет следующее содержимое:

    {     "allow-nondistributable-artifacts": ["myregistrydomain.com:5000"]   }
    

    Значение представляет собой массив адресов реестра, разделенных запятыми.

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

  2. Перезапуск Docker.

  3. Перезапустите реестр, если он не запускается автоматически.

  4. Когда вы отправляете образы в реестры в списке, их нераспространяемые слои передаются в реестр.

    Предупреждение

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

Следующие шаги

Более конкретная и расширенная информация доступна в следующих разделах: