Минимальный linux для docker

Программист — это звучит гордо

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

Страницы

понедельник, 19 сентября 2016 г.

Хватит использовать Debian и Ubuntu как базовый образ для Docker

Если пройтись по образам на docker hub, то подавляющее большинство окажется построенными на базе Ubuntu и Debian. Хотя уже встречаются робкие попытки, в официальных сборках популярных пакетов, выкладывать альтернативные образы на базе Alpine linux. Но в общей массе это капля в море. А между тем Alpine подходит для базового образа куда лучше, чем такие знакомые и родные Debian с Ubuntu.

Размер имеет значение

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

Дистрибутив Размер % от ubuntu:14.04
ubuntu:14.04 187.9 MB 100. %
ubuntu:16.04 126.6 MB 67.4 %
debian:wheezy 84.91 MB 45.1 %
debian:jessie 125.1 MB 66.5 %
alpine:3.3 4.793 MB 2.55 %
alpine:3.4 4.795 MB 2.55 %

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

Набор софта

У меня наиболее часто используемые операции в базовом образе это: скачать (wget/curl), разархивировать (unzip/tar), отредактировать (nano/vi) и посмотреть (less). Судя по размеру, alpine должен быть лишён всех этих базовых полезных возможностей. Однако реальность удивляет:

Дистрибутив wget/curl unzip nano/vi less
ubuntu:14.04 vi +
ubuntu:16.04
debian:wheezy
debian:jessie
alpine:3.3 wget + vi +
alpine:3.4 wget + vi +

А что же тогда хранят образы Ubuntu и Debian? Вот набор наибольших по размеру вещей (в зависимости от версий набор варьируется): systemd, udev, python3+python2, bash и т.п. Уж конечно без этого мы собирая образ обойтись никак не могли.

Менеджер пакетов

У Alpine есть легковесный apk, с кучей свежих пакетов на все случаи жизни. Хотя тут он убунтовскомим репозиториям по количеству софта уступает. Но зато под реалии docker’а подходит куда лучше. Давайте разберём типичную проблему: в Dockerfile мы ставим пакет, что-то с его помощью делаем и удаляем, что бы не болтался и не раздувал размер образа. Конкретный пакет не важен, пусть это будет «zip»:

Размер образа до выполнения скрипта: 4.795 MB, после — 4.813 MB, разница 18 KB. Накладные расходы есть, но терпимо, ключ «–no-cache» помог не выкачивать индекс пакетов, а воспользоваться тем, что лежит в сети.

Теперь то же для apt (ubuntu:16.04), тут обойтись без обновления индекса у меня не вышло:

Система инициализации

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

Я использую s6-overlay, эта набор скриптов поверх s6, которые разрабатывались специально под docker. Я не буду пересказывать документацию, но вкратце опишу возможности:

  • «Повесить» набор скриптов на старт и остановку контейнера.
  • Декларативно описать назначение прав на директории и файлы, вместо беспорядочных chmod и chown в разных местах.
  • Для каждого сервиса можно написать скрипт запуска под нужным пользователем, и скрипт, который будет выполняться при завершении контейнера.
  • Ну и конечно единообразное логирование каждого шага.

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

Источник

Создание собственного образа Docker

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

Установка Docker

Рассмотрим примеры установки на базе операционных систем Red Hat/CentOS и Debian/Ubuntu.

Red Hat/CentOS

Устанавливаем репозиторий — для этого загружаем файл с настройками репозитория:

* если система вернет ошибку, устанавливаем wget командой yum install wget.

. и переносим его в каталог yum.repos.d:

mv docker-ce.repo /etc/yum.repos.d/

yum install docker-ce docker-ce-cli containerd.io

Если система вернет ошибку Необходимо: container-selinux >= . , переходим на страницу пакетов CentOS, находим нужную версию container-selinux и копируем на него ссылку:

. с помощью данной ссылки выполняем установку:

yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.99-1.el7_6.noarch.rpm

После повторяем команду на установку докера:

yum install docker-ce docker-ce-cli containerd.io

