Контейнер — это среда, внутри которой имитируется определённая операционная система. В эту систему мы можем положить код и запускать его в конкретной изолированной среде и в определённых нами условиях. Как правило, в одном контейнере запускают одно приложение или даже отдельный его компонент — модуль, функцию или микросервис.
Контейнер чем-то похож на виртуальную машину, только он гораздо компактнее и проще устроен. Он не требует выделять ему конкретные ресурсы, как виртуальная машина, а работает прямо на ресурсах нашей операционной системы.
Готовая среда для запуска. Контейнер вместе с приложением сразу содержит среду для работы. В этой среде мы пишем приложение и в ней же его тестируем, чтобы убедиться в работоспособности. Это позволяет загрузить готовый контейнер на любой сервер — и быть уверенным, что приложение запустится нормально. Неважно, где и как код писали, запускаться он будет стабильно именно благодаря упаковке в контейнер.
Небольшой вес. Виртуальные машины могут весить несколько гигабайтов. Docker-контейнер чаще всего весит не больше пары сотен мегабайтов, иногда сильно меньше. Он быстро запускается и не требует больших вычислительных мощностей.
Изолированность от внешней среды. У docker-контейнера нет доступа к информации на хосте. Это делает работу приложения более безопасной.
Удобные инструменты управления. Образы docker хранятся в удобном docker-реестре, откуда можно в пару кликов запускать готовые среды и на их основе настраивать свои. Сам Docker позволяет управлять контейнерами: запускать, сохранять, редактировать, перезагружать. А если контейнеров в работе много, существуют специальные инструменты для массового управления — оркестрации. Для docker-контейнеров стандартным инструментом считается Kubernetes.
Демон. Это фоновый процесс, который управляет контейнерами. Он принимает команды от клиента и делает то, что его попросили. Плюс он всегда следит за контейнерами и в любой момент знает их состояние.
Хост. Тот сервер, на котором мы развернули Docker. Именно на нём в фоне работает демон, и на нём поднимаются контейнеры.
Реестр. Это наше хранилище образов, из которых демон разворачивает контейнеры. Это может быть общественный docker-хаб, в котором хранятся готовые образы. А может быть наше персональное хранилище, где лежат образы, сконструированные нами.
Важно понимать, что образы — это не сами контейнеры. Это скорее набор инструкций, проходясь по которым Docker собирает контейнер и запускает его. После запуска к образу добавляется слой «на запись», который позволяет его изменять — и тем самым превращает в полноценный контейнер.
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
Настройте установку из репозитория Docker, а не Ubuntu:
apt-cache policy 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
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 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
Этот файл после запуска позволяет загрузить образ и сразу задаёт контейнеру определённые настройки.
Читать также: