One place for hosting & domains

      частного

      Настройка частного реестра Docker в Ubuntu 18.04


      Автор выбрал фонд Apache Software Foundation для получения пожертвования в рамках программы Write for DOnations.

      Введение

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

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

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

      Предварительные требования

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

      • Два сервера Ubuntu 18.04, настроенных в соответствии с руководством по начальной настройке сервера Ubuntu 18.04, включая пользователя sudo без прав root и брандмауэр. На одном сервере будет располагаться ваш частный реестр Docker, а другой будет выступать в качестве сервера-клиента.
      • На обоих серверах должны быть установлены Docker и Docker-Compose в соответствии с указаниями обучающего модуля «Установка Docker-Compose в Ubuntu 18.04». Для установки Docker Compose достаточно выполнить первый шаг этого обучающего модуля. В этом обучающем модуле объясняется, как устанавливать Docker для выполнения предварительных требований.
      • На сервере частного реестра Docker должен быть установлен веб-сервер Nginx в соответствии с указаниями руководства «Установка Nginx в Ubuntu 18.04».
      • Веб-сервер Nginx на сервере частного реестра Docker должен быть защищен Let’s Encrypt в соответствии с указаниями обучающего модуля «Защита Nginx с помощью Let’s Encrypt». Убедитесь, что весь трафик протокола HTTP перенаправляется на протокол HTTPS в соответствии с указаниями шага 4.
      • Доменное имя для сервера, используемого вами для частного реестра Docker. Вы должны были настроить его во время выполнения предварительных требований по защите с помощью Let’s Encrypt.

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

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

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

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

      На том же сервере, который вы создали для размещения частного реестра Docker, вы можете создать каталог docker-registry, перейти в него, а затем создать подпапку data с помощью следующих команд:

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

      Используйте текстовый редактор для создания файла конфигурации docker-compose.yml:

      Добавьте в файл следующие строки, описывающие базовую конфигурацию реестра Docker:

      docker-compose.yml

      version: '3'
      
      services:
        registry:
          image: registry:2
          ports:
          - "5000:5000"
          environment:
            REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
          volumes:
            - ./data:/data
      

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

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

      Раздел ports с конфигурацией 5000:5000 предписывает Docker сопоставить порт 5000 на сервере с портом 5000 запущенного контейнера. Это позволяет отправить запрос на порт 5000 на сервере так, чтобы этот запрос был перенаправлен в приложение реестра.

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

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

      Output of docker-compose up

      Starting docker-registry_registry_1 ... done Attaching to docker-registry_registry_1 registry_1 | time="2018-11-06T18:43:09Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="redis not configured" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="Starting upload purge in 20m0s" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2 registry_1 | time="2018-11-06T18:43:09Z" level=info msg="listening on [::]:5000" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2

      С предупреждающим сообщением No HTTP secret provided мы разберемся в этом же обучающем модуле, но чуть позднее. Экран результатов показывает, что контейнер запускается. Последняя строка результатов показывает, что прослушивание порта 5000 началось успешно.

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

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

      Шаг 2 — Настройка перенаправления портов Nginx

      Вы уже настроили на сервере реестра Docker протокол HTTPS с Nginx, и это значит, что теперь вы можете настроить переадресацию портов с Nginx на порт 5000. После выполнения этого шага вы сможете получать доступ к своему реестру непосредственно по адресу example.com.

      На предварительном этапе «Защита Nginx с помощью Let’s Encrypt» вы уже создали и настроили файл /etc/nginx/sites-available/example.com с конфигурацией вашего сервера.

      Откройте этот файл в предпочитаемом текстовом редакторе:

      • sudo nano /etc/nginx/sites-available/example.com

      Найдите существующую строку location. Он будет выглядеть примерно так:

      /etc/nginx/sites-available/example.com

      ...
      location / {
        ...
      }
      ...
      

      Вам нужно перенаправить трафик на порт 5000, где будет работать ваш реестр. Также вам следует добавить в запрос реестра заголовки, которые будут предоставлять дополнительную информацию сервера в каждом запросе и ответе. Удалите содержимое раздела location и добавьте в него следующее:

      /etc/nginx/sites-available/example.com

      ...
      location / {
          # Do not allow connections from docker 1.5 and earlier
          # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
          if ($http_user_agent ~ "^(docker/1.(3|4|5(?!.[0-9]-dev))|Go ).*$" ) {
            return 404;
          }
      
          proxy_pass                          http://localhost:5000;
          proxy_set_header  Host              $http_host;   # required for docker client's sake
          proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
          proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
          proxy_set_header  X-Forwarded-Proto $scheme;
          proxy_read_timeout                  900;
      }
      ...
      

      Раздел $http_user_agent подтверждает, что версия клиента Docker выше 1.5 и что UserAgent не является приложением Go. Поскольку вы используете версию реестра 2.0, старые клиенты не поддерживаются. Дополнительную информацию можно найти в конфигурации заголовка nginx в руководстве по Nginx в реестре Docker.

      Сохраните и закройте файл. Перезапустите Nginx для активации изменений:

      • sudo service nginx restart

      Для подтверждения перенаправления трафика Nginx на порт 5000 запустите реестр:

      • cd ~/docker-registry
      • docker-compose up

      Откройте в окне браузера следующий url:

      https://example.com/v2
      

      Вы увидите пустой объект JSON или:

      {}
      

      Вы увидите на терминале следующий экран результатов:

      Output of docker-compose up

      registry_1 | time="2018-11-07T17:57:42Z" level=info msg="response completed" go.version=go1.7.6 http.request.host=cornellappdev.com http.request.id=a8f5984e-15e3-4946-9c40-d71f8557652f http.request.method=GET http.request.remoteaddr=128.84.125.58 http.request.uri="/v2/" http.request.useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" http.response.contenttype="application/json; charset=utf-8" http.response.duration=2.125995ms http.response.status=200 http.response.written=2 instance.id=3093e5ab-5715-42bc-808e-73f310848860 version=v2.6.2 registry_1 | 172.18.0.1 - - [07/Nov/2018:17:57:42 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7"

      Из последней строки видно, что запрос GET был направлен по адресу /v2/, который представляет собой конечную точку отправки запроса из браузера. Контейнер получил отправленный запрос посредством перенаправления портов и возвратил ответ {}. Код 200 в последней строке на экране результатов означает, что контейнер успешно обработал запрос.

      Теперь вы успешно настроили переадресацию портов и можете перейти к дальнейшему повышению безопасности вашего реестра.

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

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

      Для установки пакета htpasswd запустите следующую команду:

      • sudo apt install apache2-utils

      Теперь вы создадите каталог, где будут храниться учетные данные аутентификации, и перейдете в этот каталог. $_ раскрывается в последний аргумент предыдущей команды, в данном случае ~/docker-registry/auth:

      • mkdir ~/docker-registry/auth && cd $_

      Теперь вы создадите первого пользователя, заменив username желаемым именем пользователя. Флаг -B указывает, что нужно использовать шифрование bcrypt, которое более безопасно, чем шифрование по умолчанию. Введите пароль в диалоговом окне:

      • htpasswd -Bc registry.password username

      Примечание. Для добавления дополнительных пользователей запустите предыдущую команду еще раз с опцией -c («c» означает создание):

      • htpasswd registry.password username

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

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

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

      docker-compose.yml

      version: '3'
      
      services:
        registry:
          image: registry:2
          ports:
          - "5000:5000"
          environment:
            REGISTRY_AUTH: htpasswd
            REGISTRY_AUTH_HTPASSWD_REALM: Registry
            REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
            REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
          volumes:
            - ./auth:/auth
            - ./data:/data
      

      Для REGISTRY_AUTH вы задали htpasswd как используемую схему аутентификации, а для REGISTRY_AUTH_HTPASSWD_PATH вы задали путь к файлу аутентификации. Наконец, REGISTRY_AUTH_HTPASSWD_REALM означает имя области htpasswd.

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

      Откройте в окне браузера адрес https://example.com/v2.

      Введите username и соответствующий пароль, и вы снова увидите {}. Вы подтвердили базовую настройку аутентификации. Реестр возвратил результат только после ввода правильного имени пользователя и пароля. Вы защитили свой реестр и теперь можете переходить к его использованию.

      Шаг 4 — Запуск реестра Docker как службы

      Вам нужно, чтобы реестр запускался каждый раз во время загрузки вашей системы. В случае непредвиденного сбоя системы вам нужно сделать так, чтобы реестр перезапускался при перезагрузке сервера. Откройте файл docker-compose.yml:

      Добавьте следующую строку в раздел registry::

      docker-compose.yml

      ...
        registry:
          restart: always
      ...
      

      Вы можете запускать реестр как фоновый процесс, и тогда вы сможете выходить из сеанса ssh с сохранением процесса:

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

      Шаг 5 — Увеличение размера выгрузки файлов для Nginx

      Прежде чем вы сможете отправить образ в реестр, нужно убедиться, что реестр может принимать большие файлы. Хотя Docker разделяет выгружаемые большие образы на несколько слоев, их размер иногда может превышать 1 ГБ. По умолчанию в Nginx установлен лимит выгрузки файлов 1 МБ, так что вам нужно отредактировать файл конфигурации nginx и задать максимальный размер выгрузки файла 2 ГБ.

      • sudo nano /etc/nginx/nginx.conf

      Найдите раздел http и добавьте в него следующую строку:

      /etc/nginx/nginx.conf

      ...
      http {
              client_max_body_size 2000M;
              ...
      }
      ...
      

      Перезапустите Nginx, чтобы применить изменения конфигурации:

      • sudo service nginx restart

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

      Шаг 6 — Публикация в частном реестре Docker

      Теперь вы готовы к публикации образов в частном реестре Docker, но вначале вам потребуется создать образ. Для целей этого обучающего модуля мы создадим простой образ на базе образа ubuntu из Docker Hub. Docker Hub — это публичный реестр с множеством настроенных образов, которые можно использовать для быстрой контейнеризации приложений с помощью Docker. С помощью образа ubuntu вы протестируете отправку образов в реестр и их извлечение из реестра.

      Создайте на своем клиентском сервере небольшой пустой образ для отправки в новый реестр. Флаги -i и -t обеспечивают доступ к контейнеру через интерактивную оболочку:

      • docker run -t -i ubuntu /bin/bash

      После завершения выгрузки вы попадете в диалог Docker. Обратите внимание, что идентификатор контейнера после root@ может отличаться. Внесите быстрые изменения в файловую систему, создав файл с именем SUCCESS. На следующем шаге вы сможете использовать данный файл, чтобы определить, была ли публикация успешной:

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

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

      Сохраните изменение:

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

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

      • docker login https://example.com

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

      • docker tag test-image example.com/test-image

      Отправьте образ с меткой в реестр:

      • docker push example.com/test-image

      Экран результатов должен выглядеть примерно следующим образом:

      Output

      The push refers to a repository [example.com/test-image] e3fbbfb44187: Pushed 5f70bf18a086: Pushed a3b5c80a4eba: Pushed 7f18b442972b: Pushed 3ce512daaf78: Pushed 7aae4540b42d: Pushed ...

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

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

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

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

      • docker login https://example.com

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

      • docker pull example.com/test-image

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

      • docker run -it example.com/test-image /bin/bash

      Выведите список файлов в оболочке bash:

      Вы увидите файл SUCCESS, который вы создали для этого образа:

      SUCCESS  bin  boot  dev  etc  home  lib  lib64  media   mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
      

      Вы завершили настройку защищенного реестра для отправки и получения образов.

      Заключение

      В этом обучающем модуле вы настроили собственный частный реестр Docker и опубликовали образ Docker. Как указывалось во введении, вы также можете использовать TravisCI или другой подобный инструмент CI для автоматизации прямой отправки образов в частный реестр. Используя Docker и реестры в своем рабочем процессе, вы можете убедиться, что образ с кодом будет вести себя одинаково на любом компьютере в производственной среде или в среде разработки. Дополнительную информацию о написании файлов Docker можно найти в следующем обучающем модуле по Docker, где разъясняется данная процедура.



      Source link