DOCKER 1.9Ваши приложения в удобной упаковке
Золотов Дмитрий, ведущий инженер
Управление информатизации РГПУ им. А.И. ГерценаСанкт-Петербург
2015
Своя уютная бухта для каждой программы (в одном океане)
“Cиний кит проявляет склонность к одиночеству в большей степени, чем все остальные китообразные”
[Wikipedia]
Как использовать?
Тысячи готовых к работе программ (вместе со средой выполнения)
Возможность упаковки своих приложений и запуска на любом узле Linux (а также Windows и MacOS)
Создание кластеров из десятков-сотен-тысяч узлов с распределёнными приложениями (в т.ч. на микросервисах)
Лучше один раз увидеть
docker run -d -p 10000:80 docker.hspu.local:80/2048http://10.0.16.201:10000
Модель для сборки - Dockerfile
FROM nginx:latestMAINTAINER Dmitrii Zolotov <[email protected]>ENV DEBIAN_FRONTEND noninteractiveWORKDIR /usr/share/nginx/htmlRUN apt-get update && apt-get install -y git && rm -rf * && git clone https://github.com/gabrielecirulli/2048 .EXPOSE 80CMD ["nginx", "-g", "daemon off;"]
Отличие от виртуальных машин
Виртуальная машина (управление через vagrant)Vagrant.configure("machine") do |config| config.vm.box = "trusty64" config.vm.hostname = "machine.test" config.vm.network :private_network, ip: "192.168.0.42"
config.vm.provider :virtualbox do |vb| vb.customize [ "modifyvm", :id, "--cpuexecutioncap", "50", "--memory", "256", ] endend
Виртуальная машина
Запускается долго…
Создаёт абстракцию уровня оборудования…
Большая по размеру (т.к. полностью содержит операционную систему)...
Требует много ресурсов для выполнения...
Контейнеры
...запускаются за доли секунды
...маленькие по размеру (содержат только минимальный набор необходимых библиотек и само приложение)
...почти нет потерь в ресурсах (работают на реальном оборудовании и на одном ядре, но хорошо изолированы один от другого)
Революция?
Нет, успешный симбиоз нескольких технологий Linux-ядра:
lxc
cgroups
namespaces
apparmor
...
Open Container Initiative
Контейнеры - не на один день.
Достаточно посмотреть на логотипы участниковOpen Container Initiative.
Open Container Initiative
Единый формат контейнеров - OCF
Автономная, независимая от поставщика, реализация среды выполнения контейнеров - проект runC (создаётся также порт для Windows)
Как использовать в домашних условиях / на рабочем месте?
Если Linux - всё просто - установить Docker Engine и Docker Client (единый пакет, есть под все основные дистрибутивы)
Если Windows и MacOS - рекомендуется использовать Docker Toolbox, включающий:
docker-machine
docker-engine
docker-compose
Kitematic, Docker GUI
Kitematic
Интерфейс программы
Что изолируется?
PID namespace (могут повторяться номера процессов, первый всегда имеет номер 1)
IPC namespace - именованные объекты межпроцессного взаимодействия
mnt namespace - файловая система
net namespace - сеть
uts namespace - версия и параметры ядра
user namespace - изоляция пользователей (в т.ч. администратора)
Как видит контейнер внешний мир?
● своя файловая система● собственный сетевой
интерфейс (и localhost)● ядро представляется
собственным● межпроцессное
взаимодействие в своём адресном пространстве
● первый процесс в системе с идентификатором 1
Какой он на самом деле?Внешний мир -> контейнер
Контейнер->внешний мир
Доступ в сеть Только EXPOSE Внешняя сеть доступна, контейнеры общаются внутри хоста
Файловая система Только VOLUME -
Управление процессами
Просмотр состояния, top
Изолированное PID namespace, хост-узел недоступен
Управление ресурсамиПри запуске контейнера можно указать ограничения
--cpu-shares - доля процессорного времени (1024 - max)
--oom-kill-disable = true - запрет out-of-memory-killer
--cpu-period, --cpu-quota - управление CFS-квотами
--cpuset-cpus - ядра процессора для использования
--blkio-weight - ограничение (от 10 до 1000) на использование ввода/вывода, по умолчанию 500
--memory, --memory-swap - ограничение по памяти (обычная и с подкачкой)
--cgroup-parent - группировка контейнеров с единым пулом ресурсов
--ulimit - ограничения Linux (количество файлов, размер стека и др.)
Надёжность и безопасность
--restart - политика перезапуска контейнера (no / on-failure:<max> / always)
--rm=true - очищать изменения в контейнере и восстанавливать исходный образ после перезапуска
--security-opt - использует возможности ОС контейнера (security policy: user / role / type / level или apparmor) для применения ограничений на взаимодействие с внешним миром, запуск приложений и выполнение изменений
Хитрости
--pid=”host” - позволяет использовать разделяемое пространство идентификаторов процессов для нескольких контейнеров (общее с хост-машиной)
--uts=”host” - единое пространство именования узлов с хост-машиной
--ipc=”container:id | host” - создание единого пространства именования объектов межпроцессного взаимодействия (с узлом или другим контейнером)
--net=”host” - использование сетевого стека хост-машины
--net=”none” - отключение сетевого стека в контейнере
Связь с внешним миром--volume - связывание каталога хост-машины с каталогом контейнера
--volumes-from - связывание контейнеров через общее хранилище
--add-host - создание записи в /etc/hosts (связывание с узлом)
--dns - использование указанных DNS-серверов (вместо 8.8.8.8)
--link - связывание с другим контейнером через сеть (создаёт запись в /etc/hosts, общаются через подсеть внутри docker)
--publish - связывание tcp/udp-портов из приложения с портами хост-машины
Docker environment
Переменные окружения могут быть переопределены
docker run --name my-wordpress -e VIRTUAL_HOST=domain.com -d spencercooley/wordpress
Связывание контейнеров через сеть
Допустим, есть два контейнера с именами: web2 и db. Чтобы создать связь, нужно удалить контейнер web и пересоздать его с использованием команды:docker run --rm --name web2 --link db:db training/webapp env DB_NAME=/web2/db DB_PORT=tcp://172.17.0.5 DB_PORT_5432_TCP=tcp://172.17.0.5:5432 DB_PORT_5432_TCP_PROTO=tcp DB_PORT_5432_TCP_PORT=5432 DB_PORT_5432_TCP_ADDR=172.17.0.5
Дополнительные возможности
--device - связывание устройств хост-машины с контейнером (например, подключение USB-дисков)
--cap-add, --cap-drop - управление разрешениями Linux-ядра (например, SYS_ADMIN - для монтирования сетевых дисков)
--privileged=true - доступ ко всем функциям ядра (в т.ч. запуск docker внутри docker)
--lxc-conf - параметры в lxc (например, lxc.mount для монтирования сетевых устройств, lxc.utsname - изменения имени узла)
--exec-driver - заменить драйвер контейнера (по умолчанию - lxc)
Требования к хост-машине
Ядро Linux не менее 3.15 с поддержкой слоевой файловой системы (например, AUFS или BTRFS) и cgroups.
Поддержка аппаратной виртуализации не требуется, поскольку контейнер работает в основном ядре.
Новое в Docker 1.8 (и 1.9)
Переадресация и ротация журналов
--log-driver=json - по умолчанию (новое: --log-opt [maxsize=#] [maxfile=#] для ротации)
--log-driver=syslog - отправка журналов в syslog-накопитель (--log-opt syslog-address=udp://ip:514 syslog-tag=<метка> syslog-facility=<уровень>)
--log-driver=fluentd - отправка в fluentd-агрегатор (--log-opt fluentd-address=ip:24224 fluentd-tag=<метка>)
Новое в Docker 1.8 (и 1.9)
Плагины для сетевого взаимодействия - создают прозрачную сеть между контейнерами (с использованием libnetwork). Драйверы:
simplebridge - сеть внутри хоста
overlay - распределённая сеть между хостами (встроенная)
weave - распределённая сеть на L2 (Weave)
Новые команды Docker 1.9
docker network create --driver=... net1 - создать сеть
docker run [--publish-service=service1.net1] [--net=net1] … - зарегистрировать контейнер, как сервис в сети
docker network plug net1 <container> - подключить контейнер к сети
Для драйвера overlay необходимо внешнее key-value хранилище (например, consul) и конфигурация запуска docker, например
docker -d --kv-store=consul:10.0.16.204:8500 --label=com.docker.network.driver.overlay.bind_interface=eth0
Плагины для доступа к системам хранения:
docker run --volume-driver=<название>
Например,
flocker, glusterfs - перемещаемые между узлами хранилища
nfs - хранилище доступно через nfs
rexray - хранение в облачных сервисах (Amazon S3, …)
Новое в Docker 1.8 (и 1.9)
Взгляд разработчика. Упаковка приложений.
Инструкция по сборке среды выполнения - Dockerfile
Новый образ использует уже существующий, как основу для файловой системы.
Dockerfile:
FROM ubuntu:latest
...
FROM ubuntu:latest
# Install vnc, xvfb in order to create a 'fake' display and firefoxRUN apt-get update && apt-get install -y x11vnc xvfb firefoxRUN mkdir ~/.vnc# Setup a passwordRUN x11vnc -storepasswd 1234 ~/.vnc/passwd# Autostart firefox (might not be the best way, but it does the trick)RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900CMD ["x11vnc", "-forever", "-usepw", "-create"]
Dockerfile
Графические приложения в docker-контейнерах (для тонких клиентов)
ubuntu + application + ssh-server
docker run -p 1000:22 -d …
ssh -X -p 1000 <ip>
графические приложения запускаются с сервера на рабочей станции
Жизненный цикл контейнера
Без сохранения образов в хранилище:create | pull | build → <изменения> → [diff] → commitС сохранением образов:create | pull | build → tag → pushС переносом образа архивом:save → … → loadС переносом контейнера архивом:create | pull | build → export (создаёт tar) → import
Просмотр состояния контейнеров
docker images - список загруженных (или собранных или отправленных) образов
docker ps - список активных контейнеров
docker logs <id> - просмотр консоли контейнера (только для log-driver=json)
docker top <id> - активные процессы в контейнере
docker port <id> - просмотр отображенных портов
docker inspect <id> - подробный технический отчёт
Управление контейнерами
Создание из образа: docker create [--name название] <образ>
Сборка по Dockerfile: docker build [-t <образ>] <путь>
Запуск: docker run [--publish …] [--volume …] [--env …] <образ>
Приостановка/возобновление: docker pause <id> / docker unpause <id>
Остановка/запуск/перезапуск: docker stop <id> / docker start <id> / docker restart <id>
Удаление контейнера / образа: docker rm <id> / docker rmi <id>
FROM - базовый образ
MAINTAINER - контакты ответственного за образ
RUN - запуск команды в контейнере (при сборке)
ADD, COPY - копирование файлов в контейнер (ADD также может распаковывать .tar.gz)
ENV - определение значения переменной системного окружения по умолчанию
EXPOSE - анонс публикации портов (например, 25 или 53/udp)
Инструкции Dockerfile
Инструкции Dockerfile
VOLUME - анонс возможного связывания с каталогом или файлом
ENTRYPOINT - приложение для запуска при входе в контейнер
WORKDIR - изменение текущего каталога в контейнере
CMD - параметры приложения (могут быть переопределены в RUN)
Что, если надо запустить несколько связанных приложений?
Например, запустить фоновый php процесс и приложение, которое его использует, а также перехват вывода и отправка в syslog.
Можно использовать supervisord: конфигурация в одном файле, по семантике похожа на systemd.
Взгляд администратора
Необходимо решить несколько проблем:
координированный запуск нескольких контейнеров
регистрация сервисов и возможность их обнаружения
мониторинг состояния контейнеров (как снаружи, так и внутри)
развертывание новых узлов по набору правил и включение в состав кластера
Координированный запуск нескольких контейнеров
В случае отсутствия циклических зависимостей - регистрация контейнеров (в /etc/docker) и их запуск средствами docker daemon (для создания можно использовать, например, puppet)
Docker compose (декларация набора контейнеров вместе с параметрами и связями, также возможна сборка)
В случае циклических связей или необходимости запускать контейнеры на разных узлах - создать прокси и предварительно запускать его (ambassador pattern).
Docker composeweb: build: web command: python app.py ports: - "5000:5000" volumes: - web:/code links: - redisredis: image: redis
datadog: build: datadog links: - redis environment: - API_KEY=123 volumes: - /var/run/docker.sock:/var/run/docker.sock - /proc/mounts:/host/proc/mounts:ro - /sys/fs/cgroup:/host/sys/fs/cgroup:ro
Мониторинг состояния контейнеров (как снаружи, так и внутри)
Снаружи: docker swarm агрегирует информацию о контейнерах, либо внешняя проверка. У нас: consul health check
Внутри: захват логов (fluentd или syslog), можно использовать collectd для сбора метрик по процессору и памяти.
Регистрация сервисов и возможность их обнаружения
Можно использовать внешнее средство обнаружения сервисов - у нас используется Consul + DNSMasq
Можно использовать swarm и его механизмы обнаружения (тоже consul или etcd)
Можно посмотреть на DNS, встроенный в Libnetwork (впервые стабильная сборка появилась в Docker 1.9)
Развертывание новых узлов по набору правил и включение в состав кластера
Либо установка любого Linux-дистрибутива (с ядром не менее 3.15), либо запуск на железе минималистичного Linux (CoreOS, Atomic) и запуск рабочей среды (docker compose или любой DevOps инструмент - Puppet, Ansible, Salt, Chef, ...)
Альтернатива - Docker Machine (особенно для разработчика с Windows или MacOS)
Docker machine
Запуск образа операционной системы в виртуальной машине (драйвер может быть как локальным - например, Virtualbox, так и облачным - например, ec2).
Аналог vagrant, но интегрирован с swarm и входит в состав Docker Toolbox.
Docker registry - хранение частных образов организации
Продолжение следует...
Вторая часть семинара будет по распределённым приложениям в Docker, вопросам миграции контейнеров, использованию Swarm и управлению кластером через Shipyard.
ВАШИ ВОПРОСЫ?
Спасибо за внимание!
Приходите к нам и приглашайте друзей.Сообщество “ИТ. Герценовский университет”: http://goo.gl/FEieqK
Календарь семинаров: http://goo.gl/utyuU0
Дмитрий Золотов[email protected]
Top Related