[docker] основы docker: dockerfile и docker-compose.yml

Сетевой диск Введение

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

Для обмена файлами внутри команды существует ограничение на размер для передачи с использованием WeChat, и его можно загружать и скачивать только через общедоступную сеть; хотя передача с использованием QQ может передаваться через интрасеть, некоторые файлы являются секретами компании, и прямая передача имеет риск утечки. Это слишком хлопотно, и у разных отделов должны быть разные разрешения на работу с документами.

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

Мы собираемся поговорить о сегодняшнем главном герое — «Nextcloud», новая работа команды основателей ownCloud, основанная на разработке ownCloud, но с большим количеством функций, большей стабильностью, настраиваемым развертыванием, поддержкой различных плагинов и даже сквозным шифрованием.

(Фактически, вы также можете рассмотреть возможность использования устройств NAS, таких как Qunhui. По сравнению с нетехническим персоналом, конфигурация относительно проста, но это выходит за рамки этой статьи, и я напишу ее позже.)

Что такое Docker

Docker – это программное обеспечение, которое позволяет запускать приложения в контейнерах.

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

Docker работает и на Windows, и на Linux.

Docker очень похож на виртуальную машину, но от нее отличается.

На слайде показана классическая картинка сравнения Docker и виртуальной машины

  • У нас есть хост-система и на ней виртуализируется машина целиком. То есть она виртуализируется со всеми устройствами, жесткими дисками, процессами и гостевой операционной системой. Дальше будет наше приложение и библиотеки.

  • Docker же виртуализирует без гостевой машины – вместо этого он использует аппаратные возможности вашей машины.

Соответственно, какие мы получаем с него плюсы?

  • Он требует намного меньше ресурсов – вы дальше увидите картинку.

  • На нем очень быстро стартуют контейнеры по сравнению с виртуальной машиной.

  • И масштабировать такие контейнеры из-за этого проще.

Что нам даёт Docker с точки зрения тестирования?

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

  • Второе – благодаря тому, что он запускается достаточно быстро, его необязательно включить и долго держать, его можно запускать по запросу. То есть вы запустили, прогнали в нем тесты, контейнеры со всеми данными убили – все, чистить за ним не надо.

  • У Docker есть хорошая система взаимодействия между контейнерами, благодаря чему можно собирать матрешки из сервисов для тестирования.

  • И относительная простота администрирования – опять же, вы просто запустили контейнер, он сколько-то поработал, упал. И все, за ним следить-то и не надо.

Создание тома данных на хосте

Первым шагом необходимо создать новый каталог для размещения тома Docker. Для этого откройте окно терминала и введите команду:

Необходимо убедиться, что вновь созданный каталог размещен в том месте, к которому пользователь Docker может получить доступ (с правами на чтение и запись). После того, как вы создали этот каталог, будьте готовы его подключить к контейнеру. Предположим, вы собираетесь развернуть контейнер, основанный на официальном образе Ubuntu, который содержит каталог с именем /data. Чтобы развернуть такой контейнер, который присоединяет внутренний каталог /data к тому в каталоге хоста ~/container-data, необходимо выполнить команду:

Вышеприведенная команда обозначает следующее:

  • docker run — это основная команда, которая говорит, что мы собираемся запустить команду в новом контейнере.
  • — dit — это d для режима detached, и он гарантирует, что bash или sh могут быть выделены псевдо-терминалу.
  • — P публикует порты контейнеров на хосте.
  • — name говорит, что далее следует имя нового контейнера.
  • — v говорит, что далее объявляется том.
  • ubuntu — это образ, который будет использоваться для контейнера.

Как только команда завершится, вы получите идентификатор контейнера. Убедитесь, что вы запомнили первые четыре символа этого идентификатора, так как он понадобится вам для получения доступа к оболочке bash внутри контейнера.

Теперь вы развернули контейнер, основанный на официальном образе Ubuntu, который включает каталог /data, монтирующийся на том хоста в ~/container-data.

Используем docker-compose#

Согласно одной из легенд, появился после того, как к разработчикам Docker пришли и сказали: “Docker – отличная вещь! Но сделайте удобно!”. Будем считать что он уже поставлен у вас. Так что сразу перейдем к делу – содаем локально рядом с еще и .

