Шпаргалка по Docker Hub

Скачивать образы Docker можно не только чужие, но и свои. Однако для этого они должны быть опубликованы на хабе: https://hub.docker.com И для начала следует там зарегистрироваться. С этим без труда справится любой.

После регистрации необходимо создать репозиторий для своего образа. С этим, думаю, тоже ни у кого проблем не возникнет. Там всего-то нужно указать имя репозитория и, опционально, описание. Для примера назовем test_app, и в моем случае, с логином, это будет выглядеть так:

itpolice/test_app

Теперь необходимо залогиниться со своей машины. Выполните в терминале команду:

docker login

И введите запрошенные логин и пароль от аккаунта на докер хабе.

Теперь для уже созданного образа необходимо установить удаленный репозиторий. Выберем нужный образ из списка доступных:

docker images

У меня нужный образ тоже называется test_app, ему я и укажу тэг удаленного репозитория соответствующей командой docker tag:

docker tag  test_app itpolice/test_app

Теперь тэг образа соответствует нужному репозиторию. Осталось загрузить его на хаб:

docker push itpolice/test_app

После успешного завершения загрузки свой образ вы можете увидеть на сайте хаба, а так же скачивать на любые машины командой docker pull:

docker pull itpolice/test_app

Docker. Устанавливаем на Linux, создаем и удаляем контейнеры.

Пишем Dockerfile. Создаем и запускаем образ Docker с Flask приложением.

Мониторинг запущенных контейнеров Docker

Мониторинг запущенных контейнеров Docker

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

Ниже приведен синтаксис команды docker exec:

docker exec [опции] <container_id> <команда>

Некоторые распространенные опции для команды docker exec:

  • -i, —interactive — позволяет вам взаимодействовать с командой в контейнере.
  • -t, —tty — выделение tty (терминального устройства) для взаимодействия с командой в контейнере.
  • —user — запуск команды от имени указанного пользователя или идентификатора пользователя и группы.

Команда docker exec позволяет выполнить команды внутри контейнера без необходимости запуска нового экземпляра контейнера. Это удобно для отладки, ввода внутрь контейнера в интерактивном режиме или запуска дополнительных процессов в уже запущенном контейнере.

Рассмотрим небольшой пример использования этой команды для мониторинга ресурсов внутри контейнера. Для этого я буду использовать запущенный на удаленной машине контейнер с Flask приложением. Как установить и запустить образ я описывал в предыдущих статьях.

Запустим контейнер:

docker run -d -p 5000:5000 --restart=always itpolice/test_app

В ответ я получил ID запущенного контейнера, который нужен для docker exec. ID активного контейнера также можно узнать командой «docker ps».

Зайдем в контейнер в интерактивном режиме командой:

docker exec -it 7acdfa8f50efba6742946c6e8b85463c92c9511a5380f2b7b122f6f9d065c239 bash

В этой команде:

  • docker exec используется для выполнения команд внутри контейнера
  • -it позволяет вам использовать интерактивный режим и также подключиться к терминалу контейнера
  • строка с кучей знаков — ID моего контейнера
  • bash указывает на то, что вы хотите войти в контейнер и запустить оболочку Bash

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

Обновим индекс доступных пакетов:

apt-get update

Установим программу мониторинга системы и процессов htop внутри Docker контейнера:

apt-get install htop

После установки htop, вы можете запустить его, просто введя команду htop в терминале.

Теперь у нас должен быть установлен и запущен htop внутри bash-терминала в Docker контейнере.

Напоследок посмотрим, куда эта программа установилась, введя команду:

which htop

#/usr/bin/htop

Отсоединяемся от терминала классическим Ctrl + D или командой exit.

docker

Пишем Dockerfile. Создаем и запускаем образ Docker с Flask приложением.

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

Пусть приложение состоит из трех файлов:

  • app.py
  • requirements.txt
  • Dockerfile

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

import os

from flask import Flask, jsonify, make_response


APP = Flask(__name__)
HOST = '0.0.0.0'
PORT = 5000
SERVICE_NAME = os.environ.get('SERVICE_NAME', 'application')


@APP.route('/hello/<user>')
def hello_user(user: str):
    return make_response(
        jsonify(
            {'message': f'Hello from {SERVICE_NAME}, {user}!'}
        ),
        200
    )


if __name__ == '__main__':
    APP.run(host=HOST, port=PORT)
flask==2.2.2

А теперь будем разбираться с Dockerfile. В файлах Dockerfile содержатся инструкции по созданию образа. С них, набранных заглавными буквами, начинаются строки этого файла. После инструкций идут их аргументы. Инструкции, при сборке образа, обрабатываются сверху вниз. Слои в итоговом образе создают только инструкции FROM, RUN, COPY, и ADD. Другие инструкции что-то настраивают, описывают метаданные, или сообщают Docker о том, что во время выполнения контейнера нужно что-то сделать, например — открыть какой-то порт или выполнить какую-то команду.

Шпаргалка по инструкциям:

FROM — задаёт базовый (родительский) образ.
LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
ENV — устанавливает постоянные переменные среды.
RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
COPY — копирует в контейнер файлы и папки.
ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.
WORKDIR — задаёт рабочую директорию для следующей инструкции.
ARG — задаёт переменные для передачи Docker во время сборки образа.
ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
EXPOSE — указывает на необходимость открыть порт.
VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.

В первую очередь с помощью инструкции FROM определим базовый образ python, указав имя ‘python’ и тэг образа после двоеточия. В нем просто легковесный python с минимумом библиотек на борту.

Теперь необходимо, чтобы Docker выполнил установку зависимостей. С помощью инструкции RUN мы создаем новый каталог /app внутри файловой системы контейнера. Копируем файл с зависимостями инструкцией COPY. Ей же копируем файл приложения. И инструкцией RUN устанавливаем зависимости. Далее укажем докеру рабочую директорию, в которой мы хотим находиться в момент запуска контейнера инструкцией WORKDIR, и пропишем команду запуска приложения инструкцией ENTRYPOINT.

В итоге наш Dockerfile выглядит так:

FROM python:3.7.9-slim-stretch

RUN mkdir /app

COPY requirements.txt /app/

COPY app.py /app/

RUN python -m pip install -r /app/requirements.txt

WORKDIR /app

ENTRYPOINT ["python", "app.py"]

Собираем образ

В терминале переходим в директорию с нашим приложением и Dockerfile’ом и вызываем команду:

docker build -t test_app .

Командой docker build мы собираем образ Docker с тэгом, указанным после флага -t.

После успешной сборки образа можно запустить контейнер, используя команду docker run. Укажите порт, на котором будет запущено приложение с помощью флага -p. Пример команды:

docker run -d -p 5000:5000 test_app

После этого Flask приложение будет доступно по адресу http://localhost:5000. Проверьте работу вашего приложения, открыв указанный URL в браузере. Не забудьте использовать эндпойнт «/hello/name», чтобы получить результат работы функции.

Чтобы остановить работу контейнера, узнайте его имя командой docker ps -a:

docker ps -a

И остановите командой docker stop:

docker stop practical_kare

По поводу расстановки команд в Dockerfile. При сборке образа Docker использует кэш, поэтому команды, которые используют часто изменяемые файлы, например мы постоянно вносим правки в файл app.py, лучше опускать ниже. А еще в нашем случае вместо инструкции «RUN mkdir /app» можно сразу поставить «WORKDIR /app» и директория будет создана автоматически. Но сделаем так в другой раз. А пока наш файл должен выглядеть так:

FROM python:3.7.9-slim-stretch

RUN mkdir /app

COPY requirements.txt /app/

RUN python -m pip install -r /app/requirements.txt

COPY app.py /app/

WORKDIR /app

ENTRYPOINT ["python", "app.py"]

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

Ну и последнее. Наше приложение способно получать данные из переменной окружения, т.е. снаружи, с помощью модуля os и команды «os.environ.get». Поэтому мы можем указать имя переменной SERVICE_NAME непосредственно при запуске контейнера с помощью флага -e:

docker run -d -p 5000:5000 -e "SERVICE_NAME=Vasya" test_app

Проверить можно без браузера, с помощью консольной утилиты curl:

curl http://localhost:5000/hello/artem
#{"message":"Hello from Vasya, artem!"}

А если добавить к команде запуска ключ «—restart=always», то образ будет сам запускаться при перезапуске системы:

docker run -d -p 5000:5000 -e --restart=always "SERVICE_NAME=Vasya" test_app

Docker. Устанавливаем на Linux, создаем и удаляем контейнеры.

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

Прежде чем установить Docker на свою машину необходимо убедиться, что он не был установлен до вас. Сторожилы говорят, ставить Docker необходимо на чистое место, тогда и ошибок не будет. Поэтому для начала выполняем команду:

sudo apt-get remove docker docker-engine docker.io conteinerd runc

Эта команда удаляет пакеты Docker, Docker Engine, Docker.io, Containerd и Runc с вашей системы Ubuntu. Удаление этих пакетов приведет к удалению Docker и связанных с ним компонентов из вашей системы.

Обновим индекс доступных пакетов из всех знакомых репозиториев:

sudo apt-get update

Установим пакеты, которые позволят apt использовать пакеты по HTTPS:

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

Добавим официальный GPG ключ от репозитория Docker:

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

И добавим сам репозиторий Docker в список источников пакетов APT:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Еще раз обновим индекс пакетов и увидим там репозиторий Docker:

sudo apt-get update

Установим последнюю версию Docker:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Убедимся, что Docker встал, запустив hello world контейнер:

sudo docker run hello-world

Docker установлен. Но удобство работы с ним пока оставляет желать лучшего. Чтобы избавиться от необходимости каждый раз перед docker писать sudo выполним два простых действия.

Создадим на машине новую группу пользователей docker:

sudo groupadd docker

И добавим себя в эту группу:

sudo usermod -aG docker $USER

Теперь, если перелогиниться, команда docker run hello-world выполнится без sudo.

Пример использования Docker

Для наглядности запустим контейнер командой run с аргументом debian (образ Debian Linux) и линукс командой echo ‘Hello world’:

docker run debian echo 'hello world'

В моем случае вывод получился таким:

Unable to find image ‘debian:latest’ locally
latest: Pulling from library/debian
71215d55680c: Pull complete
Digest: sha256:e97ee92bf1e11a2de654e9f3da827d8dce32b54e0490ac83bfc65c8706568116
Status: Downloaded newer image for debian:latest
hello world

Docker не нашел образ Debian локально, поэтому пошел искать его в облачном хранилище Docker Hub, нашел, создал на его основе работающий контейнер, и выполнил в нем команду. Если выполнить команду повторно, docker исполнит ее значительно быстрее, так как ему уже не нужно будет скачивать образ.

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

docker run -i -t debian bash
#подключаемся к терминалу

ls
#смотрим содержимое виртуальной машины в контейнере

Очень похоже на подключение к удаленной машине по SSH. Сеанс интерактивной работы на подключаемом терминале был создан благодаря двум флагам -i и -t.

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

uname -a

Контейнеры работают, пока существует основной процесс. При выходе из командной оболочки контейнер прекратит работу. Выйти: Ctrl + D или командой ‘exit’.

Теперь запустим контейнер, дав имя хосту. Например «HOST»:

docker run -h HOST -i -t debian bash

И сделаем страшное, удалим каталог /bin, в котором хранятся почти все утилиты Linux:

rm -r /bin

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

docker ps

Вы получите список созданных контейнеров с удобочитаемым именем в последней колонке. Оно нам понадобится. Вводим команду ‘docker diff’ и имя:

docker diff distracted_spence

И вуаля, мы получили то, что было удалено. Docker показал нам отличия запущенного контейнера от своего образа. Кроме того, Docker еще и логи собирает, поэтому мы без труда сможем вычислить причину и виновника удаления директории /bin:

docker logs distracted_spence

Команда выведет все, что было записано в stdout b stderr контейнера во время его работы.

Если выйти из контейнера и снова ввести команду docker ps, контейнер мы уже не увидим. Однако если добавить флаг -a:

docker ps -a

То получим полный список контейнеров во всех состояниях. Перезапустить контейнеры со статусом Exited можно командой:

docker start

А чтобы окончательно удалить ненужные контейнеры, используется команда docker rm и ID контейнера. Например:

docker rm b48c278d9d43

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

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

docker run -h HOST -i -t --rm debian bash

После выхода из контейнера в списке остановленных вы его не найдете.

И последнее, выше мы скачивали образ Debian автоматически, при создании контейнера. Однако, если нужно просто скачать образ из официального Docker Hub, делается это с помощью команды docker pull, например:

docker pull ubuntu

Эта команда загрузит последний доступный образ Ubuntu из официального репозитория Docker Hub. После того, как образ будет загружен, вы сможете использовать его для создания контейнера с помощью команды «docker run ubuntu».