Debian/Ubuntu

В deb-системе ставится командой:

apt-get install docker docker.io

После установки

Разрешаем запуск сервиса docker:

systemctl enable docker

. и запускаем его:

systemctl start docker

docker run hello-world

. мы должны увидеть:

.
Hello from Docker!
This message shows that your installation appears to be working correctly.
.

Сборка нового образа

Сборка начинается с создания файла Dockerfile — он содержит инструкции того, что должно быть в контейнере. В качестве примера, соберем свой веб-сервер nginx.

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

mkdir -p /opt/docker/mynginx

* где /opt/docker/mynginx — полный путь до каталога, где будем создавать образ.

. переходим в данный каталог:

. и создаем Dockerfile:

MAINTAINER Dmitriy Mosk

RUN yum install -y epel-release && yum install -y nginx
RUN yum clean all
RUN echo «daemon off;» >> /etc/nginx/nginx.conf
RUN sed -i «0,/nginx/s/nginx/docker-nginx/i» /usr/share/nginx/html/index.html

* в данном файле мы:

  1. используем базовый образ centos 7;
  2. в качестве автора образа указываем Dmitriy Mosk;
  3. задаем временную зону внутри контейнера Europe/Moscow.
  4. устанавливаем epel-release и nginx;
  5. чистим систему от метаданных и кэша пакетов после установки;
  6. указываем nginx запускаться на переднем плане (daemon off);
  7. в индексном файле меняем первое вхождение nginx на docker-nginx;
  8. запускаем nginx.

* подробное описание инструкций Dockerfile смотрите ниже.

docker build -t dmosk/nginx:v1 .

* где dmosk — имя автора; nginx — название для сборки; v1 — тег с указанием версии. Точка на конце указывает, что поиск Dockerfile выполняем в текущей директории.

. начнется процесс сборки образа — после его завершения мы должны увидеть что-то на подобие:

Successfully built eae801eaeff2
Successfully tagged dmosk/nginx:v1

Посмотреть список образов можно командой:

Создаем и запускаем контейнер из образа:

docker run -d -p 8080:80 dmosk/nginx:v1

* в данном примере мы запустим контейнер из образа dmosk/nginx:v1 и укажем, что необходимо опубликовать внешний порт 8080, который будет перенаправлять трафик на порт 80 внутри контейнера.

Открываем браузер и переходим по адресу http:// :8080 — мы должны увидеть страницу приветствия с нашим docker-nginx:

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

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

docker stop 5fe78aca2e1d

docker start 5fe78aca2e1d

* где 5fe78aca2e1d — идентификатор контейнера.

Редактирование образа

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

Скачаем образ операционной системы CentOS:

docker pull centos:latest

Войдем в скачанный образ для его изменения:

docker run -t -i centos:latest /bin/bash

Внесем небольшие изменения, например, создадим учетную запись:

[root@8f07ef93918f /]# useradd dmosk -G wheel -m

[root@8f07ef93918f /]# passwd dmosk

* в данном примере мы создали пользователя dmosk и задали ему пароль.

docker commit -m «Add user dmosk» -a «Dmitry Mosk» 8f07ef93918f centos:my

* где -m — параметр для указания комментария; -a — указывает автора; 8f07ef93918f — идентификатор контейнера, который был нами изменен (его можно было увидеть в приглашении командной строки); centos:my — название нашего нового образа.

Новый образ создан.

Загрузка образа на Docker Hub

Заходим на Docker Hub страницу регистрации. Создаем пользователя:

На следующей странице также заполняем данные профиля. После переходим в почтовый ящик, который был указан при регистрации и переходим по ссылке Confirm Your Email With Docker для подтверждения регистрации. Регистрация закончена.

Переходим на страницу Repositories и создаем свой репозиторий, например, dmosk. Теперь можно загрузить наши образы в репозиторий.

Сначала авторизуемся в Linux под нашим зарегистрированным пользователем:

docker login —username dmosk

Задаем тег для одного из образов и загружаем его в репозиторий:

docker tag centos:my dmosk/dmosk:centos

