Docker

Михаил

Павлов

О чем мы сегодня поговорим

  1. Проблематика
  2. Виртуальные машины и Docker
  3. DockerHub
  4. Свой контейнер через Dockerfile
  5. Docker Сompose и связи между контейнерами
  6. Практика
  7. Пример "боевых" контейнеров
  8. Что дальше?

Представим, что у нас есть маленький проект

ОС

Технологии

CI / CD

Деплой

"соберу у себя на компе"

скопировать jar-файл на сервер

Время идет и проект растет

ОС

Технологии

CI / CD

Деплой

"соберу у себя на компе"

скопировать jar-файл на сервер,

скопировать артефакты клиента

скопировать jar-файл на сервер

И еще немного растет

ОС

Технологии

CI / CD

Деплой

скопировать jar-файл на сервер,

скопировать артефакты клиента

скопировать jar-файл на сервер 1,

скопировать jar-файл на сервер 2,

скопировать артефакты клиента

И еще чуть чуть

ОС

Технологии

CI / CD

Деплой

скопировать jar-файл на сервер 1,

скопировать jar-файл на сервер 2,

скопировать артефакты клиента,

собрать мобильное приложение,

выложить мобильное приложение в google play

скопировать jar-файл на сервер 1,

скопировать jar-файл на сервер 2,

скопировать артефакты клиента,

Через некоторое время

  • Время выкатывания версий растет и, как следствие, уменьшается время на разработку
  • Сложность процессов увеличивается
  • Очень разные технологии и подходы
  • Нет единой точки для управления процессом деплоя

Проблемы

Как с этим справлялись раньше?

Ответ - Виртуальные машины

Виртуальная машина

(Virtual Machine, VM)

Эмуляция одной ОС (целевая) внутри другой (хост)

+ изоляция целевой ОС от ОС хоста

* внутри целевой ОС для программ она выглядит как обычный компьютер со стандартыми ресурсами

** Эмулируется железо, при этом целевая ОС - полновесная

Проблемы виртуальных машин

  1. Большая ресурсоемкость
    • ОС потребляет ресурс
  2. Сложность управления
    • Необходима установка и настройка ОС

Что делать?

Docker спешит на помощь!

Что такое Docker?

  • Набор программ для легковесной виртуализации
  • Работает быстрее виртуальных машин за счет использования ядра ОС-хоста (эмулирует ОС, а не железо)

Что это значит?

Docker

Virtual Machine

Плюсы Docker

  • Консистентность ОС, настроек, окружения
  • Удобная упаковка приложений
  • Изоляция и управление процессами
  • Ощутимо меньший размер контейнера по сравнению с образом виртуальной машины

Давайте разберем Docker поподробнее

Docker оперирует контейнерами и образами

  • Образ - архив со слепком файловой системы для контейнера
  • Контейнеры создаются на основе образа
  • Контейнер - это процесс в ОС
  • Каждый контейнер взаимодействует со своей изолированной файловой системой

Образы и контейнеры

В терминах ООП:

  • Образ - это класс
  • Контейнер - это экземпляр класса

Как этим пользоваться?

Как установить Docker

Для разных платформ способы установки разные, подробнее тут

Проверить, что докер работает можно командой:

$ docker run hello-world

В результате команды, кроме прочего, будет такой текст:

Hello from Docker!
This message shows that your installation appears to be working correctly.

Поддерживаемые платформы

Сам Docker можно запустить на:

Контейнеры Docker есть для Linux и Windows

* Но Docker - надстройка над ОС-хостом, поэтому поставить на Linux контейнер с Windows не получится

Где взять образы?

Есть готовые - на DockerHub

* Некоторые компании поднимают свои ресурсы с образами

** У нас тоже есть свое хранилище с образами

  1. Выбрать подходящий образ
  2. Узнать название
  3. Выкачать
  4. Запустить

Как получить образ

- И это всё?

- Да!

Название образа

Команда для скачивания образа через консоль

Для старта образа

$ docker run --name my-app openjdk:12 

Несколько ключевых моментов:

  • Docker должен быть уже установлен в системе
  • Очень полезно указать имя контейнера, иначе docker присвоит ему хэш-значение
  • Если не указать версию (например просто openjdk), то скачается самая последняя

Можно сделать свой

Не подходит готовый образ?

* И запушить его в общее хранилище

Образы можно создавать самостоятельно

с помощью Dockerfile

Dockerfile - это пошаговый рецепт сборки образа (image)

Образ состоит из слоёв

Каждый слой последовательно меняет то, что получилось на прошлом слое

  • У нас есть java-приложение с именем Main.java
  • Оно лежит в папке app
  • Рядом с папкой app создадим файл с именем Dockerfile

Предварительная подготовка

class Main {
	public static void main(String []args) {
		System.out.println("Docker is alive!");
	}
}

Содержимое Main.java:

Разберем Dockerfile на примере

FROM openjdk:12
COPY app /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", "Main"]

Берем за основу существующий образ

Копируем наше java-приложение внутрь контейнера

Устанавливаем рабочую директорию для дальнейших действий внутри образа

Компилируем наше java-приложение

Запускаем наше

java-приложение

(CMD выполнится при старте контейнера)

Для запуска такого Dockerfile

$ docker build -t <имя образа> .
$ docker run --name <имя контейнера> <имя образа>
  1.  Собираем образ при помощи команды build (находясь в папке с нашим файлом)
  2. Стартуем контейнер с нашим образом через run

* По умолчанию докер ждет имя файла как Dockerfile. Чтобы указать файл с другим именем, нужно использовать атрибут -f <имя файла>

