Программирование  •  07 июля 2022  •  5 мин чтения

Что разработчику нужно знать о контейнерах Docker

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

Что такое Docker и как он работает

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

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

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

Так выглядит разница между виртуальными машинами и контейнерами
Так выглядит разница между виртуальными машинами и контейнерами. В случае ВМ у нас есть гипервизор, который управляет машинами. В случае контейнеров — Docker
Существуют разные программы для создания контейнеров, но на практике разработчики чаще всего используют Docker и docker-контейнеры.
Материал по теме:
Как стать Android‑разработчиком и расти в профессии

Преимущества использования контейнеров Docker

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

Готовая среда для запуска. Контейнер вместе с приложением сразу содержит среду для работы. В этой среде мы пишем приложение и в ней же его тестируем, чтобы убедиться в работоспособности. Это позволяет загрузить готовый контейнер на любой сервер — и быть уверенным, что приложение запустится нормально. Неважно, где и как код писали, запускаться он будет стабильно именно благодаря упаковке в контейнер.

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

Изолированность от внешней среды. У docker-контейнера нет доступа к информации на хосте. Это делает работу приложения более безопасной.

Удобные инструменты управления. Образы docker хранятся в удобном docker-реестре, откуда можно в пару кликов запускать готовые среды и на их основе настраивать свои. Сам Docker позволяет управлять контейнерами: запускать, сохранять, редактировать, перезагружать. А если контейнеров в работе много, существуют специальные инструменты для массового управления — оркестрации. Для docker-контейнеров стандартным инструментом считается Kubernetes.

Основные компоненты Docker

Docker состоит из четырёх основных компонентов: клиента, демона, хоста и реестра.
Docker состоит из четырёх основных компонентов: клиента, демона, хоста и реестра
Клиент. Это наш инструмент, в который мы отдаём команды: поднять контейнер, настроить его, перезагрузить или удалить.

Демон. Это фоновый процесс, который управляет контейнерами. Он принимает команды от клиента и делает то, что его попросили. Плюс он всегда следит за контейнерами и в любой момент знает их состояние.

Хост. Тот сервер, на котором мы развернули Docker. Именно на нём в фоне работает демон, и на нём поднимаются контейнеры.

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

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

Как установить Docker

Обычно Docker используют как консольное приложение, то есть отдают ему команды через консоль. Существует приложение для Windows и MacOS с графическим интерфейсом, но его практически никто не использует. Мы рассмотрим установку Docker именно через консоль, на операционной системе Linux Ubuntu, так как это наиболее распространённый вариант использования Docker.
  1. Обновите существующий список пакетов командой

sudo apt update

  1. Установите пакеты, которые позволяют использовать пакеты через https:

sudo apt install apt-transport-https ca-certificates curl software-properties-common

  1. Добавьте в систему ключ GPG для официального репозитория:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –

  1. Добавьте репозиторий Docker:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

  1. Обновите базу данных пакетов и добавьте пакеты Docker:

sudo apt update

Настройте установку из репозитория Docker, а не Ubuntu:

apt-cache policy docker-ce

После выполнения этой команды вы получите в консоли вывод:

docker-ce:

  Installed: (none)

  Candidate: 5:19.03.9~3-0~ubuntu-focal

  Version table:

     5:19.03.9~3-0~ubuntu-focal 500

        500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

Теперь можно устанавливать Docker командой:

sudo apt install docker-ce

Это сразу установит Docker, запустит демон-процесс и активирует запуск при загрузке. Проверить, что всё работает, можно командой:

sudo systemctl status docker

Если всё работает, вывод будет выглядеть примерно так:

docker.service - Docker Application Container Engine

    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)

    Active: active (running) since Tue 2020-05-19 17:00:41 UTC; 17s ago

