LXC контейнеры это простой способ создавать независимые системы, в том числе с разными дистрибутивами, на одном сервере. Рассмотрим как работать с LXC.
Контейнерная виртуализация выполняется на уровне операционной системы, она выгодно отличается, например от KVM тем, что не предъявляет требований к ядру.
LXC контейнеры могут работать на любом сервере с Ubuntu, в том числе на виртуальной машине.
LXC контейнер — гостевая система, которая создается в рамках хоста и создается, а затем администрируется выполнением команд с хоста.
При подготовке данного материала использовалась серверная Ubuntu 20.04. Для других версий существенных отличий быть не должно. При необходимости можно обратиться к документации на официальном сайте.
Все команды кроме тех, что вводятся в консоли гостевой системы выполняются от имени root или с sudo.
Установка LXC
Обновляем информацию о подключенных репозиториях
apt-get update
Устанавливаем необходимые пакеты
apt-get install lxc bridge-utils debootstrap
Дополнительно устанавливаем шаблоны LXC. На их основе можно будет в дальнейшем создавать контейнеры
apt install lxc-templates
После того как процесс завершится сервер желательно перезагрузить поскольку в процессе установки вносились изменения в сетевые настройки — был добавлен интерфейс, на котором будут работать гостевые системы.
Затем можно создавать первый контейнер, именем виртуальной машины будет container. Создавать машину будем из шаблона (ubuntu), все доступные шаблоны находятся в каталоге /usr/share/lxc/templates/ (туда можно загружать свои шаблоны)
lxc-create -n container -t ubuntu
Процесс продолжается довольно долго, в результате создается контейнер с Ubuntu и приватным ip адресом. Пароль стандартного пользователя ubuntu такой же — ubuntu.
Созданный контейнер появится в списке, который можно просмотреть выполнив
lxc-ls -f
Список LXC контейнеров:
Созданный контейнер будет находиться в состоянии STOPED, чтобы работать с гостевой системой его нужно запустить
lxc-start -n container
Запуск созданного контейнера:
Останавливается контейнера или виртуальная машина через lxc-stop
lxc-stop -n container
Данные конкретном контейнере можно посмотреть
lxc-info -n container
Контейнер является полноценной выделенной системой с которой можно работать по SSH
С мастер хоста можно попасть внутрь выполнив:
lxc-console -n container
Оказавшись внутри гостевой системы из нее не так просто выйти, при вводе стандартной комбинации CTRL+D вновь возникнет диалог авторизации покинуть который нельзя. Распространенным способом является работы с виртуальными машинами через console является использование screen. Также можно зайти на хост другой консолью и выполнить команду lxc-stop -n container. Потом включить контейнер.
Лучше для получения доступа использовать SSH обращаясь по приватному ip адресу.
Также гостевой системе можно выделить белый IP адрес и заходить на нее как на любой другой сервер. О настройках сети говорится в заключительной части статьи.
Поскольку LXC контейнер создавался из шаблона логин и пароль стандартные — ubuntu. Если контейнер будет доступен по публичной сети — оказавшись в системе пароль нужно сменить. Это делается с помощью утилиты passwd.
Ненужные lxc контейнеры можно удалять через lxc-destroy
lxc-destroy -n container
Возможности при работе с LXC
С виртуальными машинами можно выполнять ряд операций, позволяющих более гибко использовать технологию. Во всех случаях гостевая система должна быть предварительно остановлена.
LXC контейнер можно склонировать
lxc-clone -o container -n container-clone
Можно создать точный снимок системы, затем восстановиться из него в любой удобный момент (этот функционал идентичен другим системам виртуализации)
lxc-snapshot -n container
Восстановление выполняется так
lxc-snapshot -n container -r snap1
Чтобы восстановить состояние виртуальной машины нужно указать имя снапшота, информацию о всех доступных снапшотах с именами можно вывести в консоль
lxc-snapshot -n container -L
Настройка автозапуска LXC контейнеров
При выключении или перезагрузке хост системы все виртуальные машины выключаются, чтобы они были включены автоматически в конфигурационный файл каждой нужно внести изменения.
Они вносятся в /var/lib/lxc/CONTAINERNAME/config и заключаются в добавлении трех строк, значения второй и третьей директив можно варьировать
lxc.start.auto = 1
lxc.start.delay = 10
lxc.start.order = 40
Выделение контейнерам определенного количества серверных ресурсов
Если машину создать как это было сделано ранее она будет отдельной сущностью, однако будет в то же время использовать все ресурсы хост системы, например диск. В большинстве случаев бывает необходимо выделять машине указанное количество ресурсов.
Все корректировки применимы к существующим машинам, однако они в обязательном порядке должны быть перезагружены для того чтобы изменения в конфигурационных файлах вступили в силу. Можно задавать и для работающих, в таком случае они будут актуальны до перезагрузки — lxc-cgroup -n container memory.limit_in_bytes 512M, после перезагрузки начнут использоваться заданные в конфигурационных файлах.
Ограничение по CPU
Перед внесением изменений останавливаем тестовый LXC контейнер.
mcedit /var/lib/lxc/container/config
lxc.cgroup.memory.limit_in_bytes = 512M
Проверить все ли получилось можно запустив контейнер, затем выполнив следующую команду:
lxc-cgroup -n container memory.limit_in_bytes
Либо можно просто зайти в контейнер и посмотреть сколько памяти доступно командой free
Пример настройки ограничения приведен на скриншоте:
В файл /var/lib/lxc/container/config с помощью текстового редактора mcedit добавлена приведенная выше строка.
Можно использовать режим отладки
lxc-start -d -n container -l debug -o container.log
Затем можно выбрать из лога все упоминания о 'memory' используя grep
Настройки по ограничению памяти можно задать очень тонко, но на практике они применимы для специальных случаев в которых лучше всего обратиться к документации LXC
Ограничение по диску
Ограничить количество пространства на диске хост машины который может использовать LXC контейнер можно несколькими способами: для этого можно использовать LVM или выделить отдельный раздел в /var/lib/lxc/CONTAINAME, примонтировать его, добавить в /etc/fstab.
Второй способ применим чаще, но предполагает ограничение в .img файле, на основе которого создается машина, поэтому поменять объем диска существующей вирт. машины будет сложнее, чем с LVM.
На этапе создания машины нужно выполнить такие действия:
Ограничиваем размер файла при помощи truncate до 1 Гб
truncate -s 1G /var/lib/lxc/container.img
Создаем файловую систему ext4
mkfs.ext4 -F /var/lib/lxc/container.img
Каталог непосредственно под LXC контейнер
mkdir /var/lib/lxc/container
Создание диска для контейнера:
И монтируем раздел
mount -t ext4 -o loop /var/lib/lxc/container.img /var/lib/lxc/container
Монтирование диска:
В /etc/fstab допишем строку для автоматического монтирования раздела после перезагрузки:
mcedit /etc/fstab
/var/lib/lxc/container.img /var/lib/lxc/container ext4 loop 0 0
Теперь при создании контейнера система увидит, что заданное имя container совпадает с именем каталога и раздела и разместит данные в нем, авторизовавшись на виртуальной машине по SSH и выполнив команду df -h можно будет увидеть, что объем файловой системы составляет 1 Гб
lxc-create -t ubuntu -n container
Проверка диска LXC объема контейнера:
LXC контейнеризация и настройки сети
Виртуальные машины по умолчанию получают адреса из приватной сети, создано их может быть сколько угодно много, все машины будут иметь доступ во внешний мир через NAT заданный автоматически при установке в iptables.
Во внешней сети все виртуальные сервера при этом будут видны как один белый адрес, который на самом деле принадлежит хост машине.
Чтобы каждая гостевая система (или некоторые из них) была доступна по белому IP адресу — если хост машине выделено несколько таких адресов — можно настроить виртуальный бридж.
Но проще добавить правило в таблицу NAT цепочки PREROUTING iptables
iptables -t nat -A PREROUTING -d 123.123.123.123/32 -j DNAT --to-destination 10.0.3.141
После добавления правила, все запросы на внешний адрес будут маршрутизироваться на локальный адрес 10.0.3.141. В сети таким образом сервер будет виден как полностью самостоятельная машина (за исключением того, что IP адрес будет разрешаться в имя хост машины).
В случае если LXC контейнеры используются для размещения, например, веб-сервисов — можно также через iptables перенаправлять только запросы к портам веб-сервера.
Либо проксировать запросы на определенный приватный ip адрес с помощью Nginx.
Такой подход обеспечит максимальную безопасность.