Как упаковать приложение в docker

Обновлено: 19.09.2024

Цитируя разработчиков Docker, «контейнер — это стандартная единица программного обеспечения, в которую упаковано приложение со всеми необходимыми для его работы зависимостями — кодом приложения, средой запуска, системными инструментами, библиотеками и настройками».

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

На рынке существует немало решений, представляющих среды запуска контейнеров и оркестрации, таких как CoreOS rkt, LXC, OpenVZ, containerd, Apache Mesos и Docker Swarm. Однако более 4/5 контейнеров запускается в среде Docker, а для оркестрации более половины пользователей выбрали Kubernetes. Об этих системах мы и поговорим.

Чем полезны контейнеры

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

Техническим же специалистам контейнеры прежде всего полюбились за возможность упаковать приложение вместе с его средой запуска, решая тем самым проблему зависимостей в разных окружениях. Например, различие версий языковых библиотек на ноутбуке разработчика и в последующих окружениях рано или поздно приведёт к сбоям, и нужно будет как минимум потратить время на их анализ, а как максимум — решать проблему проникших в продакшен багов. Использование контейнеров устраняет проблему «А на моей машине все работало! ¯\_(ツ)_/¯».

Также контейнеры позволяют сократить время разработки приложения и упрощают управление им в продакшене благодаря лёгкости в настройке и изменении конфигурации, возможности версионировать её вместе с кодом приложения и удобным инструментам оркестрирования, позволяющим быстро масштабировать инфраструктуру. Кроме того, фактическое отсутствие привязки контейнеров к хостинговой платформе даёт огромную гибкость при выборе или смене провайдера — вы можете запускать их без принципиальных отличий в конечном результате на личном компьютере, bare metal серверах и в облачных сервисах.

Чем контейнеры отличаются от виртуальных машин

Наиболее частым вопросом при выборе среды запуска приложения является вопрос о различии между контейнерами и виртуальными машинами — двумя самыми популярными опциями на текущий момент. Между ними есть принципиальная разница. Контейнер, в сущности, является ограниченным внутри ОС пространством, использующим для доступа к аппаратным ресурсам ядро host-системы. ВМ представляет собой машину целиком со всеми необходимыми для её работы устройствами. Из этого образуются отличия, имеющие практическое значение:

  • Контейнеры требуют значительно меньше ресурсов для своей работы, что положительно сказывается на производительности и бюджете.
  • Контейнеры можно запускать только в той же операционной системе, что стоит на host-системе — то есть запустить Windows-контейнер на host-системе с Linux не получится (на персональных устройствах это ограничение обходится с помощью технологии виртуализации). Однако это не относится к разным дистрибутивам одной и той же ОС, например Ubuntu и Alpine Linux.
  • Контейнеры предоставляют меньшую степень изоляции, поскольку используют ядро host-системы, что потенциально создаёт бóльшие риски в эксплуатации при небрежном отношении к безопасности.

Основные принципы контейнеризации приложений

Для эффективной работы приложения в контейнерах недостаточно просто создать образ контейнера и запустить его. Нужно позаботиться о том, чтобы архитектура приложения и контейнера соответствовала базовым принципам контейнеризации, которые хорошо изложила компания RedHat.

1 контейнер — 1 сервис

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

Неизменность образа

Все изменения внутри контейнера должны вноситься на стадии сборки образа — соблюдение этого принципа страхует вас от утраты данных при уничтожении контейнера. Неизменность контейнера также даёт возможность выполнять параллельные задачи в CI/CD системах — например, можно одновременно запустить разного рода тестирования, ускоряя тем самым процесс разработки продукта.

Утилизируемость контейнеров

Этот принцип являет собой яркий пример современной концепции «Обращайся с инфраструктурой как со скотом, не как с питомцами». Это значит, что любой контейнер может быть в любой момент уничтожен и заменён на другой без остановки обслуживания. Конфигурация контейнера в виде его образа сущностно отделена от непосредственно выполняющего работу экземпляра контейнера, что позволяет «пускать под нож» экземпляры, когда потребуется — при сбое проверки состояния контейнера, масштабировании на понижение и т. д. Соответствие этому принципу означает, что выход контейнеров из строя не должен быть новостью для вашего приложения: ротация контейнеров должна стать одним из требований к разработке.