docker push dmosk/dmosk:centos

Загрузим второй образ:

docker tag dmosk/nginx:v1 dmosk/dmosk:nginx

docker push dmosk/dmosk:nginx

В Docker Hub должны появиться наш образы:

Чтобы воспользоваться образом на другом компьютере, также авторизуемся под зарегистрированным пользователем docker:

docker login —username dmosk

docker pull dmosk/dmosk:nginx

docker run -d -p 8080:80 dmosk/dmosk:nginx

Описание инструкций Dockerfile

Инструкция Описание Пример
FROM Указывает, какой базовый образ нужно использовать. Обязательная инструкция для Dockerfile FROM ubuntu:16.04
MAINTAINER Автор образа. MAINTAINER DMosk
RUN Выполняет команду в новом слое при построении образа. RUN apt-get install python
CMD Запускает команду каждый раз при запуске контейнера. Может быть вызвана только один раз. Если в Dockerfile указать несколько таких инструкций, то выполнена будет последняя. CMD [«openvpn»]
LABEL Добавляет метаданные. LABEL version=»2″
EXPOSE Указывает, какой порт должно использовать приложение внутри контейнера. EXPOSE 8080
ENV Задает переменные окружения в образе. ENV PGPASSWORD pass
ADD Добавляет файлы/папки из текущего окружения в образ. Если в качестве копируемого файла указать архив, то он будет добавлен в образ в распакованном виде. Также в качестве источника принимает URL. ADD /root/.ssh/ /root/.ssh/
COPY Также как и ADD добавляет файлы в образ, но обладает меньшими функциями — не принимает URL и не распаковывает архивы. Рекомендован для использования в случаях, где не требуются возможности ADD или когда нужно перенести архив, как архив. COPY ./mypasswd /root/
ENTRYPOINT Указывает команду, которой будет передаваться параметр при запуске контейнера. ENTRYPOINT [«/sbin/apache2»]
VOLUME Добавляет том в контейнер. VOLUME [«/opt/myapp»]
USER Задает пользователя, от которого будет запущен образ. USER user:group
WORKDIR Можно задать каталог, откуда будут запускаться команды ENTRYPOINT и CMD. WORKDIR /opt/apps
ARG Создает переменную, которую может использовать сборщик. ARG folder=/opt/apps
WORKDIR $folder
ONBUILD Действия, которые выполняются, если наш образ используется как базовый для другой сборки. ONBUILD ADD . /app/src
STOPSIGNAL Переопределяет сигнал SIGTERM для завершения контейнера. STOPSIGNAL SIGINT
HEALTHCHECK Команда, которая будет проверять работоспособность контейнера. HEALTHCHECK —interval=5m —timeout=3s CMD curl -f http://localhost/ || exit 1
SHELL Позволяет заменить стандартную оболочку для выполнения команд на пользовательскую. SHELL [«/bin/sh», «-c»]

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

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

Создание резерва

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

. и для нужного выполняем команду:

docker save -o /backup/docker/container.tar

* в данном примере мы создаем архив контейнера в файл /backup/docker/container.tar.

Чтобы уменьшить размер, занимаемый созданным файлом, раархивиркем его командой:

* в итоге, мы получим файл container.tar.gz.

Восстановление

Сначала распаковываем архив:

После восстанавливаем контейнер:

docker load -i container.tar

Смотрим, что нужный нам контейнер появился:

Дополнительные команды

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

1. Удалить один образ:

docker rmi dmosk/nginx:v1

2. Удалить все образы:

docker rmi $(docker images -q)

Мы можем получить ошибки на подобие:

Error response from daemon: conflict: unable to delete 857594f280c1 (must be forced) — image is being used by stopped container .

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

docker rm $(docker ps —filter status=exited -q)

Если нужно, можно остановить все действующие контейнеры командой:

docker stop $(docker ps -a -q)

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

* добавлена опция -f.

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

docker logs my_nginx

Также можно смотреть логи непрерывно (follow):

Источник

Читайте также:  Сочетание клавиш mac os удалить
Оцените статью