
Введение
Docker, как программа, упрощает администрирование процессов приложений в контейнерах, позволяя выполнять приложения в изолированных от ресурсов процессах. Контейнеры можно сравнить с виртуальными машинами, за исключением того, что они более портативны, не требуют больших ресурсов и не зависят от операционной системы хоста.
В этой статье мы расскажем вам об установке и настройке Docker Community Edition (CE) на Ubuntu 20.04 и 22.04 LTS. Сначала вы установите Docker, затем будете работать с контейнерами и образами, после чего сохраните образ в репозитории Docker.
Предварительные условия
Чтобы следовать этому руководству, вам понадобятся следующие вещи:
- Установите один сервер Ubuntu 20.04 или 22.04 LTS.
- Заведите учетную запись на Docker Hub, если вы предпочитаете самостоятельно создавать образы и отправлять их на Docker Hub, как вы увидите в шагах 7 и 8 этого руководства.
Шаг 1: Установите Docker
Установочный пакет Docker, предлагаемый в официальном репозитории Ubuntu, вряд ли является самой последней версией. Чтобы убедиться в этом, мы установим Docker из официального репозитория Docker. Для этого мы будем использовать новый источник пакетов, поэтому установите пакет после добавления GPG-ключа из Docker, чтобы убедиться в валидности загрузки.
Прежде чем начать, необходимо обновить существующий список пакетов:
$ sudo apt-get update
Далее, чтобы apt мог использовать пакеты по HTTPS, вам нужно установить несколько предварительных пакетов:
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
Теперь добавьте ключ GPG в официальный репозиторий Docker вашей системы:
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Теперь добавьте репозиторий Docker в источники APT:
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Теперь обновите базу данных пакетов, используя только что добавленные Docker-пакеты репозитория:
$ sudo apt-get update
Осталось установить Docker:
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Теперь Docker установлен, демон запущен, а процесс настроен на запуск при загрузке. Проверьте, что он запущен:
$ sudo systemctl status docker
Вывод должен показать, что служба активна и запущена, и должен выглядеть примерно следующим образом:
root@ServerB:/home/ubuntu# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-07-28 09:49:02 UTC; 8min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 6958 (dockerd)
Tasks: 8
Memory: 30.2M
CPU: 1.276s
CGroup: /system.slice/docker.service
└─6958 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Теперь после установки Docker у вас есть служба (демон) Docker, а также программа командной строки docker, известная как клиент Docker. Позже в этой статье мы узнаем, как использовать команду docker.
Шаг 2: Выполнение команды Docker без Sudo (не обязательно).
Команда docker может быть выполнена только пользователем root или членом группы docker, которая создается по умолчанию в процессе установки Docker. Если вы попытаетесь выполнить команду docker без префикса или без членства в группе docker, результат будет выглядеть следующим образом:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
Чтобы избежать необходимости вводить sudo каждый раз, когда вы запускаете docker команду, вам нужно добавить свое имя пользователя в docker группа:
$ sudo usermod -aG docker ${USER}
Выйдите из сервера и войдите снова или введите следующее, чтобы применить новое членство в группе:
$ su - ${USER}
Перед тем как продолжить, вам будет предложено ввести пароль пользователя:
Введите следующий текст, чтобы подтвердить, что ваш пользователь теперь добавлен в docker группа:
$ id -nG
ubuntu adm cdrom sudo dip plugdev lxd docker
При необходимости вы можете явно объявить имя пользователя, которого нужно добавить в группу docker группу, в которую вы не вошли, с помощью:
$ sudo usermod -aG docker username
Остальная часть этого руководства основана на том, что вы запускаете docker команда в качестве пользователя в docker группа. Если вы предпочитаете этого не делать, добавьте к командам sudo.
Шаг 3: Используйте команду Docker
Использование docker означает передачу ему цепочки опций и команд, после которых будут идти аргументы. Синтаксис выглядит следующим образом:
$ docker [option] [command] [arguments]
$ docker -v
ubuntu@ServerB:~$ docker -v
Docker version 20.10.17, build 100c701
Чтобы увидеть все доступные подкоманды, введите:
$ docker
Полный список всех возможных подкоманд включает в себя:
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Чтобы визуализировать возможные варианты для конкретной команды, введите:
$ docker docker-subcommand --help
Чтобы визуализировать общесистемную информацию о Docker, введите:
$ docker info
На следующем этапе мы изучим некоторые из этих образов.
Шаг 4: Работа с образами Docker
Образы, созданные с помощью Docker, используются для создания контейнеров. По умолчанию Docker получает эти образы из Docker Hub, который представляет собой реестр Docker, управляемый компанией Docker. Поскольку любой человек может использовать Docker Hub для публикации своих образов, и подавляющее большинство приложений и дистрибутивов Linux будут иметь загруженные туда образы.
Чтобы проверить, есть ли у вас доступ и можете ли вы загрузить образы, найденные на Docker Hub, введите:
$ docker run hello-world
Следующий вывод покажет, что Docker работает правильно:
ubuntu@ServerB:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:53f1bbee2f52c39e41682ee1d388285290c5c8a76cc92b42687eecf38e0af3f0
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 создал из него контейнер и запустил приложение внутри контейнера, в итоге выведя на экран сообщение.
Образы, доступные на Docker Hub, можно найти с помощью функции docker команда и поиск подкоманда. Например, чтобы найти образ Ubuntu, нужно ввести:
$ docker search ubuntu
Сценарий обратится к Docker Hub и просмотрит список всех образов, название которых соответствует поисковому запросу. В этом случае результат будет выглядеть примерно так:
ubuntu@ServerB:~$ docker search ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… 14664 [OK]
websphere-liberty WebSphere Liberty multi-architecture images … 286 [OK]
ubuntu-upstart DEPRECATED, as is Upstart (find other proces… 112 [OK]
neurodebian NeuroDebian provides neuroscience research s… 92 [OK]
ubuntu/nginx Nginx, a high-performance reverse proxy & we… 55
open-liberty Open Liberty multi-architecture images based… 53 [OK]
ubuntu-debootstrap DEPRECATED; use "ubuntu" instead 46 [OK]
ubuntu/apache2 Apache, a secure & extensible open-source HT… 39
ubuntu/mysql MySQL open source fast, stable, multi-thread… 36
kasmweb/ubuntu-bionic-desktop Ubuntu productivity desktop for Kasm Workspa… 31
...
Выбрав образ, который вы будете использовать, вы можете загрузить его на свой компьютер с помощью команды [подкоманда.
$ docker pull ubuntu
Полученный результат будет выглядеть следующим образом:
ubuntu@ServerB:~$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
405f018f9d1d: Pull complete
Digest: sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
После загрузки образа можно запустить контейнер, использующий загруженный образ, с помощью команды run
подкомандой. Как вы уже видели hello-world
примере, если изображение не было загружено, когда docker
выполняется с помощью выполнить подкоманда, клиент Docker сначала загрузит образ, а затем запустит контейнер на его основе.
Чтобы просмотреть образы, загруженные на ваш компьютер, введите следующее:
$ docker images
Вывод будет выглядеть примерно так:
ubuntu@ServerB:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 27941809078c 7 weeks ago 77.8MB
hello-world latest feb5d9fea6a5 10 months ago 13.3kB
Позже в этом руководстве вы увидите, как можно изменять образы, используемые для запуска контейнеров, и использовать их для создания новых образов, которые затем могут быть вставлены (технический термин – pushed) в Docker Hub или другие реестры Docker.
Шаг 5: Запуск контейнера в Docker
The hello-world контейнер, который вы запустили на последнем шаге, – это пример контейнера, который после выдачи тестового сообщения запустится и выйдет. Контейнеры могут быть более полезными, чем это, а также интерактивными. Они функционируют примерно так же, как виртуальные машины, с той лишь разницей, что они более дружелюбны к ресурсам.
В качестве примера запустим контейнер и воспользуемся самым последним образом Ubuntu. Комбинация переключателей -i и -t даст вам интерактивный доступ к контейнеру:
$ docker run -it ubuntu
Ваша командная строка должна измениться, чтобы показать, что вы теперь работаете внутри контейнера, и должна выглядеть следующим образом:
ubuntu@ServerB:~$ docker run -it ubuntu
root@a9bb67c47592:/#
Посмотрите внимательно на идентификатор контейнера в командной строке, который выглядит так a9bb67c47592 здесь. Этот идентификатор контейнера впоследствии понадобится для идентификации контейнера, когда вы захотите его удалить.
Теперь вы можете выполнить любую команду внутри контейнера. Например, при обновлении базы данных пакетов внутри контейнера вам не нужно будет префиксировать любую команду словами sudo, потому что вы работаете внутри контейнера как корень пользователь:
root@a9bb67c47592:/# apt update
Теперь давайте установим в него любое приложение, например, Node.js:
root@a9bb67c47592:/# apt install nodejs
Это позволит установить Node.js в контейнер, найденный в официальном репозитории Ubuntu. После установки убедитесь в этом:
root@a9bb67c47592:/# node -v
Номер версии будет отображен в вашем терминале:
v12.22.9
Все изменения, сделанные внутри контейнера, будут применяться только к этому контейнеру.
Тип выход в подсказке, чтобы выйти из контейнера.
Шаг 6: Управление контейнерами в Docker
Поработав с Docker некоторое время, вы заметите, что на вашем компьютере есть множество активных (запущенных) и неактивных контейнеров. Чтобы визуализировать активные, используйте:
$ docker ps
Вывод, который вы получите, будет похож на этот:
ubuntu@ServerB:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
В предыдущих шагах вы запустили два контейнера: один из hello-world изображение и второе из ubuntu изображение. Оба они уже не работают, но все еще находятся в вашей системе.
Чтобы визуализировать активные и неактивные контейнеры, выполните команду docker ps с -a переключатель:
$ docker ps -a
Вы получите аналогичный результат:
ubuntu@ServerB:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9bb67c47592 ubuntu "bash" 6 minutes ago Exited (127) 27 seconds ago magical_shirley
ee421c96d926 hello-world "/hello" 30 minutes ago Exited (0) 30 minutes ago wonderful_raman
Передайте -l
переключатель, чтобы визуализировать последний созданный контейнер:
$ docker ps -l
ubuntu@ServerB:~$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9bb67c47592 ubuntu "bash" 15 minutes ago Exited (127) 10 minutes ago magical_shirley
Используйте docker start
для запуска остановленного контейнера, а затем введите идентификатор контейнера или его имя. Давайте запустим контейнер на базе Ubuntu с идентификатором a9bb67c47592
:
$ docker start a9bb67c47592
Вы можете использовать docker ps чтобы увидеть состояние контейнера после его запуска:
ubuntu@ServerB:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9bb67c47592 ubuntu "bash" 23 minutes ago Up About a minute magical_shirley
Используйте docker stop
для остановки запущенного контейнера, после чего укажите его ID или имя. В этот раз мы будем использовать имя, которое Docker присвоил контейнеру, а именно quizzical_mcnulty
:
$ docker stop magical_shirley
Если контейнер вам больше не нужен, вы можете удалить его с помощью команды docker rm
, на этот раз также используя либо идентификатор контейнера, либо его имя. Для удаления контейнера используйте docker ps -a
, чтобы найти имя или идентификатор контейнера, связанного с hello-world
изображением и удалить его.
$ docker rm wonderful_raman
Вы можете создать новый контейнер и назвать его с помощью функции --name
переключатель. Также можно использовать переключатель --rm
переключатель для запуска контейнера, который удаляет себя, когда его останавливают. См. docker run help
для получения дополнительной информации об этих и других опциях.
Я могу преобразовывать контейнеры в образы, которые можно использовать для создания новых контейнеров.
Шаг 7: Внесение изменений внутри контейнера в образ на Docker
При запуске образа Docker вы можете создавать, изменять и удалять файлы, как и в случае с виртуальной машиной. Внесенные изменения будут применяться только к этому контейнеру. Я могу запускать и останавливать его, но когда я использую docker rm
команду для его уничтожения, изменения будут навсегда потеряны.
В этой части мы покажем, как сохранить состояние контейнера в виде нового образа Docker.
После установки Node.js в контейнер Ubuntu у вас теперь есть контейнер, который работает от образа, но этот контейнер не тот же самый, что образ, который вы использовали для его создания. Но вы можете захотеть использовать этот контейнер Node.js в другой раз в качестве основы для новых образов в дальнейшем.
Затем внесите изменения в новый экземпляр образа Docker с помощью следующей команды.
$ docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name
[-m
Переключатель связан с сообщением о фиксации, которое помогает вам и другим идентифицировать внесенные вами изменения, однако -a
используется для указания автора. Переключатель container_id это тот, который вы видели ранее в этом руководстве, когда запускали интерактивную сессию Docker. Адрес репозиторий обычно является вашим именем пользователя Docker Hub, если только вы не создаете новые репозитории на Docker Hub.
Например, для пользователя ubuntu ID контейнера которого a9bb67c47592, команда будет такой:
$ docker commit -m "added Node.js" -a "ubuntu" a9bb67c47592 ubuntu/ubuntu-nodejs
После того, как я совершить образ, у меня будет новый образ, сохраненный локально на моем компьютере. Позже в этом руководстве вы узнаете, как отправить образ в реестр Docker, например Docker Hub, чтобы другие люди могли получить к нему доступ.
Повторное отображение образов Docker позволит наглядно увидеть как новые, так и старые образы, из которых они были получены:
$ docker images
Вы увидите следующий результат:
ubuntu@ServerB:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu/ubuntu-nodejs latest 45f8857f0719 9 seconds ago 197MB
...
В данном случае, ubuntu-nodejs
это новое изображение, которое было извлечено из существующего ubuntu
образа из Docker Hub. Разница в размере отражает внесенные мной изменения. Изменения, которые я внес, заключаются в том, что NodeJS
был установлен. Поэтому в следующий раз, когда вам понадобится запустить контейнер с Ubuntu с предустановленным NodeJS, вы можете просто использовать новый образ.
Вы также можете создавать образы из Dockerfile который позволяет автоматизировать установку программного обеспечения в новый образ. Однако это не имеет отношения к данному руководству.
Шаг 8: Отправка образа Docker в репозиторий Docker
Следующий очевидный шаг после создания нового образа на основе существующего – поделиться им с несколькими выбранными вами людьми, широкой публикой на Docker Hub или в другом реестре Docker, к которому вы можете получить доступ. Чтобы отправить образ на Docker Hub или в любой другой реестр Docker, вам нужно иметь там учетную запись.
Для этого вам нужно сначала войти в Docker Hub.
$ docker login -u docker-registry-username
Я пройду аутентификацию, используя ваш пароль от Docker Hub.
Примечание: Если ваше имя пользователя в реестре Docker отличается от локального имени пользователя, которое вы использовали для создания образа, вам нужно будет пометить образ своим именем пользователя в реестре. В случае с последним примером вы должны ввести:
$ docker tag ubuntu/ubuntu-nodejs docker-registry-username/ubuntu-nodejs
После этого вы сможете вытолкнуть свой образ, используя:
$ docker push docker-registry-username/docker-image-name
Чтобы продвинуть ubuntu-nodejs образ в репозиторий ubuntu, выполните следующую команду:
$ docker push ubuntu/ubuntu-nodejs
Наберитесь терпения, так как процесс загрузки изображений займет некоторое время, но по завершении работы результат будет выглядеть примерно так:
The push refers to a repository [docker.io/ubuntu/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed
...
Если возникла подобная ошибка, то, возможно, вы не вошли в систему:
The push refers to a repository [docker.io/ubuntu/ubuntu-nodejs]
e3fbbfb44187: Preparing
5f70bf18a086: Preparing
a3b5c80a4eba: Preparing
7f18b442972b: Preparing
3ce512daaf78: Preparing
7aae4540b42d: Waiting
unauthorized: authentication required
Войдите в систему с помощью docker login и снова запустите процесс проталкивания. Затем убедитесь, что он действительно находится на странице вашего репозитория Docker Hub.
Теперь вы можете использовать docker pull ubuntu/ubuntu-nodejs чтобы перенести образ на новую машину и запустить новый контейнер.