Введение
Docker стал незаменимым инструментом для разработчиков и команд DevOps, обеспечивая бесшовное развертывание и управление контейнеризированными приложениями. При работе с частным реестром Docker (Docker registry) обеспечение безопасности связи между клиентами Docker и сервером реестра имеет решающее значение для защиты ваших образов контейнеров.
В этой лабораторной работе вы узнаете, как настроить локальный реестр Docker и защитить его с помощью самозаверяющего SSL-сертификата. Этот подход идеально подходит для сред разработки, тестирования и учебных сценариев, где вам нужен безопасный реестр без приобретения сертификата у доверенного центра сертификации.
К концу этого руководства у вас будет функционирующий реестр Docker, использующий HTTPS для безопасной связи, что позволит вам безопасно отправлять и извлекать образы Docker в вашей среде разработки.
Настройка базового реестра Docker
Прежде чем защищать наш реестр Docker с помощью SSL, давайте сначала разберемся, что такое реестр Docker, и настроим базовый реестр для работы.
Что такое реестр Docker?
Реестр Docker (Docker registry) — это система хранения и распространения образов контейнеров Docker. Он позволяет вам:
- Хранить ваши образы Docker в централизованном месте
- Обмениваться образами с вашей командой или организацией
- Контролировать доступ к вашим образам
- Развертывать контейнеры из ваших образов в различных средах
Docker Hub — самый известный публичный реестр, но для многих организаций наличие частного реестра имеет важное значение для безопасности, производительности и контроля.
Настройка базового реестра
Давайте начнем с запуска простого, незащищенного реестра Docker:
Создайте каталог для хранения данных нашего реестра:
mkdir -p ~/project/registry-dataЗапустите базовый реестр Docker, используя официальный образ:
docker run -d -p 5000:5000 --restart=always --name registry -v ~/project/registry-data:/var/lib/registry registry:2Эта команда:
- Запускает контейнер реестра в фоновом режиме (
-d) - Отображает порт 5000 на вашем хосте на порт 5000 в контейнере
- Настраивает автоматический перезапуск контейнера при его остановке
- Называет контейнер "registry"
- Монтирует созданный нами каталог для хранения данных реестра
- Запускает контейнер реестра в фоновом режиме (
Убедитесь, что реестр запущен:
docker psВы должны увидеть вывод, аналогичный следующему:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a7d8098de3a2 registry:2 "/entrypoint.sh /etc…" 5 seconds ago Up 4 seconds 0.0.0.0:5000->5000/tcp registryПротестируйте реестр, отправив пример образа:
Сначала извлеките небольшой образ:
docker pull hello-worldПометьте его для вашего локального реестра:
docker tag hello-world localhost:5000/hello-worldОтправьте его в свой реестр:
docker push localhost:5000/hello-worldВы должны увидеть вывод, показывающий, что образ отправляется в ваш реестр.
Остановите контейнер реестра, прежде чем мы защитим его в следующих шагах:
docker stop registry docker rm registry
Этот базовый реестр работает, но имеет существенное ограничение: он использует HTTP, который небезопасен. Клиенты Docker по умолчанию отказываются отправлять или извлекать данные из незащищенных реестров. В следующих шагах мы защитим наш реестр с помощью SSL.
Генерация самозаверяющего SSL-сертификата
Теперь, когда мы понимаем основы Docker Registry, давайте защитим его, сгенерировав самозаверяющий SSL-сертификат. Этот сертификат включит связь HTTPS с нашим реестром.
Что такое самозаверяющий сертификат?
Самозаверяющий сертификат — это SSL-сертификат, который не подписан доверенным центром сертификации (CA). Хотя самозаверяющие сертификаты не подходят для производственных сред, доступных в публичном интернете, они идеально подходят для разработки, тестирования и внутренних приложений.
Генерация сертификата и ключа
Мы будем использовать OpenSSL, широко используемый набор инструментов для криптографии, для создания нашего сертификата:
Создайте каталог для хранения наших сертификатов:
mkdir -p ~/project/registry-certs cd ~/project/registry-certsСгенерируйте закрытый ключ:
openssl genrsa -out registry.key 2048Эта команда генерирует 2048-битный закрытый ключ RSA. При успешном выполнении вы не должны увидеть никакого вывода.
Создайте запрос на подпись сертификата (CSR), используя закрытый ключ:
openssl req -new -key registry.key -out registry.csrВам будет предложено ввести информацию, которая будет включена в ваш сертификат:
Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California Locality Name (eg, city) []:San Francisco Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Company Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []:admin@example.comПримечание: Для
Common Nameвведитеlocalhost, так как мы будем подключаться к реестру на нашей локальной машине.Вам также будет предложено:
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:Вы можете оставить эти поля пустыми, нажав Enter.
Сгенерируйте самозаверяющий сертификат, используя CSR:
openssl x509 -req -days 365 -in registry.csr -signkey registry.key -out registry.crtЭта команда создает самозаверяющий сертификат, действительный в течение 365 дней.
Вы должны увидеть вывод, аналогичный следующему:
Signature ok subject=C = US, ST = California, L = San Francisco, O = Example Company, OU = IT, CN = localhost, emailAddress = admin@example.com Getting Private keyУбедитесь, что файлы сертификата и ключа были созданы:
ls -lВы должны увидеть три файла:
total 12 -rw-r--r-- 1 labex labex 1220 [date] registry.crt -rw-r--r-- 1 labex labex 1054 [date] registry.csr -rw-r--r-- 1 labex labex 1679 [date] registry.key
Теперь у нас есть необходимые файлы для защиты нашего реестра Docker. На следующем шаге мы настроим наш реестр для использования этого сертификата для связи HTTPS.
Настройка реестра Docker с SSL-сертификатом
Теперь, когда у нас есть самозаверяющий сертификат, мы можем настроить наш реестр Docker для использования SSL для безопасной связи.
Настройка безопасного реестра
Во-первых, давайте создадим простой файл конфигурации для нашего реестра. Этот файл укажет настройки HTTPS:
mkdir -p ~/project/registry-config cd ~/project/registry-config nano config.ymlДобавьте следующую конфигурацию в файл:
version: 0.1 storage: filesystem: rootdirectory: /var/lib/registry http: addr: 0.0.0.0:5000 tls: certificate: /certs/registry.crt key: /certs/registry.keyЭта конфигурация указывает реестру:
- Использовать файловую систему для хранения
- Прослушивать все интерфейсы на порту 5000
- Использовать TLS (HTTPS) с нашим сертификатом и ключом
Сохраните и выйдите, нажав
Ctrl+X, затемY, а затемEnter.Теперь давайте запустим наш реестр с SSL-сертификатом:
docker run -d -p 5000:5000 --restart=always --name registry \ -v ~/project/registry-data:/var/lib/registry \ -v ~/project/registry-certs:/certs \ -v ~/project/registry-config/config.yml:/etc/docker/registry/config.yml \ registry:2Эта команда:
- Монтирует наш каталог сертификатов и ключей
- Монтирует наш файл конфигурации
- Использует тот же каталог данных, который мы создали ранее
Убедитесь, что реестр запущен:
docker psВы должны увидеть вывод, показывающий, что контейнер реестра запущен.
Настройка клиента Docker для доверия сертификату
По умолчанию клиенты Docker не доверяют самозаверяющим сертификатам. Нам нужно указать Docker доверять нашему сертификату:
Создайте каталог для хранения доверенных сертификатов Docker:
sudo mkdir -p /etc/docker/certs.d/localhost:5000Скопируйте наш сертификат в этот каталог:
sudo cp ~/project/registry-certs/registry.crt /etc/docker/certs.d/localhost:5000/ca.crtПерезапустите службу Docker, чтобы применить изменения:
sudo systemctl restart dockerЭто может занять несколько секунд.
Поскольку перезапуск Docker остановит наш контейнер реестра, давайте запустим его снова:
docker start registryУбедитесь, что реестр снова запущен:
docker ps
Теперь наш реестр Docker настроен для использования HTTPS с нашим самозаверяющим сертификатом, а наш клиент Docker настроен для доверия этому сертификату при подключении к localhost:5000.
Тестирование безопасного реестра Docker
Теперь, когда наш реестр Docker работает с SSL, давайте протестируем его, отправляя и извлекая образы. Это подтвердит, что все работает правильно.
Тестирование с использованием образца образа
Во-первых, давайте извлечем образец образа для тестирования:
docker pull alpine:latestВы должны увидеть вывод, показывающий, что Docker загружает образ Alpine Linux.
Пометьте образ для нашего безопасного реестра:
docker tag alpine:latest localhost:5000/alpine:latestЭта команда создает новый тег, который указывает на наш локальный реестр.
Отправьте образ в наш безопасный реестр:
docker push localhost:5000/alpine:latestВы должны увидеть вывод, показывающий, что слои образа отправляются в ваш реестр:
The push refers to repository [localhost:5000/alpine] 213ec9aee27d: Pushed latest: digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f size: 528Удалите локальный образ, чтобы убедиться, что мы извлекаем из реестра:
docker rmi localhost:5000/alpine:latest docker rmi alpine:latestИзвлеките образ из нашего безопасного реестра:
docker pull localhost:5000/alpine:latestВы должны увидеть вывод, показывающий, что Docker загружает образ из вашего реестра:
latest: Pulling from alpine 213ec9aee27d: Pull complete Digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f Status: Downloaded newer image for localhost:5000/alpine:latest localhost:5000/alpine:latest
Проверка содержимого реестра
Давайте рассмотрим содержимое нашего реестра, используя API Docker Registry:
Перечислите все репозитории в реестре:
curl -X GET https://localhost:5000/v2/_catalog --cacert ~/project/registry-certs/registry.crtВы должны увидеть вывод, подобный следующему:
{ "repositories": ["alpine", "hello-world"] }Это показывает все образы, которые мы отправили в наш реестр.
Перечислите все теги для репозитория alpine:
curl -X GET https://localhost:5000/v2/alpine/tags/list --cacert ~/project/registry-certs/registry.crtВы должны увидеть вывод, подобный следующему:
{ "name": "alpine", "tags": ["latest"] }
Понимание того, что мы сделали
Давайте рассмотрим, что мы сделали:
- Настроили реестр Docker с HTTPS, используя самозаверяющий SSL-сертификат
- Настроили наш клиент Docker для доверия этому сертификату
- Успешно отправили и извлекли образы в и из нашего безопасного реестра
Эта настройка обеспечивает:
- Зашифрованную связь: Все данные, передаваемые между клиентом Docker и реестром, зашифрованы.
- Основа аутентификации: SSL — первый шаг к реализации аутентификации.
- Совместимость с клиентом Docker: Клиенты Docker по умолчанию требуют HTTPS для реестров, отличных от localhost.
Теперь вы можете использовать этот безопасный реестр для своих нужд разработки и тестирования. Для производственных сред вы обычно будете использовать сертификат от доверенного центра сертификации вместо самозаверяющего сертификата.
Резюме
Поздравляем! Вы успешно настроили безопасный реестр Docker, используя самозаверяющий SSL-сертификат. Вот чего вы достигли:
- Настроили базовый реестр Docker и поняли его назначение и функциональность
- Сгенерировали самозаверяющий SSL-сертификат для защиты вашего реестра
- Настроили реестр Docker для использования HTTPS с вашим сертификатом
- Настроили ваш клиент Docker для доверия самозаверяющему сертификату
- Успешно протестировали безопасный реестр, отправляя и извлекая образы
Эти навыки позволяют вам создавать безопасные частные реестры для ваших сред разработки и тестирования. Частные реестры дают вам контроль над тем, где хранятся ваши образы Docker и кто может получить к ним доступ, в то время как SSL-шифрование гарантирует, что ваши данные остаются безопасными во время передачи.
Для производственных сред вы обычно будете использовать сертификаты от доверенного центра сертификации, но процесс настройки будет аналогичен тому, что вы изучили в этой лабораторной работе.
Теперь вы можете уверенно внедрять безопасные реестры Docker в своих собственных проектах и рабочих процессах разработки, повышая безопасность ваших контейнеризованных приложений.



