Docker
( * Відповідь на питання розгорніть за допомого трикутного значка |> )
- Що таке Docker? В чому відмінність контейнера від образу?
Docker – програмне забезпечення для автоматизації розгортання і управління додатками в середовищах з підтримкою контейнеризації.
Образ – шаблон додатку, який містить шари файлової системи в режимі “тільки-читання”.
Контейнер – запущений образ додатку, який крім нижніх шарів в режимі “тільки читання” містить верхній шар в режимі “читання-запис”.
- Які інструкції є у Dockerfile?
| Інструкція | Опис |
|————|————————————————————————————————————————————————————————————————————–|
| FROM | Задає базовий (батьківський) образ. |
| LABEL | Описує метадані. Наприклад — відомості про те, хто створив і підтримує образ. |
| ENV | Встановлює постійні змінні середовища. |
| RUN | Виконує команду і створює шар образу. Використовується для встановлення в контейнер пакетів. |
| COPY | Копіює в контейнер файли і директорії. |
| ADD | Копіює файли і директорії в контейнер, може розпаковувати локальні .tar-файли. |
| CMD | Описує команду з аргументами, яку потрібно виконати коли контейнер буде запущений. Аргументи можуть бути перевизначені при запуску контейнера. В файлі може бути присутня лише одна інструкція CMD. |
| WORKDIR | Задає робочу директорію для наступної інструкції. |
| ARG | Задає змінні для передачі Docker під час збірки образу. |
| ENTRYPOINT | Надає команду з аргументами для виклику під час виконання контейнера. Аргументи не перевизначаються. |
| EXPOSE | Вказує на необхідність відкрити порт. |
| VOLUME | Створює точку монтування для роботи з постійним сховищем. |
- Чим відрізняється CMD від ENTRYPOINT в Dockerfile?
Інструкції CMD та ENTRYPOINT виконуються в момент запуску контейнера, тільки інструкція CMD дозволяє перевизначити передавані команді аргументи.
Приклад 1. CMD:
Опишемо збірку образу в Dockerfile.
FROM alpine
CMD ["ping", "8.8.8.8"]
В інструкцію CMD передаються 2 аргументи. Виконаємо збірку образу docker build -t test .
і запустимо контейнер.
$ docker run test
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=43 time=32.976 ms
64 bytes from 8.8.8.8: seq=1 ttl=43 time=31.998 ms
64 bytes from 8.8.8.8: seq=2 ttl=43 time=31.843 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 31.708/33.316/36.823 ms
Тепер передамо 2 нових аргументи для запуску контейнера.
$ docker run test traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 46 byte packets
1 172.17.0.1 (172.17.0.1) 0.017 ms 0.016 ms 0.009 ms
2 192.168.168.1 (192.168.168.1) 0.996 ms 1.553 ms 2.069 ms
3 * * *
4 lag-2-435.bgw01.samara.ertelecom.ru (85.113.62.125) 1.454 ms 1.427 ms 1.984 ms
5 172.68.8.3 (172.68.8.3) 19.685 ms 15.722 ms 15.565 ms
6 172.68.8.2 (172.68.8.2) 15.846 ms 22.696 ms 35.093 ms
7 one.one.one.one (1.1.1.1) 17.439 ms 17.670 ms 24.202 ms
ping
замінений на traceroute, IP адреса замінена на 1.1.1.1.
Приклад 2. ENTRYPOINT:
Опишемо збірку образу в Dockerfile.
FROM alpine
ENTRYPOINT ["ping", "8.8.8.8"]
В інструкцію ENTRYPOINT передаються 2 аргументи. Виконаємо збірку образу docker build -t test .
і запустимо контейнер.
$ docker run test2
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=43 time=36.189 ms
64 bytes from 8.8.8.8: seq=1 ttl=43 time=44.120 ms
64 bytes from 8.8.8.8: seq=2 ttl=43 time=44.584 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 36.189/41.631/44.584 ms
Тепер передамо змінимо один з аргументів для запуску контейнера.
$ docker run test2 ping 1.1.1.1
BusyBox v1.31.1 () multi-call binary.
Usage: ping [OPTIONS] HOST
Send ICMP ECHO_REQUEST packets to network hosts
-4,-6 Force IP or IPv6 name resolution
-c CNT Send only CNT pings
-s SIZE Send SIZE data bytes in packets (default 56)
-i SECS Interval
-A Ping as soon as reply is recevied
-t TTL Set TTL
-I IFACE/IP Source interface or IP address
-W SEC Seconds to wait for the first response (default 10)
(after all -c CNT packets are sent)
-w SEC Seconds until ping exits (default:infinite)
(can exit earlier with -c CNT)
-q Quiet, only display output at start
and when finished
-p HEXBYTE Pattern to use for payload
Як бачимо, аргумент передати контейнеру неможливо.
Приклад 3. ENTRYPOINT та CMD:
Опишемо збірку образу в Dockerfile.
FROM alpine
ENTRYPOINT ["ping"]
CMD ["8.8.8.8"]
В інструкцію ENTRYPOINT передається аргумент ping
, в CMD передається аргумент 8.8.8.8. Виконаємо збірку образу docker build -t test .
і запустимо контейнер.
$ docker run test3
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=43 time=41.176 ms
64 bytes from 8.8.8.8: seq=1 ttl=43 time=32.875 ms
64 bytes from 8.8.8.8: seq=2 ttl=43 time=40.395 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 32.875/38.148/41.176 ms
Пробуємо змінити 2 аргументи.
$ docker run test3 traceroute 1.1.1.1
BusyBox v1.31.1 () multi-call binary.
Usage: ping [OPTIONS] HOST
Send ICMP ECHO_REQUEST packets to network hosts
-4,-6 Force IP or IPv6 name resolution
-c CNT Send only CNT pings
-s SIZE Send SIZE data bytes in packets (default 56)
-i SECS Interval
-A Ping as soon as reply is recevied
-t TTL Set TTL
-I IFACE/IP Source interface or IP address
-W SEC Seconds to wait for the first response (default 10)
(after all -c CNT packets are sent)
-w SEC Seconds until ping exits (default:infinite)
(can exit earlier with -c CNT)
-q Quiet, only display output at start
and when finished
-p HEXBYTE Pattern to use for payload
Змінити 2 аргументи неможливо. Замінимо аргумент інструкції CMD.
$ docker run test3 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=58 time=31.412 ms
64 bytes from 1.1.1.1: seq=1 ttl=58 time=19.400 ms
64 bytes from 1.1.1.1: seq=2 ttl=58 time=15.814 ms
^C
--- 1.1.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 15.814/22.208/31.412 ms
При такій збірці образу команди ENTRYPOINT та CMD при запуску контейнера будуть запущені послідовно, але аргумент можливо змінити тільки для CMD.
- Чим відрізняється COPY від ADD в Dockerfile?
Інструкція COPY копіюють файли і директорії з хостової машини всередину контейнера, інструкція ADD копіює файли і директорії з хостової машини всередину контейнера і може розпаковувати .tar архіви.
- Які є best practices для написання Dockerfile?
- Запускати тільки один процес на контейнер.
- Намагатися об’єднувати декілька команд RUN в одну для зменшення кількості шарів образу.
- Частозмінювані шари образу необхідно розташовувати нижче по рівню, щоб прискорити процес збірки, т.к. при зміні верхнього шару, всі нижченаведені шари будуть пересобиратися.
- Вказувати явні версії образів в інструкції FROM, щоб уникнути випадку, коли вийде нова версія образу з тегом latest.
- При встановленні пакетів вказувати версії пакетів.
- Очищати кеш пакетного менеджера і видаляти непотрібні файли після виконаної інструкції.
- Використовувати multistage build для збірки артефакту в одному контейнері і розміщенні його в іншому.
- Які типи мережевих драйверів використовуються в docker?
Основні драйвери мереж docker: bridge, host, overlay, ipvlan, macvlan, none
bridge: це мережевий драйвер за замовчуванням. Бридж мережа використовується, коли ваші додатки запускаються в автономних контейнерах, які повинні взаємодіяти між собою.
Взаємодія з хостом виконується через міст docker0 і конфігурацію таблиці iptables nat. В цьому режимі буде виділено мережевий простір імен, заданий IP-адреса для кожного контейнера, а контейнер Docker на хості буде підключений до віртуального мосту. Віртуальний міст працює як фізичний комутатор, тому всі контейнери на хості підключені до мережі рівня 2 через комутатор.
host: використовує мережу хоста напряму без ізоляції контейнера і хоста.
none: цей режим поміщає контейнер в свій власний мережевий стек, але не виконує ніякого налаштування. Фактично, цей режим відключає мережеву функцію контейнера, що корисно в наступних двох ситуаціях: контейнер не потребує мережі (наприклад, тільки для пакетної задачі запису дискових томів).
macvlan: в режимі Macvlan Bridge кожен контейнер має унікальну MAC-адресу, яка використовується для відстеження співставлення MAC-адреси з портом хоста Docker. Мережа драйвера Macvlan підключається до батьківського інтерфейсу хоста Docker. Прикладами є фізичні інтерфейси, такі як eth0, субінтерфейс eth0.10 для тегування VLAN 802.1q (.10 означає VLAN 10) або навіть зв’язаний хост-адаптер, який об’єднує два інтерфейси Ethernet в єдиний логічний інтерфейс. Призначений шлюз є зовнішнім по відношенню до хоста, що надається мережевою інфраструктурою. Кожна мережа Docker в режимі Macvlan Bridge ізольована одна від одної, і тільки одна мережа може бути підключена до батьківського вузла одночасно. Кожен хост-адаптер має теоретичний ліміт, і кожен хост-адаптер може підключатися до мережі Docker. Будь-який контейнер в тій же підмережі може взаємодіяти з будь-яким іншим контейнером в тій же мережі без шлюзового мосту macvlan. Та ж мережева команда docker застосовується до драйвера vlan. В режимі Macvlan без зовнішньої маршрутизації процесів між двома мережами / підмережами контейнери в різних мережах не можуть отримати доступ один до одного. Це також відноситься до декількох підмереж в одній і тій же термінальній мережі.
overlay: Оверлейні мережі з’єднують декілька демонів Docker разом і дозволяють сервісам swarm взаємодіяти один з одним. Ви також можете використовувати оверлейні мережі для полегшення зв’язку між сервісом swarm і автономним контейнером або між двома автономними контейнерами в різних демонах Docker. Ця стратегія усуває необхідність виконувати маршрутизацію між цими контейнерами на рівні ОС.
ipvlan: Мережі ipvlan надають користувачам повний контроль над адресацією IPv4 та IPv6. Драйвер VLAN побудований на основі цієї можливості, надаючи операторам повний контроль над тегуванням VLAN рівня 2 і навіть маршрутизацією IPvlan L3 для користувачів.
- Що таке ефемерні контейнери?
Ефемерні контейнери стали бета-функцією в Kubernetes v1.23 і тепер включені за замовчуванням.
Ефемерні контейнери призначені для транзитних задач, коли вам потрібно тимчасово підключити додатковий контейнер до існуючого поду. Це ідеально підходить для відладочних операцій, коли ви хочете перевірити поди, не зачіпаючи живі екземпляри контейнерів.