Docker створення контейнера. Docker керування контейнерами: базові можливості

Жарознижувальні засоби для дітей призначаються педіатром. Але бувають ситуації невідкладної допомоги при пропасниці, коли дитині потрібно дати ліки негайно. Тоді батьки беруть на себе відповідальність і застосовують жарознижувальні препарати. Що можна давати дітям грудного віку? Чим можна збити температуру у старших дітей? Які ліки найбезпечніші?

Docker це популярний інструмент, який завдяки використанню контейнерів надає все необхідне для запуску програм. Використовуючи Docker-контейнери, ви можете бути впевненими в тому, що програма працюватиме однаково на будь-яких машинах, на яких ви її запустите.

З цього посібника ви дізнаєтесь про зв'язок контейнерів та образів Docker, а також про те, як встановлювати, запускати, зупиняти та видаляти контейнери.

Огляд

Образ Dockerможна подати як деякий шаблон, який використовується для створення контейнерів. Образи зазвичай починаються з кореневої файлової системи, до якої потім зверху шарами додаються різні змінита відповідні параметри запуску. На відміну від типових дистрибутивів Linux, Docker зазвичай містить тільки частини, які необхідні для запуску програми. У образів немає статусів і вони не змінюються. Правильніше сказати, що вони є вихідною точкою, основою контейнерів Docker.

Образи «оживають» в той момент, коли ви вводите команду docker run - вона відразу створює контейнер в результаті додавання поверх образу новий рівень для читання і запису. Ця комбінація рівнів тільки для читання (поверх яких додається рівень для читання та запису) також відома як UnionFS - файлова система, що здійснює каскадно-об'єднане монтування файлових систем. Коли в існуючий файл запущеного контейнера вноситься будь-яка зміна, файл копіюється з області лише для читання рівень для запису і читання, де й застосовуються ці зміни. І тепер початковий файл прихований версією з рівнем для запису та читання, але він не видалений. Подібні зміни в рівні для запису та читання існують лише всередині окремого контейнера. Коли контейнер видаляється, всі зміни також губляться (якщо вони не були збережені).

Робота з контейнерами

Щоразу, коли ви використовуєте команду docker run, із того образу, який ви вказуєте, створюється новий контейнер. Нижче буде розглянуто більш конкретні приклади.

Крок 1: створення двох контейнерів

Написана нижче команда docker run створює новий контейнер, який як основу використовуватиме образ Ubuntu. Ключ -t надасть термінал, а -i – можливість взаємодіяти з ним. Для того щоб опинитися всередині контейнера, можна використовувати стандартну команду bash. Тобто ви можете запровадити:

$ docker run -ti ubuntu

$ docker run -i -t ubuntu:14.04 /bin/bash

(у другому випадку ви запустите команду /bin/bash всередині контейнера і автоматично опинитеся всередині контейнера)

У командному рядку з'явиться підтвердження того, що ви знаходитесь всередині контейнера як суперкористувач. Після знака @ ви побачите ID контейнера, у якому перебуваєте:

[email protected]:/#

Тепер, використовуючи команду echo, внесіть зміни до директорії /tmp, а потім перевірте, чи зміни були записані за допомогою команди cat:

Echo "Example1" > /tmp/Example1.txt cat /tmp/Example1.txt

На екрані ви повинні побачити:

Тепер вийдіть із контейнера:

Як тільки команда була виконана, і ви вийшли з командного рядка, контейнер Docker перестав працювати. Побачити це ви можете, якщо ви використовуєте команду docker ps:

Серед запущених контейнерів ви не побачите той, який використовувався вище:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Однак ви можете додати ключ -a для того, щоб побачити всі контейнери - як працюючі, так і зупинені - і тоді висвітиться контейнер, в якому ви працювали раніше:

$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11cc47339ee1 ubuntu "/bin/bash" 9 хвилин ago Exited (127) 10 sec ago

Коли створюється контейнер, у нього з'являється ID та автоматично згенерована назва. В даному випадку 11cc47339ee1 – це ідентифікаційний номер (ID) контейнера, а small_sinoussi – згенероване ім'я. Команда ps -a показує ці дані, а також образ, з якого контейнер був створений (в даному випадку ubuntu), коли контейнер був створений (9 хвилин тому) і яка команда була в ньому запущена ("/bin/bash"). Також ви можете подивитися статус контейнера (з нього вийшли 10 секунд тому), якщо б контейнер досі працював, ви б побачили статус "Up" і час, який він вже працює.

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

$ docker run -ti ubuntu

Незважаючи на те, що команда виглядає так само, як минулого разу, вона створить абсолютно новий контейнер - він матиме інший ідентифікаційний номер, а якщо ви спробуєте подивитися вміст файлу Example1, який редагували раніше, то ви його не знайдете.

[email protected]:/# cat /tmp/Example1

Висновок буде:

Cat: /tmp/Example1: Немає такого файлу або directory

Вам може здатися, що дані зникли, але справа, звичайно, не в цьому. Вийдіть з другого контейнера, щоб переконатися, що обидва контейнери (у тому числі перший із потрібним файлом) існують у системі.

[email protected]:/# exit $ docker ps -a

Висновок буде:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e4341887b69 ubuntu "/bin/bash" Отримати за хвилину (1) 6 seconds ago kickass_borg 11cc47339ee1 1/2

Крок 2: перезапуск першого контейнера

Щоб заново запустити вже створений контейнер, необхідно команду start використовувати із двома ключами -ai. Насамкінець вам необхідно написати ідентифікаційний номер контейнера, з яким ви хочете працювати, або його назву. У результаті ваша команда виглядатиме так:

