Как войти в запущенный Docker-контейнер и почему так делать не надо

Вы когда-нибудь были на собеседовании на должность младшего разработчика, где от вас ожидали, что вы знаете, как работает Docker? Сегодня интервьюеры ожидают, что вы хорошо знаете восемь, десять или даже более технологий. Это сумасшествие. Скорее всего, вы не изучали Docker в университете. Если у вас есть знания в этой области, вы отличаетесь от других людей.

Введение

Думаю, не нужно каких-то подробных пояснений на тему того, что такое Докер и зачем он нужен. Сейчас этот продукт у всех на слуху. В частности, он используется по дефолту в популярном кластерном продукте по автоматическому развертыванию и управлению контейнерами — Kubernetes. По сути он стал стандартом отрасли, хотя поддерживает работу не только на базе docker, но по факту в основном используют его. Я это все к тому, что docker с нами надолго 🙂

Пару тройку лет назад считалось, что docker лучше всего разворачивать на Ubuntu. С Centos были некоторые проблемы, но где-то в середине развития 7-й ветки они все были решены. Подробности я уже не помню, но по факту сейчас нет принципиальной разницы. Я запускаю контейнеры как на ubuntu, так и на centos. Обычно разработчики просят убунту, так как она им привычна. Лично я сам предпочитаю Centos. Там еще пока нет рекламы в syslog.

С установкой Docker на Centos 7 нет никаких проблем. С 8-й версией есть нюансы. Расскажу обо всем по порядку. Если у вас еще нет готовой системы, то вот мои статьи по теме — установка и настройка centos.

О вреде старых привычек

Часто вижу «оригинальные» подходы а ля «запущу ка я supervisord как entry point, а в нём подниму все остальные процессы». Спорить не буду – такой финт ушами пройдёт, но он возникает в основном от того, что лень разбираться с Docker, что повлечёт весьма странное поведение системы.

Используйте стандартные средства, не скупитесь на контейнеры: один контейнер – один небольшой простой процесс.

И если вам нужно перезапускать упавшие сервисы (некоторые пеняют на это) – используйте политики перезапуска Docker.

Что такое Docker

О том, как появился Docker:

Docker — это программное обеспечение, которое начинало с того, что зародилось в одной компании, как внутренний проект platform-as-a-service в компании dotCloud.

Читайте также:  Haiku: Знакомимся с экзотической операционной системой-преемницей BeOS

В процессе развития Докера, он вырос из масштабов внутреннего проекта, стал доступен для широких масс, и затмил своей популярностью своего родителя dotCloud, из-за чего было принято решение создать новую отдельную компанию под названием Docker Incorporated. Направление новосозданной компании было только в разработке Докера, и развитию его экосистемы.

На сайте доккера можно найти статью, в которой рассказывается, что такое Docker. Из их слов — это стандартизированное пакетное программное обеспечение, для разработки и развёртывания проектов.

Но, что это на самом деле значит?

Давайте на секунду забудем про Докер, и вспомним про такую ностальгическую штуку, как GameBoy Color:

Если вы помните, игры для этой приставки поставлялись в виде картриджей:

И я уверен в том, что производители видео игр пользуются успехом из-за своей простоты:

  1. Когда ты хочешь поиграть, ты просто вставляешь картридж в приставку, и игра сразу же работает.
  2. Ты можешь поделиться своей игрой с друзьями, передав всего лишь картридж, который они вставят в приставку, и сразу же смогут играть.

Docker следует похожему принципу — позволяет запускать своё ПО настолько просто, что это соизмеримо с вставкой картриджа и нажатием кнопки ON на приставке. Это основная суть, почему Docker настолько полезен — теперь кто угодно, у кого установлен Docker может запустить приложение, написанное с запуском под Docker, выполнив для этого всего несколько команд.

Раньше, вы, создавая приложения, к примеру на PHP, устанавливали локально PHP, MySql, возможно, NodeJs, при этом устанавливая зависимости в виде нужных расширений и библиотек. И, в случае передачи вашего скрипта какому-то знакомому, ему требовалось настраивать аналогичное окружение, аналогичных версий, иметь аналогичные расширения и конфигурацию, чтобы успешно запустить ваше приложение. Сейчас же, при использовании Докера, такой проблемы не возникнет впринципе. Теперь вам достаточно иметь установленную программу Docker, которая по одной вашей команде установит окружение, описанное для запуска вашего приложения.

Какое программное обеспечение можно запустить с помощью докера? В техническом плане, Docker чем-то похож на виртуальную машину:

Докер — это движок, который запускает виртуальную операционную систему, имеющую чрезвычайно маленький вес (в отличие от Vagrant-а, который создаёт полноценную виртуальную ОС, Докер, имеет особые образы ПО, запускающиеся в виртуальной среде, не создавая полную копию ОС).

Читайте также:  Защитить Wi-Fi, как повысить безопасность беспроводной сети?

Docker позволяет запустить ОС Linux в изолированной среде очень быстро, в течение нескольких минут.

Технология контейнеризации Docker

Хотя Docker начался как проект с открытым кодом для того, чтобы строить специализированную LXC, он позже превратился в собственную контейнерную среду исполнения. Docker — это инструмент Linux, который эффективно создает, отправляет и запускает контейнеры.

Контейнеры Docker и LXC — легковесные механизмы виртуализации в пользовательском пространстве, которые применяют контрольные группы и пространства имен, чтобы управлять изолированием ресурсов. Но между Docker и LXC есть несколько фундаментальных отличий — рассмотрим их.

Единственный процесс vs множество процессов

Docker ограничивает контейнеры, заставляя их работать как единый процесс. Если ваша среда приложения состоит из X одновременных процессов, Docker запустит X контейнеров, каждый со своим процессом. В отличие от Docker, LXC контейнеры могут запускать множество процессов.

Чтобы запустить простое многоуровневое веб-приложение в Docker, вам понадобится PHP контейнер, Nginx контейнер (веб-сервер), MySQL контейнер (для процесса базы данных) и несколько контейнеров данных для того, чтобы хранить таблицы баз данных и другую информацию приложения.

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

У однопроцессных контейнеров также есть ограничения. Например, вы не можете запускать агенты, скрипты регистрации или автоматически запускаемые SSH-процессы внутри контейнера. Также нелегко незначительно обновлять однопроцессный контейнер на уровне приложения. Вам придется запускать новый обновленный контейнер.

Бесструктурность vs структурность

Контейнеры Docker сделаны так, чтобы быть более бесструктурными, чем LXC.

Во-первых, Docker не поддерживает внешнее хранилище. Docker обходит это тем, что позволяет вам подключать хранилище хоста в качестве тома Docker из ваших контейнеров. Так как тома подключаются, они не считаются частью среды контейнера.

Во-вторых, контейнеры Docker состоят из слоев в режиме чтения. Это значит, что как только создается образ контейнера, он не меняется. Во время выполнения программы, если процесс в контейнере меняет свое внутреннее состояние, создается разница между внутренним состоянием и образом, из которого был создан контейнер.

Если вы выполняете команду docker commit, разница между двумя версиями становится частью нового образа — не оригинального, а нового, из которого вы можете создавать новые контейнеры. Если вы удалите контейнер, разница версий исчезнет.

Бесструктурный контейнер — интересная сущность. Вы можете обновлять контейнер, но серия обновлений создаст серию новых образов контейнеров, поэтому в системе так легко откатываться.

Читайте также:  Apple iPhone 11 vs Apple iPhone 12 - Какой выбрать в 2021 году?

Портативность

Пожалуй, это самое важное преимущество Docker над LXC. Docker больше отделяет сетевые ресурсы, хранилище и детали ОС, чем LXC. С Docker приложение действительно не зависит от настроек этих низкоуровневых ресурсов. Когда вы перемещаете контейнер Docker от одного хоста Docker к другой машине с Docker, Docker гарантирует, что среда для приложения останется неизменной.

Прямое преимущество этого подхода — это то, что Docker помогает программистам создавать локальные среды разработки, которые выглядят как продакшн-сервер. Когда программист заканчивает писать и начинает тестировать код, он может обернуть его в контейнер, опубликовать напрямую на сервере или в приватном облаке, и он сразу будет работать, так как это одна и та же среда.

СLXC программист может запустить что-то на своей машине, но обнаружить, что код работает неправильно при разворачивании на сервере. Среда сервера будет другой, и программисту придется потратить много времени, чтобы починить эту разницу и исправить проблему. С Docker этих проблем нет.

Мораль.

В общем, настроить взаимодействие контейнеров между собой по TCP/HTTP — не проблема. Причём, я взял только самые базовые инструменты. А ведь есть еще разные типы сетей, можно создавать собственные сетевые мосты и даже overlay networks, которые объединяют сети между несколькими машинами в одну так, что контейнерам кажется, будто они все находятся на одном хосте. Но это — повод для других статей.

Поделиться ссылкой:

  • Нажмите здесь, чтобы поделиться контентом на Facebook. (Открывается в новом окне)
  • Нажмите, чтобы поделиться на Twitter (Открывается в новом окне)
  • Нажмите, чтобы поделиться на LinkedIn (Открывается в новом окне)
  • Нажмите, чтобы поделиться записями на Pocket (Открывается в новом окне)

Заключение

Привязка портов в Docker  —  важная концепция, которую необходимо понимать, если вы работаете с контейнерами. Поначалу она может сбить с толку и вызвать вопросы о том, зачем вам нужно настраивать входящие соединения. Docker предоставляет всю необходимую документацию. Однако некоторые концепции Docker нам, разработчикам, понять труднее, чем другие.

Я надеюсь, эта статья прояснила для вас привязку портов.

Спасибо за чтение!

  • Список важнейших команд в Docker
  • Сканируем образы Docker на уязвимости
  • Docker для разработки Go с горячей перезагрузкой

Перевод статьи Dieter Jordens: How Does Docker Port Binding Work?