LXD позволяет создавать контейнеры и управлять ими. В статье разберём, как настроить LXD и использовать его для запуска Nginx в контейнере. А также рассмотрим, как перенаправить трафик из Интернета в контейнер, чтобы сделать пробную веб-страницу доступной.
Данный материал не претендует на самое современное правильное решение для продакшена, а больше формирует понимание работы контейнеров, существующих альтернатив Docker.
Вам понадобится
сервер под управлением Ubuntu 20.04;
не менее 5 ГБ блочного хранилища. В конфигурации блочного хранилища выберите Manually Format & Mount — это понадобится для хранения всех данных, связанных с контейнерами.
Примечание: начиная с Ubuntu 20.04, LXD официально доступен в виде snap-пакета. Snap-пакет можно установить в любой дистрибутив Linux, поддерживающий snap-пакеты. При запуске LXD snap-пакета рекомендуется использовать сервер с объёмом оперативной памяти не менее 2 ГБ. В таблице приведены общие характеристики LXD snap-пакета:
feature |
snap package |
доступные версии LXD |
2.0, 3.0, 4.0, 4.x
|
требования к памяти |
рекомендуется сервер с 2 ГБ оперативной памяти |
политика обновлений |
можно отложить обновление LXD до 60 дней
|
возможность обновления с другого формата |
можно перейти с deb на snap |
Шаг 1: подготовка среды для LXD
Прежде чем настраивать и запускать LXD, подготовим среду сервера. Для этого добавим пользователя sudo в группу lxd и настроим серверную часть хранилища.
Добавление учётной записи в lxd без полномочий суперпользователя
Добавим учётную запись без полномочий root в группу lxd с помощью команды adduser. В качестве аргументов команда adduser принимает учётную запись пользователя и группу Unix:
sudo adduser sammy lxd
Применим новые привилегии:
su sammy
Введём пароль и нажмём ENTER. Затем подтвердим, что наш пользователь добавлен в группу lxd:
id -nG
Должен получиться такой вывод:
sammy sudo lxd
Подготовка серверной части хранилища
Рекомендуемое хранилище для LXD — файловая система ZFS. Чтобы включить поддержку ZFS в LXD, сначала обновим список пакетов, а затем установим вспомогательный пакет zfsutils-linux:
sudo apt update
sudo apt install -y zfsutils-linux
Мы почти готовы запустить скрипт инициализации LXD. Но, прежде чем сделать это, определим и запишем имя устройства для блочного хранилища. Используем ls, чтобы проверить каталог /dev/disk/by-id/:
ls -l /dev/disk/by-id/
В этом примере полный путь к имени устройства — /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-0:
Запишем полный путь к файлу для устройства хранения. Мы будем использовать его на следующем шаге при настройке LXD.
«Администрирование Linux. Мега»
Шаг 2: инициализация и настройка LXD
LXD доступен в виде snap-пакета в Ubuntu 20.04. Он поставляется предустановленным, но его нужно настроить.
Сначала убедимся, что LXD snap-пакет установлен. Команда snap list показывает установленные snap-пакеты:
snap list
Ubuntu 20.04 предустанавливает LXD 4.0.3, и он отслеживает канал 4.0/stable. LXD 4.0 поддерживается в течение пяти лет (до 2025 года). Он получает только обновления для системы безопасности:
Чтобы найти дополнительную информацию об установленном LXD snap-пакете, запустим snap info lxd. Мы сможем увидеть доступные версии, включая дату последнего обновления пакета.
Настройка параметров хранилища для LXD
Запустим процесс инициализации LXD с помощью команды sudo lxd init:
sudo lxd init
Сначала программа спросит, хотим ли мы включить кластеризацию LXD. Введём no и затем нажмём ENTER:
Следующие шесть подсказок относятся к пулу хранения. Дайте следующие ответы:
ENTER, чтобы настроить новый пул хранения.
ENTER, чтобы принять имя пула хранения по умолчанию.
ENTER, чтобы принять серверную часть хранилища zfs по умолчанию.
ENTER, чтобы создать новый пул ZFS.
yes, чтобы использовать существующее блочное устройство.
Наконец, введём полный путь к имени блочного устройства хранения (это то, что мы записали заранее. Должно быть что-то вроде: /dev/disk/by-id/device_name).
Ответы будут выглядеть следующим образом:
Настройка параметров сети для LXD
LXD спросит, хотим ли мы подключиться к серверу MAAS (Metal As A Server). MAAS — это программное обеспечение, благодаря которому сервер с «голым железом» выглядит и обрабатывается как виртуальная машина.
Мы запускаем LXD в автономном режиме, поэтому примем значение по умолчанию и ответим no:
Дальше нас попросят настроить сетевой мост для контейнеров LXD. Это позволит использовать следующие функции:
контейнеры автоматически получают частный IP-адрес;
контейнеры могут взаимодействовать друг с другом по частной сети;
контейнеры могут инициировать подключение к интернету;
контейнеры по умолчанию остаются недоступным из Интернета — мы не можем инициировать подключение из интернета и получить доступ к контейнеру, если явно не включим это.
На следующем шаге разберём, как разрешить доступ к определённому контейнеру.
Когда нас попросят создать новый локальный сетевой мост, выберем yes:
Затем примем имя по умолчанию, lxdbr0:
Примем автоматический выбор диапазона частных IP-адресов для моста:
LXD задаст несколько вопросов. Когда он спросит, хотим ли мы управлять по сети, нажмём ENTER или ответим no:
На вопрос, хотим ли мы автоматически обновлять устаревшие образы контейнеров, нажмём ENTER или ответим yes:
Когда спросит, хотим ли мы просмотреть и сохранить только что созданную конфигурацию YAML, ответим yes, если хотим. В противном случае нажмём ENTER или ответим no:
Скрипт будет работать в фоновом режиме, чтобы не получать никаких выходных данных.
Мы настроили параметры сети и хранилища для LXD. Теперь можем перейти к созданию первого контейнера LXD.
Шаг 3: создание и настройка контейнера LXD
В LXD мы управляем контейнерами с помощью команды lxc, за которой следует действие: list, launch, start, stop и delete.
Используем lxc list, чтобы посмотреть доступные установленные контейнеры:
lxc list
Поскольку это первый раз, когда команда lxc связывается с гипервизором LXD, она показывает информацию о том, как запустить контейнер. Наконец, она отображает пустой список контейнеров. Это ожидаемо, потому что мы ещё ничего не создали:
Создадим контейнер, который запускает Nginx. Для этого сначала используем команду lxc launch, чтобы создать и запустить контейнер Ubuntu 18.04 с именем webserver.
Создадим контейнер webserver. 18.04 в ubuntu:18.04 — это ярлык для Ubuntu 18.04. ubuntu: — идентификатор предварительно настроенного репозитория образов LXD. Также можем использовать ubuntu:bionic для имени образа:
lxc launch ubuntu:20.04 webserver
Поскольку мы впервые создаём контейнер, эта команда загрузит образ из интернета и кэширует его. Мы увидим такой вывод, как только новый контейнер завершит загрузку:
После запуска контейнера webserver используем команду lxc list, чтобы отобразить информацию о нём. Добавим --columns ns4, чтобы показывать только столбцы для имени, состояния и IPv4-адреса. Команда lxc list по умолчанию показывает ещё три столбца: IPv6-адрес, является ли контейнер постоянным, доступны ли снэпшоты для каждого контейнера:
lxc list --columns ns4
В выходных данных отобразится таблица с именем каждого контейнера, его текущим состоянием, IP-адресом и типом:
DHCP-сервер LXD предоставляет этот IP-адрес, и в большинстве случаев он останется таким же, даже если сервер будет перезагружен. Однако на следующих шагах мы создадим правила iptables для пересылки подключений из интернета в контейнер. Поэтому следует указать DHCP-серверу LXD всегда предоставлять контейнеру один и тот же IP-адрес.
Следующий набор команд сконфигурирует контейнер для получения статического IP-адреса. Сначала переопределим сетевую конфигурацию для устройства eth0, унаследованную от профиля LXD по умолчанию. Это позволит нам установить статический IP-адрес, который обеспечит корректную передачу веб-трафика в контейнер и из него.
lxc config device — команда, которая выполняет действие config для настройки устройства. Первая строка содержит подкоманду override для переопределения устройства eth0 с веб-сервера контейнера. Вторая строка содержит подкоманду для установки поля ipv4.address устройства eth0 контейнера webserver на IP-адрес, который был предоставлен DHCP-сервером в самом начале.
Запустим команду config:
lxc config device override webserver eth0
Получим такие выходные данные:
Теперь установим статический IP:
lxc config device set webserver eth0 ipv4.address your_webserver_container_ip
Если команда выполнена успешно, мы не получим никакого вывода.
Перезапустим контейнер:
lxc restart webserver
Затем проверим состояние контейнера:
lxc list
Мы должны увидеть, что контейнер запущен, а IPV4-адрес — наш статический адрес.
Шаг 4: настройка Nginx внутри контейнера LXD
На этом шаге подключимся к контейнеру webserver и настроим веб-сервер.
Чтобы подключиться к контейнеру, введём команду lxc shell:
lxc shell webserver
Внутри контейнера командная строка будет выглядеть так:
[environment second]
Оболочка, даже если это корневая оболочка, ограничена контейнером. Все, что мы запускаем в ней, остаётся в контейнере и не может выйти на хост-сервер.
Обновим список пакетов и установим Nginx:
apt update
apt install nginx
После установки отредактируем веб-страницу Nginx по умолчанию. В частности, добавим две строки текста, чтобы было ясно, что этот сайт размещён внутри контейнера webserver.
С помощью редактора откроем файл var/www/html/index.nginx-debian.html:
nano /var/www/html/index.nginx-debian.html
Добавим две выделенные фразы в файл:
Сохраним файл и выйдем из текстового редактора.
Теперь выйдем из контейнера:
logout
Как только приглашение сервера по умолчанию вернётся, используем curl, чтобы проверить, работает ли веб-сервер в контейнере. Для этого нам понадобится IP-адрес веб-контейнера, который мы нашли ранее с помощью команды lxc list.
Используем curl для проверки:
curl http://your_webserver_container_ip
В качестве выходных данных мы получим приветственную HTML-страницу Nginx. Она включает в себя наши правки:
Веб-сервер работает, но мы можем получить к нему доступ только на хосте, используя частный IP-адрес. На следующем шаге будем направлять внешние запросы в этот контейнер, чтобы доступ к нашему веб-сайту можно было получить через интернет.
Шаг 5: переадресация входящих подключений к контейнеру Nginx с помощью LXD
Для начала нужно настроить сервер на пересылку любых подключений, которые он может получать по порту 80. Чтобы сделать это, создадим правило iptables для пересылки сетевых подключений.
Для команды iptables требуются два IP-адреса: общедоступный (your_server_ip) и частный (your_webserver_container_ip), который мы можем получить с помощью команды lxc list.
Выполним эту команду, чтобы создать новое правило IPtables:
PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip IFACE=eth0 sudo -E bash -c 'iptables -t nat -I PREROUTING -i $IFACE -p TCP -d $PUBLIC_IP --dport $PORT -j DNAT --to-destination $CONTAINER_IP:$PORT -m comment --comment "forward to the Nginx container"'
Разберём команду:
-t nat
указывает, что мы используем таблицу nat для преобразования адресов;-I PREROUTING
указывает, что мы добавляем правило в цепочку PREROUTING;-i
указывает интерфейс eth0, который является общедоступным сетевым интерфейсом на хосте для дроплетов;-p TCP
говорит, что мы используем протокол TCP;-d $PUBLIC_IP
указывает IP-адрес для правила;--dport $PORT:
указывает порт (например, 80);-j DNAT
говорит, что мы хотим выполнить переход к Destination NAT (DNAT);--to-destination $CONTAINER_IP:" class="formula inline">PORT
говорит, что мы хотим, чтобы запрос направлялся на IP-адрес конкретного контейнера и порт назначения.
Теперь перечислим правила IPTables:
sudo iptables -t nat -L PREROUTING
Вы увидите подобные выходные данные:
Проверим, доступен ли веб-сервер из интернета. Используем команду curl с локального компьютера для проверки подключений:
curl --verbose 'http://your_server_ip'
Увидим заголовки, за которыми следует содержимое веб-страницы, созданной нами в контейнере:
Это подтверждает, что запросы отправляются в контейнер. Сохраним правило брандмауэра, чтобы оно применялось повторно после перезагрузки. Для этого сначала установим пакет iptables-persistent:
sudo apt install iptables-persistent
При установке пакета приложение предложит сохранить текущие правила брандмауэра. Примем и сохраним все текущие правила.
Когда мы перезагрузим компьютер, загрузится правило брандмауэра. А сервис Nginx в контейнере LXD автоматически перезапустится.
Шаг 6: остановка и извлечение контейнеров с помощью LXD
В какой-то момент нам может потребоваться остановить или удалить контейнер. На этом шаге разберём, как сделать это.
Сначала остановим контейнер:
lxc stop webserver
Используем команду lxc list для проверки статуса:
lxc list
Состояние контейнера читается как STOPPED:
Чтобы удалить контейнер, используем lxc delete:
lxc delete webserver
Повторный ввод lxc list показывает, что контейнер не запущен:
lxc list
Команда выведет следующее:
Используем команду lxc help, чтобы просмотреть дополнительные параметры.
Чтобы удалить правило брандмауэра, которое направляет трафик в контейнер, сначала найдём правило в списке правил с помощью команды, которая связывает номер строки с каждым правилом:
sudo iptables -t nat -L PREROUTING --line-numbers
Найдём правило с префиксом в виде номера строки, вот такое:
Используем номер строки, чтобы удалить правило:
sudo iptables -t nat -D PREROUTING 1
Перечислим правила ещё раз, чтобы гарантировать удаление:
sudo iptables -t nat -L PREROUTING --line-numbers
Правило удалено:
Сохраним изменения, чтобы правило не возвращалось при перезапуске сервера:
sudo netfilter-persistent save
Теперь мы можем открыть другой контейнер со своими собственными настройками и добавить новое правило брандмауэра для переадресации трафика на него.
Заключение
В этой статье мы установили и настроили LXD. Затем создали веб-сайт, используя Nginx, работающий внутри контейнера LXD, и сделали его общедоступным в IPtables.
Комментарии (6)
ophil
00.00.0000 00:00snap всего лишь доп. вариант, у этого же автора статья как сделать точно такое же под lxd: https://www.digitalocean.com/community/tutorials/how-to-set-up-and-use-lxd-on-ubuntu-18-04
Johan_Palych
00.00.0000 00:00В Ubuntu 18.04 последний deb-пакет lxd (3.0.3-0ubuntu1~18.04.2)
Начиная с Ubuntu 20.04 только snap (Transitional package - lxd -> snap (lxd))Ну и:
Ubuntu 18.04.6 LTS - End of Standard Support: April 2023 Ubuntu 18.04.6 ESM - Start of ESM: April 2023 End of Life: April 2028 https://ubuntu.com/pro (Free for personal use - Anyone can use Ubuntu Pro for free on up to 5 machines, or 50 if you are an official Ubuntu Community member.)
TIEugene
00.00.0000 00:00lxc-utils
по идее должно быть достаточно, без всякихlxd
.По крайней мере в CentOS достаточно. В убунте не пробовал пока.
den787
00.00.0000 00:001) LXD 4.0 умеет делать не только контейнеры, но и полноценные виртуалки. Ключ --vm
2) Не заморачивался с пробросом портов, настроил сеть в режиме моста, без nat.
13werwolf13
серверное ПО через snap.. какая мерзость. вот по этому убунта и умирает в мучениях.
в нормальных дистрибутивах вроде opensuse и centos (тут подразумеваются все rh based дистры) всё ещё есть возможность поставить lxd в виде rpm пакета из репозиториев.
Johan_Palych
Классический CentOS все(выступал в роли "downstream": собирался из уже сформированных стабильных релизов RHEL)
July 9, 2019 IBM Closes Landmark Acquisition of Red Hat.(IBM закрыла сделку по поглощению Red Hat)
IBM прикрывает халяву:
Red Hat ограничила время поддержки - CentOS Linux 8 will reach End of Life on December 31, 2021.
CentOS Stream "upstream" для RHEL: тестовая обкатка пакетов перед включением в релизы RHEL.