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

    О чем мы расскажем:

    — Почему мы решили перейти на LXC контейнеры?
    — Как создать контейнер и запустить на нем хост на базе Битрикс?

    Для кого это будет полезно:

    Для всех, кто хочет попробовать новое решение, при этом используя меньше ресурсов.

    Преимущества LXC перед виртуальными машинами


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

    1. Меньше потерь производительности CPU, дисковых операций и оперативной памяти. Почти всё, что доступно в контейнере, работает со скоростью сервера.
    2. Не нужно выделять оперативную память под ядро ОС, видеопамять, дисковые буферы и т.д.
    3. Быстрый запуск. Фактически запускаются только те приложения, которые необходимы для работы контейнера.
    4. Поддерживается запуск в контейнере отдельных приложений, а не полной системы. Удобно, что доступы можно выдавать простым добавлением пользователя, (а не chroot), так как у нас только один проект в контейнере (на виртуалках было несколько).
    5. Возможность управлять ресурсами каждого контейнера.
    6. Быстро и легко перемещать контейнеры между серверами.

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

    rsync -alvz старыйСервер:/var/lib/lxd/container/test/ /var/lib/lxd/container/test/

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

    Посмотреть статистику потребления ресурсов можно командой: lxc info test

    Remote: unix://
    Архитектура: x86_64
    Создано: 2018/12/04 14:27 UTC
    Status: Running
    Type: persistent
    Профили: default
    Pid: 28317
    IPs:
    eth0:	inet	172.27.2.204	vethF91F2U
    Resources:
    Процессы: 56
    CPU usage:
    Использование ЦП (в секундах): 20583
    Memory usage:
    Memory (current): 1.03GB
    Memory (peak): 3.11GB
    Network usage:
    eth0:
    Получено байтов: 17.45GB
    Отправлено байтов: 9.93GB
    

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

    • lxc config set test limits.memory 2048M # устанавливаем лимит памяти.
    • lxc config set test limits.cpu 1,2,3,8 # привязываем контейнер к ядрам CPU.
    • lxc config set test cpu.allowance 10% # ограничиваем потребление ресурсов CPU.
    • lxc config set test root size 50GB # ограничиваем объём используемого контейнером дискового пространства(работает только с ZFS или btrfs).
    • lxc config get test limits.memory – просматриваем установленное значение лимита

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

    Настраиваем сервер и переносим стандартный хост с Bitrix из виртуалки на контейнер


    1. Настройка сервера

    1.1 Устанавливаем на сервер последнюю версию Ubuntu 18.04 server. В ней уже есть LXD. LXD это надстройка над LXC, гипервизор, который упрощает взаимодействие с системой контейнеризации.
    1.2 apt install bridge-utils # установим bridge-utils
    1.3 lxd init # инициализируем lxd
    1.4 lxc profile edit default # редактируем файл профиля:

    devices:
    eth0:
    name: eth0
    nictype: bridged
    parent: br0
    type: nic
    root:
    path: /
    pool: default
    type: disk
    name: default
    

    1. 5 lxc launch ubuntu:18.04 test # создаем контейнер с названием test. Он сам скачает образ, создаст и запустит его. На этом настройка и создание контейнера закончены, дальше переходим к настройке контейнера и переносу хоста на него.

    2. Настройка контейнера для хоста и перенос сайта

    2.1 lxc exec test /bin/bash # Заходим в созданный контейнер.
    2.2 add-apt-repository ppa:ondrej/php # Добавляем репозиторий.
    2.3 apt update # Обновляем репозиторий.
    2.4 apt install
    php7.1{fpm,bcmath,bz2,cli,common,curl,dev,enchant,fpm,gd,gmp,imap,intl,json,
    ldap,mbstring,mcrypt,mysql,odbc,opcache,phpdbg,pspell,readline,recode,soap,
    tidy,xml,xmlrpc,xsl,zip} #
    Устанавливаем php и все нужные модули для битрикса.
    2.5 apt install nginx # Устанавливаем nginx.
    2.6 vim /etc/netplan/50-cloud-init.yaml # Делаем ip статичным:

    network:
    version: 2
    ethernets:
    eth0:
    addresses: [172.27.2.108/16]
    gateway4: 172.27.0.1
    nameservers:
    addresses: [172.27.1.1]
    dhcp4: false

    2.7 Копируем конфиги php и nginx с нашей виртуалки, проверяем, что все запускается и работает.
    2.8 Переносим весь сайт с нашей виртуалки. Например:

    rsync -alvz стараяВиртуалка:/var/www/ /var/www/

    3. Создание отдельного контейнера для базы данных

    3.1 Повторим шаги 1.5, 2.1 и 2.6, назвав контейнер к примеру test-db.
    3.2 apt install mysql-server # установим БД
    3.3 apt install pv # Установим PV, чтобы видеть прогресс, когда будем заливать БД.

    4. Настройка нового сервера БД

    Для начала соберем информацию со старого сервера:

    4.1 Нам понадобится user и pass от нужной базы.
    4.2 mysql -u test -p'test' -e «show create database testDB;» # Узнаем как создана БД (то, что нам понадобится выделено):

    mysql: [Warning] Using a password on the command line interface can be insecure.
    +----------+--------------------------------------------------------------------------+
    | Database | Create Database |
    +----------+--------------------------------------------------------------------------+
    | demoshop | <b>CREATE DATABASE `demoshop` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */ |</b>
    +----------+--------------------------------------------------------------------------+

    4.3 mysqldump -ER --single-transaction --quick testDB | gzip > testDB.sql.gz # Выполним эту команду на сервере, где лежит наша БД. Она сделает дамп и сожмет его в архив.

    Зайдем в нашу новую базу и выполним следующие действия:

    4.4 rsync -alvz стараяБД:/root/ testDB.sql.gz /root/ # перенесем архив с дампом на наш контейнер.
    4.5 mysql # Зайдем в нашу базу
    4.5.1 CREATE USER 'user'@'%' IDENTIFIED BY 'pass'; # создадим такого же пользователя и пароль.
    4.5.2 Из пункта 4.2 введем команду: CREATE DATABASE `имяБД` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */;
    4.5.3 GRANT ALL PRIVILEGES ON имяБД .* TO 'user'@'%' IDENTIFIED by 'pass'; # Дадим права нашей базе.
    4.6 Выйдем из базы и из консоли контейнера выполним: pv testDB.sql.gz |zcat | mysql testDB # Заливаем дамп в нашу базу

    5. Проверка

    5.1 Меняем параметры подключения к БД, указываем новый IP нашей базы.
    5.2 После этого сайт должен открываться по IP или DNS, это зависит от вашей конфигурации.

    Заключение


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

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

      +1
      proxmox/opennebula — из коробки lxc

      пост имхо ну такое… бенчмарков для сравнения под нагрузкой lxc vs kvm нет

      PS: битрикс и в docker разворачивается, и еще тоньше в управлении и конфигурации
        0
        proxmox/opennebula — работают через виртуальные диски, что создает неудобства при планировании ресурсов.
        Про docker — да, мы знаем, делали, но кейс состоял в предоставлении разработчикам более привычного окружения командной строки
          0
          Опишите тогда вашу архитектуру с дисками, т.к. кроме как вынести файлы и сам сервер баз даных в контейнер, я не вижу разницы с docker. То-есть, разработчику нужен bash/php cli? но это ведь делается и запуском комманды из контейнера… Чет я кейса не пойму вашего.

          Firecracker пробовали?
            0
            Один из кейсов, почему мы перешли на LXC\LXD, это уменьшение комплексной сложности. Поэтому выбиралось самое доступное из применимых решений
            0

            А в чём выражается это неудобство при планировании ресурсов? Не могли бы вы уточнить?
            К контейнерам в docker'е ведь тоже можно подключаться по cli, а если ещё и кластер k8s, то, например, тот же Gitlab со своими Environment'ами мог совсем красоту навести (там можно к окружению подключиться прямо из интерфейса).

              +1
              Неудобство при планировании ресурсов — оверхед на виртуализацию, необходимость иметь выделенное хранилище под образы ВМ, отсутствие гибкости в использовании дискового пространства. С контейнерами всё сильно упрощается, до уровня «скопировал-вставил».

              Это всё тоже есть, используем k3s в тех же lxc контейнерах или в KVM виртуалке, но не всегда удобно и нужно. Докер используется для портативных сред разработки. Многие проекты приходят с классическим деплоем, или заказчик не хочет docker+k8s, таких кейсов, к сожалению, пока подавляющее большинство. К тому же, по нашему опыту, для многих специалистов контейнеры до сих пор выглядят как магия, или что то сильно оторванное от реальности. В общем случае, мы предпочитаем работать тем инструментом, который подходит к реализации конкретной задачи
                0

                Но ведь в Proxmox хранилищем может быть и обычная директория? Никто не заставляет иметь отдельное хранилище. Зато GUI и API, а значит и возможности гибкого управления. А оверхед lxc вы итак имеете, а проксмокс просто набор скриптов над ним.

          +1

          В своём опыте применения LXC, главная боль — переименование параметров в файлах конфигурации. Очень, очень плохо сделанный transition, из-за чего вся автоматизация пошла плохим путём.

            0
            Мы используем гипервизор для контейнеров lxd, проблем с автоматизацией развертывания не испытывали
              +1

              С какой версии дистрибутива вы начали и на какой вы сейчас?

                0
                Начали с ubuntu 16.04, перешли на 18.04
            0
            rsync -alvz
            буква l лишняя, z скорее всего тоже, какой смысл сжимать передаваемые данные.

            php7.1{fpm,bcmath,bz2,cli,common,curl,dev,enchant,fpm,gd,gmp,imap,intl,json,ldap,mbstring,mcrypt,m
            тут явно недописана строка, притом что развернется она в названия вида php7.1common, а в репозитории php7.1-common
              0
              При форматировании публикации, часть строки оказалась вне поля зрения, благодарим за внимательность, поправили
              +2
              Можно не ставить pv, а обойтись параметром «status=progress» в команде dd. Не надо ставить лишний софт на сервера, это плохая привычка.
                0
                А как Вы предлагаете использовать dd в данном случае?
                  +1
                  «pv testDB.sql.gz» меняется на «dd if=testDB.sql.gz status=progress»
                  Если ключ of для dd не указан, то вывод файла будет осуществлён в stdout — на экран, либо в пайп. Больше ничего менять не нужно при этом.
                +1
                Вот несколько ключевых преимуществ LXC перед виртуальными машинами

                А где же недостатки?
                  +1
                  А недостатки — недостаточная изолированность, используется общее ядро
                    0
                    То-есть вы жертвуете безопасностью, ради удобства для программистов? :)
                      0
                      У нас сервера находятся в закрытом контуре, доступны только внутри сети
                  0
                  Намучался в ProxMox с этими вашими контейнерами. Ну их подальше. Для тестов хорошо, а так, одно баловство.
                    0

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

                      +1
                      У нас CEPH, LXC контейнеры не работают с libceph, нужно использовать драйвер ядра специально для контейнеров. Если в контейнере что с большой нагрузкой, контейнер зависал. Нету live migration для них.
                        0

                        А чем тогда пользуетесь? Какую версию использовали или используете?

                          +1
                          Контейнеры достались в наследство. Большинство переделали в виртуалки. Остальное, наверное, живёт. ProxMox 4, а потом 5. Контейнеры труднее мониторить, к примеру. Как у них замерить system load? Будет показывать хоста. А на нём куча виртуалок…
                            0

                            Мне казалось наоборот проще через центральный узел и дерево процессов. Но руки ещё не дошли и пока просто смотрю в GUI, поэтому надо будет проверить.

                    +1

                    А с нагрузкой на дисковую систему что делаете? Мы используем lxc-контейнеры, но вот проблемы возникают с дисками

                      +1
                      Мы используем ssd-cache, об этом напишем статью чуть позже

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

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