И приводим его к такому виду:

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

Тут мы говорим: – поднять, – собрать, – пусть робит в фоне. После чего мы можем посмотреть список запущенных сервисов:

К слову у вас может быть несколько файлов и их можно включать все например вот такой конструкцией:

Кейс: в файле может быть больше доступа. Или для среды разработки можно поднимать моки вместо реальных сервисов.

Так же замечу, что все сервисы описанные в рамках одного файла (в нашем примере это сервисы и ), будут сразу “из коробки” видеть друг друга по указанным именам.

Ну а теперь откройте в браузере http://127.0.0.1:8000/swagger/ и убедитесь, что приложение поднялось и заработало – откроется Swagger-документация по API нашего приложения. По крайней мере так может казаться на первый взгляд.

Удаление контейнеров

Удаление одного или нескольких конкретных контейнеров

Используйте команду с флагом для поиска имен или идентификаторов контейнеров, которые вы хотите удалить:

Список:

Удаление:

Удаление контейнера при выходе

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

Запуск и удаление:

Удаление всех контейнеров, из которых выполнен выход

Вы можете найти контейнеры с помощью команды и отфильтровать их по статусу: created (создан), restarting (перезапускается), running (работает), paused (пауза) или exited (выполнен выход). Чтобы просмотреть список контейнеров, из которых выполнен выход, используйте флаг для фильтрации по статусу. Убедитесь, что вы хотите удалить эти контейнеры, и используйте флаг для передачи идентификаторов в команду .

Список:

Удаление:

Удаление контейнеров с использованием нескольких фильтров

Фильтры Docker можно комбинировать, повторяя флаг фильтра с дополнительным значением. В результате выводится список контейнеров, соответствующих любому из указанных условий. Например, если вы хотите удалить все контейнеры со статусом Created (статус, который может возникнуть при запуске контейнера недопустимой командой) или Exited, вы можете использовать два фильтра:

Список:

Удаление:

Удаление контейнеров по шаблону

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

Обратите внимание, что эти утилиты не поставляются Docker и могут быть доступны не во всех системах:

Список:

Удаление:

Остановка и удаление всех контейнеров

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

Список:

Удаление:

Пример Dockerfile: образ для установки MongoDB

Теперь попробуйте создать Dockerfile и добавить в него пошаговые инструкции по установке MongoDB.

Примечание: Все нижеприведённые команды и аргументы нужно добавить в Dockerfile последовательно. В конце руководства можно найти полный код файла.

Создайте Dockerfile с помощью текстового редактора:

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

Задайте базовый образ:

Укажите его автора:

Обновите список репозитория приложения.

Задайте команды и аргументы для загрузки MongoDB:

Затем укажите порт по умолчанию:

Сохраните Dockerfile, добавив в него всё необходимое. Для этого нажмите CTRL+X и Y.

В результате файл должен выглядеть так:

Теперь можно собрать образ MongoDB с помощью этого сценария.

Примечание: Флаг -t задаёт название образа. Чтобы получить справку по сборке, введите команду:

Запуск MongoDB

С помощью образа MongoDB можно создать контейнер.

Примечание: Чтобы задать имя контейнера, добавьте флаг -name [].

Если при запуске контейнера вы не укажете его имя, docker присвоит ему сложный алфавитно-цифровой ID. Его можно узнать с помощью команды:

Чтобы отключить контейнер, нажмите CTRL+P и CTRL+Q.

DockerDockerfilesLXCMongoDB

Официальный образ Docker

GitLab предлагает готовый образ Docker который поставляется со всем необходимым для развертывания программного обеспечения

В этом уроке мы сосредоточимся на этом изображении, но стоит обратить внимание на его ограничения

Образ является монолитным по своей природе, объединяя все компоненты GitLab, поэтому они работают в одном контейнере. Это упрощает настройку, но затрудняет масштабирование установки в будущем. Это идет вразрез с передовыми методами контейнеризации, поскольку в контейнере запускается несколько отдельных компонентов.

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

Образы Docker#

Для начала заглянув в документацию вспомним, что же такое контейнер Docker и поймем, что Docker-контейнер — это Docker image (образ) который оживили. Собственно говоря Docker image — это то, из чего запускается любой Docker-container.