Отчётность

Контейнер должен иметь точки проверки состояния его готовности (readiness probe) и жизнеспособности (liveness probe), предоставлять логи для отслеживания состояния запущенного в нём приложения.

Управляемость

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

Самодостаточность

Образ с приложением должен обладать всеми необходимыми зависимостями для работы — библиотеками, конфигами и прочим. Сервисы же к этим зависимостям не относятся, иначе это противоречило бы принципу «1 контейнер — 1 сервис». Связность контейнеров, зависящих друг от друга, можно определить с помощью инструментов оркестрирования, о чём будет рассказано ниже.

Лимитирование ресурсов

К лучшим практикам эксплуатации контейнеров относится настройка ресурсных лимитов (CPU и RAM): следование этой практике позволяет сохранять внимательное отношение к экономии ресурсов и вовремя реагировать на их избыточное потребление.

Docker

Когда мы говорим о контейнерах в современных IT-системах, прежде всего мы подразумеваем Docker — open-source-технологию, благодаря своей популярности ставшую в IT синонимом слова «контейнер».

Основные сущности Docker

Dockerfile

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

Image

Готовая файловая система, сформированная по инструкциям из Dockerfile и служащая прообразом для запускаемых контейнеров.

Instance

Запущенный экземпляр образа, минимальная единица деплоя в Docker.

Volume

Подключаемая к контейнерам файловая система, не являющаяся их неотъемлемой частью и существующая независимо от образа. С помощью объектов Volume решается проблема сохранности данных, записанных в процессе работы контейнеров в локальной файловой системе после их уничтожения.

Registry

Репозиторий, используемый для хранения Docker-образов. Registry может быть как публичным, так и приватным, защищённым механизмом аутентификации.

Процесс разработки в среде Docker

Типичный процесс разработки в среде Docker выглядит следующим образом: разработчики устанавливают на свои машины Docker, загружают собранный заранее образ с установленной средой сборки и выполнения приложения, а затем запускают контейнер командой, которая также пробросит в него директорию с исходниками. Для установки Docker не требуется особого железа — он может быть установлен на вполне заурядной машине. Однако у него имеются ограничения по версиям ОС — Windows 7 64bit или выше для ПК с поддержкой Hyper-V, macOS Sierra 10.12 для устройств от Apple и версией ядра 3.10 для систем с Linux. Контейнеры Docker являются родной технологией для ОС Linux и запускаются на других с помощью виртуальных машин под её управлением.

Инструкции по установке Docker на разных платформах: Windows, Mac, Linux Ubuntu.

Чтобы запустить ваш первый контейнер на Docker, после его установки введите в командной строке docker run hello-world — эта команда загрузит образ hello-world с Docker hub’а (публично доступный Docker registry), создаст контейнер, используя этот образ, и выдаст приветственную фразу:

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

Оркестрирование контейнеров: Kubernetes

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

NetApp Kubernetes Service позволит создать cloud-agnostic кластер с уже реализованными механизмами деплоя и управления жизненным циклом приложения, автоматическим масштабированием инфраструктуры, интеграцией с сервисами хранилищ данных и многим другим, снизив затраты на конфигурацию и поддержку сложной инфраструктуры.

Основные сущности, которыми оперирует Kubernetes

Node (master и slave)

Узлы, из которых состоит кластер Kubernetes. Master-нода осуществляет контроль над кластером через планировщик и менеджер контроллеров, обеспечивает интерфейс взаимодействия с пользователями посредством API-сервера и содержит хранилище etcd, где находится конфигурация кластера, статусы его объектов и метаданные. Slave-нода предназначена исключительно для запуска контейнеров, для этого на ней установлены два сервиса Kubernetes — сетевой маршрутизатор и агент планировщика.

Namespace

Структурный объект, позволяющий разграничивать ресурсы кластера между пользователями и командами.

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

ReplicaSet

Объект, описывающий и контролирующий соответствие запущенного на кластере количества реплик Pod’ов. Установка количества реплик больше одной требуется для повышения отказоустойчивости и масштабирования приложения. Общепринято создавать ReplicaSet с помощью Deployment.

