What Is Docker and How Does It Work? – Docker Explained
If you have an application or service and want it to work on different systems like VPSs or dedicated machines without any issues, consider using containers. One of the most popular container platforms is Docker, although not everyone knows what it is and how it works.
In this tutorial, we’ll explain what Docker is, how it works, and how it differs from virtual machines (VMs) and systems, like Kubernetes and Jenkins. We’ll also go through the pros and cons of Docker and list its most popular use cases.
What Is Docker?
Docker is open-source software used to deploy applications inside virtual containers. Containerization allows various applications to work within different complex environments. For example, Docker allows running the WordPress content management system on Windows, Linux, and macOS systems without any issues.
Docker vs Virtual Machine
While Docker and virtual machines serve a similar purpose, their performance, OS support, and portability differ significantly.
The main difference is that Docker containers share the host’s operating system, while virtual machines also have a guest operating system running on top of the host system. This method of operation affects the performance, hardware needs, and OS support. Check the table below for an in-depth comparison.
Docker vs Kubernetes and Jenkins
In the following section, we’ll discuss how Docker stacks up against Kubernetes and Jenkins and explain the differences between them.
Comparing Kubernetes With Docker
While Docker is a platform for building and running containers, Kubernetes is an open-source container orchestration system. These two systems cannot be compared directly – Docker is responsible for creating containers, and Kubernetes manages them at a great scale.
However, Docker offers its own orchestration system called Docker Swarm. Here’s a table with a comparison of Kubernetes and Docker Swarm:
The Docker architecture consists of four main components along with Docker containers which we’ve covered earlier.
- Docker client – the main component to create, manage, and run containerized applications. The Docker client is the primary method of controlling the Docker server via a CLI like Command Prompt (Windows) or Terminal (macOS, Linux).
- Docker server – also known as the Docker daemon. It waits for REST API requests made by the Docker client and manages images and containers.
- Docker images – instruct the Docker server with the requirements on how to create a Docker container. Images can be downloaded from websites like Docker Hub. Creating a custom image is also possible – to do it, users need to create a Dockerfile and pass it to the server. It’s worth noting that Docker doesn’t clear any unused images, so users need to delete image data themselves before there’s too much of it.
- Docker registry – an open-source server-side application used to host and distribute Docker images. The registry is extra useful to store images locally and maintain complete control over them. Alternatively, users can access the aforementioned Docker Hub – the world’s largest repository of Docker images.
Expert Tip
Using Docker on Hostinger is as easy as getting a VPS and installing it on your Linux distribution like Ubuntu or CentOS.
Site Availability Engineer
The Pros and Cons of Docker
While Docker has many advantages, it does fall short in some respects. In this section, we’ll go over the main pros and cons of the software.
Docker Advantages
- Portability – the main appeal of Docker is its portability. It allows users to make or install a complex application on a machine and be sure that it will work on it. Docker containers include everything that an application needs with little to no input from the user.
- Automation – with the help of cron jobs and Docker containers, users can automate their work easily. Automation helps developers avoid tedious and repetitive tasks as well as save time.
- Community – Docker has a dedicated Slack channel, community forum, and thousands of contributors on developer websites like StackOverflow. What’s more, there are over 9 million container images hosted on Docker Hub.
Docker Drawbacks
- Speed – even though running an app via a Docker container is faster than doing so on a virtual machine, it is still considerably slower than running applications natively on a physical server.
- Ease of use – Docker is not meant to run applications that require a graphical user interface (GUI). This means that users need to be familiar with the command line and perform all actions there. The steep learning curve, OS-specific caveats, and frequent updates make mastering Docker challenging. Even if you feel that you know Docker inside out, there is still orchestration to consider, adding another level of complexity.
- Security – Docker runs on the host’s operating system. This means that any malicious software hidden in containers may find its way to the host machine.
Expert Tip
Don’t download Docker images from unknown sources as they could contain malware.
Head of Cyber Security
Docker Use Cases
Docker has a wide range of applications. In this section, we’ll go over three common Docker use cases and explain how you can benefit from it.
To Try New Software
With Docker, you can try out new software without installing it manually. Docker is also useful if you need to have a piece of software ready quickly. For example, setting up a MySQL server is a long and tedious process. With Docker, it only takes one command via the CLI to do it.
To Learn About the CLI
Even though Docker can run on all types of machines, it was primarily designed for Linux. Therefore, we recommend setting it up on a Linux-based system. It will provide you with an excellent opportunity to learn more about system administration, command-line interface, and scripting.
To Reduce Incident Risk
In case of hardware failure, users can quickly revert any changes if they have a Docker image ready. They only need to import the image backup to a new machine, and Docker will do the rest. Docker image backups are also beneficial when developers want to roll back to a previous version of specific software due to bugs or incompatibility.
Conclusion
Developing an application is a challenge, and making sure that it works in every environment is an even bigger milestone. Docker containers solve this issue by giving developers a way to port software easily.
In this article, we’ve gone over the differences between virtual machines and Docker, explained how it works, and compared it to popular systems like Kubernetes and Jenkins. We’ve also discussed Docker’s pros and cons and covered some of its use cases.
We hope that this article has helped you to learn more about Docker. If you have any questions or suggestions, let us know in the comments section below.
Check Out More Docker Related Tutorials
What Is Docker FAQ
Docker vs Docker Engine
Docker is the name of the platform, while Docker Engine is an open-source container technology that consists of a Docker server (daemon), client, and APIs. People might also confuse the software with the Docker client because it’s also called docker, only in lowercase letters.
Docker Community Edition vs Enterprise Edition
Docker CE and EE are 2 different versions of Docker. The former is free, and the latter a premium service. Both offer the same core features and functionality but work on different OSs. If you’re not creating software at a great scale, we recommend opting for the CE.
Is Docker Hard to Learn?
It can take a while to master Docker, although launching your first container won’t take long. To get started, Docker provides its users with an easy-to-use Docker Desktop application and offers comprehensive documentation for beginners and intermediate users.
Ignas takes great satisfaction in helping people tackle even the most complex technical issues. His current goal is to write easy-to-follow articles so that these issues will not happen at all. During his free time, Ignas likes to play video games and fix up things around his house.
Docker: что это и как используется в разработке
На дворе закат 2022-го, и большая часть IT-индустрии только и делает, что работает с контейнерами. Откуда они появились, как добились глобального признания и при чём тут Docker? Расскажет разработчица в команде инфраструктуры Яндекса, действующий автор курса «DevOps для эксплуатации и разработки» Дарья Меленцова.
Из этой статьи вы узнаете:
- что такое Docker и его главные возможности;
- почему Docker стал де-факто современной индустрией программного обеспечения;
- как создавать и развёртывать Docker-контейнеры.
Начнём с основ
Что такое Docker
Разработчики Docker дают ему такое определение: «Docker helps developers bring their ideas to life by conquering the complexity of app development», что можно перевести как «Docker помогает разработчикам воплощать свои идеи в жизнь, преодолевая сложность разработки приложений». Звучит многообещающе, не правда ли?
Если конкретнее, Docker — это инструмент, с помощью которого разработчики, системные администраторы и все желающие могут легко запускать разные приложения в изолированных контейнерах на одном сервере.
Контейнеры не знают, что рядом развёрнуты другие контейнеры с приложениями, они полностью изолированы друг от друга. В каждом контейнере можно настроить окружение, необходимое именно для этого приложения.
В отличие от виртуальных машин, контейнеры не требуют серьёзных мощностей, что позволяет более эффективно использовать ресурсы сервера.
Что такое контейнер
Ещё недавно приложения разворачивали на физических серверах, поэтому возникали сложности, когда это нужно было сделать быстро.
- Все серверы настраивались вручную (или почти вручную). Подключение сервера, установка ОС, настройка правильного окружения, сети и других параметров занимали много времени.
- Были проблемы с гибким масштабированием. Представьте, что у вас на сервере развёрнут интернет-магазин. В обычное время приложение справляется с потоком пользователей, но в канун Нового года аудитория возрастает, ведь все хотят закупиться подарками. И тут оказывается, что интернет-магазин не справляется с нагрузкой и надо либо добавить ресурсы на сервер, либо поднять ещё несколько экземпляров сервиса. Да, мы можем заранее подумать о празднике и предвидеть наплыв покупателей, но что делать с теми ресурсами, которые будут простаивать после Нового года?
- Требовалось эффективнее использовать ресурсы. Если на большом и мощном физическом сервере разместить какое-нибудь скромное приложение, которому нужно от силы 20% всех мощностей, что делать с остальным запасом? Может быть, подселить к этому приложению ещё одно или несколько? Казалось бы, вариант, пока вы не узнаете, что для работы приложений нужны разные версии одного и того же пакета.
Программисты — умные и творческие люди, поэтому они начали думать, как можно избежать этих сложностей. Так родилась виртуализация!
Виртуализация — технология, которая позволяет создавать виртуальное представление ресурсов отдельно от аппаратных. Например, под операционную систему (далее — ОС) можно отдать не весь диск, а только часть, создав его виртуальное представление.
Есть много разных видов виртуализации, и один из них — аппаратная виртуализация.
Идея в том, чтобы взять сервер и разделить его на кусочки. Допустим, у вас есть сервер, на котором установлена хостовая ОС, и внутри неё запускаются виртуальные машины (далее — ВМ) с гостевыми ОС. Между хостовой ОС и ВМ есть прослойка — гипервизор, который управляет разделением ресурсов, а также изоляцией гостевых ОС.
У аппаратной виртуализации есть большой плюс: внутри ВМ можно запускать абсолютно разные ОС, отличные от хостовой, но ценой дополнительных расходов на гипервизор.
Казалось бы, проблемы с утилизацией ресурсов и изоляцией приложений решены, но как быть с установкой ОС и настройкой окружения: всё ещё делаем вручную и на каждой ВМ? Да и зачем платить за гипервизор, если не нужно держать на одном сервере Windows и Linux — достаточно ядра хостовой ОС?
На этот случай придумали контейнерную виртуализацию. При таком типе виртуализация происходит на уровне ОС: есть хостовая ОС и специальные механизмы, которые позволяют создавать изолированные контейнеры. В роли гипервизора выступает хостовая ОС — она отвечает за разделение ресурсов между контейнерами и обеспечивает их изолированность.
Контейнер — это изолированный процесс, который использует основное ядро ОС. Работа с контейнерами помогает решить следующие проблемы:
- утилизации ресурсов (на одном сервере можно запустить несколько контейнеров);
- изоляции приложений;
- установки ОС (по сути, мы используем хостовую ОС);
- настройки окружения для приложения (можно один раз настроить окружение и быстро клонировать его между контейнерами).
Почему контейнеры и Docker
Как мы уже знаем, контейнер — это изолированный процесс, который работает со своим кусочком файловой системы, памятью, ядром и другими ресурсами. При этом он думает, что все ресурсы принадлежат только ему.
Все механизмы для создания контейнеров заложены в ядро Linux, но на практике обычно используют готовые среды выполнения вроде Docker, containerd и cri-o, которые помогают автоматизировать развёртывание и управление контейнерами.
- Короткий жизненный цикл. Любой контейнер можно остановить, перезапустить или удалить. Данные, которые содержатся в контейнере, тоже пропадут. Поэтому при проектировании приложений, которые подходят для контейнеризации, используют правило: не хранить важные данные в контейнере. Такой подход проектирования называют Stateless.
- Контейнеры маленькие и лёгкие, их объём измеряется в мегабайтах. Так получается, потому что в контейнер упаковывают лишь те процессы и зависимости ОС, которые необходимы для приложения. Легковесные контейнеры занимают мало места на диске и быстро запускаются.
- Контейнеризация обеспечивает изоляцию процессов. Приложения, которые работают внутри контейнера, не имеют доступа к основной ОС.
- Благодаря контейнерам можно перейти с монолита на микросервиснуюархитектуру.
- Не нужно тратиться на гипервизор, и можно запустить больше контейнеров, чем ВМ на одних и тех же ресурсах.
- Контейнеры хранятся в специальных репозиториях, и каждый контейнер содержит всё необходимое окружение для запуска приложения, благодаря чему можно автоматизировать развёртывание приложения на разных хостах.
Теперь обсудим, какие преимущества даёт Docker.
- Сообщество. Существует огромное хранилище контейнеров с открытым исходным кодом, и вы можете скачать готовый образ для конкретной задачи.
- Гибкость. Docker позволяет создавать базовые шаблоны контейнеров (image) и использовать их повторно на различных хостах. Docker-контейнеры можно легко запустить как на локальном устройстве, так и в любой облачной инфраструктуре.
- Скорость развёртывания. Шаблон контейнера содержит всё необходимое окружение и настройки для работы приложения, нам не нужно настраивать всё это каждый раз с нуля.
- Нет проблемы с зависимостями и версиями пакетов. Docker позволяет упаковывать различные языки программирования и стек технологий в контейнер, чем избавляет от проблемы несовместимости разных библиотек и технологий в рамках одного хоста.
Благодаря каким механизмам работает Docker
Как вы уже знаете, в ядре Linux из коробки есть все необходимые механизмы для создания контейнеров:
- capabilities — позволяет выдать процессу часть расширенных прав, которые доступны только root . Например, разрешить удалять чужие файлы, завершать другие процессы (команда kill ) или изменять атрибуты у файлов (команда chown );
- namespace — это абстракция в Linux, с помощью которой можно создавать своё изолированное окружение в ОС. То есть такую коробочку, в которой свои пользователи, своя сеть, свои процессы и всё остальное. При этом изменения в namespace видны только членам этого namespace. Есть шесть типов пространств имён (namespaces): IPC, Network, Mount, PID, User, UTS.
- Network namespace отвечает за ресурсы, связанные с сетью. У каждого namespace будут свои сетевые интерфейсы, свои таблицы маршрутизации.
- User namespace специализируется на пользователях и группах в рамках namespace.
- PID namespace заведует набором ID процессов. Первый процесс, созданный в новом namespace, имеет PID = 1 , а дочерним процессам назначаются следующие PID.
- cgroup объединяет несколько процессов в группу и управляет ресурсами для этой группы.
Традиционно лимиты в Linux можно задавать для одного процесса, и это неудобно: вы могли задать какому-то процессу не больше n мегабайт памяти, но как указывать лимиты на приложение, если у него больше одного процесса? Поэтому появились cgroups , позволяющие объединить процессы в группу и навесить на неё лимиты.
Давайте разберёмся, как Docker создаёт контейнер из capabilities, namespace и cgroup.
Docker — это очень тонкая прослойка вокруг ядра. Он создаёт контейнер на основе docker image c заданными настройками. Когда вы попросите Docker создать контейнер, он автоматически создаст набор namespaces и cgroup для этого контейнера.
PID Namespace нужны для того, чтобы процессы внутри контейнера не могли видеть другие процессы, которые работают в другом контейнере или на хостовой системе, и влиять на них.
Network namespace — контейнер получит свой сетевой стек, а значит, он не сможет получить доступ к сокетам или сетевым интерфейсам другого контейнера.
Аналогичная история со всеми остальными пространствами имён — для каждого контейнера своё дерево каталогов, хостнеймы и прочее.
При создании Docker-контейнера мы можем указать, сколько памяти или cpu выдать конкретному контейнеру, и ОС будет следить за этим лимитом. Такой контроль нужен, чтобы один контейнер случайно не убил всю систему, съев всю память или перегрузив процессор.
По умолчанию Docker при создании контейнера урезает все capabilites внутри него, оставляя только часть возможностей — смену атрибутов UID и GID ( chown ), kill , chroot и несколько других. Это сделано в целях безопасности, чтобы злоумышленнику не достались все root-права, если бы он смог выбраться из контейнера.
Терминология
Прежде чем начать работу с Docker, нужно изучить несколько терминов.
Docker Image
Образ — это шаблон для ваших будущих контейнеров. В образе описывается, что должно быть установлено в контейнере и какие действия нужно выполнить при старте контейнера.
В практической части вы будете использовать команду docker pull , чтобы загрузить busybox image из специального хранилища Docker образов — docker hub.
Docker Container
Контейнер — это исполняемый экземпляр образа (image). Его можно создавать, запускать, останавливать и удалять. Также можно подключать к контейнеру хранилище, объединять контейнеры одной или несколькими сетями и общаться с контейнерами, используя Docker API или CLI.
Увидеть список запущенных контейнеров можно через команду docker ps .
Docker Daemon
Docker-демон (dockerd) — фоновый процесс в операционной системе, который обрабатывает запросы Docker API и управляет объектами Docker: образами, контейнерами, сетями и томами.
Docker Client
Docker-клиент — инструмент командной строки (Comand Line Interface — CLI), через который пользователь взаимодействует с демоном.
Когда вы используете команду docker run , то Docker-клиент отправляет команду dockerd. Аналогичная история с другими командами docker <команда> .
Docker Hub
Docker Hub — это общедоступный Docker registry, то есть хранилище всех доступных Docker-образов. При необходимости можно разворачивать свои приватные Docker registry, размещать собственные реестры Docker и использовать их для извлечения образов.
Запуск и начальная настройка Docker
Для работы потребуются:
- базовые навыки работы с командной строкой;
- Git;
- Docker.
Docker — довольно популярный инструмент, и установить его на любую ОС не составит труда. В руководстве «Начало работы с Docker» есть подробные инструкции по настройке Docker на Mac, Linux и Windows.
После установки Docker стоит проверить, что он работает.
Для этого выполните:
Запускаем Busybox
Теперь, когда Docker установлен, запустим в нём первый контейнер. За основу контейнера возьмите Busybox image. Введите в терминале команду:
$ docker pull busybox
Примечание Вы можете увидеть ошибку permission denied после выполнения команды. Если вы работаете на Mac, убедитесь, что ядро Docker (engine) запущено. Если вы работаете в Linux, добавьте к командам docker префикс sudo . Кроме того, вы можете создать docker group, чтобы избавиться от этой проблемы.
Команда pull скачает (спулит) busybox image из Docker registry и сохранит его в вашей системе.
Чтобы увидеть список всех образов в вашей системе, используйте команду docker images :
Docker Run
Отлично! Давайте теперь запустим Docker-контейнер на основе этого образа. Используйте команду docker run :
Пусть вас не смущает, что ничего не произошло. Ошибки здесь нет, и всё идёт по плану. Когда вы вызываете run , Docker-клиент находит образ (в нашем случае busybox), загружает контейнер и запускает в нём команду.
Когда вы запустили docker run busybox , то не передали команду, поэтому контейнер загрузился, выполнил ничего и затем вышел.
Давайте передадим команду и посмотрим, что будет:
Ура, хоть какой-то результат! Docker клиент выполнил команду echo в busybox-контейнере, а затем вышел из него. И всё это произошло довольно быстро.
Хорошо, контейнер вы запустили, а как посмотреть, какие контейнеры запущены на сервере прямо сейчас? Для этого есть команда docker ps :
Сейчас нет запущенных контейнеров, и вы видите пустую строку. Попробуйте более полезный вариант — docker ps -a :
Появился список всех контейнеров, которые вы запускали. Заметьте, столбец STATUS показывает, что эти контейнеры были закрыты несколько минут назад.
Итак, вы запустили контейнер, выполнили одну команду, и контейнер завершился. Какой в этом смысл? Может быть, есть способ запускать больше одной команды?
Конечно, есть! Давайте выполним docker run -it busybox sh :
run с флагами -it подключит вас к интерактивному терминалу в контейнере. Теперь можно запускать в контейнере столько команд, сколько захотите.
Попробуйте выполнить ваши любимые команды в контейнере. А ещё стоит потратить немного времени на изучение возможностей команды run , так как именно её вы будете использовать чаще всего.
Чтобы увидеть список всех флагов, которые поддерживает run , выполните docker run —help .
Docker rm
Раз вы научились создавать контейнеры, нужно потренироваться их удалять. Вы сами видели, что даже после остановки контейнера информация о нём остаётся на хосте. Можно запускать docker run несколько раз и получать бесхозные контейнеры, которые будут занимать место на диске.
Место на диске нерезиновое, поэтому надо прибираться и удалять ненужные контейнеры. В этом поможет команда docker rm :
Если на хосте много контейнеров, которые надо удалить, то придётся копировать много CONTAINER ID , а это может быть утомительно. Чтобы облегчить себе жизнь, можно использовать docker container prune :
Команда удалит все остановленные контейнеры.
Чтобы удалить образы, которые больше не нужны, запустите docker image prune .
Развёртывание веб-приложения
Static-site
Итак, вы рассмотрели запуск docker и поиграли с контейнером. Настало время перейти к более реальным вещам и развернуть веб-приложение с помощью Docker.
Первым делом запустите очень простой статический сайт. Для этого заберите Docker-образ из Docker Hub, запустите его и проверьте, что у вас есть рабочий веб-сервер.
Образ, который вы будете использовать, — одностраничный веб-сайт, специально созданный для демонстрации и размещённый в registry — ifireice/static-site .
Вы можете загрузить и запустить образ сразу, используя docker run , флаг —rm автоматически удалит контейнер при выходе из него, а флаг -it запустит интерактивный терминал, из которого можно выйти с помощью Ctrl+C. Контейнер при этом будет уничтожен.
Так как образа ещё нет на хосте, Docker-клиент сначала скачает образ с registry, а потом запустит его. Если всё пойдёт по сценарию, вы должны увидеть сообщение Nginx is running. в терминале.
Сервер запущен, но как увидеть сайт? На каком порту работает сайт? Как получить доступ к контейнеру?
Клиент не предоставляет никаких портов, поэтому вам нужно повторно запустить docker run и опубликовать порты. Нажмите Ctrl+C, чтобы остановить контейнер.
Также вам надо сделать так, чтобы работающий контейнер не был привязан к терминалу. Это нужно для того, чтобы после закрытия терминала контейнер продолжил работать, — принцип действия detached mode:
- -d — отсоединить терминал,
- -P — опубликовать все открытые порты на случайные порты,
- —name — задать имя контейнеру.
Теперь вы можете увидеть порты, запустив команду docker port [CONTAINER] :
Откройте http://localhost:55000 в браузере. Также можно указать собственный порт, на который Docker-клиент будет перенаправлять подключения к контейнеру.
Если вы устали писать «Hello world!», самое время перейти на «Hello Docker!»
Чтобы остановить контейнер, запустите docker stop , указав идентификатор контейнера. В этом случае можно использовать имя static-site , которое вы задали контейнеру при запуске.
Чтобы развернуть этот же сайт на удалённом сервере, вам нужно установить Docker и запустить указанную выше команду.
Создание Docker Image
Теперь, когда вы посмотрели, как запустить веб-сервер внутри образа Docker, наверное, хочется создать собственный Docker-образ?
Помните команду docker images , которая выводит список образов, располагающихся локально?
Перед вами список образов, скачанных из registry, а также образы, которые созданы нами:
- TAG — относится к конкретному снимку изображения;
- IMAGE ID — уникальный идентификатор этого image.
Образы могут быть зафиксированы с изменениями и иметь несколько версий. Если вы не укажете конкретный номер версии, по умолчанию для клиента будет установлена последняя — latest . Например, вы можете вытащить конкретную версию образа ubuntu :
Новый образ можно или скачать из registry, или создать собственный.
Первый image
Допустим, вы хотите создать образ, который засунет в контейнер простое приложение на Django, отображающее случайную картинку с котиком. Для начала клонируйте это приложение к себе на локальный компьютер (не в Docker-контейнер):
Теперь это приложение нужно упаковать в image. Здесь пригодятся определения про образы.
- Базовые образы — это образы, у которых нет родительского образа. Обычно это образы ОС — ubuntu, busybox или debian;
- Дочерние образы — это образы, созданные на основе базовых образов с дополнительной функциональностью.
Также есть такие понятия, как официальный и пользовательский образы.
- Официальные образы поддерживаются Docker-сообществом. Обычно их имя состоит из одного слова, например, python, ubuntu, busybox и hello-world.
- Пользовательские образы созданы пользователями. Они строятся на основе базового и содержат дополнительную функциональность. Только поддерживаются уже не сообществом, а пользователем, который его создал. Имя у таких образов обычно имеет вид имя пользователя/изображения.
Вы будете создавать пользовательский образ, основанный на Python, потому что используете приложение на Django. Также вам понадобится Dockerfile.
Dockerfile
Dockerfile — это простой текстовый файл со списком команд, которые Docker-клиент вызывает при создании образа. Команды почти как в Linux, а значит, не нужно изучать ещё один язык для создания Dockerfile.
В директории приложения уже есть Dockerfile , но вы будете создавать его с нуля. Поэтому переименуйте его и создайте пустой файл с именем Dockerfile в директории Django-приложения.
Начните с определения базового image. Для этого используйте ключевое слово FROM :
Потом задайте рабочую директорию и скопируйте все файлы приложения:
Теперь, когда у вас есть файлы, можете установить зависимости:
Добавьте порт, который нужно открыть. Приложение работает на порту 5000, его и укажите:
Последний шаг — написать очень простую команду для запуска приложения: python ./manage.py runserver 0.0.0.0:5000 . Для этого используйте команду CMD . Она говорит, какую команду должен запустить контейнер при старте.
Теперь ваш Dockerfile готов и выглядит вот так:
Раз у вас есть Dockerfile , нужно собрать образ. Для этого используйте docker build и передайте необязательный флаг -t — имя тега и расположение каталога, содержащего Dockerfile .
Чтобы сохранить (запушить) готовый image на Docker Hub, нужно создать там учётную запись. Сохранитесь, чтобы потом вы могли получить образ и развернуть контейнер на его основе на любом сервере.
В теге yourusername должно быть имя вашей учетной записи в Docker Hub, иначе ничего не сработает.
Если на локальной машине нет образа python:3.8 , Docker-клиент сначала скачает образ, а затем создаст ваш. Тогда вывод команды может отличаться.
Если всё прошло хорошо, то image готов! Запустите его, не забыв изменить yourusername на правильный:
Команда взяла порт 5000 внутри контейнера и сопоставила его с портом 8888 на хосте. И теперь, если вы обратитесь на порт 8888 хостовой машины, запрос будет перенаправлен в контейнер на порт 5000 . Узнать, что вернёт приложение на запрос, можно с помощью пути: http://0.0.0.0:8888 .
Поздравляем! Вы успешно создали свой первый Docker-образ.
Docker push
Осталось дело за малым — сохранить ваш образ в registry. Сначала авторизуйтесь в Docker Hub? Не забудьте про логин из yourusername .
Когда будете вводить пароль, он не отобразится в консоли. Это норма, он и не должен быть виден всем подряд.
Чтобы сохранить образ в registry, просто введите docker push yourusername/cats . Важно, чтобы тег имел формат yourusername/image_name . Тогда Docker-клиент будет знать, куда сохранять образ:
Как работает Docker: подробный гайд от техлида
Олег Накрайников раскрывает концепцию, устройство и принципы работы Docker и делится упражнениями, которые помогут освоить инструмент.
Фото: Bloomberg / Getty Images
Олег Накрайников
Technical Lead. Любит GYM, путешествия и компьютерные игры. Пишет технические статьи и иногда технические треды в Twitter.
Ссылки
Контейнеризация — новая идеология в IT. В литературе приводят много аналогий, когда поставщики, то есть разработчики, упаковывают всё в один контейнер, как груз в порту. Это очень хорошая аналогия. Ведь цифровой контейнер точно так же перевозится и распаковывается в готовый продукт.
Основной инструмент контейнеризации — Docker, на его основе даже выстраивают внутреннюю сервисную инфраструктуру. Docker используют в сочетании с оркестраторами, такими как Kubernetes и OpenShift. Эти сервисы знаменуют переход от классических виртуалок к облачной инфраструктуре. С их помощью можно гибче, быстрее и динамичнее управлять ресурсами.
Что такое Docker
Docker — это платформа, которая позволяет упаковать в контейнер приложение со всем окружением и зависимостями, а затем доставить и запустить его в целевой системе.
Приложение, упакованное в контейнер, изолируется от операционной системы и других приложений. Поэтому разработчики могут не задумываться, в каком окружении будет работать их приложение, а инженеры по эксплуатации — единообразно запускать приложения и меньше заботиться о системных зависимостях.
Docker разработали в 2008 году. Изначально это был внутренний проект компании dotCloud, которую впоследствии переименовали в Docker Inc. В 2013 году dotCloud открыла исходный код Docker для сообщества.
Ранние версии Docker представляли собой усовершенствованную обёртку LXC , а с 2015 года Docker уже использовал собственную библиотеку libcontainer, абстрагирующую виртуализационные возможности ядра Linux. Так он превратился в самостоятельную технологию. Платформа неслучайно переехала на libcontainer: гибкость и управляемость LXC-контейнеров оставляла желать лучшего.
Популярность Docker продолжает расти, потому что его поддерживает большое сообщество. Платформа попала в мейнстрим на волне популярности DevOps, быстрых конвейеров доставки и автоматизации.
Устройство и принцип работы Docker
Виртуализация в Docker реализуется на уровне ОС. Виртуальная среда запускается прямо из ядра основной операционной системы и использует её ресурсы.
В поставку Docker входят следующие компоненты:
- Docker host — это операционная система, на которую устанавливают Docker и на которой он работает.
- Docker daemon — служба, которая управляет Docker-объектами: сетями, хранилищами, образами и контейнерами.
- Docker client — консольный клиент, при помощи которого пользователи взаимодействуют с Docker daemon и отправляют ему команды, создают контейнеры и управляют ими.
- Docker image — это неизменяемый образ, из которого разворачивается контейнер.
- Docker container — развёрнутое и запущенное приложение.
- Docker Registry — репозиторий, в котором хранятся образы.
- Dockerfile — файл-инструкция для сборки образа.
- Docker Compose — инструмент для управления несколькими контейнерами. Он позволяет создавать контейнеры и задавать их конфигурацию.
- Docker Desktop — GUI-клиент, который распространяется по GPL. Бесплатная версия работает на Windows, macOS, а с недавних пор и на Linux. Это очень удобный клиент, который отображает все сущности Docker и позволяет запустить однонодовый Kubernetes для компьютера.
Docker изначально создавался под Linux. Поэтому на Windows и macOS запускают виртуальную машину с Linux, а поверх неё — Docker. В macOS используют VirtualBox, а в Windows — Hyper-V.
Работа поверх виртуалок повышает потребление ресурсов. Поэтому Docker на macOS и Windows работает медленнее и с рядом ограничений. Для разработки это приемлемо, но «в бою» так делать никто не будет. На всех популярных платформах в проде используют Linux.
Чем виртуализация отличается от контейнеризации
Контейнеры и виртуальные машины — это разные способы виртуализации. Только виртуалка реализует её на уровне железа, а Docker — на уровне операционной системы.
Виртуальная машина функционирует как отдельный компьютер с собственным оборудованием и операционной системой. Распространённая практика — купить большой сервер и установить на него гипервизор, базу для виртуалок. Сервер «нарезается» на много виртуальных компьютеров, что избавляет нас от необходимости покупать их отдельно.
Виртуальные компьютеры вполне полноценны. На них можно установить операционную систему любого семейства и работать в ней, например, через графический интерфейс в многопользовательском режиме, устанавливая и запуская множество приложений и сервисов.
Если цель виртуалки — полностью воспроизвести устройство компьютера, то основная цель Docker — создать среду для одного приложения. Виртуальная среда контейнера запускается внутри операционной системы. Ей не нужно виртуализировать оборудование — она использует его через ОС. Поэтому контейнеры Docker потребляют меньше ресурсов, быстрее развёртываются, проще масштабируются и меньше весят.
Выделять под приложение целую виртуалку, устанавливать и настраивать операционную систему, раздавать права доступа — слишком дорого. В большинстве случаев достаточно простого окружения, в котором запустится приложение. Для этого как раз подходит контейнер, который вмещает одно главное приложение.
Оба способа изолируют приложение от основной операционной системы, но если на виртуалку можно поставить любую ОС, то Docker ориентирован на ядро Linux. Недавно добавили возможность поднимать Windows, но я ещё не пробовал это делать.
Docker и виртуальные машины не очень хорошо сочетаются друг с другом. Да, иногда в продакшене сервер нарезают на виртуалки и в них запускают контейнеры. Но такая схема, с двойной виртуализацией, приводит к избыточному расходу ресурсов. Её часто критикуют, и, надо признаться, по делу. Если в компании всё же сложилась такая практика, вместо гипервизора можно поставить Kubernetes, который будет устанавливать приложения напрямую на железо.
Обычно в крупных компаниях работают на виртуальных машинах, которые разворачиваются на железных машинах в ЦОДах . Инфраструктурные инженеры нарезают виртуальные компьютеры и выстраивают на них инфраструктуру. С помощью оркестраторов можно убрать эту лишнюю «прослойку».
Если же у вас много ресурсов, то можно поставить Docker на виртуалку, чтобы изолировать приложения друг от друга.
Сущности Docker
Docker работает с несколькими сущностями.
Docker image (образ). Это шаблон, по которому создают контейнеры. Его часто сравнивают со слоёным пирогом: мы накладываем слой файловой системы поверх слоя базового образа и получаем неизменяемый образ. В него можно установить приложение, конфигурации и зависимости. Другие образы могут наследоваться, поэтому если положить сверху слой файлов и закоммитить, то мы получим ещё один неизменяемый образ.
Dockerfile. Если Docker image — это пирог, то Dockerfile — рецепт его приготовления. В этом файле описаны основные инструкции для сборки образа: какой базовый образ взять, откуда и куда положить файлы и так далее.
Контейнер — это runtime-сущность на основе образа, приложение, которое мы развернули с помощью Docker. Можно провести такую аналогию: образ — это инсталлятор программы, а контейнер — уже запущенная программа.
При развёртывании контейнера поверх файловой системы создаётся ещё один изменяемый слой. Приложение внутри контейнера может записывать туда данные или редактировать их. После удаления контейнера данные стираются, но их можно сохранить с помощью volumes.
Docker Registry. Это репозиторий, в котором хранятся Docker-образы. Он может быть как локальным, так и публичным. Репозитории создают на платформах вроде Docker Hub и GitLab и размещают в них образы с описанием, разными версиями и тегами.
Как Docker помогает на практике
Приведу несколько примеров использования Docker, которые хорошо иллюстрируют его преимущества.
Разработка приложений с зависимостями
Обычно, чтобы установить какую-то библиотеку или базу данных, разработчику нужно прочитать инструкцию на сайте. Он её скачивает, устанавливает, настраивает и запускает. А когда нужно перейти на другую зависимость — удаляет. И так приходится возиться с каждой зависимостью.
Docker предоставляет альтернативный путь. Вендоры библиотек, фреймворков и баз данных практически каждый день публикуют на Docker Hub свой софт в виде Docker image. Образ можно скачать и развернуть через Docker, поработать с ним, запушить, а потом остановить или удалить, и в операционной системе не останется никаких следов.
Единый интерфейс управления исключает необходимость индивидуальных команд. Достаточно выучить команды Docker: как скачивать образы, запускать контейнеры, пробрасывать, останавливать и удалять порты. С Docker можно запустить сколько угодно одинаковых баз внутри одной операционки. Благодаря изоляции, если что-то пойдёт не так, ошибки не затронут операционную систему и ничего не сломают.
Автоматизация тестирования
Чтобы запустить автотесты, требуются определённые зависимости, например базы данных, брокеры сообщений и тому подобное. Их необходимо предварительно установить и сконфигурировать на сервере сборки. В этом месте иногда возникают проблемы: если при настройке упустить какую-то деталь, то можно испортить данные или что-то поломать. Гораздо безопаснее автоматически развернуть зависимости в виде контейнера прямо на сервере. Это позволяет быстро прогнать тесты, а после — бесследно удалить контейнеры.
Даже если тесты «сломают» какие-то данные, они удалятся вместе с контейнером. Кроме того, сам сервер с Docker, на котором запускаются автотесты, станет универсальным. Ведь благодаря контейнеризации на нём можно будет запускать что угодно. А значит, вы сэкономите на железе и настройке системы.
Публикация приложения
После тестирования проект упаковывают в образ и публикуют, передают клиентам или инфраструктурным инженерам.
Docker упрощает дальнейшее развёртывание приложения. SRE не нужно думать, какие зависимости установить, ведь всё уже упаковано в образ. Для них это чёрный ящик, который они обновляют единообразно и автоматически через одни и те же команды.
Среда для деплоя тоже становится универсальной, потому что всегда имеет дело только с контейнерами. Сегодня в ней развернули один контейнер, завтра — другой. При этом в контейнерах могут быть упакованы совершенно не похожие друг на друга приложения.
Минусы Docker
Как известно, за удовольствие приходится платить. И Docker — не исключение.
Высокое потребление ресурсов. Docker создаёт дополнительную логическую прослойку и потребляет дополнительные ресурсы. Поэтому вы должны определить, что для вас более важно — ресурсы или удобства. Если ресурсов с запасом, можно смело ставить Docker — будете удобно обновлять и версионировать приложения, не боясь испортить операционную систему. Если же ресурсы в дефиците, то лучше использовать классическую схему установки приложений.
Для больших приложений нужен оркестратор. Docker подходит для запуска нескольких контейнеров. В стандартной поставке Docker Compose есть механизм, который позволяет управлять их запуском с помощью конфигурационного файла YAML. Но этот механизм простой, он не потянет приложение, включающее 50–100 сервисов. У Docker не хватит механизмов управления и распределения ресурсов, резервирования и отказоустойчивости, чтобы реализовывать разные схемы обновления контейнеров.
В больших приложениях с микросервисной архитектурой используют оркестраторы Kubernetes или OpenShift. Единицей управления в Kubernetes является контейнер Docker, но на голом Docker прод практически никто не держит. Когда-то в России были такие компании — они рассказывали о своём травмирующем опыте на конференциях 🙂
Kubernetes — это мощный слой абстракции над железом, альтернатива гипервизорам у виртуалок. Он позволяет настраивать политики безопасности, реализует различные схемы обновления и позволяет гибко управлять ресурсами.
Проблемы с установкой на Windows и macOS. Как я сказал ранее, Docker создавался под Linux. На других операционках он не поддерживает некоторые типы сетей. В большинстве случаев никто этого не заметит, но об этом ограничении нужно помнить. Также на некоторых устройствах возникает конфликт с Virtual Box при установке Docker на Windows.
Как изучать Docker
Я рекомендую изучать Docker по книгам, сайтам и закреплять прочитанное на практике.
Книги. Есть две хорошие книги — Using Docker и Docker in Action. Правда, они немного устарели (опубликованы в 2018–2019 годах), поэтому там может быть неактуальная информация. Надеюсь, скоро будет переиздание.
Сайт docker.com — основной сайт Docker. На нём есть справочники и референсы по Docker, Docker-файлам, образам и Docker Compose. Читаете книгу, проверяете на сайте актуальность команд и изучаете примеры.
Упражнения. Я провожу тренинги и внутреннее обучение в командах. Обычно рекомендую такие упражнения:
- Установите Docker на рабочий компьютер. Возьмите готовый Docker image с Docker Hub с базой данных и запустите на его основе контейнер. Это можно сделать по инструкции, которую производитель image выкладывает на Docker Hub. Затем подключитесь к запущенной БД каким-нибудь клиентом и убедитесь, что всё работает.
- Напишите простенький сервис REST API и Docker-файл для упаковки сервиса в образ, подглядывая в референсы или книгу. Ваша задача — разобраться в теории, получить Docker image и проставить теги.
- Из полученного ранее образа создайте и запустите контейнер. Вам придётся разобраться с параметрами команды Docker run, настройками портов, передачей переменных окружению, монтированием и основными параметрами. Также стоит научиться подключаться к контейнеру, выполнять bash-команды и смотреть логи приложения.
- Усложните тестовый сервис, научив его работать с базой данных. Затем разверните контейнеры с сервисом и базой данных и соедините их внутренней сетью. Простое и в то же время очень полезное упражнение, на котором очень часто возникают затруднения на собеседованиях.
- Переходим к Docker Compose. Посмотрите, как написать YAML и создать группу контейнеров, как соединять их в сеть и работать с маунтами.
- Опубликуйте свой Docker image в Docker Hub. На одном аккаунте можно бесплатно публиковать только один образ, но есть GitLab, где нет таких ограничений. Правда, он устроен немного сложнее, новичок может запутаться. Ещё в том же GitLab можно создать приватный registry-режим и публиковать проекты без ограничений.
Читайте также:
LXC — система виртуализации на уровне ОС. Позволяет запускать несколько изолированных экземпляров Linux на одном узле в отдельных виртуальных окружениях с собственным пространством процессов и сетевым стеком.
Что такое Docker?
Если вы планируете начать свою карьеру как DevOps engineer или вы уже работающий DevOps, или разработчик в компании, который еще не освоил этот инструмент, то сейчас самое время. На этом уроке мы рассмотрим, что такое Docker и чем он может быть полезен.
Введение в Docker
Docker — это платформа, которая упрощает процесс сборки, запуска, управления и распространения приложений с помощью виртуализации операционной системы (ОС), на которой он установлен. Первый релиз Docker состоялся в марте 2013 года и был разработан с использованием языка программирования Go (он же Golang), который взял всё самое лучшее из языков Cи и С++ для решения актуальных проблем разработчиков облачных приложений.
Один из самых частых вопросов: «Чем же Docker-контейнеры отличаются от виртуальных машин?». Дело в том, что виртуальная машина работает с помощью программы Гипервизор (Hypervisor), которая создает новую машину внутри вашей системы, основываясь на ресурсах, которые вы выделили под нее. Примерами таких программ являются Oracle VM Virtualbox или VMware Workstation Player. Docker же использует возможности ядра Linux, которые позволяют ему создать так называемую виртуализацию операционной системы (англ. «OS-level virtualization»). Таким образом, процессы приложений, запущенных с помощью Docker, вы сможете увидеть в списке процессов вашей операционной системы.
На следующем рисунке вы можете увидеть отличия контейнеризации от виртуализации:
Главное отличие виртуализации от контейнеризации заключается в том, что в виртуализации аппаратные составляющие (например, виртуальный процессор, виртуальная оперативная память и пр.) создаются с помощью Hypervisor, на которые затем устанавливаются полноценные операционные системы, тогда как во время контейнеризации аппаратные ресурсы (например, процессорное время, сетевые интерфейсы и пр.) выделяются с помощью ядра операционной системы и изолируются пространствами имен.
Подход с контейнерами более гибкий и легковесный, потому что контейнеры не отнимают столько ресурсов, сколько виртуальные машины.
Какие проблемы решает Docker?
Допустим у нас есть три разных приложения на языке программирования Python, которые мы планируем разместить на одном сервере (не важно будет ли это виртуальный сервер или физическая машина). Каждое из этих приложений использует разные версии интерпретатора Python, библиотек и имеет отличные от других приложений зависимости. Так как мы не можем иметь разные версии интерпретатора Python, установленные в одной системе, то это не позволит нам разместить наши приложения на одной машине.
Для решения данной задачи мы могли бы использовать три разные физические машины или одну настолько мощную, что позволило бы нам создать на ней три виртуальные. Оба этих варианта решают проблему установки разных версий Python, нужных нам библиотек и зависимостей, но стоит учесть, что это покупка дополнительных машин/железа, которое затем нужно будет еще и настроить должным образом.
С помощью Docker мы можем сэкономить время и деньги. Машина, на которой запущен Docker, называется Docker host. То есть, когда вы хотите развернуть приложение на своей машине, Docker создает логическую сущность для развертывания приложения — контейнер.
Сам по себе Docker-контейнер не имеет операционной системы, но он имеет виртуальную копию списка процессов, сетевого интерфейса и путей монтирования файловой системы. Всё это он наследует от операционной системы, на которой он запущен, так как операционная система распределяет свое ядро между всеми запущенными контейнерами. Эта особенность и позволяет изолировать контейнеры внутри системы и отделить их друг от друга. Таким образом, у нас появляется возможность запускать разные контейнеры с разными приложениями, с разными зависимостями и библиотеками внутри одной системы до тех пор, пока они имеют одинаковые требования к ОС.
Правило: Docker виртуализирует операционную систему, на которой он установлен и запущен, а Hypervisor виртуализирует аппаратные компоненты системы.
Плюсы и минусы использования Docker
Ключевые преимущества использования Docker как платформы:
Docker поддерживает большое количество разных приложений с их требованиями и зависимостями, которые можно разместить на одной машине.
Большое количество приложений размещаются в системе в качестве контейнеров, которые занимают всего несколько мегабайт дискового пространства.
Контейнер не имеет установленной операционной системы, поэтому он потребляет относительно небольшое количество памяти в сравнении с виртуальной машиной (которая требует установки полноценной ОС).
Docker не требователен к аппаратным ресурсам в сравнении с виртуальными машинами.
Минусы использования Docker как платформы:
Приложения, которые требуют разные операционные системы, не могут быть размещены на одном и том же Docker host. Например, если у нас есть 2 приложения под Windows и 2 под Linux, то для них потребуются отдельные машины с установленными ОС Windows и OC Linux, соответственно.
Ключевые составляющие Docker
Docker Engine является одним из самых главных компонентов платформы Docker. Он отвечает за работу Docker как платформы в целом.
Docker Engine — это клиент-серверное приложение, которое состоит из трех главных компонентов:
Сервер — это программа, которая работает в фоновом режиме как daemon-процесс (демон dockerd ).
REST API — предоставляет интерфейсы, через которые программы могут взаимодействовать с daemon-процессом.
Интерфейс командной строки (сокр. «CLI» от англ. «Command Line Interface») — с помощью него мы общаемся с REST API (демон docker ).
Заключение
На этом уроке мы рассмотрели, что такое Docker, чем он отличается от виртуальных машин, его ключевые преимущества и минусы использования, а также затронули тему ключевых компонентов Docker. На следующих уроках мы рассмотрим установку Docker на Linux и на Windows.