TriggeredBy: ● docker.socket

     Docs: https://docs.docker.com

   Main PID: 24321 (dockerd)

      Tasks: 8

      Memory: 46.4M

      CGroup: /system.slice/docker.service

              └─24321 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock


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

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

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

docker run hello-world

Если всё работает нормально, вы получите вывод:

Unable to find image 'hello-world:latest' locally

latest: Pulling from library/hello-world

0e03bdcc26d7: Pull complete

Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1

Status: Downloaded newer image for hello-world:latest

Hello from Docker!

This message shows that your installation appears to be working correctly.

Здесь мы видим, что Docker не нашёл локальный образ hello-world, поэтому он обратился в Docker Hub, загрузил его, развернул контейнер из образа. После этого приложение в контейнере загрузилось, и мы увидели в консоли сообщение.

Искать нужные образы можно командой docker с субкомандой search.
Например, так:

docker search ubuntu

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

NAME

DESCRIPTION                                        STARS
OFFICIAL           AUTOMATED
ubuntu
Ubuntu is a Debian-based Linux operating sys…      10908
[OK]

dorowu/ubuntu-desktop-lxde-vnc
Docker image to provide HTML5 VNC interface …      428
[OK]

rastasheep/ubuntu-sshd
Dockerized SSH service, built on top of offi…      244
[OK]

consol/ubuntu-xfce-vnc
Ubuntu container with "headless" VNC session…      218
[OK]

ubuntu-upstart
Upstart is an event-based replacement for th…      108
[OK]

ansible/ubuntu14.04-ansible
Ubuntu 14.04 LTS with


...

Выбранный образ можно загрузить субкомандой pull:

docker pull ubuntu

Вывод может выглядеть так:

Using default tag: latest

latest: Pulling from library/ubuntu

d51af753c3d3: Pull complete

fc878cd0a91c: Pull complete

6154df8ff988: Pull complete

fee5db0ff82f: Pull complete

Digest:
sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7

Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

После загрузки можно запускать контейнер командой run. Если до этого образ не был загружен, команду docker можно выполнить сразу с run — тогда Docker сам загрузит образ и запустит с ним контейнер.

Посмотреть загруженные образы можно командой:

docker images

Вывод выглядит так:

REPOSITORY          TAGnbsp;         IMAGE ID

CREATED             SIZE

ubuntu              latest           1d622ef86b13           3
weeks ago         73.9MB

hello-world         latest           bf756fb1ae65           4
months ago        13.3kB

Загруженные образы можно менять и использовать для создания docker-образов. После этого новые образы можно помещать в Docker Hub или другие реестры Docker.

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

Мы запускали простой контейнер hello-world, который выполнялся сразу после запуска. Попробуем запустить более сложный, с образом Ubuntu:

docker run -it ubuntu

Переключатели -i и -t дадут доступ к командам по изменению контейнера.

На вывод вы получите идентификатор контейнера. Он пригодится, чтобы потом работать с контейнером и удалять его. Идентификатор имеет такой вид:

root@d9b100f2f636:/#

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

Есть ещё один способ сборки контейнера — команда docker build. Чтобы её использовать, нужен Dockerfile — текстовый сценарий, который позволяет собрать контейнер по определённому описанию. Выглядеть он, например, может так:

# syntax=docker/dockerfile:1

FROM node:12-alpine

RUN apk add --no-cache python2 g++ make

WORKDIR /app

COPY . .

RUN yarn install --production

CMD ["node", "src/index.js"]

EXPOSE 3000

Этот файл после запуска позволяет загрузить образ и сразу задаёт контейнеру определённые настройки.

Статью подготовили:

Артем Стрельцов
Яндекс
Разработчик
Лена Шпрингер
Яндекс Практикум
Редактор

Дайджест блога: ежемесячная подборка лучших статей от редакции

Поделиться 

Успейте начать учебу в Практикуме до конца ноября со скидкой 20%

Tue Nov 12 2024 13:18:38 GMT+0300 (Moscow Standard Time)