Linux контейнеры - установка LXC в Debian GNU/Linux, подробная шпаргалка по командам
Расскажу о том что такое Linux контейнеры (LXC) и где они применяются, как быстро установить поддержку этого механизма в Debian GNU/Linux.
Опишу важные настройки в конфигурационном файле контейнеров. Приведу список часто используемых команд (шпаргалку) - LXC cheat sheet. Кратко и по сути.
Содержание:
- Что такое LXC и для чего это нужно
- Быстрая установка LXC в Debian GNU/Linux
- Список директорий, используемых механизмом LXC
- Конфигурационный файл контейнера и его опции
- DOWNLOAD IMAGES LIST
- LIST & INFO
- MONITOR
- CREATE
- START
- AUTOSTART
- STOP
- WAIT
- FREEZE / UNFREEZE
- EXECUTE
- CONSOLE
- ATTACH
- COPY
- SNAPSHOT
- CHECKPOINT
- DESTROY
- CGROUP
- DEVICE
- Диагностика и решение проблем
- В завершение
Что такое LXC и для чего это нужно
LXC - сокращение от LinuXContainers, мощная система управления контейнерами, использующая общее ядро Linux и механизмы разделения/ограничения пользовательского пространства (имен, ресурсов) для запуска служб и программ. Является свободным программным обеспечением.
Механизм LXC контейнеров построен на основе системы CGroups (Control Groups), которая содержится в ядре Linux и позволяет выделять для работы изолированные пространства имен, ограничивать ресурсы процессов и т.п.
По своей сути LXC - это набор программных средств и утилит, которые позволяют управлять встроенными возможностями ядра Linux по созданию и управлению изолированных окружений. Нечто похожее к LXC есть также в ОС FreeBSD - это называется Jails (клетки, изолированные комнаты для процессов).
Исходя из вышесказанного следует ограничение - запуск LXC возможен только на операционных системах класса GNU/Linux.
В отличии от популярного Docker, который является системой контейнеризации ориентированной на изоляцию отдельных служб и приложений (микросервисы, microservices), LXC - это контейнеризация окружения полноценной ОС, базирующейся на Linux ядре хоста, в которой может работать вся инфраструктура ОС с множеством запущенных программ и служб.
LXC контейнер содержит миниатюрную копию файловой системы ОС с базовым набором программ и скриптов, поэтому в некоторых случаях такие образы могут занимать не мало места.
Например чистый контейнер с Debian Stretch (9) для архитектуры amd64 будет занимать примерно 370 МБ. Образ Alpine GNU/Linux amd64 - примерно 44 МБ.
Как видим, размеры готовых контейнеров не такие уж и большие, тем не менее после установки какого-то необходимого ПО они могут быть значительно выше, что справедливо для любой системы контейнеризации.
LXC контейнеры отлично подойдут если вы собираетесь запустить несколько изолированных друг от друга виртуальных серверов для сетевых многопользовательских игр, систем распределения трафика, socks5-серверов и т.п.
Также это хороший выбор при тестировании и разработке программного обеспечения, обеспечивающий минимальные затраты по ресурсам и времени для поднятия необходимого изолированного окружения.
При необходимости в контейнер можно пробросить одну или несколько директорий и даже отдельных файлов, также можно выполнить проброс устройств с хоста внутрь контейнера (например сделать доступной в контейнере USB-вебкамеру, подключенную к хосту и т.п.).
Хочу отметить удобство клонирования и резервирования контейнеров, доступны снепшоты (snapshots). Например, чтобы сделать резервную копию контейнера достаточно его остановить и упаковать директорию с файлами (rootfs, config) в архив.
Все контейнеры можно держать вместе как на одной машине, так и на отдельных связанных сетью хостах. Конфигурация и управление ими - очень простые.
А еще эта технология поддерживает возможность создания вложенных изолированных контейнеров, то есть в одном из готовых контейнеров вы можете установить LXC и создать внутри еще несколько вложенных изолированных друг от друга контейнеров.
LXC - отличный инструмент!
Быстрая установка LXC в Debian GNU/Linux
Установка среды изоляции и управления LXC очень проста, все необходимое для работы уже содержится в официальных пакетах для GNU/Linux, поэтому нужно выполнить лишь несколько команд и провести простую настройку.
Установка свежего пакета lxc:
sudo apt-get update
sudo apt-get install lxc
Установка пройдет быстро, размер закачиваемых пакетов составит всего лишь несколько мегабайт.
Проверка конфигурации и доступных возможностей:
sudo lxc-checkconfig
Теперь, если с конфигурацией все хорошо, осталось настроить и включить постоянный сетевой мост для контейнеров. Сперва откроем в редакторе файл 'lxc-net':
sudo nano /etc/default/lxc-net
Добавим в этот файл строчку:
USE_LXC_BRIDGE="true"
Сохраним файл и выйдем из редактора (CTRL+X, Y).
Изменим шаблон с опциями настройки по умолчанию для контейнеров, отредактируем файл default.conf:
sudo nano /etc/lxc/default.conf
Добавляем строчки конфигурирования сети и безопасности:
В LXC 3.0 (для Debian 10)
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
В LXC 2.x (для Debian 9)
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
Сохраняем файл и выходим.
Перезапустим сетевую службу для LXC:
sudo systemctl restart lxc-net.service
Проверим создан ли интерфейс виртуального сетевого моста - lxcbr0:
ip a
Если интерфейс присутствует в списке - значит сетевой мост настроен, можно приступать к работе с LXC контейнерами!
IP-адрес и маска сети хостовой машины по умолчанию - 10.0.3.1/24, контейнеры будут получать IP-адреса из подсети 10.0.3.0/24.
Хочу обратить внимание на то, что данной конфигурации вполне достаточно для работы из под привилегированного пользователя (root), но не достаточно для выполнения команд от имени обычного пользователя.
При запуске lxc-команд от пользователя root и от обычного пользователя - размещение контейнеров и файлов с настройками LXC будут отличаться!
О настройке и запуске контейнеров от имени непривилегированного пользователя можно узнать на страничке [2].
Список директорий, используемых механизмом LXC
Для привилегированного пользователя (root):
- /var/lib/lxc - директория где хранятся контейнеры и их настройки;
- /etc/lxc - настройки LXC;
- /etc/default/lxc-net - настройки сетевой подсистемы;
- /var/cache/lxc - скачиваемые образы файловых систем ОС;
- /var/lib/lxcsnaps - тут хранятся снепшоты;
- /var/log/lxc - логи;
- /usr/share/lxc/templates/ - шаблоны.
Для НЕ привилегированного пользователя:
- ~/.local/share/lxc - директория где хранятся контейнеры и их настройки;
- ~/.config/lxc - настройки LXC;
- ~/.cache/lxc - скачиваемые образы файловых систем ОС;
- ~/.local/share/lxcsnaps - тут хранятся снепшоты;
Конфигурационный файл контейнера и его опции
Конфигурационные файлы контейнеров носят имя 'config' и хранятся в директориях соответствующих контейнеров. Например, путь к конфигурационному файлу контейнера 'container1' для привилегированного пользователя - '/var/lib/lxc/container1/config'.
Конфигурационный файл любого из созданных контейнеров можно открыть для редактирования в любом удобном вам текстовом редакторе.
Пример загрузки конфигурационного файла для контейнера 'container1' в консольном редакторе 'nano':
nano /var/lib/lxc/container1/config
Опция для ограничения доступно контейнеру памяти:
# Memory limit = 256M
lxc.cgroup.memory.limit_in_bytes = 256M
Опция для ограничения количества ядер CPU:
# CPU Cores
lxc.cgroup.cpuset.cpus = 1
Монтируем файл /etc/rinetd.conf из хостовой машины в контейнер:
lxc.mount.entry = /etc/rinetd.conf etc/rinetd.conf none bind 0 0
Примечание: путь назначения (в контейнере) не должен начинаться с бек-слеша, это путь относительно корня контейнера.
Монтируем файл блочного устройства /dev/sde внутри контейнера, создаем файл если он не существует в точке назначения:
lxc.mount.entry = /dev/sde dev/sde none bind,optional,create=file
Монтируем директорию /media/zzz на хосте в директорию /var/lib/mysql/zzz внутри контейнера:
lxc.mount.entry=/media/zzz var/lib/mysql/zzz none bind,create=dir 0 0
Монтирование директории /dev/mapper/lvmfs-home из другой файловой системы в контейнер:
lxc.mount.entry = /dev/mapper/lvmfs-home home ext4 defaults 0 2
Настройки автозапуска контейнера (включение, задержка, порядок запуска):
lxc.start.auto = 1
lxc.start.delay = 15
lxc.start.order = 50
Указываем группу для контейнера:
lxc.group = ph0en1x_servers
Перед стартом контейнера 'container1' выполнить 'хук' (hook) - запустить скрипт 'prepare-start.sh', который лежит в директории контейнера (рядом с конфигурационным файлом):
lxc.hook.pre-start = /var/lib/lxc/container1/prepare-start.sh
Список других полезных хуков для LXC:
Опция | Описание | Исполнение скрипта |
lxc.hook.pre-start | Перед стартом контейнера (окончание загрузки консоли, монтирования файловых систем) |
Хост |
lxc.hook.pre-mount | Перед монтированием rootfs | Контейнер |
lxc.hook.mount | После монтирования файловых систем, перед pivot_root |
Контейнер |
lxc.hook.autodev | После процедуры монтирования и других хуков связанных с монтированием, перед pivot_root |
Контейнер |
lxc.hook.start | Прямо перед инициализацией INIT | Контейнер |
lxc.hook.stop | После остановки контейнера | Хост |
lxc.hook.post-stop | После остановки контейнера | Хост |
lxc.hook.clone | Когда контейнер склонирован | Хост |
lxc.hook.destroy | Когда контейнер уничтожен | Хост |
lxc.network.script.up lxc.net.[i].script.up |
После создания сетевого интерфейса | Хост |
lxc.network.script.down lxc.net.[i].script.down |
Перед уничтожением сетевого интерфейса |
Хост |
Список сетевых настроек контейнера:
Опция | Описание | Примеры значений |
lxc.network.type lxc.net.[i].type |
Тип сетевой вирутализации | none, empty, veth, vlan, macvlan, phys |
lxc.network.link lxc.net.[i].link |
Сетевой интерфейс на Хосте | eth0, wlan0... |
lxc.network.flags lxc.net.[i].flags |
Действие, выполняемое на машине | up |
lxc.network.hwaddr lxc.net.[i].hwaddr |
MAC-адрес сетевого интерфейса | 00:16:3e:11:22:33 |
lxc.network.mtu lxc.net.[i].mtu |
Maximum Transfer Unit (MTU) | 1500 |
lxc.network.name lxc.net.[i].name |
Имя сетевого интерфейса | |
lxc.network.ipv4 lxc.net.[i].ipv4 |
IPv4 адрес интерфейса | 10.0.3.55/24 |
lxc.network.ipv4.gateway lxc.net.[i].ipv4.gateway |
IPv4 адрес шлюза | 10.0.3.1/24 |
lxc.network.ipv6 lxc.net.[i].ipv6 |
IPv6 адрес интерфейса | |
lxc.network.ipv6.gateway lxc.net.[i].ipv6.gateway |
IPv6 адрес шлюза |
Примечание: опции формата "lxc.net.[i]." - для LXC версии 3.0. Где "[i]" - цифра, номер сетевого интерфейса. Например: "lxc.net.0.ipv4" - для первого сетевого интерфейса.
Более детальную информацию о конфигурационном файле для контейнера в LXC можно узнать из [3] или же используя встроенную в GNU/Linux справочную систему man:
man lxc.container.conf
DOWNLOAD IMAGES LIST
Как узнать список доступных к скачиванию образов в LXC? - достаточно запустить команду создания контейнера с опцией "-t download" без указания архтекутры, имени и версии образа. На экран будет выведен весь список хранящихся удаленно образов, программа попросит вас выбрать дистрибутив.
Пример команды:
lxc-create --template download --name test1
Вот часть из вывода команды:
Setting up the GPG keyring
Downloading the image index
---
DIST RELEASE ARCH VARIANT BUILD
---
alpine 3.10 amd64 default 20190921_13:00
alpine 3.10 arm64 default 20190921_13:00
.......
debian sid s390x default 20190922_05:24
debian stretch amd64 default 20190922_05:24
debian stretch arm64 default 20190922_05:24
debian stretch armel default 20190922_05:24
debian stretch armhf default 20190922_05:55
debian stretch i386 default 20190922_05:24
debian stretch ppc64el default 20190922_05:24
debian stretch s390x default 20190922_05:24
.......
voidlinux current i386 default 20190921_17:10
---
Distribution:
Для создания контейнера на основе Debian - вводим слово 'debian', на запрос релиза - например, 'stretch', а на запрос архитектуры, например 'amd64'.
Если контейнер не нужно создавать, то для отмены можно нажать CTRL+C.
LIST & INFO
Узнаем версию установленной подсистемы LXC:
lxc-info --version
Список существующих (в директории хранения по умолчанию) контейнеров (только имена):
lxc-ls
Список существующих контейнеров включая информацию (статус, автозапуск, группы, IPv4/6):
lxc-ls -f
Список контейнеров, работающих из директории (тома) '/media/ssd1':
lxc-ls -f -P /media/ssd1
lxc-ls -f --lxcpath=/media/ssd1
Информация о контейнере 'container1':
lxc-info -n container1
Пример вывода этой команды:
Name: container1
State: RUNNING
PID: 32293
IP: 10.0.3.152
CPU use: 0.35 seconds
BlkIO use: 16.00 KiB
Memory use: 17.21 MiB
KMem use: 3.71 MiB
Link: vethVQSF7J
TX bytes: 1.58 KiB
RX bytes: 1.28 KiB
Total bytes: 2.85 KiB
Также узнать используемый контейнером размер памяти можно следующей командой:
cat /sys/fs/cgroup/memory/lxc/container1/memory.usage_in_bytes
Заменив в вышеприведенной команде 'memory.usage_in_bytes' на 'memory.stat' можно узнать очень подробную информацию по использованию памяти в указанном контейнере.
MONITOR
Мониторинг состояний контейнера 'container1':
lxc-monitor -n container1
Мониторинг нескольких указанных контейнеров:
lxc-monitor -n 'container1|container2'
Мониторинг по шаблону для имени (начинается со слова 'container' либо с буквы 'X'):
lxc-monitor -n '[container|X].*'
CREATE
Создать контейнер 'container1', предлагая перед этим выбрать дистрибутив:
lxc-create -t download -n container1
Создать контейнер с образом ОС Debian и релизом Stretch:
lxc-create -n container1 -t debian -- -r stretch
Создать контейнер с ОС Debian, релизом Stretch и архитектурой amd64:
lxc-create -t download -n container1 -- -d debian -r stretch -a amd64
Создать контейнер с Debian Jessie (8) с ограниченной файловой системой размером 10ГБ:
lxc-create -B loop --fssize 10G -t debian -n container1 -- -r jessie
Создать контейнер, разместив его содержимое в директории '/media/ssd1/container1':
lxc-create -P /media/ssd1/ -n container1 -t debian -- -r stretch
lxc-create --lxcpath==/media/ssd1 -n container1 -t debian -- -r stretch
START
Запуск контейнера 'container1'
lxc-start -n container1
Запуск контейнера, хранящегося в директории '/media/ssd1':
lxc-start -P /media/ssd1 -n container1
Запуск в фоновом режиме (daemon):
lxc-start -n container1 -d
Запуск с записью лога в файл /var/log/lxc.log:
lxc-start --logfile=/var/log/lxc.log -d -n container1
Запуск + запись лога в файл + установка приоритета логирования 'DEBUG':
lxc-start -d -l DEBUG --logfile=debug.log -n container1
Список значений для опции '-l': FATAL, CRIT, WARN, ERROR, NOTICE, INFO, DEBUG.
Запуск контейнера на переднем плане (автоматическое подключение к консоли):
lxc-start --foreground -n container1
AUTOSTART
Запуск контейнеров, у которых в конфигурационном файле установлена опция ' lxc.start.auto'.
Список контейнеров с опцией автозапуска:
lxc-autostart --list
Запуск всех контейнеров имеющих возможность автозапуска:
lxc-autostart --all
Вывести список контейнеров в группе 'socks5':
lxc-autostart --list --group socks5
Запуск всех контейнеров в группе 'socks5':
lxc-autostart --group socks5
Запуск групп контейнеров в порядке их указания:
lxc-autostart -g "lamp,socks5,mangos"
STOP
Остановка контейнера 'container1':
lxc-stop –n container1
Принудительно завершить работу контейнера (без корректной остановки, KILL):
lxc-stop -k -n container1
WAIT
Ожидаем пока контейнер 'container1' не окажется в статусе STOPPED:
lxc-wait -n container1 -s 'STOPPED'
Ждем когда контейнер получит любой из статусов - RUNNING или STARTING:
lxc-wait -n container1 -s 'RUNNING|STARTING'
Список возможных статусов контейнера:
- RUNNING;
- STOPPED;
- STARTING;
- STOPPING;
- ABORTING;
- FREEZING;
- FROZEN.
FREEZE / UNFREEZE
Заморозить процессы в контейнере 'container1':
lxc-freeze -n container1
Разморозить этот же контейнер:
lxc-unfreeze -n container1
Узнать статус заморозки у контейнера:
cat /sys/fs/cgroup/freezer/lxc/container1/freezer.state
EXECUTE
Запуск приложения 'app1.bin' в контейнере 'container1':
lxc-execute -n container1 app1.bin
CONSOLE
Подключение текущего терминала к консоли контейнера 'container1':
lxc-console -n container1
Для отключения используйте комбинацию клавиш CTRL+A, потом нажмите Q.
ATTACH
Запуск процесса 'passwd' в запущенном контейнере 'container1' для установки пароля суперпользователя:
lxc-attach -n container1 passwd
Запуск командного интерпретатора BASH внутри контейнера и доступ к нему в текущем терминале:
lxc-attach -n container1 /bin/bash
Выйти из запущенного в контейнере интерпретатора команд можно введя команду 'exit' или же нажав комбинацию клавиш CTRL+D.
Запуск в контейнере команды 'df' с ключем '-h' (вывод статистики файловых систем контейнера):
lxc-attach -n container1 -- df -h
Разделитель '--' указывает на то что следующие параметры не нужно интерпретировать как параметры команды 'lxc-atatch', а отнести их к команде для выполнения внутри указанного контейнера.
COPY
Копирование контейнера под именем 'container1' в новый контейнер под именем 'container1_COPY':
lxc-copy -n container1 --newname container1_COPY
Копирование контейнера 'lamp-server', размещенного в директории /media/ssd1 в контейнер под названием 'lamp-srv-clone' (будет размещен в той же директории):
lxc-copy -n lamp-server -P /media/ssd1 --newname lamp-srv-clone
SNAPSHOT
Вывести список снепшотов для контейнера 'container1':
lxc-snapshot -n container1 -L
Создать снепшот для этого же контейнера:
lxc-snapshot -n container1
Восстановить состояние контейнера 'container1' из снепшота 'snap0':
lxc-snapshot -n container1 -r snap0
Создать (восстановить) контейнер 'container1-from-snap0' из снепшота 'snap0', созданного для контейнера 'container1':
lxc-snapshot -n container1 -r snap0 container1-from-snap0
CHECKPOINT
Сохранить состояние контейнера на диск (в директории '/media/checkpoint') с последующей возможностью восстановления этого состояния:
lxc-checkpoint -n container1 -D /media/checkpoint
Восстановление состояния контейнера:
lxc-checkpoint -r -n container1 -D /media/checkpoint
DESTROY
Уничтожить контейнер 'container1':
lxc-destroy -n container1
Примечание: перед уничтожением контейнер должен быть остановлен.
CGROUP
Получить значение лимита памяти в Байтах для контейнера 'container1':
lxc-cgroup -n container1 memory.limit_in_bytes
Примечание: если значение с лимитом памяти для контейнера не было установлено то команда выведет очень большое целое число.
Установка лимита памяти для контейнера - 256МБ:
lxc-cgroup -n container1 memory.limit_in_bytes 256000000
Установка лимита памяти для контейнера - 512МБ:
lxc-cgroup -n container1 memory.limit_in_bytes 512M
Другие значения параметров для возможной установки:
- cpu.shares - приоритет использования CPU, пример: A = 2000, B = 1000 - контейнер B будет иметь в 2 раза меньший приоритет по использованию ЦПУ чем контейнер A;
- cpuset.cpus - количество и/или номера ядер CPU для использования в контейнере, примеры: 0,1,2 или 0-3;
- memory.memsw.limit_in_bytes - суммарный лимит памяти (ОЗУ + файл подкачки);
- blkio.weight - приоритет использования блочной системы ввода-вывода (IO).
Более подробную информацию по CGroups вы можете узнать по ссылке [3].
DEVICE
Подключение (проброс) устройства с файлом '/dev/video0' (напрмиер веб-камера) в контейнер 'container1':
lxc-device -n container1 add /dev/video0
Подключение сетевого адаптера с интерфейсом 'veth0' (на хост-машине) к контейнеру и назначение в ненм нового имени интерфейса eth1:
lxc-device -n container1 add veth0 eth1
Диагностика и решение проблем
Может случиться так, что в какой-то момент (после высокой загруженности сервера, перевода лептопа в спящий режим и т.п.) созданный LXC контейнер потерял свой IP-адрес или же и вовсе создаваемые контейнеры перестали получать сетевые настройки.
В такой ситуации, первым делом нужно проверить работу сервисов на хост-машине. Смотрим присутствует ли в системе сетевой интерфейс (мост, bridge) для LXC-контейнеров и каковы его настройки:
ip a show lxcbr0
Если с этим интерфейсом все хорошо, то в результате исполнения команды увидим IP-адрес моста и другие параметры:
5: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 10.0.3.1/24 scope global lxcbr0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fe00:0/64 scope link
valid_lft forever preferred_lft forever
Для получения контейнерами сетевых настроек от хостовой машины механизмом LXC используется служба "dnsmasque", проверяем запущена ли она:
ps ax | grep "[d]nsmasq"
Если служба работает и присутствует в процессах, то в выводе вышеуказанной команды мы увидим строку, где будет указан PID процесса и его параметры, например (для удобства чтения я перенес параметры в отдельные строчки):
16734 ? S 0:00 dnsmasq -u dnsmasq --strict-order --bind-interfaces
--pid-file=/run/lxc/dnsmasq.pid --listen-address 10.0.3.1
--dhcp-range 10.0.3.2,10.0.3.254 --dhcp-lease-max=253 --dhcp-no-override
--except-interface=lo --interface=lxcbr0
--dhcp-leasefile=/var/lib/misc/dnsmasq.lxcbr0.leases --dhcp-authoritative
Как видим, здесь указан интерфейс и IP-адрес сетевого моста, на котором работает служба, а также пул адресов, доступный для присваивания LXC-контейнерам (2-254).
Теперь переходим к диагностике сети внутри контейнера, приведенные ниже команды должны выполняться в консоли запущенного LXC-контейнера.
Смотрим список доступных и активных сетевых интерфейсов внутри контейнера:
ip a
При настройках по умолчанию, как правило, в списке должны присутствовать минимум 2 сетевых интерфейса:
- lo - loopback (локальная петля), локальный сетевой интерфейс;
- eth0 - сетевой интерфейс, связанный с хост-машиной.
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:53:02:cd brd ff:ff:ff:ff:ff:ff
inet 10.0.3.139/24 brd 10.0.3.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fe53:2cd/64 scope link
valid_lft forever preferred_lft forever
Если у сетевого интерфейса eth0 нет IP-адреса, то возможно что причина таится где-то в самом контейнере и его службах.
Посмотрим получил ли контейнер список DNS-серверов от сервиса dnsmasq, запущенного на хост-машине, выполним команду внутри контейнера:
cat /etc/resolv.conf
В случае если все сконфигурировано правильно, в выводе получим строчку:
nameserver 10.0.3.1
Если же полученных настроек IP-адреса и DNS-сервера в контейнере нет, то можем заставить его сделать повторную попытку получения этих сетевых настроек по протоколу DHCP от хост-машины:
dhclient -r
Теперь можем пропинговать какой-то сайт и проверить корректно получены ли сетевые настройки:
ping reddit.com
Исправность работы сетевого механизма LXC-системы проще всего проверить создав какой-нибудь новый контейнер. Если новосозданные контейнеры не получают сетевых натсроек - проблема, скорее всего, на стороне хост-машины, в каком-то звене сетевой подсистемы LXC.
Очень вероятно что проблему удастся решить перезапуском сетевой службы LXC на хост-машине:
systemctl restart lxc-net.service
Для перезапуска всего механизма LXC:
systemctl restart lxc.service
Если и это не помогло, то может быть что где-то сбились основные настройки сети LXC, стоит перепроверить все параметры, которые были задействованы на этапе установки и настройки механизма LXC.
Еще не помешает проверить правила файрвола IPTables, которые могут блокировать сетевые пакеты на пути от хост-машины к контейнерам.
В более сложных случаях возможна даже не работоспособность самой службы "dnsmasq", нужно изучить ее логи и на основе этих данных устранить проблему.
Еще одна проблема, которая может возникать - невозможность получения GPG ключей от доверенных серверов по причине их перегрузки или неработоспособности.
Результатом станет то, что скачать шаблон и создать из него контейнер не получится, будет выдана следующая ошибка:
Setting up the GPG keyring
ERROR: Unable to fetch GPG key from keyserver
lxc-create: test1: lxccontainer.c: create_run_template: 1617 Failed to create container from template
lxc-create: test1: tools/lxc_create.c: main: 327 Failed to create container test1
Решить эту проблему можно экспортировав в окружение специальную переменную, в которой указать адрес сервера с которого должны браться ключи.
# Set environment variable
# Also you can add this command in your ~/.bashrc
export DOWNLOAD_KEYSERVER="pgp.mit.edu"
# Run commands
lxc-create ...arguments...
Список некоторых доверенных серверов, для пробы:
- pgp.mit.edu
- keyserver.ubuntu.com
Также при запуске команды 'lxc-create' можно отключить проверку цифровой подписи для скачиваемого шаблона, для этого достаточно добавить опцию '--no-validate'. Но я так делать не рекомендую!
В завершение
В дополнение к приведенной выше шпаргалке по командам могу сказать что документация по ним всегда есть под рукой - это система man pages. Пример вызова справки по команде lxc-snapshot:
man lxc-snapshot
LXC - очень мощный и относительно не сложный в использовании инструмент, позволяющий запускать в изолированной среде исполнения как отдельные приложения, так и целые связки из приложений. При этом каждое приложение будет работать в полноценной среде выбранной операционной системы Debian, Ubuntu, CentOS, Alpine и т.п.
Открытый исходный код, свобода распространения и простая установка из репозитория GNU/Linux делают эти контейнеры очень привлекательными для использования в тестировании и разработке программ и информационных систем.
Используя вышеприведенные команды можно построить небольшой менеджер для удобного управления Linux-контейнерами на одном из популярных языков программирования или и вовсе на SH/Bash-скриптах.
Полезные ссылки и литература:
- https://linuxcontainers.org/
- Debian Wiki - LXC;
- kernel.org - CGroups v.1
- lxc.container.conf manpage
- Ivanov K. - "Containerization with LXC", 2017.
Thanks !!
Добавлен пример конфигурационного файла для настройки постоянного сетевого моста под GNU/Linux Debian 10 (Buster).