Docker start -ai 11cc47339ee1

Тепер ви знову перебуваєте в оболонці bash всередині контейнера і можете переконатися, що файл, який ви створювали на початку статті, все ще знаходиться тут:

Cat /tmp/Example1.txt

Ви побачите на екрані:

Тепер ви можете вийти з контейнера:

Таким чином, усі зміни всередині контейнера зберігаються, навіть якщо ви зупиняєте і потім знову запускаєте контейнер. Дані видаляються лише тоді, коли видаляється сам контейнер. Також приклад свідчить, що зміни стосуються одного окремого контейнера (а не всіх контейнерів відразу).

Крок 3: видалення обох контейнерів

Завершальним кроком буде видалення двох контейнерів, які ви створили, дотримуючись цього посібника. Для цього потрібно використати команду docker rm. Однак вона діє лише на зупинені контейнери. Після команди необхідно вказати ідентифікаційний номер або назву одного або кількох контейнерів. Наприклад, щоб видаляти контейнери, створені раніше, необхідно запровадити команду:

Docker rm 6e4341887b69 small_sinoussi

На екрані висвітиться:

6e4341887b69 small_sinoussi

Тепер обидва контейнери було видалено.

Висновок

З цього керівництва ви дізналися про основних командахдля роботи в Docker і навчилися створювати, зупиняти, знову запускати та видаляти контейнери.

Ми не раз торкалися тематики і розглядали безліч систем для їх побудови. Сьогодні ми познайомимо ще із однією чудовою системою контейнерами Docker.

Почнемо з того, що опишемо базовий функціонал, який стане в нагоді в подальших статтях циклу, і коротко нагадаємо про архітектуру Docker. Docker використовує клієнт-серверну архітектуру та складається з клієнта – утиліти docker, яка звертається до сервера за допомогою RESTful API, та демона в операційній системі Linux (див. рис. 1). Хоча Docker працює і на відміну від Linux ОС, у цій статті вони не розглядаються.

Основні компоненти Docker:
    • Контейнери– ізольовані за допомогою технологій операційної системи користувацькі оточення, в яких виконуються програми. Найпростіше дати визначення контейнеру Docker як запущеному з образу додатку. До речі, саме цим ідеологічно і відрізняється Docker, наприклад, від LXC ( Linux Containers), хоча вони використовують одні й самі технології ядра Linux. Розробники проекту Docker сповідує принцип: один контейнер – це одна програма.
    • Образи– доступні лише для читання шаблони програм. Поверх існуючих образів можуть додаватися нові рівні, які спільно становлять файлову систему, змінюючи або доповнюючи попередній рівень. Зазвичай новий образ створюється або за допомогою збереження вже запущеного контейнера новий образ поверх існуючого, або за допомогою спеціальних інструкцій для утиліти . Для розділення різних рівнів контейнера на рівні файлової системи можна використовувати AUFS, btrfs, vfs та Device Mapper. Якщо передбачається використання Docker спільно з SELinux, то потрібно Device Mapper.
    • Реєстри (registry), що містять репозиторії ( repository) образів, - мережеві сховища образів. Можуть бути як приватними, і загальнодоступними. Найвідомішим реєстром є .

Для ізоляції контейнерів в операційних системах GNU/Linux використовуються стандартні технології ядра Linux, такі як:
  • Простір імен ( Linux Namespaces).
  • Контрольні групи ( Cgroups).
  • Засоби управління привілеями ( Linux Capabilities).
  • Додаткові, мандатні системи безпеки, такі як AppArmor або SELinux.

Розглянемо перелічені технології трохи докладніше.

Механізм контрольних груп (Cgroups)надає інструмент для тонкого контролю за розподілом, пріоритизацією та управлінням системними ресурсами. Контрольні групи реалізовані у ядрі Linux. У сучасних дистрибутивах управління контрольними групами реалізовано через systemd, однак зберігається можливість керування за допомогою бібліотеки libcgroupта утиліти cgconfig. Основні ієрархії контрольних груп (їх також називають контролерами) наведені нижче:

  • blkio- задає ліміти на операції введення-виводу та на доступ до блокових пристроїв;
  • cpu- Використовуючи планувальник процесів, розподіляє процесорний час між завданнями;
  • cpuacct– створює автоматичні звіти щодо використання ресурсів центрального процесора. Працює спільно з контролером cpuописаним вище;
  • cpuset– закріплює за завданнями певні процесори та вузли пам'яті;
  • devices– регулює доступ завдань до певних пристроїв;
  • freezer- Зупиняє або відновлює завдання;
  • memory– встановлює ліміти та генерує звіти про використання пам'яті завданнями контрольної групи;
  • net_cls- Здійснює тегування мережеві пакетиідентифікатором класу ( classid). Це дозволяє контролеру трафіку ( команда tc) та брандмауеру ( iptables) враховувати ці теги під час обробки трафіку;
  • perf_event– дозволяє проводити моніторинг контрольних груп за допомогою утиліти perf;
  • hugetlb– дозволяє використовувати віртуальні сторінки пам'яті великого розмірута застосовувати до них ліміти.

Простір імен,своєю чергою, контролюють не розподіл ресурсів, а доступом до структур даних ядра. Фактично це означає ізоляцію процесів один від одного і можливість мати паралельно «однакові», але не ієрархії процесів, користувачів і мережевих інтерфейсів, що не перетинаються один з одним. За бажання різні послуги можуть мати навіть свої власні loopback-інтерфейси.