Каждому Docker image соответствует свой набор инструкций и файл с такими инструкция называется – без расширений и каких-либо точек. Из в дальнейшем собираются Docker images (образы). Сброка нового образа выполняется запуском команды:

Учитывая, что наш Dockerfile расположен в той же директории где и мы запускаем команду сборки, то команду можно упростить до такого вида:

Каждый контейнер состоит из слоев, а каждый слой контейнера (за исключением последнего) предназначен исключительно для чтения. Собственно основная задача Dockerfile состоит в том, чтобы описать последовательность данных слоев – в каком порядке они идут.

Учитывая, что в Unix все есть файл мы можем сказать, что отдельный слой это всего лишь файл, который описывает изменение состояния по сравнению с предыдущим слоем.

Базовый образ является лишь исходным слоем (слоями) создаваемого образа (иногда называют родительским образом).

Volumes

docker cp file <containerID>:/ — Скопировать в корень контейнера filedocker cp <containerID>:/file . — Скопировать file из корня контейнера в текущую директорию командной строки
docker volume create todo-db — Создать volume для постоянного хранения файловdocker run -dp 3000:3000 —name=dev -v todo-db:/etc/todos container-name — Добавить named volumу todo-db к контейнеру (они ok когда мы не заморачиваемся где конкретно хранить данные)
docker run -dp 3000:3000 —name=dev —mount source=todo-db,target=/etc/todos container-name — тоже самое что команда сверху
docker volume ls — Отобразить список всех volume’ов
docker volume inspect — Инспекция volume’ов
docker volume rm — Удалить volume

Резервное копирование вашей установки

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

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

docker exec -t gitlab gitlab-backup create

Резервные копии сохраняются в каталог по умолчанию. Это означает, что они будут храниться вне контейнера, в одном из подключенных томов Docker. Для большей безопасности вы должны настроить GitLab для загрузки резервных копий в провайдер удаленного хранилища объектов, добавив эти строки в ваш файл конфигурации:

gitlab_rails'backup_upload_connection' = {
    "provider" => "AWS",
    "region" => "eu-west-1",
    "aws_access_key_id" => "access_key",
    "aws_secret_access_key" => "secret_key",
    # "endpoint" => "https://..."
}

Теперь Команда автоматически загрузит сгенерированные архивные файлы, сохраняя их отдельно от вашего контейнера GitLab и хоста Docker. Вашим последним шагом должно быть добавление задача в вашей системе, которая периодически запускает сценарий резервного копирования:

0 * * * * docker exec -t gitlab gitlab-backup create

Этап 3. «Оптимизация»

Следующий этап, к которому мы перешли – оптимизация всего этого дела.

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

  • Настройка инфраструктуры через Ansible. Ansible – это такое программное обеспечение, которое позволяет описать вашу инфраструктуру декларативно. Вы можете заводить описания, какие вам пакеты надо поставить, в том числе можно описывать, какие платформы вы хотите поставить – какое дополнительное ПО вам надо, и оно раскатывается на все ваши машины. У нас был набор из шести-восьми машин, и они все идентичные.

  • Ну и не забываем, опять же, мониторить метрики – теперь нам надо было мониторить восемь машин вместо одной.

На этом этапе мы проработали достаточно долго – примерно полгода без каких-либо проблем. А потом, как обычно, что-то пошло не так.

Что такое Webhooks ?

Webhook — это специальные функции, которые работают с событиями, и это способ для приложения предоставлять информацию в режиме реального времени другому приложению. В настоящее время почти каждое приложение предоставляет функцию webhook, поэтому Docker Hub также имеет эту функцию.

Это HTTP push API, запускаемый пользовательскими событиями. Мы можем использовать webhook в Docker, чтобы уведомить приложение или службу, которая использует соответствующие образы. Как правило, мы настраиваем веб-хук с докером как конвейер событий, так что любая загрузка новых образов вызовет тестирование приложений для запуска подчеркнутых тестовых случаев.

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

Особенности Docker

Итак, что же сделать, чтобы со всем этим работать?

Во-первых, поймите, что Docker – это не страшно, это не какая-то магия, его вполне можно поставить к себе на компьютер и попробовать с ним работать. Это достаточно удобно, особенно если вы хотите попробовать какой-нибудь сервис. Например, вы хотите внедрить в код-ревью. Мне нравится Upsource – это достаточно удобный сервис для код-ревью. Вместо того, чтобы ставить на какой-то машине, вы можете скачать официальный образ, развернуть его у себя, попробовать с ним поработать и убрать, если он вам не подойдет.