Как передать параметры при билде

FROM openjdk:12
COPY app /usr/src/myapp
WORKDIR /usr/src/myapp
ARG MY_ARG
RUN echo $MY_ARG
RUN javac Main.java
CMD ["java", "Main"]
$ docker build -t my-container --build-arg MY_ARG=10 .

Для дебага

$ docker ps

Очень полезная команда (документация)

Некоторые атрибуты:

  • а - показывает все контейнеры (без атрибута показывает только запущенные)
  • f - фильтрует по фиксированному числу полей, по частичному соответствию
    • -f "name=T01" выведет и СТТ-Т01 и SDE-T01

Что делать, если ваши контейнеры должны взаимодействовать?

Нам поможет

Docker Сompose

* На самом деле Compose - это "синтаксический сахар" для удобства работы.

Всё, что делает Compose, можно сделать и командами docker, но не так удобно

*Для Docker Desktop (Win, Mac) он включен сразу

Для Linux нужно установить отдельно

Docker Сompose

  • Инструмент для управления многоконтейнерными приложениями
  • Позволяет делать несколько взаимосвязанных контейнеров
  • Настройки производятся в конфигурационном Yaml-файле
  • После настройки можно управлять всеми приложениями буквально несколькими командами

Пример docker-compose файла

version: "3.1"

services:

  backend:
    image: myimage

Версия формата compose-файла

(связана с версией Docker)

Список сервисов, в этом блоке перечисляются наши контейнеры

Уникальное, в рамках файла, имя нашего сервиса, на него можно ссылаться при описании других сервисов

Имя образа, по которому будет запущен сервис

Основные команды

create создает сервисы
start запускает сервисы
stop останавливает сервисы
up create + start
down останавливает и удаляет сервисы и пр.
restart stop + start
build собирает или пересобирает сервисы
ps выводит список контейнеров

Внимание!

Опасная команда

Обычно лучше использовать stop

$ docker-compose up -d

Пример вызова:

 * "- d" удобный атрибут, который запускает контейнер без блокировки терминала

Иногда нужны дополнительные настройки

Порты и переменные среды

version: "3.1"

services:
    
  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydb
    ports:
      - 5577:5432

Указываем переменные среды, которые нужны базе данных

Берем из готового образа, а не из Dockerfile

Указываем, какие порты должны быть проксированы "наружу" контейнера

*Слева порты хоста,

справа - сервиса

Обращение к данным хост-машины

filebeat-logstash:
  image: prima/filebeat:5.6
  volumes:
    - ./filebeat-logstash.yml:/filebeat.yml
    - ./ssl:/etc/filebeat/ssl

Для получения данных с хост-машины есть специальный блок - volumes

* Как и с портами, слева идет папка или файл с хост машины, справа, после двоеточия, идет путь в контейнере

Связь между сервисами

version: "3.1"

services:

  backend:
    image: myimage
    depends_on:
      - db
    links:
      - db
    
  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydb
    ports:
      - 5577:5432
version: "3.1"

services:

  backend:
    image: myimage
version: "3.1"

services:
    
  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 1234
      POSTGRES_DB: mydb
    ports:
      - 5577:5432

Опробуем изученное

Пример "боевых" контейнеров

version: '2'
services:
  db:
    image: de1m0s/postgres-compose:1.1
    container_name: CTT-T01-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: tomcat_db
    ports:
      - "55555:5432"

  web-server:
    image: dh.sis-it.pro/tomcat:8.5.35-jre8
    restart: unless-stopped
    container_name: CTT-T01-web
    environment:
      TOMCAT_DB_NAME: tomcat_db
      TOMCAT_DB_HOST: db
      TOMCAT_DB_JNDI_NAME: jdbc/contractor
      TOMCAT_EXTERNAL_FOLDER: /var/external-files/
      MaxMetaspaceSize : 1024m
      JAVA_XMX: -Xmx2g
    ports:
      - "9999:8080"
    links:
      - db
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./ssl/:/usr/local/tomcat/ssl
  nginx-conf:
    image: nginx
    restart: unless-stopped
    container_name: CTT-T01-nginx
    volumes:
      - ./ctt.conf:/etc/nginx/conf.d/ctt.template
    ports:
      - "8888:80"
    environment:
      NGINX_PROXY_HOST: web-server
      NGINX_PROXY_PORT: 7775
      remote_addr: $$remote_addr
      http_host: $$http_host
      proxy_add_x_forwarded_for: $$proxy_add_x_forwarded_for
    links:
      - web-server

  webdav:
    image: ionelmc/webdav
    container_name: CTT-T01-webdav
    restart: unless-stopped
    environment:
      UID: 0
    volumes:
      - /var/external-files/webdavfiles-ctt-t01:/media
      - ./webdav-entrypoint.sh:/entrypoint.sh
    ports:
      - "7777:8080"

Домашнее задание

Базовое:

  1. Создать/запустить контейнер с nginx
  2. Отдать с помощью контейнера с nginx статическую html-страничку со своей машины

Для тех, кому хочется больше:

  1. Сделать 2 контейнера (сервер + база данных), например, Java + PostgreSQL
  2. Обратиться с сервера к базе данных, получить и сохранить какие-либо данные

Полезные ссылки

Что делают команды CLI

Dockerfile Image
build
create
start
stop
run

Container

Stopped

Container

Running

А еще есть

  • UI-интерфейсы для докера (portainer, kitematic, docker-ui)
  • Multi-stage compose-файлы
  • Интеграция DockerHub c GitHub
  • Kubernetes

Но это уже совсем другая история

Спасибо за внимание!

Made with Slides.com