Приклади просторів імен, які використовуються Docker:
  • PID, Process ID- Ізоляція ієрархії процесів.
  • NET, Networking- Ізоляція мережевих інтерфейсів.
  • PC, InterProcess Communication- Управління взаємодією між процесами.
  • MNT, Mount- Управління точками монтування.
  • UTS, Unix Timesharing System– ізоляція ядра та ідентифікаторів версії.

Механізм під назвою Capabilitiesдозволяє розбити привілеї користувача root на невеликі групи привілеїв та призначати їх окремо. Цей функціонал у GNU/Linux з'явився починаючи з версії ядра 2.2.Спочатку контейнери запускаються вже з обмеженим набором привілеїв.

За допомогою опцій команди docker можете дозволяти та забороняти:
  • операції монтування;
  • доступ до сокетів;
  • виконання частини операцій із файловою системою, наприклад зміна атрибутів файлів чи власника.

Детальніше ознайомитися з привілеями можна за допомогою man-сторінки CAPABILITIES(7).

Установка Docker

Розглянемо інсталяцію Docker на прикладі CentOS. При роботі з CentOS у вас є вибір: використовувати останню версію з u pstreamабо версію, зібрану проектом CentOS із додатками Red Hat. Опис змін доступний на сторінці.

В основному це зворотне портування виправлень з нових версій upstream та зміни, запропоновані розробниками Red Hat, але поки що не прийняті в основний код. Найбільш помітною відмінністю на момент написання статті було те, що у нових версіях сервіс docker був поділений на три частини: демон docker, containerd та runc. Red Hat поки не вважає, що ця зміна стабільна, і постачає монолітний файл версії 1.10.

Налаштування репозиторію для встановлення upstream-версії, як і інструкції для інсталяції в інших дистрибутивах та ОС, наведено у посібнику з інсталяції на офіційному сайті . Зокрема, налаштування для репозиторію CentOS 7:

# cat /etc/yum.repos.d/docker.repo name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7 enabled=1 gpgcheck=1 gpgkey=https://yum .dockerproject.org/gpg

# cat /etc/yum.repos.d/docker.repo

name = Repository

baseurl = https://yum.dockerproject.org/repo/main/centos/7

enabled = 1

gpgcheck = 1 gpgkey = https://yum.dockerproject.org/gpg

Встановлюємо необхідні пакети на та запускаємо та включаємо сервіс:

# yum install -y docker-engine # systemctl start docker.service # systemctl enable docker.service

# yum install -y docker-engine

# systemctl start docker.service

# systemctl enable docker.service

Перевіряємо статус сервісу:

# systemctl status docker.service

# systemctl status docker.service

Також можна подивитися системну інформаціюпро Docker та оточення:

# docker info

При запуску аналогічної команди у разі встановлення Docker з репозиторіїв CentOS побачите незначні відмінності, зумовлені використанням старішої версії програмного забезпечення. З висновку docker infoможемо дізнатися, що як драйвер для зберігання даних використовується Device Mapper, а як сховище – файл у /var/lib/docker/:

# ls -lh /var/lib/docker/devicemapper/devicemapper/data -rw-------. 1 root root 100G 27 грудня 12:00 /var/lib/docker/ devicemapper/devicemapper/data

# ls -lh /var/lib/docker/devicemapper/devicemapper/data

Rw -- -- -- - . 1 root root 100G Dec 27 12 : 00 / var / lib / / devicemapper / devicemapper / data

Опції запуску демона, як це зазвичай буває в CentOS, зберігаються в /etc/sysconfig/. У цьому випадку ім'я файлу docker. Відповідний рядок /etc/sysconfig/docker, що описує опції:

OPTIONS="--selinux-enabled --log-driver=journald"

Якби ви запустили команду docker не користувачем root і не користувачем, що входить до групи docker, ви побачили б подібну помилку:

$ docker search mysql

$search mysql

Warning: failed to get default registry endpoint from daemon (Cannot connect to the Docker daemon. Is the docker daemon running on this host?). Using system default: https://index. docker.io/v1/

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

Зверніть увагу, що фактично включення користувача до групи docker рівносильне включенню цього користувача до групи root.

У розробників RHEL/CentOS дещо інший підхід до безпеки демона Docker, ніж у розробників самого Docker з upstream. Докладніше про підхід Red Hat написано у статті розробника дистрибутива RHEL Дена Уолша.

Якщо ж ви хочете «стандартну» поведінку Docker, встановленого з репозиторіїв CentOS (тобто описану в офіційній документації), необхідно створити групу docker і додати в опції запуску демона:

OPTIONS="--selinux-enabled --log-driver=journald ↵ --group=docker"

OPTIONS = "--selinux-enabled --log-driver=journald ↵ --group=docker"

Після цього рестартуємо сервіс і перевіряємо, що файл сокету docker належить групі docker, а не root:

# ls -l /var/run/docker.sock

Пошук образів та теги Docker

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

$ docker search haproxy

$search haproxy


У цьому висновку ми одержали список ряду образів HA Proxy. Найвищий елемент списку – це HA Proxy із офіційного репозиторію. Такі образи відрізняються тим, що в імені немає символу «/» , що відокремлює ім'я репозиторія користувача від імені контейнера. У прикладі за офіційним показано два образи haproxy з відкритих репозиторіїв користувачів eeacms та million12.

Образи, подібні до двох нижніх, можете створити самі, зареєструвавшись на Docker Hub. Офіційні ж підтримуються спеціальною командою, яка спонсорується Docker, Inc. Особливості офіційного репозиторію:

  • Це рекомендовані для використання образи, створені з урахуванням найкращих рекомендацій та практик.
  • Вони є базовими образами, які можуть стати відправною точкою для більш тонкого налаштування. Наприклад, базові образи Ubuntu, CentOS або бібліотек та середовищ розробки.
  • Містять останні версіїпрограмного забезпечення з усуненими уразливістю.
  • Це офіційний канал розповсюдження продуктів. Щоб шукати лише офіційні образи, можете скористатися опцією -filter "is-official=true"команди docker search.

Число зірок у виведенні команди docker searchвідповідає популярності образу. Це аналог кнопки Likeу соціальних мережах або закладок для інших користувачів. Automatedозначає, що образ збирається автоматично із спеціального сценарію засобами Docker Hub. Зазвичай слід віддавати перевагу образам, що автоматично збираються внаслідок того, що його вміст може бути перевірено знайомством з відповідним файлом .

Завантажуємо офіційний образ HA Proxy:

$ docker pull haproxy Використання детального tag: latest

Повне ім'я образу може виглядати так:

[ім'я користувача]ім'я образу[:тег]

Переглянути список завантажених образів можна командою docker images:

Запуск контейнерів

Для запуску контейнера не обов'язково заздалегідь завантажувати образ. Якщо він доступний, то буде завантажено автоматично. Давайте спробуємо запустити контейнер з Ubuntu. Ми не будемо вказувати репозиторій, і буде завантажено останній офіційний образ, підтримуваний Canonical.

$ docker run -it ubuntu [email protected]:/#

$ run - it ubuntu

root @ d7402d1f7c54 : / #

Окрім команди run, ми вказали дві опції: -i– контейнер повинен запуститися в інтерактивному режимі та -t– має бути виділено псевдотермінал. Як видно з висновку, у контейнері ми маємо привілеї користувача root, а як ім'я вузла відображається ідентифікатор контейнера. Останнє може бути справедливим не для всіх контейнерів і залежить від розробника контейнера. Перевіримо, що це дійсно оточення Ubuntu:

[email protected]:/# cat /etc/*release | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"

root @ d7402d1f7c54 : / # cat /etc/*release | grep DISTRIB_DESCRIPTION

DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

Команду uname -aдля таких цілей використовувати не вийде, оскільки контейнер працює з ядром хоста.

Як одна з опцій можна було б задати унікальне ім'я контейнера, на яке можна для зручності посилатися, крім ID-контейнер.Вона задається як -name<имя>. Якщо опція опущена, ім'я генерується автоматично.

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

Переглянути список запущених контейнерів можна командою. Для цього відкриємо другий термінал:

Однак якщо віддати команду контейнера, створеного з образу mysql, ми не виявимо. Скористаємося опцією -aяка показує всі контейнери, а не тільки запущені:

Очевидно, що під час запуску контейнера не було вказано обов'язкових параметрів. Ознайомитися з описом змінних середовища, необхідних для запуску контейнера, можна знайти офіційний образ MySQL на Docker Hub. Повторимо спробу, використовуючи опцію -eяка задає змінні оточення в контейнері:

$ docker run --name mysql-test ↵ -e MYSQL_ROOT_PASSWORD=docker -d mysql

Останнім параметром є команда, яку ми хочемо виконати всередині контейнера. У цьому випадку це командний інтерпретатор Bash. Опції -itаналогічні за призначенням використаним раніше у команді docker run.

Фактично після запуску цієї команди у контейнер mysql-testдодається ще один процес – bash. Це можна побачити за допомогою команди pstree. Скорочений висновок до команди docker exec:

Усередині Docker тільки Linuxі, експериментально, FreeBSD. Запускається нативно під Linux і, експериментально, під FreeBSD. Під MacOSX, Windows – через віртуальну машину.

Докер – це подвійна ізоляція.Ізоляція того, що лежить усередині контейнера Докера від операційної системита ізоляція операційної системи від того, що лежить усередині Докер. Ізоляція передбачає ізоляцію всіх файлів, портів, пріоритетів.

Це майже віртуальна машина. Майже, та не зовсім.

Є таке поняття "пекло залежностей". Будь-яке ПЗ, що встановлюється на комп'ютер, тягне за собою залежності(Конфігураційні файли, статичні файли звані зазвичай asset, допоміжні утиліти/сервіси, бібліотеки та ін.). Ряд із цих бібліотек/утиліт/сервісів несумісний один з одним.А з урахуванням того, що кожна з цих бібліотек/утиліт/сервісів має свої залежності - ситуація ще гірша.

Наприклад, ми використовуємо Yandex.Cocaine, яка нормально компілюється лише на Ubuntu 14.04 (і, начебто, на Debian 7). Але не під CentOS 6, 7, Debian 8, FreeBSD 9, 10, Ubuntu 15, 16 та ін. скомпілювати його неможливо. Запускаємо у цих операційних системах у Докері.

З іншого боку, і одночасно з цим вам необхідно встановити інше, більш сучасне ПЗ. І водночас старіше. Причому навіть не йдеться про версії Linux, що серйозно відрізняються. Наприклад, одне ПЗ вимагає не менше Ubuntu 14.10, а інше не більше Linux 14.04.

Docker – це одна програма всередині індивідуального оточення із індивідуальною версією операційної системи.За рахунок листкових контейнерів, якщо ви використовуєте один корінь для всіх чином, то розмір Docker контейнера всього на кілька кілобайтів більше розміру бінарного файлу,запускається під Docker.

Таким чином, ми маємо бінарний файл, який запускається як би у своїй операційній системі.

Ви можете сказати - ба, та це ж давно відома віртуальна машина. Але ж ні, це не так.Це так звані контейнери. Жодної віртуальної машиною там і не пахне. За винятком Windows та MacOSX,де робота без віртуальної машини поки що експериментально можлива тільки, а нормою в цих ОС є використання Докера всередині повноцінної віртуальної машини.

Але віртуальні машини з Докер використовуються тільки для розробки. Для запуску в production віртуальні машини з Докер не використовуються.

Докер використовує контейнери для операційної системи. LXC у Linux, Jails у FreeBSD. Контейнер – це область операційної системи, ізольована від основної частини операційної системи. У контейнері своє дерево каталогів (включаючи системні /dev, /bin, /sbin та ін.), свої мережеві порти та ін.

Але при цьому не використовується повна віртуалізація. Що суттєво економить ресурси. Запустити 100 повноцінних віртуальних машиннавряд чи вийде навіть потужному сервері. А от запустити 100 контейнерів Docker навіть на слабкому домашньому комп'ютері- можливо.

Щоправда, використання не повної віртуалізації обмежує використання операційних систем усередині контейнерів. Як правило, це спеціально підготовлені версії Linux чи FreeBSD. Саме спеціально підготовлені. Windows – у принципі в контейнері запустити неможливо.

Контейнери існували до Docker. Докер, строго кажучи, це всього лише дуже зручний набір інструментівзібраних воєдино, для управління контейнерною віртуалізацією. Але дуже зручний.

Для чого це використовується?

Хлопці з усіляких Dropbox, Facebook та ін гігантах, що запускають по 1 млн. різних програм у своїх сервісах, зіткнулися, що неможливо скрізь гарантувати ідентичні налаштування операційної системи.А це критично.

Аж до того, що ідеально написана і тестована програма на реальному сервері починає поводитися непередбачено.

Тому хтось із цих розумних хлопців народив нову концепцію – кожна програма на серверах запускається у своєму індивідуальному оточенні, з індивідуальними налаштуваннями операційної системи.

Більше того – спочатку розробник програмного забезпечення тестує програму в контейнері Докер, з певними налаштуваннями. І в цьому ж (або з такими самими налаштуваннями) контейнері Докера програма їде на сервер.

Це дозволяє гарантувати набагато більшу ідентичність середовища розробки та середовища виконання.

До цього люди мучилися, вигадували хитрі інсталятори.

Потім плюнули на спроби впорядкувати оточення в ОС- і зараз концепція така - встановлювати програми на сервері разом зі своїми індивідуально налаштованими під них операційними системами- тобто усередині контейнерів. 1 контейнер = 1 налаштування ОС = 1 програма всередині.

Іншими словами:

  • Докер-контейнер слід використовувати для налагодження.
  • Той самий Докер-контейнер потрібно використовувати і на сервері.

Це дозволяє не працювати з налаштуваннями "під сервер"локально на машині розробника. Це дозволяє розробляти на машині розробника абсолютно різні програми одночасно, які вимагає несумісних налаштувань операційної системи. Це дозволяє давати набагато більше гарантій, що програма на сервері поводитиметься так само, як і на машині розробника. Це дозволяє розробляти під Windows/MacOSX із зручним "прозорим" тестуванням під Linux.

Докер застосовується до створення/налаштування тільки серверного програмного забезпечення під Linux(Експериментально під FreeBSD). Чи не для смартфонів. А якщо десктопів – то тільки програмне забезпеченнябез GUI.

Оскільки Докер дозволив одним махом спростити роботу розробникам та адмінам та підвищити якість результату- зараз бум на Докер. Придумано величезна гора інструментів для управління розгортанням додатків, створених з Докером. Якщо раніше щоб запустити 10 000 програм на 1000 серверах потрібно було як мінімум 3 висококваліфікованих девопса, які писали купу описів якце зробити на Puppet, Salt, Chef, Ansible, та й то не було гарантій, це все тестувалося місяцями. То зараз з Докером навіть один кваліфікований девопс може керувати мільйонами програм на десятках тисяч серверів. З більшою гарантією, що все це заведеться нормально.

Може скластися помилкове враження, що розробник готує контейнери до Докер, а потім передає їх адміну.
Правильна методологія все ж таки інша:

Розробник віддає весь свій результат у систему CI (зазвичай через git)
CI на кожен новий коміт робить за допомогою Docker образ для тестування.
Якщо тести проходять успішно, то цей же Docker образ відправляється на розгортання в production.
Або, трохи інакше в системах, що компілюються, де вихідники не потрібні в production: в Docker проводиться розгортання середовища для компіляції, а для тестування розгортається другий образ з вже відкомпільованим добром, який вже відправляється в production.

Тобто при правильній огранізації справи розробник не може/не повинен впливати на те, яким буде образ.
А ось у тестовому середовищі (який запускається на сервер, недоступному розробнику у великих командах) і в production якраз використовується той самий образ.

Основна ідея - що тестували, як і запускаємо на бойовому сервері. Один-в-один, включаючи самі файли (Не такі ж, а саме ті самі).

Довідка по командам управління образами та контейнерами Docker.

Терміни

Образ– це статичний білд на основі певної OS.

Контейнер- це занедбаний інстанс образу.

Права на запуск docker

Щоб запускати Docker контейнери під своїм користувачем (без sudo), потрібно додатись до відповідної групи:

Sudo usermod -aG docker YOU_USER

Сервіс Docker

Управління сервісом Docker"а:

Sudo service docker start|stop|restart|status sudo restart docker # аліас

Образи

Список доступних образів:

Docker images

Завантажити образ (або весь репозиторій) з офіційного регістру (сховища образів):

Docker pull ubuntu:14.04

Переглянути інформацію про образ:

Docker inspect ubuntu

Видалити образ:

Docker commit CONTAINER_ID IMAGE_NAME

Контейнери

Увага!

Після запуску Docker контейнера сервіси/демони (як-то SSH, Supervisor та інші) не запускатимуться автоматично! Я витратив кілька годин на налагодження помилки: " ssh_exchange_identification: read: Connection reset by peer", при спробі підключитися до контейнера по SSH. А виявилося, що всього не запускався демон sshd. Ви повинні будете вручну запускати потрібні демони або супервізор після старту контейнера:"

Docker exec CONTAINER_ID bash -c "service ssh start"

Список всіх контейнерів (запущених та зупинених):

Docker ps -a

Видалити контейнер(и):

Docker rm CONTAINER_ID CONTAINER_ID

Видалити всі контейнери:

Docker rm $(docker ps -aq)

Створити та запустити Docker контейнер з Ubuntu 14.04 в інтерактивному режимі (відкрити shell цього контейнера):

Docker run -it ubuntu bash docker run [опції] образ [команда] -i Інтерактивний режим, тримаємо STDIN відкритим -t Allocate/creates a pseudo-TTY that attaches stdin and stdout --name Ім'я контейнера замість ID-w --workdir) -e Встановити змінну оточенняв контейнері -u Користувач:група під яким повинен бути запущений контейнер -v Змонтувати в контейнер файл або каталог хост-системи -p Прокинути порт(и) контейнера -<порт хост-системы>:<порт контейнера>(--publish=) --entrypoint Замінити дефолтну команду з ENTRYPOINT файлу Dockerfile

Примітка

Щоб від'єднати TTY без зупинки контейнера, натисніть Ctr + P + Ctrl + Q .

Створити і запустити Docker контейнер в режимі демона з прокиданням SSH порту:

Docker run -itd -p 127.0.0.1:221:22 ubuntu

Створити та запустити контейнер з подальшим видаленням цього контейнера після зупинки (корисно для налагодження):

Docker run -i -t --rm ubuntu bash

Запустити зупинений контейнер інтерактивно:

Docker start -i CONTAINER_ID

Підключитися до демонізованого контейнера:

Docker attach CONTAINER_ID

Команди Docker

Usage: docker COMMAND docker daemon [--help | ...] docker [--help | -v | --version ] A self-sufficient runtime for containers. Options: --config=~/.docker Location of client config files -D, --debug=false Enable debug mode --disable-legacy-registry=false Не contact legacy registries -H, --host= Daemon socket( s) натиснути на -h, --help=false Print usage -l, --log-level=info Натисніть на позначення рівня --tls=false Use TLS; implied by --tlsverify --tlscacert=~/.docker/ca.pem Trust certs signed only by this CA --tlscert=~/.docker/cert.pem Path to TLS certificate file --tlskey=~/.docker/ key.pem Path to TLS key file --tlsverify=false Use TLS and verify remote -v, --version=false Print version information and quit Commands: attach Attach to running container build Build an image from Dockerfile commit Create a New image from container"s changes cp Copy files/folders between container and local filesystem create Create a new container diff Inspect changes on container"s filesystem events Get real time events from the server exec Run command in running container export Export a container"s filesystem as a tar archive history Show the history of image images List images import Import the contents from tarball to create a filesystem image info Display system-wide information inspect Return low-level information on container or image kill Kill a running container l oad Load image з tar archiv or STDIN Login Registrar або log in to docker registry logout Log out from Docker registry logs Fetch the logs of container network Manage Docker networks pause Pause all process within container port List port mappings specific mapping for CONTAINER ps List containers pull Pull image or repository from registry push Push image or repository to registry rename Rename container restart Restart container rm Remove one or more containers rmi Remove one or more command in a new container save Save an image(s) to a tar archive search Search the Docker Hub для images start Start one or more stopped containers stats Відтворення Live Stream Container(s) stop Stop Running container tag Tag на зображення в репозиторії вгорі Display running process of container unpause Unpause all process within container volume Manage Docker volumes wait Block until container stops, the print its exit code Run "docker COMMAND --help" for more information on a command.

Вже кілька місяців використовую docker для структуризації процесу розробки/доставки веб-проектів. Пропоную читачам "Хабрахабра" переклад вступної статті про docker - "Understanding docker".

Що таке докер?

Докер - це відкрита платформа для розробки, доставки та експлуатації програм. Docker розроблений для швидшого викладання ваших додатків. За допомогою docker ви можете відокремити вашу програму від вашої інфраструктури і звертатися з інфраструктурою як керованим додатком. Docker допомагає викладати ваш код швидше, швидше тестувати, швидше викладати програми та зменшити час між написанням коду та запуску коду. Docker робить це за допомогою легковагої платформи контейнерної віртуалізації, використовуючи процеси та утиліти, які допомагають керувати та викладати ваші програми.

У своєму ядрі docker дозволяє запускати практично будь-яку програму, безпечно ізольовану в контейнері. Безпечна ізоляція дозволяє запускати на одному хості багато контейнерів одночасно. Легковажна природа контейнера, який запускається без додаткового навантаження гіпервізора, дозволяє вам досягати більше від заліза.

Платформа та засоби контейнерної віртуалізації можуть бути корисними у таких випадках:

  • упаковка вашої програми (і так само використовуваних компонентів) в контейнери docker;
  • роздача та доставка цих контейнерів вашим командам для розробки та тестування;
  • викладання цих контейнерів на ваші продакшени, як у дата центри так і в хмари.

Навіщо я можу використовувати docker?

Швидке викладання ваших додатків

Docker чудово підходить для організації циклу розробки. Docker дозволяє розробникам використовувати локальні контейнери з програмами та сервісами. Що надалі дозволяє інтегруватися з процесом постійної інтеграції та викладання (continuous integration and deployment workflow).

Наприклад, ваші розробники пишуть код локально і діляться своїм стеком розробки (набором образів docker) з колегами. Коли вони готові, отруюють код та контейнери на тестовий майданчик та запускають будь-які необхідні тести. З тестового майданчика вони можуть оправити код та образи на продакшен.

Простіше викладання та розгортання

Заснована на контейнерах платформа docker дозволять легко портувати ваше корисне навантаження. Docker контейнери можуть працювати на вашій локальній машині як реальної так і на віртуальній машині в дата центрі, так і в хмарі.

Портованість та легковажна природа docker дозволяє легко динамічно керувати вашим навантаженням. Ви можете використовувати docker, щоб розгорнути або погасити вашу програму або сервіси. Швидкість docker дозволяє це робити майже в режимі реального часу.

Високі навантаження та більше корисних навантажень

Docker легковажний та швидкий. Він надає стійку, рентабельну альтернативу віртуальним машинам з урахуванням гіпервізора. Він особливо корисний в умовах високих навантажень, наприклад, при створенні власної хмари або платформа-як-сервіс (platform-as-service). Але він також корисний для маленьких і середніх додатків, коли вам хочеться отримувати більше з наявних ресурсів.

Головні компоненти Docker

Docker складається з двох головних компонентів:
  • Docker: платформа віртуалізації з відкритим кодом;
  • Docker Hub: наша платформа-як-сервіс для розповсюдження та управління docker контейнерами.
Примітка! Docker поширюється на Apache 2.0 ліцензії.

Архітектура Docker

Docker використовує архітектуру клієнт-сервер. Docker клієнт спілкується з демоном Docker, який бере на себе вага створення, запуску, розподілу ваших контейнерів. Обидва клієнт і сервер можуть працювати на одній системі, ви можете підключити клієнт до віддаленого демона docker. Клієнт та сервер спілкуються через сокет або через RESTful API.

Docker-демон

Як показано на діаграмі, демон запускається на хост-машині. Користувач не взаємодіє із сервером на пряму, а використовує для цього клієнт.

Docker-клієнт

Docker-клієнт, програма docker – головний інтерфейс до Docker. Вона отримує команди від користувача та взаємодіє з docker-демоном.

Усередині docker-а

Щоб розуміти, з чого складається docker, вам потрібно знати про три компоненти:
  • образи (images)
  • реєстр (registries)
  • контейнери

Образи

Docker-образ - це read-only шаблон. Наприклад, образ може містити операційну систему Ubuntu c Apache та додатком на ній. Образи використовуються створення контейнерів. Docker дозволяє легко створювати нові образи, оновлювати існуючі, або ви можете завантажити образи, створені іншими людьми. Образи - це компонент збірки docker-а.

Реєстр

Docker-реєстр зберігає образи. Існують громадські і приватні реєстри, у тому числі можна завантажити чи завантажити образи. Публічний Docker-реєстр - це Docker Hub. Там зберігається величезна колекція образів. Як ви знаєте, образи можуть бути створені вами або ви можете використовувати образи, створені іншими. Реєстри – це компонента поширення.

Контейнери

Контейнери схожі на директорію. У контейнерах міститься все, що потрібне для роботи програми. Кожен контейнер створюється із образу. Контейнери можуть бути створені, запущені, зупинені, перенесені або вилучені. Кожен контейнер ізольований та є безпечною платформою для застосування. Контейнери – це компонент роботи.

То як працює Docker?

Поки що ми знаємо, що:
  • можемо створювати образи, в яких знаходяться наші програми;
  • можемо створювати контейнери з образів для запуску додатків;
  • можемо розповсюджувати образи через Docker Hub чи інший реєстр образів.
Погляньмо, як ці компоненти поєднуються.

Як працює образ?

Ми вже знаємо, що образ - це read-only шаблон, з якого створюється контейнер. Кожен образ складається із набору рівнів. Docker використовує union file system поєднання цих рівнів в один образ. Union file system дозволяє файлам та директоріями з різних файлових систем (різним гілкам) прозоро накладатися, створюючи когерентну файлову систему.

Одна з причин, через яку docker легковажний - це використання таких рівнів. Коли ви змінюєте образ, наприклад, оновлюєте програму, створюється новий рівень. Так, без заміни всього образу або його перескладання, як вам можливо, доведеться зробити з віртуальною машиною, тільки рівень додається або оновлюється. І вам не потрібно роздавати весь новий образ, лунає лише оновлення, що дозволяє розповсюджувати образи простіше та швидше.

В основі кожного образу є базовий образ. Наприклад, ubuntu, базовий образ Ubuntu або fedora, базовий образ дистрибутива Fedora. Також ви можете використовувати образи як базу для створення нових образів. Наприклад, якщо у вас є образ apache, ви можете використовувати його як базовий образ для ваших веб-застосунків.

Примітка! Docker зазвичай бере образи з реєстру Docker Hub.

Docker образи можуть створюватися з цих базових образів, кроки опису створення цих образів ми називаємо інструкціями. Кожна інструкція створює новий образ чи рівень. Інструкціями будуть наступні дії:

  • запуск команди
  • додавання файлу або директорії
  • створення змінної оточення
  • вказівки що запускати коли запускається контейнер цього образу

Ці інструкції зберігаються у файлі Dockerfile. Docker зчитує це Dockerfile, коли ви збираєте образ, виконує ці інструкції, і повертає кінцевий образ.

Як працює docker реєстр?

Реєстр – це сховище docker образів. Після створення образу ви можете опублікувати його на публічному реєстрі Docker Hub або на особистому реєстрі.

За допомогою клієнта docker ви можете шукати вже опубліковані образи і завантажувати їх на вашу машину з docker для створення контейнерів.

Docker Hub надає публічні та приватні сховища образів. Пошук та скачування образів з публічних сховищ доступне всім. Вміст приватних сховищ не потрапляє у результат пошуку. І тільки ви і ваші користувачі можуть отримувати ці образи і створювати контейнери.

Як працює контейнер?

Контейнер складається з операційної системи, файлів користувача та метаданих. Як знаємо, кожен контейнер створюється з образу. Цей образ каже docker-у, що у контейнері, який процес запустити, коли запускається контейнер та інші конфігураційні дані. Docker образ доступний лише для читання. Коли docker запускає контейнер, він створює рівень читання/запису зверху образу (використовуючи union file system, як було зазначено раніше), у якому може бути запущено додаток.

Що відбувається, коли контейнер запускається?

Або за допомогою програми docker або за допомогою RESTful API, docker клієнт каже docker демону запустити контейнер.

$ sudo docker run -i -t ubuntu /bin/bash

Давайте розберемося із цією командою. Клієнт запускається за допомогою команди docker, з опцією run, яка говорить, що буде запущено новий контейнер. Мінімальними вимогами для запуску контейнера є такі атрибути:

  • який образ використовуватиме створення контейнера. У нашому випадку ubuntu
  • команду, яку ви хочете запустити, коли контейнер буде запущений. У нашому випадку /bin/bash

Що відбувається під капотом, коли ми запускаємо цю команду?

Docker, по порядку, робить таке:

  • завантажує образ ubuntu: docker перевіряє наявність образу ubuntu на локальній машині, і якщо його немає, то завантажує його з Docker Hub. Якщо образ є, то використовує його для створення контейнера;
  • створює контейнер:коли образ отримано, docker використовує його створення контейнера;
  • ініціалізує файлову систему та монтує read-only рівень:контейнер створений у файловій системі і read-only рівень доданий образ;
  • ініціалізує мережу/міст:створює мережевий інтерфейсщо дозволяє docker-у спілкуватися хост машиною;
  • Встановлення IP-адреси:знаходить та задає адресу;
  • Запускає цей процес:запускає вашу програму;
  • Обробляє та видає висновок вашої програми:підключається та логує стандартний вхід, висновок та потік помилок вашої програми, що б ви могли відстежувати як працює ваша програма.
Тепер у вас є робочий контейнер. Ви можете керувати своїм контейнером, взаємодіяти з вашим додатком. Коли ви вирішите зупинити програму, видаліть контейнер.

Використовувані технології

Докер написаний на Go і використовує деякі можливості ядра Linux, щоб реалізувати наведений вище функціонал.

Простір імен(namespaces)

Docker використовує технологію namespaces для організації ізольованих робочих просторів, які ми називаємо контейнерами. Коли ми запускаємо контейнер, docker створює простір імен для даного контейнера.

Це створює ізольований рівень, кожен аспект контейнера запущений у своєму просторі імен і не має доступу до зовнішньої системи.

Список деяких просторів імен, які використовує docker:

  • pid:для ізоляції процесу;
  • net:для керування мережевими інтерфейсами;
  • ipc:для керування IPC ресурсами. (ICP: InterProccess Communication);
  • mnt:для керування точками монтування;
  • utc:для ізолювання ядра та контролю генерації версій (UTC: Unix timesharing system).

Control groups (контрольні групи)

Docker також використовує технології cgroups або контрольні групи. Ключ до роботи програми в ізоляції, надання додатку тільки ресурсів, які ви хочете надати. Це гарантує, що контейнери будуть добрими сусідами. Контрольні групи дозволяють розділяти доступні ресурси заліза і, якщо необхідно, встановлювати межі та обмеження. Наприклад, обмежити можливу кількість пам'яті контейнеру.

Union File System

Union File Sysem або UnionFS - це файлова система, яка працює створюючи рівні, роблячи її дуже легковагою та швидкою. Docker використовує UnionFS для створення блоків, із яких будується контейнер. Docker може використовувати кілька варіантів UnionFS, включаючи: AUFS, btrfs, vfs і DeviceMapper.

Формати контейнерів

Docker поєднує ці компоненти в обгортку, яку ми називаємо форматом контейнера. Формат, який використовується за замовчуванням, називається libcontainer . Також docker підтримує традиційний формат контейнерів в Linux за допомогою LXC. У майбутньому Docker можна буде підтримувати інші формати контейнерів. Наприклад, інтегруючись із BSD Jails або Solaris Zones.
Підтримайте проект - поділіться посиланням, дякую!
Читайте також
Як встановити безкоштовний антивірус аваст Як встановити безкоштовний антивірус аваст Як очистити комп'ютер від вірусів самостійно Як очистити комп'ютер від вірусів самостійно Як повністю очистити комп'ютер від вірусів Як повністю очистити комп'ютер від вірусів