Deployment

Объект, декларативно описывающий Pod’ы, количество реплик и стратегию их замены при обновлении параметров.

StatefulSet

Действует по тому же принципу, что и ReplicaSet, однако дополнительно позволяет описывать и сохранять при перезапуске уникальный сетевой адрес Pod’ов или их дисковое хранилище.

DaemonSet

Объект, обеспечивающий контроль за тем, что на каждой ноде (или нескольких выбранных) будет запущено по экземпляру указанного Pod’а.

Job и CronJob

Объекты, запускающие соответственно однократно и регулярно по расписанию указанный Pod и отслеживающие результат завершения его работы.

Label и Selector

Метки, позволяющие маркировать ресурсы и тем самым упрощать групповые манипуляции, связанные с ними.

Service

Инструмент для публикации приложения в качестве сетевого сервиса, в том числе реализующий балансировку нагрузки между Pod’ами приложения.

Если сравнить объекты Docker и Kubernetes, то станет понятна разница в задачах, решаемых этими инструментами: можно сказать, что Docker управляет контейнерами, в то время как Kubernetes управляет самим Docker.

Управление конфигурацией (Configuration/Complexity Management)

Развитие IT-систем ведёт ко всё большему их усложнению, и это порождает проблемы управления — даже на небольшом количестве серверов или контейнеров ручное управление приложением превращает практически любое изменение конфигурации в трудовой подвиг, а на десятках или сотнях делает его абсолютно невозможным. К счастью, новые проблемы ведут и к новым решениям — в этом разделе мы расскажем о некоторых инструментах управления конфигурацией (configuration management) или, как ещё принято говорить, управления сложностью (complexity management). Они используются для установки, управления и обновления приложений Kubernetes: например, с их помощью можно описать приложение, состоящее из фронтенда, бэкенда и всех необходимых для их работы сервисов, таких как объекты Kubernetes, контейнеры с веб-серверами, базами данных, серверами очередей и т. д.

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

Kustomize

Благодаря популярности у пользователей и своей простоте, начиная с версии Kubernetes 1.14, Kustomize является встроенным инструментом управления конфигурацией. Для описания приложений использует чистый язык разметки YAML без возможности шаблонизации и использования параметров, что является одновременно его сильной и слабой сторонами, упрощая процесс настройки и вместе с тем сильно его ограничивая.

Ansible

Управляйте хранилищами данных в автоматизированном режиме с помощью модулей интеграции Ansible NetApp.

Jsonnet

Также как и Ansible, Jsonnet не является чем-то специфичным для Kubernetes, однако многие знакомы с ним именно благодаря K8s. Jsonnet описывает объекты с помощью расширенного JSON, включающего комментарии, текстовые блоки, параметры, переменные, условные включения и функции. Очень мощный и гибкий инструмент.

Пакетный менеджер приложений Kubernetes. Этот инструмент описывает приложения в виде декларативных диаграмм (charts), создающихся с помощью языка разметки YAML и шаблонов Golang. Helm обладает широкой базой готовых диаграмм, даёт возможность версионировать конфигурации и переключаться между версиями релизов, т. е. откатывать конфигурацию. Из всех приведенных здесь инструментов является наиболее функциональным в отношении управления приложениями Kubernetes и одновременно обладает наиболее сложным способом описания конфигурации из-за шаблонов Golang, весьма требователен к пользовательским навыкам.

Платформы для хостинга контейнеров

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

Своё железо (bare metal)

Этот подход можно назвать консервативным — выбрав его, вы покупаете или арендуете серверы, нанимаете специалистов и строите свой собственный кластер. Очевидные его плюсы — тонкая настройка, возможность полного контроля над инфраструктурой и, как следствие, превосходящая производительность с более высокой отдачей от бюджета в долгой перспективе. Из минусов можно отметить большие финансовые (в том числе капитальные) и временные затраты на конфигурацию и поддержку, а также зависимость от специалистов по её поддержке. Как правило, этот вариант выбирают компании, имеющие выверенные долгосрочные планы, уже обеспеченные солидным бюджетом.

Облачные решения (SaaS)

Крупные облачные провайдеры предоставляют своим клиентам сервисы для запуска контейнеров — готовые среды, обёрнутые удобным интерфейсом управления. Построенные по такому принципу решения называются Software as a Service (SaaS). Они не требуют никаких капитальных затрат, поскольку вся инфраструктура арендуется, а конфигурация создаётся в минимальном объёме, относящемуся исключительно к запускаемому приложению. Сами же кластеры настраиваются провайдером по указанному пользователем небольшому объему параметров. SaaS-решения — оптимальный вариант для стартап-компаний, небольших и развивающихся проектов. Самым большим минусом этого решения можно назвать повышенную в сравнении с bare metal стоимость при условии многолетнего использования.

Тремя наиболее популярными облачными платформами на сегодня являются Amazon Web Services, Microsoft Azure и Google Cloud. Все три провайдера имеют доступный в виде сервиса Kubernetes, и все три из них предлагают пробный период пользования сервисами, выдавая депозит на сумму 200–300 $. Чтобы оценить удобство и качество облачных решений и сравнить друг с другом их поставщиков, вам даже не придется тратить свои деньги.

Хотите обеспечить максимальную сохранность данных, создаваемых и используемых в контейнерах? NetApp Trident позволит легко интегрировать в вашу контейнерную инфраструктуру надежное и функциональное хранилище данных enterprise-уровня.

Заключение

Ещё недавно не смолкали дебаты на тему оправданности использования контейнеров в продакшене, то и дело были слышны обвинения в их ненадежности. Однако время не стоит на месте, индустрия оценила их перспективность, сделала свой выбор, и инвестиции в контейнерные решения потекли широкой рекой, с каждым днем делая решения на их базе всё удобнее и привлекательнее. На сегодняшний день примитивную настройку кластера и деплой приложений в него можно выполнить используя один лишь веб-интерфейс, предварительно прочитав несколько страниц документации — настолько это стало просто. А их низкая по сравнению с виртуальными машинами стоимость откусывает у ВМ всё большую долю рынка, забирая то, что не требует для своей работы специфики устройства ВМ. Безусловно, контейнеры зарекомендовали себя как жизне- и конкурентоспособное решение, сокращающее время вывода продукта на рынок, стоимость его разработки и эксплуатации.

докер

Что такое Docker и почему он полезен?

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

Это изображение будет одинаковым для всех в вашей команде, поэтому вы сможете мгновенно запускать свое приложение со всеми необходимыми зависимостями, управляемыми для вас. Это также исправляет классическую проблему «это не работает на моей машине», потому что образы Docker везде будут работать одинаково.

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

Конфигурация рабочего сервера с Docker.

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

Создать Dockerfile

Точка входа для сборки вашего контейнера называется Dockerfile. Создайте новый каталог проекта для размещения ваших файлов, затем создайте новый Dockerfile с простым именем Dockerfile без расширения:

Откройте этот файл в вашем любимом текстовом редакторе.

Вы, вероятно, не хотите начинать все с нуля, поэтому вы можете раскошелиться на существующее изображение из Docker Hubтакие как Ubuntu:

Обратите внимание, что даже если вы это сделаете, вам придется сделать это FROM scratch ,

В процессе сборки Docker создает модифицируемый «слой», который вы можете создавать поверх него. Вам разрешено копировать файлы и запускать команды, как если бы они выполнялись на компьютере, аналогично тому, как вы настраивали сервер вручную. В этом файле вы выполните все настройки сервера, по сути, автоматизируя процесс, который вы пройдете, если запустили пустой ящик Linux и получили указание запустить его в производство. Это может занять много времени.

Вы можете выполнить большинство этих команд из командной строки и настроить изображение вручную. Если вы хотите получить оболочку bash в контейнере, вы можете запустить:

И сохраните ваши изменения с:

Тем не менее, вы должны использовать это только для тестирования и делать все ваши фактические настройки в Dockerfile.

Команды Dockerfile

Мы пройдемся по большинству общих команд и объясним их использование и рекомендации по их применению. Для более расширенной справки, вы можете проконсультироваться этот шпаргалкаили обратитесь к «Лучшие практики для написания Dockerfiles» запись документов.