Запуск тестов фактически не отличается – код, который использовался для запуска теста в Jenkins, перекочевал как каковой с Windows-машин на Linux-машины

Единственное, на что нужно обращать внимание – это регистр, потому что Linux регистрозависимый, какие слеши вы используйте в путях, и будьте аккуратнее с правами доступа на уровень файловой системы.

Kubernetes – это тоже в принципе не страшно. Можете поставить себе minikube

Он работает и под Windows в том числе. Это такой кластер на одну вашу машину. Вы можете легко позапускать в нем какие-то данные.

Развертывание и оркестрация Docker

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

Docker Compose

Если все контейнеры, применяемые для создания приложения, расположены на одном и том же хосте, то для управления архитектурой приложения можно использовать Docker Compose. Docker Compose создает файл YAML со списком сервисов для добавления в приложение, а также позволяет развертывать и запускать контейнеры с помощью одной команды. Кроме того, в Docker Compose можно определить постоянные тома для хранения данных, указать базовые узлы, а также задокументировать и настроить зависимости между сервисами.

Kubernetes

Для мониторинга и управления жизненным циклом контейнеров в более сложных средах требуется специальный инструмент оркестрации контейнеров. Большинство разработчиков предпочитают использовать Kubernetes, хотя в Docker есть встроенный инструмент оркестрации под названием Docker Swarm.

Kubernetes — контейнерная платформа с открытым исходным кодом, созданная в процессе работы над внутренним проектом Google. Kubernetes обеспечивает планирование и автоматизацию задач, связанных с управлением контейнерными архитектурами, включая развертывание контейнеров, обновления, обнаружение служб, предоставление ресурсов хранилища, распределение нагрузки, мониторинг состояния и т. п. Кроме того, существует открытая экосистема инструментов для Kubernetes, включая Istio и Knative, позволяющая развернуть высокопроизводительные предложения PaaS (платформа как услуга) для контейнеризованных приложений и ускорить переход к бессерверным вычислениям.

Для получения более подробной информации о Kubernetes рекомендуем посмотреть видеоролик «Kubernetes в деталях»:

Kubernetes в деталях (10:59)

Создание образа контейнера для приложения

В этом учебнике используется простое приложение Todo.

Приложение позволяет создавать рабочие элементы и помечать их как завершенные или удалять их.

Чтобы создать приложение, создайте Dockerfile.
Dockerfile — это текстовый сценарий инструкций, который используется для создания образа контейнера.

  1. Перейдите в репозиторий Учебник по началу работы с Docker, а затем выберите Код > Скачать ZIP-файл.
    Извлеките содержимое в локальную папку.

  2. В VS Code выберите Файл > Открыть папку.
    Перейдите в папку app в извлеченном проекте и откройте ее.
    Вы увидите файл с именем package.json и две папки с именами src и spec.

  3. Создайте файл с именем Dockerfile в той же папке, где находится файл package.json со следующим содержимым.

    Observação

    Убедитесь, что файл не имеет расширения файла, например .

  4. В проводнике в левой части в VS Code щелкните правой кнопкой мыши Dockerfile и выберите пункт Собрать образ.
    В поле ввода текста введите getting-started в качестве тега для образа.

    Тег — это понятное имя для образа.

    Чтобы создать образ контейнера из командной строки, используйте следующую команду.

    Observação

    Чтобы выполнить эту команду, во внешнем окне Bash перейдите в папку с параметром Dockerfile.

Вы создали образ контейнера с помощью Dockerfile.
Возможно, вы заметили, что было скачано много слоев.
Dockerfile начинается с образа .
Если его еще нет на компьютере, скачайте его.

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

в конце команды указывает, что Docker должен искать Dockerfile в текущем каталоге.

Шаг 7 — Извлечение образов из частного реестра Docker

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

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

Теперь вы готовы к извлечению образа. Используйте доменное имя и имя образа, к которому вы добавили метку на предыдущем шаге:

