LXC контейнеры в Ubuntu


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 контейнеров:

lxc контейнеры


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

lxc-start -n container



Запуск созданного контейнера:

lxc start


Останавливается контейнера или виртуальная машина через 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

Пример настройки ограничения приведен на скриншоте:

lxc лимит по ram


В файл /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


Монтирование диска:

монтирование диска для lxc контейнера


В /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.

Такой подход обеспечит максимальную безопасность.

Сказать спасибо