Как работает docker: подробный гайд от техлида

Работа с docker registries

Install your Registry (on your server or locally)

Docker-Registry is a simple Python app, installing it is straight-forward:

git clone https://github.com/dotcloud/docker-registry.git
cd docker-registry
cp config_sample.yml config.yml
pip install -r requirements.txt
gunicorn --access-logfile - --log-level debug --debug 
    -b 0.0.0.0:5000 -w 1 wsgi:application

Your Registry is now running on localhost (port 5000) in a development flavor and using local storage. Obviously, in a production environment, you might want to run the Registry on port 443 (or 80 on a local network) and make it accessible on a hostname like “registry.domain.tld”, and point it to use S3 or other storage.

Adding SSL Certificates

A registry on localhost has limited functionality and can not be accessed from external sources. That is why adding an SSL certificate for a secure connection is vital when hosting a registry.

This section assumes you have the following requirements:

  • You have your own secure domain e.g. https://mydomain.com
  • Your DNS configuration allows accessing the registry on port 443
  • You have obtained a certificate from a certificate authority (CA) e.g. Let’s Encrypt

There are different ways of adding a certificate to your registry. We will look at the most common one which will cover most use-cases.

Adding a certificate:

If you already have a .crt and .key file from your CA, then you just need to copy them into a directory named certs in your project and add the following lines to your docker-compose file.

These environment variables tell the container where to find the certificates. The registry should now be secure and run on port 443 which is the default HTTPS port.

Шаг 1: Установка Docker

Почитал мануалов и сказано в них, что не по-пацански (не по админски) устанавливать Docker из репозиториев, ибо грех это! И так какие VPS у меня есть на текущий момент в работе? Это Debian, Ubuntu 22 и CentOS 7. Значит устанавливаем Docker и там и там и сравниваем отличия в установке.

Шаг 1.1 : Установка в Debian, Ubuntu

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

Обновление репозитория и установка зависимостей:

apt update
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common lsb-release

Теперь можно загрузить и установить пакет Docker. Добавьте в систему GPG-ключ репозитория Docker.

Для Debian:

curl -fsSL https://download.docker.comlinuxdebiangpg | sudo apt-key add -

Для Ubuntu (версии 18.04 LTS и выше):

curl -fsSL https://download.docker.comlinuxubuntugpg | sudo gpg --dearmor -o usrsharekeyringsdocker-archive-keyring.gpg

Добавьте этот репозиторий Docker в APT и обновить индекс пакетов.

Для Debian:

add-apt-repository "deb  https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt update

Для Ubuntu:

 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee etcaptsources.list.ddocker.list > devnull
apt update

Чтобы установить Docker, введите,

Для Debian:

apt install docker-ce

Для Ubuntu:

apt install docker-ce docker-ce-cli containerd.io

После установки должен запустится демон и настроится автозапуск процесса, проверим командой:

systemctl status docker

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

docker run hello-world

Проверяем, что всё установилось. У вас должны работать следующие команды (версии могут различаться)

# docker -v
Docker version 23.0.3, build 3e7cbfd

Шаг 1.2 : Установка в CentOS 7, 8

Теперь попробуем установить Docker в всё еще не умирающем CentOS версии 7. Кстати Доккер официально поддерживается только в 7 и 8 версии CentOS, а 6 забыли, хотя она до сих пор распространена.

В CentOS сначала придется удалить все намеки на старую версию Docker.

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

Рекомендуемый подход: настроить репозитории Docker и устанавливать из них него простоты установки и обновления. Для этого установим пакет yum-utils, который содержит утилиту yum-config-manager и настроим стабильный (stable) репозиторий. Есть еще nightly репозиторий, но думаю стабильного нам хватит:)

yum install -y yum-utils
 
yum-config-manager \
    --add-repo \
    https://download.docker.comlinuxcentosdocker-ce.repo

Теперь установка самого Docker:

yum install docker-ce docker-ce-cli containerd.io

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

systemctl start docker
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from libraryhello-world
2db29710123e: Pull complete
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
Status: Downloaded newer image for hello-world:latest
 
Hello from Docker!

Последний штрих, проверяем загружается ли при перезагрузке Linux наш Докер автоматически, используем для этого systemctl:

# systemctl is-enabled docker
disabled

Конечно же нет, добавим в автозагрузку Docker:

# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service
to /usr/lib/systemd/system/docker.service.

Шаг 1.3 : Установка Docker в Windows

Все что нужно знать об установки Docker в Windows 10 Pro это то, что у вас перестанут работать программы, такие как VirtualBox, эмуляторы Android.

А там уже смотрите сами, нужно ли вам такое счастье или нет.

Что такое Docker

Docker представляет собой систему управления контейнерами. Она позволяет «упаковать» приложение или веб-сайт со всем его окружением и зависимостями в контейнер, которым в дальнейшем можно легко и просто управлять: переносить на другой сервер, масштабировать, обновлять.

Docker был написан на языке программирования Go и выпущен в 2013 году. Изначально он работал только с Linux-системами, однако на данный момент его можно использовать также в Windows и macOS. Несмотря на то, что проект является относительно новым, Докер широко используется многими специалистами и продолжает завоевывать популярность.

Важной частью экосистемы Docker является Docker Hub – открытый репозиторий образов контейнеров. В нем можно найти десятки готовых приложений от официальных разработчиков. Среди них – nginx, MySQL, Apache, Gitlab, Redmine, Elasticsearch, Jenkins и другие

Среди них – nginx, MySQL, Apache, Gitlab, Redmine, Elasticsearch, Jenkins и другие.

Например, для запуска WordPress с помощью Docker достаточно выполнить следующие команды:

docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=wpmsqlpsswd -d mysql:5.7
<вывод пропущен>
docker run --name my-wordpress --link wp-mysql:mysql -d -p 80:80 wordpress

После этого откройте в браузере страницу http://12.34.56.78 (здесь укажите реальный IP-адрес вашего VDS) и приступите к настройке CMS!

Теперь расскажем о том, что представляет собой Docker. Три основных термина в экосистеме Docker:

  • Образ (image) – шаблон, который используется для создания контейнеров. Представляет собой слепок файловой системы, в котором расположен код приложения и его окружение.
  • Реестр (registry) – репозиторий образов. Docker Hub, о котором шла речь выше, – это публичный репозиторий, где хранится огромное количество образов.
  • Контейнер (container) – запущенное приложение, т.е. совокупность процессов и образа.

Часть 0.2 Процессы в контейнерах

  1. Контейнер живет, пока живет процесс, вокруг которого рождается контейнер.
  2. Внутри контейнера этот процесс имеет pid=1
  3. Рядом с процессом с pid=1 можно порождать сколько угодно других процессов (в пределах возможностей ОС, естественно), но убив (рестартовав) именно процесс с pid=1, контейнер выходит. (см п.1)
  4. Внутри контейнера вы увидите привычное согласно стандартам FHS расположение директорий. Расположение это идентично исходному дистрибутиву (с которого взят контейнер).
  5. Данные, создаваемые внутри контейнера остаются в контейнере и нигде более не сохраняются (ну, еще к этому слою есть доступ из хостовой ОС). удалив контейнер — потеряете все ваши изменения. Поэтому данные в контейнерах не хранят, а выносят наружу, на хостовую ОС.

Шаг 2: Как пользоваться командами, ключами Docker

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

docker   

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

docker subcommand --help

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

docker info
docker -v
Docker version 20.10.14, build a224086

Шаг 2.1: Управление контейнерами

Для просмотра запущенных контейнеров применяется команда docker ps, ключ а также показывает все контейнеры в системе. Разберем поля вывода команды

docker ps -a
или
docker container ls -a
  • CONTAINER ID — идентификатор контейнера, он уникален.
  • IMAGE — название образа, на основе которого запущен контейнер;
  • COMMAND — выполняемая при запуске контейнера команда;
  • CREATED — Когда был создан контейнер.
  • STATUS — статус контейнера, активен он или выключен.
  • PORTS — порты, через которые сервисы извне взаимодействует с контейнером и тем, что внутри него;
  • NAMES — имя контейнера.

Для просмотра последних созданных контейнеров используется опция -l:

docker ps -l
  • docker stats информация о потреблении ресурсов
  • docker logs ID вывод логов из указанного контейнера -f вывод логов в стиле tail –f
docker logs -f eef97a115270
  • docker kill ID принудительная остановка указанного контейнера, кроме того: stop, pause, unpause, restart.
  • -it опции, говорящие о том, что мы хотим интерактивно взаимодействовать с контейнером (оказаться «внутри» него). Добавление опций -i (видеть, что происходит в контейнере) и -t (взаимодействовать, то есть пересылать в контейнер наши команды) предоставляет доступ в интерактивном режиме к командному процессору.
  • -d, –detach указывает запуск в фоновом режиме
  • -p 8080:80 Проброс порта. Порт 80 «изнутри» контейнера становится портом 0.0.0.0:8080
  • Чтобы узнать IP адрес контейнера, используйте вывод ключа inspect:
docker container inspect ee7c5bd0f90e | grep IPAddress

Шаг 2.2: Как зайти в контейнер и выполнить команду внутри

Для того, чтобы выполнять команды внутри контейнера, надо для начала в него попасть. Для этого необходимо получить ID необходимого контейнера. Делается это командой:

docker ps

После получения списка всех запущенных контейнеров, мы выбираем (в первом столбце) ID нужного нам контейнера и подставляем в следующую команду вместо <container_id>:

docker exec -it <container_id> bash

Данная команда в контейнере <container_id> запустит bash прямо в вашей консоли. После чего, можно выполнять внутри контейнера все правки, которые нам необходимы. Не забывайте, что после перезапуска контейнера — все правки пропадут, для сохранения правок изучите .

FAQ: в чем разница между Docker Run, Start и Create в Docker

Команда Docker create создает новый новый контейнер из образа Docker, но он не запускается сразу.

Команда start запустит любой остановленный контейнер. Если вы использовали команду docker create для создания контейнера, вы можете запустить его с помощью этой команды.

Команда run представляет собой комбинацию create и start, поскольку она создает новый контейнер и запускает его немедленно. Фактически, команда docker run может извлечь образ из Docker Hub, если она не находит упомянутый образ в вашей системе.

Управление Docker от имени пользователя,не являющегося пользователем root

Демон Docker привязывается к сокету Unix, а не к TCP-порту. По умолчанию этот сокет Unix принадлежит пользователю , и другие пользователи могут получить к нему доступ только с помощью . Демон Docker всегда запускается от имени пользователя .

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

Чтобы создать группу и добавить своего пользователя:

  1. Создайте группу .

    $ sudo groupadd docker
    
  2. Добавьте своего пользователя в группу .

    $ sudo usermod -aG docker $USER
    
  3. Выйдите из системы и снова войдите,чтобы членство в группе было переоценено.

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

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

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

    $ newgrp docker 
    
  4. Убедитесь, что вы можете запускать команды без .

    $ docker run hello-world
    

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

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

    WARNING: Error loading config file: /home/user/.docker/config.json -
    stat /home/user/.docker/config.json: permission denied
    

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

    $ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
    $ sudo chmod g+rwx "$HOME/.docker" -R
    

Настройка места,где демон Docker прослушивает соединения

По умолчанию демон Docker прослушивает подключения к сокету UNIX, чтобы принимать запросы от локальных клиентов. Можно разрешить Docker принимать запросы от удаленных хостов, настроив его на прослушивание IP-адреса и порта, а также сокета UNIX. Для получения более подробной информации об этом параметре конфигурации см. раздел «Привязать Docker к другому хосту/порту или сокету unix» в справочной статье Docker CLI .

Настроить Docker для приема удаленных подключений можно с помощью файла системного модуля для дистрибутивов Linux, использующих systemd, таких как последние версии RedHat, CentOS, Ubuntu и SLES, или с помощью файла , который рекомендуется для дистрибутивов Linux, которые не используйте системд.

Настройка удаленного доступа с помощью юнит-файла

  1. Используйте команду , чтобы открыть файл переопределения для в текстовом редакторе.

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

    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
    
  3. Сохраните файл.

  4. Перезагрузите конфигурацию .

     $ sudo systemctl daemon-reload
    
  5. Restart Docker.

    $ sudo systemctl restart docker.service
    
  6. Проверьте, было ли принято изменение, просмотрев выходные данные , чтобы убедиться , прослушивает настроенный порт.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Настройка удаленного доступа с помощью

  1. Установите массив в для подключения к сокету UNIX и IP-адресу следующим образом:

    {
      "hosts" "unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"
    }
    
  2. Restart Docker.

  3. Проверьте, было ли принято изменение, просмотрев выходные данные , чтобы убедиться , прослушивает настроенный порт.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Настройка Docker

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

1. Настроить logging driver

Дело в том, что по умолчанию используется драйвер json-file, который по умолчанию не имеет ограничения на размер файла, где будут скапливаться логи с соответствующего контейнера. Подправить на Linux это можно, отредактировав файл /etc/docker/daemon.json. Файла по умолчанию может и не быть – создайте. Содержимое к добавлению:
‌Таким образом мы настраиваем json-file, чтобы он не создавал более одного файла с логами на контейнер, причем файл не должен превышать 100 МБ. Это все можно переопределить на этапе запуска контейнера, но в будущем это освобождает от поисков ответа на вопрос: «Куда делись 6 ГБ за день?»

2. Запустить службу Docker

Бывает, не запускается он сам после установки. Можно поправить на Linux с помощью:

‌sudo systemctl enable --now docker.service

‌Здесь мы с помощью systemctl запустили Docker Engine и поставили его в автозагрузку.

3. Добавить пользователя в группу docker

Чтобы иметь возможность обращаться к Docker Engine от имени непривилегированного пользователя (без sudo), нужно добавить его в группу docker.

sudo usermod -aG docker "$USER"

‌Для того чтобы изменения вступили в силу, нужно перезагрузиться или воспользоваться ACL.

‌sudo setfacl -m "u:${USER}:rwx" /var/run/docker.sock

Docker

Dockerfile

Одна из важнейшей характеристик образа — это его размер. Компактный образ быстрее скачается с удаленного репозитория, займет меньше места, и ваш сервис быстрее стартует. Любой образ строится на основании базового образа, и рекомендуется выбирать наиболее минималистичный вариант. Хорошим вариантом является Alpine — полноценный дистрибутив Linux с минимумом пакетов.

Для начала попробуем написать Dockerfile «в лоб» (сразу скажу, что это плохой способ, не делайте так):

Здесь мы используем базовый образ на основе Alpine с уже установленным JDK для сборки нашего проекта. Командой ADD мы добавляем в образ текущую директорию src, отмечаем ее рабочей (WORKDIR) и запускаем сборку. Команда EXPOSE 8080 сигнализирует докеру, что приложение в контейнере будет использовать его порт 8080 (это не сделает приложение доступным извне, но позволит обратиться к приложению, например, из другого контейнера в той же сети докера).

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

В результате получаем образ размером в 456 Мбайт (из них базовый образ JDK 340 занял Мбайт). И все притом, что классов в нашем проекте по пальцем пересчитать. Чтобы уменьшить размер нашего образа:

  • Используем многошаговую сборку. На первом шаге соберем проект, на втором установим JRE, а третим шагом скопируем все это в новый чистый Alpine образ. Итого в финальном образе окажутся только необходимые компоненты.
  • Воспользуемся модуляризацией java. Начиная с Java 9, можно с помощью инструмента jlink создать JRE только из нужных модулей

Для любознательных, вот хорошая статья про подходы уменьшения размеров образа https://habr.com/ru/company/ruvds/blog/485650/.

Итоговый Dockerfile:

Пересоздаем образ, и он в итоге похудел в 6 раз, составив 77 МБайт. Неплохо. После, готовые образы можно загрузить в реестр образов, чтобы ваши образы были доступны для скачивания из интернета.

Совместный запуск сервисов в Docker

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

Далее запустим контейнер бекенда с именем ‘backend’ с образом microservices-backend:1.0.0:

Запускаем шлюз:

В этой команде мы указываем, что мы пробрасываем 80 порт нашего хоста на 8080 порт контейнера. Опции env мы используем для установки переменных среды, которые автоматически будут вычитаны спрингом и переопределят свойства из application.properties.

Understanding Image Names

Typically we work with images from Docker Store, which is the default registry for Docker. Commands using just the image repository name work fine, like this:

is the repository name, which we are using as a short form of the full image name. The full name is . That breaks down into three parts:

  • — the hostname of the registry which stores the image;
  • — the repository name, in this case in format;
  • — the image tag.

If a tag isn’t specified, then the default is used. If a registry hostname isn’t specified then the default for Docker Store is used. If you want to use images with any other registry, you need to explicitly specify the hostname — the default is always Docker Store.

With a local registry, the hostname and the custom port used by the registry is the full registry address, e.g. . In this sample we’ll just be using as that’s already been added to the daemon.

Traefik

В первую очередь, я использую Traefik – что это такое, более подробно можно прочитать на сайте https://doc.traefik.io/traefik/.

Traefik – это реверс-прокси, который позволяет нам публиковать ресурсы в интернете. Это альтернатива Nginx, обладающая немного более богатыми возможностями. Основная преимущество Traefik – он может в автоматическом режиме публиковать уже развернутые контейнеры в интернете.

Traefik слушает два порта: 80 и 443. Все входящие запросы на эти порты он анализирует через свои правила и смотрит, относительно какого URL идет обращение. И в зависимости от URL запросы заворачиваются на контейнеры, которым установлен определенный лейбл.

Дополнительным плюсом является то, что Traefik с коробки может работать с сертификатами выписанными Letsencript, как для основного домена, так и поддоменов любого уровня.

Running a Registry

The Docker Registry server is distributed as its own Docker image. You can get it from Docker Hub. The server is exposed on port 5000; you’ll need to bind a host port to it so that clients can connect.

You must also set up a volume so Docker Hub has somewhere to persistently store uploaded images. Make sure you’ve got sufficient free space on your host. An actively used registry can quickly grow.

Begin by creating a file to describe your deployment. You can adjust the ports and filesystem paths to match your preferences. This example will make the registry accessible on port 5000. Images will be stored in the folder within your working directory.

version"3"
services:
  registry:
      imageregistry:2
      ports        - 5000:5000
      environment:
        - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY/data
      restartunless-stopped
      volumes        - ./data:/data

Save the file and run to launch your registry. docker-compose will pull the registry image from Docker Hub. It’ll then start a new container using your configuration.

Инструкции Dockerfile#

  1. — задаёт базовый (родительский) образ.
  2. — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
  3. — устанавливает постоянные переменные среды.
  4. — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
  5. — копирует в контейнер файлы и папки которые лежат локально.
  6. — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы, а так же получать на вход URL и скачивать файл внутрь image.
  7. — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция .
  8. — задаёт рабочую директорию для следующей инструкции.
  9. — задаёт переменные для передачи Docker во время сборки образа.
  10. — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
  11. — указывает на необходимость открыть порт. Также можно открыть socket, но это тема для отдельной заметки.
  12. — создаёт точку монтирования для работы с постоянным хранилищем.

Подробности и нюансы можно почерпнуть из официальной документации.

middleware

The option is optional. Use this option to inject middleware at
named hook points. All middleware must implement the same interface as the
object they’re wrapping. This means a registry middleware must implement the
interface, repository middleware must implement
, and storage middleware must implement
.

An example configuration of the middleware, a storage middleware:

Each middleware entry has and entries. The must
correspond to the name under which the middleware registers itself. The
field is a map that details custom configuration required to
initialize the middleware. It is treated as a . As such,
it supports any interesting structures desired, leaving it up to the middleware
initialization function to best determine how to handle the specific
interpretation of the options.

cloudfront

Parameter Required Description
yes at which Cloudfront is served.
yes Private Key for Cloudfront provided by AWS.
yes Key pair ID provided by AWS.
no

Specify a by providing an integer and a unit. Valid time units are , (or ), , , , . For example, is a valid duration; there should be no space between the integer and unit. If you do not specify a or specify an integer without a time unit, this defaults to 20 minutes.

redirect

In place of the storage middleware, the
storage middleware can be used to specify a custom URL to a location
of a proxy for the layer stored by the S3 storage driver.

Parameter Required Description
baseurl yes at which layers are served. Can also contain port. For example, .

Сущности Docker

Docker работает с несколькими сущностями.

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

Скриншот: Skillbox Media

Dockerfile. Если Docker image — это пирог, то Dockerfile — рецепт его приготовления. В этом файле описаны основные инструкции для сборки образа: какой базовый образ взять, откуда и куда положить файлы и так далее.

Контейнер — это runtime-сущность на основе образа, приложение, которое мы развернули с помощью Docker. Можно провести такую аналогию: образ — это инсталлятор программы, а контейнер — уже запущенная программа.

КонтейнерыСкриншот: Skillbox Media
КонтейнерыСкриншот: Skillbox Media

При развёртывании контейнера поверх файловой системы создаётся ещё один изменяемый слой. Приложение внутри контейнера может записывать туда данные или редактировать их. После удаления контейнера данные стираются, но их можно сохранить с помощью volumes.

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

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

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

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

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

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

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

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

docker-compose.yml

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

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

Откройте в окне браузера адрес .

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

auth

The option is optional. There are
currently 3 possible auth providers, , and . You can configure only
one provider.

silly

The auth is only for development purposes. It simply checks for the
existence of the header in the HTTP request. It has no regard for
the header’s value. If the header does not exist, the auth responds with a
challenge response, echoing back the realm, service, and scope that access was
denied for.

The following values are used to configure the response:

Parameter Required Description
yes The realm in which the registry server authenticates.
yes The service being authenticated.

token

Token based authentication allows the authentication system to be decoupled from
the registry. It is a well established authentication paradigm with a high
degree of security.

Parameter Required Description
yes The realm in which the registry server authenticates.
yes The service being authenticated.
yes The name of the token issuer. The issuer inserts this into
the token so it must match the value configured for the issuer.
yes The absolute path to the root certificate bundle. This bundle contains the
public part of the certificates that is used to sign authentication tokens.

For more information about Token based authentication configuration, see the specification.

htpasswd

The htpasswd authentication backed allows one to configure basic auth using an
Apache htpasswd
file. Only
format passwords are supported.
Entries with other hash types will be ignored. The htpasswd file is loaded once,
at startup. If the file is invalid, the registry will display an error and will
not start.

Parameter Required Description
yes The realm in which the registry server authenticates.
yes Path to htpasswd file to load at startup.

Разворачивание контейнера с Jenkins

Это выглядит так – у нас есть файл docker-compose.yml, который поднимает сервис Jenkins.

Traefik просматривает все существующие Docker-контейнеры и ищет лейблы. Если он находит лейбл с указанием traefik.enable=true, он включается и начинает маршрутизировать трафик, который на него идет.

В частности, публикует этот сервис по от указанному URL.

Чтобы запустить Jenkins, мне нужно вызвать команду:

Контейнер с Jenkins запустился и работает, а на сайте ci.demoncat.ru выводится приглашение Jenkins.

Как видите, я развернул Jenkins с нуля за 20 минут – все запустилось одной командой.

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

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

  • Два сервера 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.

Заключение

Мы поставили Docker, познакомились с DockerHub, запустили пару контейнеров и опробовали базовые команды для запуска приложений с помощью Docker Community Edition.

От редакции

Если вам интересно посещать бесплатные онлайн-мероприятия по DevOps, Kubernetes, Docker, GitlabCI и др. и задавать вопросы в режиме реального времени, подключайтесь к каналу DevOps by REBRAIN

*Анонсы мероприятий каждую неделю

Практикумы для специалистов по инфраструктуре и разработчиков — https://rebrainme.com.Наш Youtube-канал — https://www.youtube.com/channel/UC6uIx64IFKMVmj12gKtSgBQ.

Понравилась статья? Поделиться с друзьями:
Быть в курсе нового
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: