Внедрение Docker для небольшого проекта в Production, часть 2

    image

    Часть 1

    В первой части мы подготовили нашу операционную систему для использования Docker контейнеров.

    После того как мы выполнили перезагрузку, мы увидим приглашения к авторизации, но с консоли сервера сделать это будет не возможно, по той причине что авторизация в системе возможна лишь по ключу. А по умолчанию пользователь core не имеет пароля. Конечно его можно установить используя команду:

    sudo passwd core

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

    Можно использовать как терминальный клиент если вы пользователь Linux, MacOS или же Putty если вы работаете с Windows. Как настроить подключение к нашему серверу я описывать не буду, это тривиальная задача. Необходимо лишь учесть что в процессе установки мы поменяли порт со стандартного на 2222. Следовательно не забываем указать это в параметрах подключения.

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

    Source IP: Your Public IP Address
    Source Port: 2222
    Destination IP: Your Private IP Address
    Destination Port: 2222
    

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

    /usr/share/oem/cloud-config.yml

    Сделать это довольно просто, я покажу на примере поднятия в качестве службы контейнера с sshguard (демон который читает журнал авторизации и добавляет не желательных пользователей в список блокировки IPTABLES).

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

    /cloud/containers - корневая папка, где будут храниться наши контейнеры, файлы необходимые для сборки
    /cloud/etc/ - корневая папка наших конфигов, для каждого контейнера, так проще потом бекапить и ничего не забыть
    /cloud/data/ - тут храним данные наших контейнеров, скрипты сайтов, приложений и тд...
    /cloud/run/ - сюда я буду помещать unix сокеты различных сервисов для разделяемого доступа, например для php-fpm или сокеты uwsgi приложений

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

    vi Dockerfile

    Почему я использую редактор vi? Напоминаю система минималистичная, поэтому в CoreOS нет других редакторов, например vim nano mcedit и прочих (как решить эту проблему я расскажу несколько позже, не будем забегать вперед).

    После запуска редактора переводим его в режим вставки нажатием клавиши «i» на клавиатуре, и размещаем следующий текст:

    FROM alpine:3.2
    
    RUN apk add --update \
        iptables \
        ip6tables \
        sshguard \
     && rm -fr /var/cache/apk/*
    
    ENTRYPOINT ["/usr/sbin/sshguard"]

    Первая строка FROM указывает, какой базовый образ для сборки нашего контейнера использовать, как я и говорил будем использовать Alpine Linux версии 3.2.

    Строкой начинающийся с RUN мы говорим, выполни следующие команды, в нашем примере установим дополнительные пакеты и сам sshguard. После чего укажем точку входа в наш контейнер /usr/sbin/sshguard.

    На этом все, теперь нам нужно сохранить файл конфигурации контейнера. Для этого на клавиатуре покинем режим вставки нажатием клавиши «ESC», затем переведем vi в коммандный режим нажатием «Shift + :» и напишем «wq» и нажмем «Enter». Все на этом мы закончили с файлом конфигурации. Теперь приступим к сборке нашего контейнера. Для этого в консоли выполним следующее:

    docker build -t local/sshguard .

    Рассмотрим эту команду подробнее, мы через команду build указываем Docker, что необходимо выполнить сборку контейнера в репозитарий local с именем sshguard, в место local можно использовать например свой репозитарий на hub.docker.com, но после чего нужно не забыть сделать docker push repo/container. Ключик -t ждет следующим параметром как тегировать (назвать) наш образ, в данном случае мы сосздаем локальный образ local/sshguard. Вместо точки нужно указать путь до нашего Dockerfile, но если мы находимся в том же каталоге что и сам файл, то точки будет достаточно.

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

    docker images

    Удалить образ указав один или несколько имен или id через пробел:

    docker images rmi image_id или image_name

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

    Для этого приступим к редактированию файла /usr/share/oem/cloud-config.yml, и добавим туда следующее содержимое. Используем наш полюбившийся vi, по аналогии выше.

    #cloud-config
    
    coreos:
      units:
        - name: sshguard.service
          command: start
          content: |
            [Unit]
            Description=sshguard
            After=docker.service
            Requires=docker.service
            [Service]
            TimeoutStartSec=0
    
            ExecStartPre=-/usr/bin/docker kill sshguard
            ExecStartPre=-/usr/bin/docker rm sshguard
            ExecStartPre=/usr/bin/docker pull local/sshguard
    
            # setup sshguard tables
            ExecStartPre=-/usr/sbin/iptables -N sshguard
            ExecStartPre=-/usr/sbin/ip6tables -N sshguard
    
            # block abuser traffic
            ExecStartPre=-/usr/sbin/iptables -D INPUT -j sshguard
            ExecStartPre=-/usr/sbin/ip6tables -D INPUT -j sshguard
            ExecStartPre=-/usr/sbin/iptables -A INPUT -j sshguard
            ExecStartPre=-/usr/sbin/ip6tables -A INPUT -j sshguard
    
            ExecStart=/bin/sh -c 'journalctl --no-pager -q -f -t sshd | sed -u "s/\\[[0-9]*\\]//" | docker run -i --name sshguard --rm --net=host --privileged local/sshguard'
    
            ExecStop=-/usr/bin/docker stop sshguard
            ExecStop=-/usr/bin/docker rm sshguard

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

    sudo coreos-cloudinit --from-file /usr/share/oem/cloud-config.yml

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

    Результатом наших действий стал готовый сервер, умеющий блокировать нарушителей консольного порядка на определенный интервал времени. О дополнительных параметрах sshguard можно почитать в официальной документации и настроить его на свой вкус. Мы же использовали настройки по умолчанию. Более детально я лишь рассмотрю саму команду запуска:

    ExecStart=/bin/sh -c 'journalctl --no-pager -q -f -t sshd | sed -u "s/\\[[0-9]*\\]//" | docker run -i --name sshguard --rm --net=host --privileged local/sshguard'

    так как все логи у нас через journalctl попадают на сервер логирования, нам их нужно извлечь, при этом отфильтровать и передать на вход sshguard стартующим в контейнере. Параметр --net=host говорит о том, что все действия нам нужно выполнять на нашей машине, где запущен демон Docker, при этом мы запускаем контейнер в привилегированном режиме указывая ключ --privileged.

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

    Это отличный облачный дашборд для управления вашими контейнерами. Но для начала его нужно установить, в случае CoreOS сделать это крайне просто, для этого выполним:

    sudo curl -s http://getnucleus.io/install/coreos_installer.sh | bash -s --

    Подробнее об установке можно почитать тут.

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

    docker run -p 80:80 -p 443:443 --name=nginx nginx

    После выполнения команды у нас в списке появиться контейнер с именем nginx и опубликованными портами 80 и 443. О том как пробросить конфигурацию сервера, файлы и скрипты можно почитать в других статьях, либо в официальной документации. При нажатии на сендвич, в колонке Control Deck можно не только управлять нашим контейнером но и посмотреть потребляемые им ресурсы, память, цпу, сети и прочее.

    В следующей статье я расскажу о том, как организовать инфраструктуру для блога на WP с использованием Varnish, Memcached, PHP7.1-FPM, Nginx, Mariadb, а так же как и какие расширения для php 7.1 включить и как все это настроить. Спасибо за внимание.
    • +15
    • 14,9k
    • 9
    Поделиться публикацией

    Комментарии 9

      0
      После запуска редактора переводим его в режим вставки нажатием клавиши «i» на клавиатуре, и размещаем следующий текст:

      Не критики ради, совета для.
      Если уж человек разбирается с docker'ом, ему такие подробности не нужны. Иначе нужно еще рассказать как запустить терминал.
        0
        Согласен с вами, но статья не только для тех кто разбирается…
          0
          Не все кто разбираются в виртуализации и контейнеризации знают vi! Я например пришел из Windows админов и сетевиков… и докер контейнеры работающие на ZFS в продкашене уже использую но без vi как то обходился… Если в рамках статьи vi обязателен, то я бы на месте автора тоже написал бы точные команды…
            0
            любой редактор подойдет, новичкам я бы советовал mcedit
          0
          Большое спасибо за статью, очень интересно. У меня просьба — не используйте некросовтовский термин «папка» когда вы говорите о *nix, это очень режет слух, директория или каталог звучит куда органичней. К тому же, каждый раз когда кто нибудь так делает, бог убивает одного котёнка(.
            0
            Я не очень люблю кошек, больше собак, поэтому как обладатель охотничий собаки…
            А вообще согласен, каталог и директория как то приятней.
            Просто пишу статью когда не отвлекают, и то умудряются отсюда описки ошибки не точности… на подходе следующие части.
          • НЛО прилетело и опубликовало эту надпись здесь
              +1
              Я как бы не фанат данной ОС, и особых достоинств в ней не наблюдаю. В этой среде сложно с различного рода решениями, которые есть в семействе Linux/Unix. А использовать для мира WEB вообще не вижу смысла эту ос.
              Windows интересна скорей геймерам, так как по долгу моей работы и интересов мне эта ось вообще без надобности, потому как поставленные мной задачи она просто не в состоянии решать без бубна.

              Так что под эту ос, я материалов писать не буду…
              • НЛО прилетело и опубликовало эту надпись здесь

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

            Самое читаемое