Docker загрузит образ и вернется в командную строку. Если вы запустите образ на сервере реестра, вы увидите, что ранее созданный файл находится в этом образе:

Выведите список файлов в оболочке bash:

Вы увидите файл , который вы создали для этого образа:

Вы завершили настройку защищенного реестра для отправки и получения образов.

Запуск образа в новом экземпляре

Теперь, когда образ создан и отправлен в реестр, попробуйте запустить приложение в совершенно новом экземпляре, которому незнаком этот образ контейнера.
Чтобы запустить приложение, используйте сайт Play with Docker.

  1. Откройте Play with Docker в браузере.

  2. Войдите со своей учетной записью Docker Hub.

  3. Нажмите кнопку Пуск, а затем щелкните ссылку + Добавить новый экземпляр в левой части.
    Через несколько секунд в браузере откроется окно терминала.

  4. Запустите приложение в окне терминала.

    Play with Docker извлекает образ и запускает его.

  5. Щелкните значок 3000 рядом с пунктом ОТКРЫТЬ ПОРТ.
    Вы должны увидеть приложение с внесенными изменениями.

    Если значок 3000 не отображается, выберите ОТКРЫТЬ ПОРТ и введите «3000».

Best Practice

Следуй принципу минимальных привилегий, процессы в контейнере никогда не должны выполняться из под рута, кроме редких случаев, нужно добавлять команду user и менять юзера на non-root.
Не привязываться к UID, он динамичен, можно записать во временную папку UID.
Сделать все исполняемые файлы владельцем рута, чтобы никто не изменил исполняемые файлы, а пользователю достаточно только права на выполнение.
Чем меньше компонентов и открытых портов, тем меньше поверхность для атак.
Использовать multistage для промежуточного контейнера для компиляции всего, зависимостей, временных файлов, образ может весить на треть меньше.
Distroless с чистого листа, использовать минимальный набор пакетов, например избавиться от образа Ubuntuи выбрать Debian-base, наши контейнеры содержат уязвимости изначального образа, чекать это.
Нужно обновлять всё до того, как выйдет из под поддержки.
Оставлять только те порты, которые реально нужны, избегать 22 и 21 3389 (ssh & ftp & rdp).
Никогда не помещайте логины/пароли в команде, в докерфайлах, переменных, docker secret или любой другой менеджер секретов ok.
Не использовать ADD, только COPY (когда используем точку — это воркдир где лежит докерфайл).
При сборке используйте .dockerignore чтобы убрать сенситив дату, это как .gitignore.
При сборке вначале команд лучше кешировать команду ран, а потом скопировать исходные данные.
Метадату записать.
Использовать тесты типа Linter и сканеры образов для CI.
Время от времени делать prune, докер любит много места жрать

docker images

Списко образов верхнего уровня, их теги, размеры и репозитории можно получить выполнив

docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
andreyolegovichru/docker101tutorial latest dd2e76a16950 9 hours ago 26.8MB
docker101tutorial latest dd2e76a16950 9 hours ago 26.8MB
<none> <none> f5578f194936 9 hours ago 123MB
<none> <none> 409d2b2d3c0b 9 hours ago 110MB
<none> <none> c26bbf7dc236 9 hours ago 224MB
python alpine fbfb63e3c6bb 17 hours ago 80.3MB
nginx alpine ecd67fe340f9 4 days ago 21.6MB
node 12-alpine 057fa4cc38c2 2 weeks ago 89.3MB
hello-world latest bf756fb1ae65 6 months ago 13.3kB

Использование диска контейнерами

Каждый раз, когда создается контейнер, в папке на хост-машине появляется несколько папок и файлов. Среди них:

  • Папка (ID — уникальный идентификатор контейнера). Если контейнер использует драйвер логгирования по умолчанию, все логи будут сохранены в файле JSON внутри нее. Создание слишком большого количества логов может повлиять на файловую систему хост-машины.
  • Папка в , содержащая слой чтения-записи контейнера (overlay2 является предпочтительным драйвером хранилища в большинстве дистрибутивов Linux). Если контейнер сохраняет данные в своей собственной файловой системе, они будут храниться в на хост-машине.

Представим, что у нас есть совершенно новая система, в которой только что был установлен Docker.

$ docker system dfTYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLEImages         0          0          0B         0BContainers     0          0          0B         0BLocal Volumes  0          0          0B         0BBuild Cache    0          0          0B         0B