COPY Инструкция довольно проста: она позволяет вам заполнить ваш образ Docker данными и конфигурацией.

Например, если у вас есть папка в каталоге вашего проекта с именем /config/nginx/ это содержало ваш nginx.conf , sites-available/ и другие каталоги, вы можете скопировать это в конфигурационную папку nginx по умолчанию в вашем контейнере:

Таким образом, вы можете хранить все ваши конфигурационные файлы nginx в том же каталоге проекта, что и все остальное, то есть они будут контролироваться версией с git наряду с остальной частью вашего кода.

БЕГАТЬ

RUN Инструкция запускает команду в вашем контейнере и сохраняет изменения в файловой системе контейнера.

каждый команда run создает новый «слой»так что вы, вероятно, захотите выполнить сложную настройку внутри скрипта установки. Вам нужно скопировать этот скрипт на изображение, а затем запустить его:

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

Если вы хотите сократить время сборки контейнера, вы можете создать базовый контейнер со всеми уже установленными программами, а затем собрать основной контейнер. FROM этот контейнер, хотя вам нужно будет управлять зависимостями и конфигурацией отдельно.

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

Только последний CMD Команда вступает в силу. Вы можете переопределить CMD при запуске со следующим синтаксисом:

ВХОДНАЯ ТОЧКА

ENTRYPOINT это специальная версия CMD что позволяет контейнеру работать так как исполняемый файл Например, если все, что делает контейнер, запускается nginx Вы можете указать nginx как ENTRYPOINT :

А затем запустите этот контейнер в командной строке, передав аргументы в качестве аргументов точке входа:

ПОДВЕРГАТЬ

Expose помечает определенные порты контейнера как открытые для работающего хоста. Например, если вы используете веб-сервер, вы, вероятно, захотите

Это не связывает порт автоматически, но сообщает среде выполнения Docker, что порт доступен. Чтобы на самом деле связать это, вы хотите использовать -P флаг (в верхнем регистре) без аргументов для привязки всех открытых портов.

Запуск вашего приложения

Во-первых, вам нужно создать свой имидж:

Вы можете запустить свой контейнер с docker run :

Однако само по себе это не слишком полезно, потому что с ним невозможно взаимодействовать. Для этого вам необходимо привязать порты с помощью флага -p, например так:

« ro ”Flag гарантирует, что это соединение доступно только для чтения, поэтому контейнер Docker не может вносить какие-либо изменения в хост-ОС. Это также можно использовать для предоставления контейнерам Docker доступа к постоянным данным, хранящимся в хост-ОС.

У меня есть приложение, написанное на NodeJS. Как я могу упаковать его в образ Docker, чтобы запускать как контейнер?

vk39672097 Создано: 2017-12-08 20:52:20.959622 Обновлено: 2017-12-08 20:52:20.959622

Docker - система управления контейнерами в POSIX-совместимых операционных системах (на данный момент поддерживается Linux). Особенностью Docker является возможность упаковать приложение со всем необходимым окружением таким образом, чтобы запускать его на другой системе без долгих и сложных процедур установки зависимостей или сборки из исходников. Запакованное приложение, готовое к развёртыванию, называется "образом". Образы Docker основываются на "шаблонах" - предварительно настроенных рабочих окружениях. Можно рассматривать это как дистрибутивы операционной системы, хотя это и не совсем так. Кроме того, изучив документацию на Docker, вы сможете создать собственный шаблон. Преимуществом такого подхода является то, что образ вашего приложения будет содержать только само приложение, а необходимое для него окружение будет скачиваться автоматически из репозитория шаблонов. Docker слегка напоминает chroot или bsd jail, но работает иначе.

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

Предположим, что у вас есть приложение на NodeJS, которое вы хотите упаковать в контейнер. Предположим, что файл, который запускает ваше приложение называется server.js, а для работы приложение слушает порт 8000. В качестве шаблона мы будем использовать "node:carbon". Для контейнеризации приложения вам нужно создать в каталоге, где расположены файлы вашего приложения, файл "Dockerfile", в котором будут описаны параметры подготовки образа:

Содержимое файла может быть примерно таким:

Чтобы исключить ненужные файлы из образа, вы можете перечислить их имена в файле ".dockerignore". Допускается использование маски (*.log).

Сборка образа осуществляется следующей командой:

Где username - это условное имя автора образа, а node-web-app - имя образа. После сборки образ появляется в локальном хранилище образов. Вы можете увидеть список имеющихся образов, введя команду "docker images".

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

В этом примере создаётся контейнер из образа "username/node-web-app" и сразу запускается. Порт приложения 8000 доступен на локальной машине (localhost) и для того, чтобы он был доступен "снаружи", он "пробрасывается" на порт 49160. Можно выбрать любой свободный порт, кроме того возможно пробросить порт приложения "как есть", указав опцию "-p 8000:8000".

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

Управление контейнером можно осуществлять различными командами, указывая ID этого контейнера:

$ docker pause ecce33b30ebf - приостановить работу контейнера с ID ecce33b30ebf
$ docker resume ecce33b30ebf - возобновить работу контейнера с ID ecce33b30ebf
$ docker stop ecce33b30ebf - остановить контейнер c ID ecce33b30ebf
$ docker rm ecce33b30ebf - удалить контейнер (при этом удаляются все данные, созданные приложением внутри контейнера)

В этом учебнике рассмотрены следующие задачи.

Предварительные требования

Установите следующие необходимые компоненты:

Дерево папок будет выглядеть следующим образом:

Команда dotnet new создает папку с именем App и консольное приложение Hello World. Измените каталоги и перейдите в папку App из сеанса терминала. Используйте команду dotnet run , чтобы запустить приложение. Приложение запустится и выведет Hello World! под командой:

Шаблон по умолчанию создает приложение, которое выводит текст в терминал и затем завершает работу. В этом руководстве описано, как использовать приложение с бесконечным циклом выполнения. Откройте файл Program.cs в текстовом редакторе.

Если вы используете Visual Studio Code, в предыдущем сеансе терминала введите следующую команду:

Откроется папка App, которая содержит проект в Visual Studio Code.

Замените его кодом, который считает числа каждую секунду:

Сохраните файл и протестируйте программу еще раз с помощью команды dotnet run . Помните, что это приложение выполняется бесконечно. Остановите его с помощью команды отмены, нажав клавиши CTRL+C . Ниже представлен пример таких выходных данных:

Если приложению передать число в командной строке, оно досчитает до такого числа и завершит работу. Введите команду dotnet run -- 5 , чтобы приложение досчитало до пяти.

Все параметры после -- не передаются команде dotnet run , а передаются в приложение.

Эта команда компилирует приложение и помещает результат в папку publish. Путь к папке publish из рабочей папки должен быть таким: .\App\bin\Release\net5.0\publish\

Получите список файлов для папки publish из папки App, чтобы убедиться, что файл NetCore.Docker.dll создан.

Воспользуйтесь командой ls , чтобы получить список каталога и проверить, был ли создан файл NetCore.Docker.dll.

Создание файла Dockerfile

Файл Dockerfile используется командой docker build для создания образа контейнера. Это текстовый файл с именем Dockerfile, не имеющий расширения.

Сохраните файл Dockerfile. Структура каталогов рабочей папки должна выглядеть следующим образом. Некоторые файлы и папки на более глубоком уровне были опущены для экономии места в статье:

В терминале выполните следующую команду:

Docker обработает все строки файла Dockerfile. Символ . в команде docker build используется, чтобы выполнить с помощью Docker поиск файла Dockerfile в текущей папке. Эта команда создает образ и локальный репозиторий с именем counter-image, который указывает на такой образ. После завершения работы этой команды выполните команду docker images , чтобы просмотреть список установленных образов:

Обратите внимание, что два образа имеют одинаковое значение IMAGE ID. Это связано с тем, что единственная команда в файле Dockerfile создает новый образ на основе существующего. Добавим в файл Dockerfile еще три команды. Каждая команда (или инструкция)создает новый уровень образа —, а последняя команда представляет получившуюся точку входа в репозиторий counter-image.

Команда COPY предписывает Docker скопировать указанную папку на вашем компьютере в папку в контейнере. В этом примере папка publish копируется в папку с именем App в контейнере.

Команда WORKDIR изменяет текущий каталог в контейнере на App.

Следующая команда ENTRYPOINT используется, чтобы настроить с помощью Docker контейнер для запуска в качестве исполняемого файла. При запуске контейнера выполняется команда ENTRYPOINT . После выполнения команды контейнер автоматически остановится.

Для повышения безопасности вы можете отказаться от конвейера диагностики. Такой отказ позволяет контейнеру выполняться в режиме только для чтения. Для этого укажите переменную среды DOTNET_EnableDiagnostics как 0 (непосредственно перед шагом ENTRYPOINT ).

В окне терминала выполните команду docker build -t counter-image -f Dockerfile . , а после ее выполнения — команду docker images .

Каждая команда в файле Dockerfile создает уровень и экземпляр IMAGE ID. Последний экземпляр IMAGE ID (ваш идентификатор будет отличаться) имеет значение cd11c3df9b19. Теперь вы создадите контейнер на основе этого образа.

Создание контейнера

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

Команда docker create выше создает контейнер на основе образа counter-image. В выходных данных этой команды присутствует CONTAINER ID (ваш идентификатор будет отличаться) созданного контейнера. Чтобы просмотреть список всех контейнеров, воспользуйтесь командой docker ps -a :

Управление контейнером

Контейнер был создан с определенным именем core-counter . Для управления контейнером используется это имя. В следующем примере используется команда docker start для запуска контейнера, а затем — команда docker ps для отображения только запущенных контейнеров:

Аналогично, команда docker stop останавливает контейнер. В следующем примере используется команда docker stop для остановки контейнера, а затем — команда docker ps для подтверждения того, что контейнеры не запущены:

Подключение к контейнеру

После запуска контейнера вы можете подключиться к нему, чтобы просмотреть выходные данные. С помощью команд docker start и docker attach запустите контейнер и просмотрите поток вывода. В этом примере команда, вызываемая нажатием клавиш CTRL+C , используется для отключения от запущенного контейнера. Нажатие клавиш завершает процесс в контейнере, если не указано иное, что приведет к остановке контейнера. Параметр --sig-proxy=false гарантирует, что команда, вызываемая нажатием клавиш CTRL+C , не остановит процесс в контейнере.

После отключения от контейнера снова подключитесь к нему, чтобы убедиться в том, что он продолжает работать и считать числа.

Удаление контейнера

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

В примере ниже выводится список всех контейнеров, а затем используется команда docker rm для удаления контейнера. После этого выполняется повторная проверка наличия запущенных контейнеров.

Однократный запуск

Docker предоставляет единую команду docker run для создания и запуска контейнера. Она исключает необходимость в поочередном выполнении команд docker create и docker start . Вы также можете настроить ее для автоматического удаления контейнера при его остановке. Например, команда docker run -it --rm выполняет две операции. Сначала она автоматически подключается к контейнеру с помощью текущего терминала, а потом, после завершения работы контейнера, удаляет его:

Во время выполнения docker run -it команда, вызываемая нажатием клавиш CTRL+C , остановит процесс, запущенный в контейнере. А это, в свою очередь, приведет к остановке контейнера. Так как в команде указан параметр --rm , контейнер автоматически удалится после остановки процесса. Убедитесь, что он больше не существует:

Изменение команды ENTRYPOINT

Команда docker run также позволяет изменить команду ENTRYPOINT из файла Dockerfile для запуска другой программы, но только для соответствующего контейнера. Например, воспользуйтесь указанной ниже командой, чтобы запустить bash или cmd.exe . При необходимости измените команду.

В этом примере команда ENTRYPOINT изменена на cmd.exe . Нажав клавиши CTRL+C , вы можете завершить процесс и остановить контейнер.

В этом примере команда ENTRYPOINT изменена на bash . Команда exit позволяет завершить процесс и остановить контейнер.

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

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

Очистка ресурсов

В этом учебнике описано, как создать контейнеры и образы. При желании эти ресурсы можно удалить. Ниже представлены команды, которые позволяют сделать следующее:

Вывести список всех контейнеров.

Остановить запущенные контейнеры по имени.

С помощью команды docker images просмотрите список установленных образов.

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

Читайте также: