Термины
Виртуализация - технология, позволяющая запускать экземпляры операционных систем (гостевые машины) параллельно и изолированно на единственной хост-машине. При этом каждой гостевой машине предоставляются собственные ресурсы, а гостевая операционная система может быть полностью отличной от операционной системы хост-машины;
Гипервизор - программное обеспечение, позволяющее запускать множественные гостевые (виртуальные) машины на единственной физической машине (хост-машине), а также обеспечивающее предоставление ресурсов виртуальным машинам;
Гостевая машина - виртуальная машина, запускаемая в изолированной среде системы виртуализации внутри хост-машины;
Гостевая операционная система - операционная система, работающая на гостевой машине;
Хост-машина - машина, в операционной системе которой запущена система виртуализации, под управлением которой работают гостевые машины.
Типы виртуализации в ОС СН
Программное обеспечение входящее в состав ОС СН поддерживает два типа виртуализации:
- Полная виртуализация - технология виртуализации обеспечивающая полное моделирование используемого оборудования полностью индивидуальное для каждой гостевой ОС. Гостевые ОС полностью изолированы друг от друга, и каждая гостевая ОС работает в собственной программно-аппаратной среде, полностью копирующей реальное оборудование и содержащей полную копию всех необходимых ресурсов;
- Контейнерная виртуализация - технология виртуализации обеспечивающая совместное использование ресурсов гостевыми операционными системами. Экземпляры операционных системах, выполняющихся в контейнерах, изолированы друг от друга, но при этом некоторые ресурсы используются ими совместно.
draw.io Diagram | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Системы виртуализации в ОС СН
В состав ОС СН входят две системы виртуализации, поддерживающие два описанных выше типа виртуализации:
- libvirt - система полной виртуализации;
- docker - система контейнерной виртуализации.
Система контейнерной виртуализации Docker
Термины
Докерфайл - текстовый документ, содержащий все команды, выполнение которых требуется для создания образа Docker. Образы могут создаваться автоматически путём интерпретации докерфайлов;
Контейнер - образаобраз, находящийся в работе, то есть образ с новым изменяющимся слоем. При работе контейнера все изменения сохраняются в новом слое, а образ (т.е. все предыдущие слои) остаётся неизменным;
Образ - основа контейнеров. Представляет собой 1) базовую файловую систему, 2) упорядоченный набор изменений ("слоёв") в этой файловой системе и 3) базовые параметры исполнения, применяемые при запуске контейнеров. Не имеет состояний и не изменяется;
Слой - внутри образов слой это изменение файловой системы, представленное инструкцией в докерфайле. Слои последовательно "накладываются" на базовую файловую систему образа, создавая итоговый образ. Любой слой может использоваться несколькими образами одновременно. При изменении образа в нём заменяются только изменившиеся слои, что позволяет обновлять образы быстро и с небольшими затратами ресурсов. Размер образа равен сумме размеров входящих в него слоёв;
Реестр образов - сетевое хранилище подготовленных образов, доступных для загрузки на целевые машины.
Особенности
Система контейнерной виртуализации Docker позиционируется не только как система виртуализации, но как система быстрого распространения и развёртывания приложений.
Традиционный способ развёртывания приложений предполагает:
- передачу пользователю приложения комплекта неких файлов приложения как правило:
- исполнимый файл;
- конфигурационный файл;
- сценарии установки и удаления;
- инструкции по установке;
- выполнение пользователем для развёртывания предоставленных сценариев и инструкций на целевой машине.
При этом, несмотря на то, что разработчиками приложений тратятся значительные усилия на создание сценариев развёртывания, учитывающих всевозможные особенности целевыз машин целевых машин и возможные конфликты с другими приложениями, выполнение действий по установке часто завершается неудачей,
Docker предлагает альтернативный вариант развёртывания: поставщик приложений передаёт пользователям приложений предварительно настроенные контейнеры с приложениями. Эти контейнеры просто запускаются пользователем на целевой машине, предоставляя каждому приложению изолированное преварительно настроенное окружение для работы. Таким образом исключается существенная часть ошибок, связанных с предварительной настройкой нестандартных пользовательских систем. Хорошим примером использования возможностей Docker по быстрому развёртыванию приложений является пример развёртывания собственного реестра образов, выполняемого путём простого скачивания подготовленного образа (см. раздел "Администрирование" - "Создание собственного реестра образов").
При этом, по сравнению с системами полной виртуализации, запуск контейнеров требует значительно меньеших вычислительных ресурсов, и, кроме того, Docker для экономии ресурсов поддерживает систему повторного использования "слоёв". "Слой" в терминологии Docker - это некий моментальный снимок состояния системы, а "образ" - это итоговое состояние системы с учётом состояний всех подлежащих слоёв. При этом "слои" могут использоваться повторно разными "образами":
draw.io Diagram | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Дополнительным эффектом от повторного использования "слоёв" является снижение объёмов передаваемых данных при передаче подготовленных в виде образов прикладных программ: при использовании реестра образов Docker передаваться будет только новые слои, в примере выше - слой "Базовая система Astra Linux SE" будет загружен из реестра образов только один раз, далее загружаться будут только новые слои.
Ограничения Docker
Предупреждение |
---|
|
Администрирование Docker
Установка Docker
Установка Docker для работы в привилегированном режиме (не рекомендуется)
Предупреждение |
---|
Данный способ установки наиболее прост, однако не рекомендуется к применению в силу потенцильной потенциальной небезопасности использования контейнеров в привилегированном режиме. |
В ОС СН Смоленск 1.7 Docker представлен пакетом docker.io и может быть установлен с помощью графического менеджера пакетов или из командной строки командой:
Command |
---|
sudo apt install docker.io |
Установка выполняется от имени пользователя, являющегося администратором системы, и после установки Docker рекомендуется предоставить этому пользователю право работать с контейнерами не используя sudo. Для этого пользователя нужно включить в группу docker:
Command |
---|
sudo usermod -aG docker $USER |
Изменение вступит в силу после перезапуска пользовательской сессии.
Для более ранних версий Astra Linux см. статью: Установка и настройка Docker в ОС Astra Linux
Установка Docker для работы в непривилегированном (rootless) режиме (рекомендованый режим)
Предупреждение |
---|
Данная возможность в ОС СН пока официально не поддерживается. |
Информация |
---|
Данный режим является рекомендованным к применению. Данный режим официально поддерживается в версиях Docker начиная с версии 20.10. |
- Предварительная настройка системы:
- Установить Docker для работы в привилегированном режиме, как описано в предыдущем разделе;
Остановить службу docker, запретить её запуск и удалить сокет /var/run/docker.sock:
Command sudo systemctl stop docker
sudo systemctl mask docker
sudo rm /var/run/docker.sockЕсли ранее не был установлен пакет uidmap установить его:
Command sudo apt install uidmap Убедиться, что в файлах конфигурации системы отображения пространства имён (файлы /etc/subuid и /etc/subgid) для пользователя, от имени которого будут запускаться контейнеры, выделено не менее 65 536 идентификаторов.
Информация При работе на компьютере, введённом в домен, убедиться, что выделенные диапазоны не пересекаются с диапазонами идентификаторов доменных пользователей. Для пользователя, создаваемого при установке ОС, диапазоны выделяются автоматически. Выделенные диапазоны определяются в файлах /etc/subuid и /etc/subgid записями, содержащими имя пользователя, начало диапазона и количество выделенных идентификаторов:
Блок кода имя_пользователя:100000:65536
Если таких записей нет - то добавить их, а при необходимости устранить пересечения диапазонов - модифицировать записи.
Добавить в файл /etc/sysctl.conf строчку
Блок кода kernel.unprivileged_userns_clone=1
после чего выполнить команду:
Command sudo sysctl --system Для подключения и использования рекомендованного драйвера систем хранения данных overlay2 выполнить команду:
Command sudo modprobe overlay permit_mounts_in_userns=1 Для того, чтобы драйвер подключался автоматически после перезагрузки системы добавить в файл /etc/modprobe.d строчку:
Блок кода overlay permit_mounts_in_userns=1
- Установить Docker для работы в привилегированном режиме, как описано в предыдущем разделе;
Установить пакет curl:
Command sudo apt install curl Для установки выполнить сценарий, доступный по ссылке https://get.docker.com/rootless:
Command curl -fsSL https://get.docker.com/rootless | sh Запустить непривилегированную службу:
Command systemctl --user start docker Для того, чтобы непривилегированная служба автоматически запускалась при старте системы разрешить её запуск и разрешить работу вне пользовательской сессии:
Command systemctl --user enable docker
sudo loginctl enable-linger $(whoami)Для работы клиента docker указать путь к выполнимым файлам и к непривилигерованному сокету:
Command export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix:///run/user/$UID/docker.sockДля того, чтобы эти параметры автоматически устанавливались при входе в пользовательскую сессиию добавить указанные команды в файл .bashrc.
Создание собственного реестра образов
Предупреждение |
---|
Данная возможность в ОС СН официально не поддерживается. |
Загрузить подготовленный образ Docker, содержащий приложение "Реестр образов Docker". Образ "Реестр образов Docker" загружается из реестра образов Docker:
Command | ||
---|---|---|
| ||
|
После выполнения указанной команды локальный реестр образов автоматически запущен и готов к работе. Управление работой контейнера реестра осуществляется так же как управление любым другим контейнером. например остановка работы реестра:
Command |
---|
sudo docker container stop registry |
Удаление реестра:
Command |
---|
sudo docker container stop registry && sudo docker container rm -v registry |
Создание и модификация собственных образов
Создание простого образа из chroot-окружения
Простой пример создания собственного образа см. в статье Создание собственного образа для использования в Docker
Модификация образа с помощью докерфайла
Подробное описание структуры и работы с докерфайлами доступно в справочной системе man:
Command |
---|
man dockerfile man docker-build |
Докер может создавать образы автоматически, получая инструкции из докерфайла. Докерфайл представляет собой текстовый файл содержащий все инструкции которые понадобилось бы выполнить пользователю создавая образ. Используя команду docker build пользователи могут использовать для создания образов автоматические сценарии, содержащие множество команд. Команда docker build создаёт образ из докерфайла и контекста. Контекст представляет набор файлов в указанной локации. Локация контекста может быть задана как путь (PATH) в файловой системе или как ссылка (URL) на сетевой репозиторий Git. По умолчанию используется докерфайл с именем Dockerfile, расположенный в корне контекста.
Команда docker build выполняется службой (демоном) dockerd, при этом полное содержимое контекста рекурсивно пересылается службе dockerd и может по мере надобности копироваться в создаваемый образ. Копирование выполняется командами, указанными в докерфайле.
Предупреждение |
---|
Не используйте в качестве контекста корневой каталог файловой системы, так как в этом случае будет предпринята попытка передать всё содержимое файловой системы. |
Перед началом выполнения инструкций, указанных в докерфайле, проводится проверка всех инструкций на корректность. Инструкции выполняются последовательно, и результат выполнения каждой инструкции фиксируется в отдельном слое. Рабочим каталогом по умолчанию является корневой католог (может быть изменён инструкцией WORKDIR в докерфайле). Инструкции выполняются без передачи контекста, т.е., например, при выполнении инструкций:
Command |
---|
RUN cd /home ; pwd RUN pwd |
в первой инструкции команда pwd будет выполнена в каталоге /home, во второй инструкции команда pwd будет выполнена в рабочем каталоге, заданном по умолчанию.
Далее приведён пример сборки образа с помощью команды docker build. Сборка выполняется на основе ранее созданного образа wiki/astralinux:orel (см. Создание собственного образа для использования в Docker). Порядок действий:
Создать каталог контекста сборки и файлы этом каталоге:
Command mkdir build-orel
echo "Это импортированные данные" > build-orel/data-to-importТ.е. в контексте сборки создан файл с именем data-to-import и содержащий текст "Это импортированные данные" (без кавычек).
В файл build-orel/Dockerfile внести следующие данные:
Блок кода # указание из какого образа выполнять сборку FROM wiki/astralinux:orel # скопировать файл data-to-import из контекста сборки в образ COPY /data-to-import /srv # создать в образе пустой файл /srv/created-file RUN touch /srv/created-file # вывести на печать содержимое скопированного файла RUN cat /srv/data-to-import # вывести на печать рабочий каталог RUN echo Current work directory is $(pwd)
Выполнить сборку образа с тегом test:
Command Title docker build -t test build-orel/ Sending build context to Docker daemon 5.12kB
Step 1/5 : FROM wiki/astralinux:orel
---> 60d0611fe56a
Step 2/5 : COPY /data-to-import /srv
---> 7a75a002d29f
Step 3/5 : RUN touch /srv/created-file
---> Running in 709bb54af8c3
Removing intermediate container 709bb54af8c3
---> b5fd28178901
Step 4/5 : RUN cat /srv/data-to-import
---> Running in 4c69f455cf2f
Это импортированные данные
Removing intermediate container 4c69f455cf2f
---> c8f8c7c3797a
Step 5/5 : RUN echo Current work directory is $(pwd)
---> Running in 27db5fcaaba5
Current work directory is /
Removing intermediate container 27db5fcaaba5
---> 14446097a09e
Successfully built 14446097a09e
Successfully tagged test:latest
На шаге 4 выводится содержимое скопированного из контекста файла, на шаге 5 выводится рабочий каталог;
Убедиться, что образ test появился в списке образов:
Command Title docker images REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 14446097a09e 2 minutes ago 290MB
wiki/astralinux orel 60d0611fe56a About an hour ago 290MB
busybox latest b97242f89c8a 7 days ago 1.23MB
Запустить контейнер из образа и проверить содержимое:
Command Title docker run --rm -it test root@978a4cc9fbd8:/# ls -l /srv
total 4
-rw-r--r-- 1 root root 0 Jan 20 10:12 created-file
-rw-r--r-- 1 root root 51 Jan 20 10:11 data-to-import
root@978a4cc9fbd8:/# cat /srv/data-to-import
Это импортированные данные
root@978a4cc9fbd8:/# exit
exit
В контейнере в каталоге /srv присутствует скопированный в образ файл data-to-import содержащий текст "Это импортированные данные" и созданный при создании образа пустой файл created-file.
Управление Docker-ом
Подробная справка по командному интерфейсу Docker представлена на сайте разработчиков: https://docs.docker.com/engine/reference/commandline/docker/. При работе в системе список команд можно получить с помощью команды:
Command |
---|
docker help |
Более подробную справку по аргументам команд можно получить с помощью ключа --help, или с помощью справочной системы man, например:
Command |
---|
docker attach --help man docker-attach |
Часто употребимые команды (аргументы команд для краткости не указаны):
Команда | Краткое описание | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
docker attach | Подключить стандартные каналы ввода-вывода (stdin, stdout, stderr) к активному контейнеру | ||||||||||
docker build | Построить Docker-образ из Docker-файла | ||||||||||
docker builder | Управление модулем построения Docker-образов | ||||||||||
docker commit | Создание нового Docker-образа из активного контейнера | ||||||||||
docker config | Управление конфигурациями Docker | ||||||||||
docker container | Управление контейнерами:
| ||||||||||
docker context | Управление контекстами Docker | ||||||||||
docker cp | Копирование файлов или каталогов между локальной файловой системой и файловой системой контейнера | ||||||||||
docker create | Создать новый изменяемый слой в указанном контейнере | ||||||||||
docker diff | Вывести список файлов и каталогов, изменённых с момента создания контейнера | ||||||||||
docker events | Вывести событий, произошедших с различными объектами Docker | ||||||||||
docker exec | Выполнить команду в активном контейнере | ||||||||||
docker export | Экспортировать файловую систему контейнера как архив формата tar | ||||||||||
docker history | Показать историю образа | ||||||||||
docker image | Управление образами:
| ||||||||||
docker images | Вывести список образов верхнего уровня | ||||||||||
docker import | Создать файловую систему образа из архива | ||||||||||
docker info | Вывод системной информации | ||||||||||
docker inspect | Вывод подробной информации об объектах Docker | ||||||||||
docker kill | Принудительно деактивировать активный контейнер (контейнеры) | ||||||||||
docker load | Загрузить образ из архива tar или из стандартного ввода | ||||||||||
docker login | Войти в реестр образов | ||||||||||
docker logout | Выйти из реестра образов | ||||||||||
docker logs | Извлечь журналы контейнера | ||||||||||
docker manifest | Управление манифестами и списками манифестов Docker | ||||||||||
docker network | Управление сетями | ||||||||||
docker node | Управление узлами кластеров Docker | ||||||||||
docker pause | Приостановить все процессы в активном контейнере (контейнерах) | ||||||||||
docker plugin | Управление плагинами | ||||||||||
docker port | Вывести список отображения портов контейнера | ||||||||||
docker ps | Вывести список активных контейнеров | ||||||||||
docker pull | Загрузить образ на локальный компьютер из реестра образов | ||||||||||
docker push | Загрузить образ с локального компьютера в реестр образов | ||||||||||
docker rename | Переименовать контейнер | ||||||||||
docker restart | Перезапустить контейнер (контейнеры) | ||||||||||
docker rm | Удалить контейнер (контейнеры) | ||||||||||
docker rmi | Удалить образ (образы) | ||||||||||
docker run | Выполнить команду в новом контейнере, то есть: создать в существующем образе новый изменяемый слой, и выполнить команду, сохраняя изменения в этом слое
| ||||||||||
docker save | Сохранить образ (образы) в архиве tar (через стандартный вывод по умолчанию) | ||||||||||
docker search | Поиск образов Docker в сети Интернет | ||||||||||
docker secret | Управление паролями кластеров Docker | ||||||||||
docker service | Управление сервисами кластеров Docker | ||||||||||
docker stack | Управление стеками | ||||||||||
docker start | Запустить контейнер (контейнеры) | ||||||||||
docker stats | Отобразить в режиме реального времени статистику потребления ресурсов контейнером | ||||||||||
docker stop | Остановить активный контейнер (контейнеры) | ||||||||||
docker swarm | Управление кластерами Docker | ||||||||||
docker system | Управление службой Docker | ||||||||||
docker tag | Создать тег (метку) образа, ссылающийся на существующий образ | ||||||||||
docker top | Вывести список процессов активного контейнера | ||||||||||
docker trust | Управление ключами и подписями образов | ||||||||||
docker unpause | Продолжить выполнение приостановленного активного контейнера (контейнеров) | ||||||||||
docker update | Обновить конфигурацию контейнера (контейнеров) | ||||||||||
docker version | Отобразить версию Docker | ||||||||||
docker volume | Управление томами хранения данных для контейнеров | ||||||||||
docker wait | Ожидание завершения работы контейнера (контейнеров) и вывод кодов завершения |
Загрузка образа в реестр
Предупреждение |
---|
Данная возможность в ОС СН официально не поддерживается. |
Получить список доступных на локальной машине образов:
Command | ||
---|---|---|
| ||
REPOSITORY TAG IMAGE ID CREATED SIZE wiki/astralinux se17rc5 5d69ce8720a7 25 hours ago 318MB registry 2 678dfa38fcfa 12 days ago 26.2MB localhost:5000/hello-world-se latest bf756fb1ae65 12 months ago 13.3kB hello-world latest bf756fb1ae65 12 months ago 13.3kB |
Пометить загружаемый образ тегом (tag) для загрузки в нужный реестр:
Command |
---|
sudo docker tag wiki/astralinux:se17rc5 localhost:5000/se17rc5 |
Перепроверить список доступных образов, чтобы убедиться, что тег присвоен верно:
Command | ||
---|---|---|
| ||
REPOSITORY TAG IMAGE ID CREATED SIZE wiki/astralinux se17rc5 5d69ce8720a7 25 hours ago 318MB localhost:5000/se17rc5 latest 5d69ce8720a7 25 hours ago 318MB registry 2 678dfa38fcfa 12 days ago 26.2MB localhost:5000/hello-world-se latest bf756fb1ae65 12 months ago 13.3kB hello-world latest bf756fb1ae65 12 months ago 13.3kB |
В примере выше первые две строки сообщают об одном и том же образе (идентификатор образа 5d69ce8720a7). При этом образ помечен как размещённый в двух локациях - на локальной машине wiki/astralinux и сетевом реестре на локальной машине localhost:5000.
Загрузить образ в реестр:
Command | ||||
---|---|---|---|---|
| ||||
The push refers to repository [localhost:5000/se17rc5] d5f516170dbe: Pushed latest: digest: sha256:8d12b1c9ebe3b3060734965bbd7214a0063633261bf1da17d3caf50ed4f1f534 size: 529 |
Использование Docker
Получение образа из реестра
Предупреждение |
---|
Данная возможность в ОС СН официально не поддерживается. |
Пример получения образа Docker из реестра описан выше (см. "Создание собственного реестра образов"). При этом для получения образа используется просто команда запуска контейнера (docker run), которая, не найдя на локальной машине указанный образ, ищет образ в реестре образов, и, если образ найден, автоматически загружает и запускает его.
Образ также можно просто загрузить из реестра с помощью команды docker pull, например:
Command |
---|
docker pull debian |
Копирование образа без использования реестра
Образ, хранящийся на локальной машине может быть скопирован (например, на другую (целевую) машину) без использования реестра образов. Далее для примера используется стандартный образ hello-world из реестра образов Docker. Перенос образа на другую машину:
Выгрузить образ в файл архива:
Command docker save -o hello-world.bz2 hello-world Опция -o указывает имя файла, в который нужно выводить данные. Если опция не указана, то вывод осуществляется в стандартный вывод (stdout), что можно использовать для автоматизации работы (см. далее).
- Скопировать полученный файл hello-world.bz2 на целевую машину любым доступным способом;
На целевой машине загрузить файл в локальный реестр образов:
Command docker load -i hello-world.bz2 Опция -i указывает имя файла, из которого должен загружаться образ. Если опция не указана - образ загружается из стандартного ввода.
Или, как вариант, выполнить все указанные выше шаги одной командой, скопировав создаваемый файл через SSH (естественно, на целевом компьютере для этого должен быть настроен SSH):
Command |
---|
docker save hello-world | bzip2 | ssh user@host 'bunzip2 | docker load' |
Где:
- docker save hello-world - команда выгрузки образа с именем hello-world. В отличие от примера выше команда используется без указания файла, то есть выводит в стандартный вывод (stdout);
- bzip2 - программа сжатия данных (архиватор);
- ssh user@host 'bunzip2 | docker load' - подключение через SSH к компьютеру с именем host от имени пользователя user и запуск команды загрузки образа из стандартного ввода (stdin). Пользователь user на целевом компьютере должен иметь право работать с Docker без использования sudo.
Создание контейнеров из образов и основы работы с контейнерами
При запуске приложений, упакованных в контейнеры Docker, важно понимать разницу между "образом" (неизменяемым набором данных) и "контейнером" (изменяемым набором данных, создаваемых из "образа").
Для примера используем стандартный образ busybox, который загрузим из ресстра Docker:
Command |
---|
docker pull busybox |
Исходное состояние: в локальном репозитори имеются образы hello-world и busybox:
Command | ||
---|---|---|
| ||
|
И нет ни одного контейнера:
Command | ||
---|---|---|
| ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
Создание нового контейнера из образа busybox и его запуск выполняется одной командой:
Command | ||
---|---|---|
| ||
/ # |
Где:
- --name run-busybox - присвоить создаваемому контейнеры имя run-busybox. Имя можно не указывать, тогда оно будет создано автоматически.
- --rm - уничтожить контейнер после завершения его работы;
- -i - запустить контейнер в интерактивном режиме;
- -t - создать терминал;
- /# - приглашение интерактивного режима запущенного контейнера и ожидание ввода.
Проверим из отдельной терминальной сессии список контейнеров:
Command | ||
---|---|---|
| ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09c793a139b2 busybox "sh" 3 minutes ago Up 3 minutes run-busybox |
В списке появился новый контейнер с именем run-busibox.
Вернёмся в первую терминальную сессию, и выйдем из интерактивного контейнера командой exit. Повторная проверка командой docker container ls -a покажет, что список контейнеров пуст (опция --rm указывает удалить контейнер после завершения работы).
Повторно запустим контейнер, уже без опции --rm, и, для примера, не задавая имя контейнера:
Command | ||
---|---|---|
| ||
/ # |
Снова проверим список контейнеров из отдельной сессии:
Command | ||
---|---|---|
| ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 825a33f9c18c busybox "sh" 28 seconds ago Up 28 seconds amazing_morse |
В списке появился новый контейнер с автоматически созданным именем amazing_morse.
Снова вернёмся в первую терминальную сессию, и выйдем из интерактивного контейнера командой exit. Повторная проверка покажет, что теперь в списке контейнеров сохранился контейнер:
Command | ||
---|---|---|
| ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 825a33f9c18c busybox "sh" About a minute ago Exited (0) 2 seconds ago amazing_morse |
Повторно выполним команду docker run:
Command | ||
---|---|---|
| ||
/ # |
И из отдельной терминальной сессии увидим, что контейнеров теперь стало 2: 1) ранее созданный amazing_morse (неактивный) и 2) новый admiring_murdock (активный):
Command | ||
---|---|---|
| ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b894e0b0b22d busybox "sh" 17 seconds ago Up 16 seconds admiring_murdock 825a33f9c18c busybox "sh" 3 minutes ago Exited (0) About a minute ago amazing_morse |
То есть:
Информация | ||
---|---|---|
Команда
создаёт из указанного образа новый контейнер и запускает его. Из одного образа можно создать сколько угодно контейнеров, которые можно сохранять или не сохранять после завершения их работы. |
Для запуска созданного и сохранённого контейнера используется команда docker start (обратите внимание, используется не образ, а контейнер):
Command | ||
---|---|---|
| ||
/ # |
опции -ai задают подключение в интерактивном режиме, но контейнер можно можно запустить и в фоновом режиме:
Command | ||
---|---|---|
| ||
amazing_morse |
К контейнеру работающему в фоновом режиме можно подключиться командой docker attach:
Command | ||
---|---|---|
| ||
/ # |
Отключиться от конейнера, не останавливая его, можно нажав последовательно клавиши Ctrl+p Ctrl+q, можно также остановить контейнер, введя команду exit.
Выше описано, как работать с контейнерами, в том числе сохраняя сделанные изменения. То есть, первоначальный образ можно "изменить" (естественно, не сам образ, который неизменен, изменения регистрируются в контейнере), и далее контейнер можно преобразовать в образ с помощью команды docker container commit:
Command | ||
---|---|---|
| ||
sha256:6f607ea38417448f73f3db5faeddf901832546b8d2882beab4e93062035df680 |
Проверим список образов:
Command | ||
---|---|---|
| ||
REPOSITORY TAG IMAGE ID CREATED SIZE new-busybox latest 6f607ea38417 2 seconds ago 1.23MB busybox latest b97242f89c8a 6 days ago 1.23MB hello-world latest bf756fb1ae65 12 months ago 13.3kB |
Монтирование файловых ресурсов хост-машины
Docker поддерживает следующие варианты монтирования файловых ресурсов хост-машины:
bind - монтирование файла или каталога хост-машины в контейнер. Примонтированный ресурс доступен по его абсолютному пути на хост машине.
Предупреждение Метод монтирования является устаревшим и не рекомендуется к применению. - mount - монтирование заранее созданных изолированных томов для размещения данных.
- tmpfs - монтирование временных ресурсов вне файловой системы хост-машины и вне изменяемого слоя контейнера в памяти хост-машины. Данные уничтожаются после остановки контейнера и не могут разделяться между контейнерами.
Опции монтирования задаются при создании контейнеров из образов, и сохраняются в параемтрах контейнера. Опции монтирования могут задаваться в двух альтернативных форматах: "формат -v" и "формат --mount". Значение "формат -v" состоит их трех фиксированных полей, разделённых символами двоеточия: ресурс монтирования, точка монтирования, опции монтирования. Значение "формат --mount" состоит из списка пар вида "опция=значение", разделённых запятыми, см. примеры далее. Опции монтирования в варианте bind фактически отличается от опция монтирования в варианте mount названием монтируемого ресурса: в первом случае это путь к файловому объекту, во втором - имя заранее созданного тома монтирования. Если точка монтирования внутри контейнера не существует то она создаётся автоматически, причём всегда в виде каталога.
Опции монтировниния "формат --mount":
Опция | Значение | Комментарий |
---|---|---|
type | Тип монтирования, может быть bind, volume (по умолчанию) или tmpfs. Тип монтирования tmpfs | |
source или src | Для монтирования bind - путь к файловому объекту хост-машины. Не используется при монтировании с типом tmpfs. | |
destination или dst или target. | Точка монтирования в контейнере | |
readonly | Монтирование в режиме только чтение | Опция ro в "формате -v" |
bind-propagation | По умолчанию имеет значение rprivate, а для монтирования bind может быть private, rshared, shared, rslave, slave. Подробнее см. документацию на ядро: https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt | |
tmpfs-size | Лимит размера ресурса в байтах, по умолчанию размер не ограничен. | Применимо только для монтирования tmpfs |
tmpfs-mode | Восьмеричная маска доступа для фаловых объектов (например, 700 или 0770). По умолчанию 1777, т.е. доступно на запись всем. | Применимо только для монтирования tmpfs |
Предупреждение |
---|
Опции монтирования ":z" и ":Z" ("формат -v") не поддерживаются и сохранены для совместимости. Ресурсы всегда монтируются как разделяемые (":z"). |
Запуск контейнера с bind-монтированием текущего каталога на хост-машине в каталог /app контейнера:
Формат --mount | Формат -v | ||||
---|---|---|---|---|---|
|
|
Создание тома с именем my-vol для последующего монтирования:
Command | ||
---|---|---|
| ||
my-vol |
Запуск контейнера с mount-монтированием тома my-vol на хост-машине в каталог /app контейнера:
Формат --mount | Формат -v | ||||
---|---|---|---|---|---|
|
|
Запуск контейнера с tmpfs-монтированием:
Формат --mount | Формат -v | Параметры монтирования по умолчанию |
---|---|---|
docker run --rm -it --mount type=tmpfs,destination=/app busybox | не поддерживается | docker run --rm -it --tmpfs /app busybox |
Рекомендации по контролю безопасности контейнеров
По материалам: https://www.stackrox.com/post/2017/08/hardening-docker-containers-and-hosts-against-vulnerabilities-a-security-toolkit/
- По умолчанию клиенты Docker обмениваются информацией со службой Docker через Unix-сокет /var/run/docker.sock. При неверно установленных правах доступа этот сокет может быть примонтирован контейнером, который в таком случае получит полный контроль над службой Docker.
Для предотвращения такого рода угроз следует использовать соответствующие профили SELinux/AppArmor. - При монтировании к контейнерам файловых ресурсов хост-машины содержащих информацию о хост-машине (например, каталоги /etc/ или /usr/).
Для предупреждения нежелательного изменения информации следует использовать монтирование в режиме "только чтение" и, по возможности, следует исключить применение монтирования файловых объектов, влияющих на конфигурацию хост-машины. - Привилегированные контейнеры имеют практически такие же права, как привилегированный пользователь хост-машины.
При работе привилегированных контейнеров следует использовать для них ограничения привилегий. - Использование ssh для работы с контейнерами затрудняет управление ключами и политиками доступа ssh.
Следует по использовать доступ ssh к только хост-машине, а для доступа к контейнерам использовать команды docker exec или docker attach. При запуске контейнеров, требующих доступ к ним через сеть, используются параметры запуска, указывающие сетевые порты, через которые разрешен доступ (опция -p команды doсker run), например:
Command docker run -d -p 5000:5000 --restart=always --name registry registry:2
Проверить к каким портам разрешён доступ у работающих контейнеров можно выполнив команду docker inspect. Пример выполнения этой команды для всех запущенных контейнеров:Command Title docker ps --quiet | xargs docker inspect --format '{{ .Id }}: Ports={{ .NetworkSettings.Ports }}' 385c73836ec1f12469c6a9f46ec5b06e63cc59f02722bed2a2f42eda83944420: Ports=map[5000/tcp:[map[HostIp:0.0.0.0 HostPort:5000]]] В примере приведён вывод команды для единственного ранее запущенного контейнера registry:2, доступ к которому разрешен через порт 5000.
- Контейнеры по умолчанию запускаются с применением ограничений AppArmour/SELinux и seccomp. С помощью опции --unconfined возможен запуск контейнеров без применения этих ограничений.
Следует избегать применения опции --unconfined. - Контейнеры могут запускаться с опциями --pid и --net в пространствах имён хост-машины (пространство процессов и сетевое пространство соответственно). Такие контейнеры получают возможность контролировать процессы хост-машины или подключаться к привилегированным сетевым портам хост-машины.
Следует избегать использования контейнеров, работающих в пространствах имён хост-машины. - При использовании контейнеров предоставляющих службы по сетевому протоколу TCP следует использовать защиту передаваемых данных с помощью TLS (см. https://docs.docker.com/engine/security/https/).
В Astra Linux возможно монтирование файловых ресурсов в режимах "разделяемый" (shared), "подчинённый" (slave) или "частный" (private). При монтировании в режиме "разделяемый" изменения, сделанные через любую точку монтирования распространяются на все точки монтирования, что может привести нарушению работы контейнеров из-за нежелательных изменений файловых объектов другими контейнерами.
Следует избегать монтирования с опцией ":shared", т.е команд запуска контейнеров вида:Command docker run --volume=/hostPath:/containerPath:shared <имя_образа> Проверить используют ли контейнеры разделяемое монтирование можно командой:
Command docker ps --quiet --all | xargs docker inspect --format '{{ .Id }}: Propagation={{range $mnt := .Mounts}} {{json $mnt.Propagation}} {{end}}'
Возможный сценарий применения Docker
Таким образом, возможный сценарий применения Docker:
- Создать (загрузить) исходный образ;
- Создать из этого образа контейнер, работая в котором выполнить и сохранить дополнительные настройки;
- Конвертировать контейнер с выполненными настройками в новый образ;
- Скопировать новый образ на целевые машины для использования;
- На целевых машинах:
- Можно использовать контейнеры, сохраняющие возникающие при эксплуатации изменения в этих контейнерах;
- Можно использовать образ, монтируя к нему внешние каталоги, в которых сохраняются изменения, не сохраняя изменения в контейнерах;
- Можно комбинировать указанные варианты.