Во-первых, запустим контейнер NGINX:

$ docker container run --name www -d -p 8000:80 nginx:1.16

Снова запустив команду , мы увидим:

  • один образ размером 126 Мбайт. Его загрузил NGINX: 1.16, когда мы запустили контейнер;
  • контейнер , запускающийся из образа NGINX.
$ docker system dfTYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLEImages         1          1          126M       0B (0%)Containers     1          1          2B         0B (0%)Local Volumes  0          0          0B         0BBuild Cache    0          0          0B         0B

Поскольку контейнер запущен, а образ в данный момент используется, освобождаемого пространства пока нет. Так как его размер (2B) незначителен, и поэтому его нелегко отследить в файловой системе, создадим пустой файл размером 100 Мбайт в файловой системе контейнера. Для этого мы используем удобную команду dd из контейнера www.

$ docker exec -ti www \  dd if=/dev/zero of=test.img bs=1024 count=0 seek=$

Этот файл создается в слое чтения-записи, связанном с этим контейнером. Если мы снова проверим вывод команды , то увидим, что он теперь занимает некоторое дополнительное дисковое пространство.

$ docker system dfTYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLEImages         1          1          126M       0B (0%)Containers     1          1          104.9MB    0B (0%)Local Volumes  0          0          0B         0BBuild Cache    0          0          0B         0B

Где находится этот файл на хосте? Проверим:

$ find /var/lib/docker -type f -name test.img/var/lib/docker/overlay2/83f177...630078/merged/test.img/var/lib/docker/overlay2/83f177...630078/diff/test.img

Не вдаваясь глубоко в детали — этот файл был создан на слое чтения-записи контейнера, который управляется драйвером overlay2. Если мы остановим контейнер, используемое им дисковое пространство станет пригодным для восстановления. Посмотрим:

# Остановка контейнера www$ docker stop www# Влияние на использование диска$ docker system dfTYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLEImages         1          1          126M       0B (0%)Containers     1          0          104.9MB    104.9MB (100%)Local Volumes  0          0          0B         0BBuild Cache    0          0          0B         0B

Как можно восстановить это пространство? Путем удаления контейнера, что приведет к удалению связанного с ним слоя чтения-записи.

Следующие команды позволяют нам удалить все остановленные контейнеры сразу и освободить место на диске, которое они используют:

$ docker container pruneWARNING! This will remove all stopped containers.Are you sure you want to continue? [y/N] yDeleted Containers:5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2Total reclaimed space: 104.9MB

Из вывода видно, что больше нет места, используемого контейнерами, и, поскольку образ больше не используется (контейнер не работает), пространство, которое он использует в файловой системе хоста, может быть восстановлено:

$ docker system dfTYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLEImages         1          0          126M       126M (100%)Containers     0          0          0B         0BLocal Volumes  0          0          0B         0BBuild Cache    0          0          0B         0B

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

Подкоманда , которую мы применяли выше, удаляет остановленные контейнеры. Если нам нужно удалить все — и запущенные, и остановленные, мы можем использовать одну из следующих команд (обе эквивалентны):

# Старая команда$ docker rm -f $(docker ps -aq)# Более современная$ docker container rm -f $(docker container ls -aq)

Примечание: во многих случаях стоит использовать флаг при запуске контейнера, чтобы он автоматически удалялся при остановке процесса PID 1, тем самым немедленно освобождая неиспользуемое пространство.

Что такое Контейнер?

С официального сайта Docker

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

Это может показаться немного запутанным, так что, надеюсь, картинка из RightScale немного прояснит ситуацию.

Запущенный контейнер – это просто стандартный процесс операционной системы, а также зависимости файловой системы и сетевые подключения. На рисунке выше крайняя левая диаграмма показывает абстрактную модель процесса, где зеленый PGM показывает основной программный код, а MEM-память, используемую запущенным процессом. Два других блока немного продвинуты, но в основном это текущее состояние регистров процессора и таблица процессов, используемая ОС.

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

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

Отлично! Но зачем вообще беспокоиться об этом?

Основные причины, по которым мне нравится заставлять Docker работать в моем рабочем процессе, заключаются в следующем:

  • Позволяет разбивать большие приложения на составные части, что помогает поддерживать низкую когнитивную нагрузку и обеспечивает более легкую отладку и большую прозрачность.
  • Завершите сложные инструкции по применению таким образом, чтобы помочь документировать, как создавать и настраивать программное обеспечение.
  • Если вы используете Docker как для разработки, так и для производства, то у вас есть идентичные стеки. Это уменьшает когнитивную нагрузку от знания того, как использовать несколько установок. Это также предотвращает оправдания “это работает для меня”, когда что-то ломается.
  • Не нужно беспокоиться о сумасшедших шагах компиляции для установки программного обеспечения и обслуживания вашей машины.
  • Помогает сохранить вашу работу по разработке независимой от вашей ОС (так что обновление Ubuntu не начинает касаться ваших библиотек разработки и т. Д.)

Для управляемых развертываний используйте общую файловую систему (AWS EFS)

Если вы развертываете в AWS ECS, вы не сможете использовать обычное связывание или монтирование тома, потому что, как только вы закроете контейнер, вы, вероятно, не будете работать на той же машине при следующем запуске. , победив цель настойчивости.

Тем не менее, вы все еще можете добиться устойчивости, используя другой сервис AWS — Elastic File System (EFS). EFS является общей сетевой файловой системой. Вы можете подключить его к нескольким серверам EC2, и к ним будут синхронизироваться все данные. Например, вы могли бы использовать это для размещения статического контента и кода для вашего веб-сайта, а затем запустить все ваши рабочие узлы в ECS для обработки фактической подачи вашего контента. Это позволяет обойти ограничение не хранить данные на диске, поскольку монтирование тома привязано к внешнему диску, который сохраняется во всех развертываниях ECS.

Чтобы настроить это, вам нужно создать файловую систему EFS. Это довольно просто и может быть сделано из Консоль управления EFS, но вы захотите записать идентификатор тома, так как он понадобится вам для работы с томом.

Если вам нужно вручную добавить или изменить файлы в томе EFS, вы можете подключить его к любому экземпляру EC2. Вам нужно установить :

sudo yum install -y amazon-efs-utils

А затем подключите его с помощью следующей команды, используя идентификатор:

sudo mount -t efs fs-12345678:/ /mnt/efs

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

Далее вам нужно подключить ECS к этому объему. Создайте новое определение задачи в Консоль управления ECS, Прокрутите вниз и выберите «Настроить через JSON». Затем замените пустой ключ «volume» следующим JSON, добавив в конце ключ «family»:

"volumes": [
        {
            "name": "efs-demo",
            "host": null,
            "dockerVolumeConfiguration": {
                "autoprovision": true,
                "labels": null,
                "scope": "shared",
                "driver": "local",
                "driverOpts": {
                    "type": "nfs",
                    "device": ":/",
                    "o": "addr=fs-XXXXXX.efs.us-east-1.amazonaws.com,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport"
                }
            }
        }
    ],
"family":"nginx",

замещать с реальным адресом тома EFS. Вы должны увидеть новый том:

Вы можете использовать это в своем определении контейнера как точку монтирования. Выберите «Добавить контейнер» (или отредактируйте существующий) и в разделе «Хранение и ведение журнала» выберите вновь созданный том и укажите путь к контейнеру.

Сохраните определение задачи, и при запуске кластера с этим новым определением все контейнеры смогут получить доступ к вашей общей файловой системе.

Как все будет работать в итоге

  • Мы установим следующую сборку: PHP (5.4 — 7.4), Apache, MySQL, phpMyAdmin. Сможем зайти из браузера на localhost и запустить ваш проект (или просто в данном случае index.php)
  • Будет папка, в которой хранится ваш проект. Т.е. используете ваш любимый IDE для разработки. Со всеми файлами вы работаете из своей родной ОС (mac/windows).
  • Докер сделает виртуальный контейнер, в котором запустит необходимую сборку (в нашем случае lamp) и все файлы будут синхронизированы
  • Доступны конфиги php.ini, apache, дампы mysql, которые загружаются в виртуальный контейнер docker
  • при желании c помощью командной строки можно зайти на виртуальный сервер (контейнер) и сделать при желании там все необходимое (подправить конфиг, запустить команду и тд).
Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
3D-тест
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: