Установка и использование LXD в Ubuntu 16.04

Контейнер Linux – это группа процессов, изолированных от остальной части системы с помощью функций безопасности ядра Linux, таких как пространства имен и контрольные группы. Этот механизм похож на виртуальную машину, но контейнер гораздо легче: он не требует ресурсов на запуск дополнительного ядра или эмулирование аппаратного обеспечения. Это означает, что вы можете легко создать несколько контейнеров на одном сервере.

Представьте, что у вас есть сервер, на котором запущены несколько веб-сайтов. В традиционной установке все веб-сайты представлены виртуальными хостами, которые обслуживаются одним веб-сервером Apache или Nginx. Но с Linux Containers каждый веб-сайт можно изолировать в его собственном контейнере с индивидуальным веб-сервером. Linux Containers позволяет поместить приложение и все  его зависимости в один контейнер, не влияя на систему в целом.

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

Требования

  • Сервер Ubuntu 16.04, настроенный согласно этому мануалу.
  • Опционально: блочное хранилище в 20 Гб или больше. Здесь вы сможете хранить все данные контейнера.

Читайте также:

1: Настройка LXD

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

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

sudo usermod --append --groups lxd 8host

Выйдите из системы и снова войдите, чтобы обновить параметры. После входа в систему вы можете начать настройку LXD.

Начните с бэкэнда. Для LXD рекомендуется использовать файловую систему ZFS, которая хранится в предварительно распределенном файле, либо в блочном хранилище. Чтобы включить поддержку ZFS в LXD, обновите индекс пакетов и установите пакет zfsutils-linux:

sudo apt-get update
sudo apt-get install zfsutils-linux

Теперь можно запустить инициализацию LXD:

sudo lxd init

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

Сначала вам будет предложено создать резервную копию хранилища, где есть два варианта: dir или zfs. Опция dir будет хранить контейнеры в каталогах файловой системы сервера. Опция zfs использует объединенную файловую систему ZFS и диспетчер логических томов.

Используйте опцию zfs, она предлагает более эффективное хранение и высокую отзывчивость. Например, если вы создадите десять контейнеров из одного и того же исходного образа, на диске все они займут пространство только одного образа. В бэкэнде будут храниться только их отличия от исходного образа контейнера.

Name of the storage backend to use (dir or zfs) [default=zfs]: zfs

После выбора zfs вам будет предложено создать новый пул ZFS и выбрать имя для него. Выберите yes, чтобы создать пул, и назовите его lxd:

Create a new ZFS pool (yes/no) [default=yes]? yes
Name of the new ZFS pool [default=lxd]: lxd

Затем программа спросит, хотите ли вы использовать существующее блочное устройство:

Would you like to use an existing block device (yes/no) [default=no]?

Если вы выберете yes, вам нужно будет указать LXD, где найти это устройство. Если вы выберете no, LXD будет использовать предварительно выделенный файл. С помощью этой опции вы будете использовать свободное пространство на самом сервере.

Ниже приведены два раздела, которые помогут вам выполнить настройку в зависимости от того, что вы выберете – предварительно выделенный файл или блочное устройство. Следуйте соответствующему разделу.

Вариант 1: Предварительно выделенный файл

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

Когда программа спросит, хотите ли вы использовать блочное устройство, введите no:

Would you like to use an existing block device (yes/no) [default=no]? no

Затем вам будет предложено указать размер loop device (в LXD это и есть предварительно выделенный файл).

Используйте рекомендуемый размер по умолчанию:

Size in GB of the new loop device (1GB minimum) [default=15]: 15

Как правило, 15 ГБ – действительно наименьший из возможных размеров файла; вы должны выделить достаточное пространство, чтобы у вас осталось не менее 10 ГБ свободного места после создания контейнеров.

После настройки устройства вам будет предложено настроить сеть. Перейдите к разделу 2, чтобы продолжить настройку.

Вариант 2: Блочное устройство

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

Найдите устройство с помощью команды для форматирования тома. В частности, так вы найдете путь, указанный в команде sudo mkfs.ext4 -F. Не запускайте ни одну из команд с этой страницы, так как вам просто нужно найти правильное имя устройства, чтобы указать его в настройке LXD. Имя устройства может выглядеть так:


$ sudo mkfs.ext4 -F /dev/disk/by-id/scsi-0D0_Volume_volume-fra1-01

Также определить имя устройства поможет эта команда:

ls -l /dev/disk/by-id/
total 0
lrwxrwxrwx 1 root root  9 Sep  16 20:30 scsi-0DO_Volume_volume-fra1-01 -> ../../sda

В данном случае устройство называется /dev/disk/by-id/scsi-0D0_Volume_volume-fra1-01. Имя вашего устройства будет отличаться, потому не забудьте откорректировать последующие команды.

Теперь можно продолжить настройку LXD. Когда программа спросит, хотите ли вы использовать блочное устройство, введите yes:

Would you like to use an existing block device (yes/no) [default=no]? yes
Path to the existing block device: /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01

Указав путь к устройству, вы можете приступать к настройке сети.

2: Настройка сети

Настроив бэкэнд, вы должны настроить сетевые соединения LXD.

LXD спросит, хотите ли открыть доступ к LXD по сети. Если вы выберете yes, вы сможете управлять LXD с локального компьютера, не подключаясь к серверу по SSH. Это опасно, потому оставьте значение по умолчанию no:

Would you like LXD to be available over the network (yes/no) [default=no]? no

Если же вы хотите включить эту функцию, пожалуйста, ознакомьтесь с LXD 2.0: Remote hosts and container migration.

Затем программа предложит настроить сетевой мост для контейнеров LXD. Это позволяет использовать следующие функции:

  • Каждый контейнер автоматически получает внутренний IP-адрес.
  • Контейнеры могут взаимодействовать друг с другом через частную сеть.
  • Каждый контейнер может инициировать подключения к Интернету.
  • Контейнеры, которые вы создаете, остаются недоступными из Интернета; вы не можете установить соединение из Интернета и получить доступ к контейнеру, если вы явно не включили его (о том, как разрешить доступ к определенному контейнеру, вы узнаете в следующем разделе).

Когда LXD предложит настроить мост, введите yes:

Do you want to configure the LXD bridge (yes/no) [default=yes]? yes

На экране появится диалоговое окно:

[…]
Would you like to setup a network bridge for LXD containers now?  (yes/no)

Подтвердите создание моста.

Программа предложит выбрать название моста. Примите значение по умолчанию.

Вам будет предложено настроить сеть как для IPv4, так и для IPv6. В этом мануале используется только IPv4.

Когда программа предложит настроить подсеть IPv4, выберите Yes. Программа сообщит о том, что она настроила случайную подсеть. Нажмите Ok, чтобы продолжить.

При запросе валидного IPv4-адреса примите значение по умолчанию.

Когда будет предложено ввести валидную маску CIDR, примите значение по умолчанию.

При запросе первого адреса DHCP примите значение по умолчанию. Сделайте то же самое для последнего DHCP-адреса, а также для максимального количества DHCP-клиентов.

Выберите Yes при запросе NAT для трафика IPv4.

Когда программа предложит настроить подсеть IPv6, выберите No. После завершения настройки сетевых подключений вы увидите следующий вывод:

Warning: Stopping lxd.service, but it can still be activated by:
lxd.socket
LXD has been successfully configured.

Теперь можно создать первый контейнер.

3: Создание контейнера для Nginx

Вы успешно настроили LXD, и теперь можно создать первый контейнер и попробовать управлять им. Для управления контейнерами существует команда lxc.

Используйте lxc list для просмотра доступных установленных контейнеров:

lxc list
Generating a client certificate. This may take a minute...
If this is your first time using LXD, you should also run: sudo lxd init
To start your first container, try: lxc launch ubuntu:16.04
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+

Поскольку это первый случай взаимодействия команды lxc с гипервизором LXD, команда автоматически создала клиентский сертификат для безопасной связи с LXD. Затем команда выводит некоторую информацию о том, как запустить контейнер. В конце она выводит пустой список контейнеров.

Создайте контейнер для Nginx. Для этого запустите команду lxc launch, которая создаст и запустит контейнер Ubuntu 16.04 по имени webserver.

lxc launch ubuntu:x webserver

Символ х в ubuntu:x – это сокращение от Xenial, кодового имени Ubuntu 16.04. ubuntu: — это идентификатор предварительно настроенного репозитория образов LXD. Также в команде можно было указать имя образа ubuntu:16.04.

Примечание: Вы можете найти полный список всех доступных образов Ubuntu с помощью команды:

lxc image list ubuntu:

Полный список доступных образов для других дистрибутивов выведет команда:

lxc image list images:

Поскольку это первый созданный контейнер, команда загрузит образ контейнера из Интернета и кэширует его локально, так что остальные контейнеры на основе этого образа будут создаваться быстрее. По мере создания нового контейнера на экране будет появляться вывод:

Generating a client certificate. This may take a minute...
If this is your first time using LXD, you should also run: sudo lxd init
To start your first container, try: lxc launch ubuntu:16.04
Creating webserver
Retrieving image: 100%
Starting webserver

Снова запросите список контейнеров:

lxc list

В выводе появится таблица, в которой указано имя каждого контейнера, его текущее состояние, IP-адрес, тип и наличие снапшотов.

+-----------+---------+-----------------------+------+------------+-----------+
|  NAME     |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+-----------+---------+-----------------------+------+------------+-----------+
| webserver | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+-----------+---------+-----------------------+------+------------+-----------+

Примечание: Если вы включили протокол IPv6 в LXD, вывод команды lxc list может быть слишком широким для вашего экрана. В таком случае вы можете использовать команду:

lxc list --columns ns4tS

которая показывает только имя, состояние, IPv4, тип и наличие снапшотов.

Запишите IPv4 адрес контейнера. Он понадобится при настройке брандмауэра.

Теперь нужно добавить в контейнер Nginx.

4: Настройка контейнера Nginx

Подключитесь к контейнеру webserver и настройте в нем веб-сервер.

Чтобы подключиться к контейнеру, используйте команду lxc exec, которая принимает имя контейнера и команду, которую нужно выполнить:

lxc exec webserver -- sudo --login --user ubuntu

Первая строка — означает, что здесь заканчиваются параметры для lxc, и остальная часть строки будет передана как команда, которая должна выполняться внутри контейнера. Команда sudo —login —user Ubuntu предоставляет оболочку входа для предварительно сконфигурированной учетной записи ubuntu внутри контейнера.

Примечание: Чтобы подключиться к контейнеру как root, используйте:

lxc exec webserver -- /bin/bash

В контейнере командная строка выглядит так:

ubuntu@webserver:~$

Этот пользователь ubuntu имеет предварительно настроенный доступ к sudo и может запускать команды sudo, не указывая пароль. Эта оболочка ограничена пределами контейнера. Все команды, что вы запускаете в этой оболочке, останутся в контейнере и не повлияют на остальную систему сервера.

Установите Nginx в этом контейнере. Обновите индекс пакетов экземпляра Ubuntu внутри контейнера и установите Nginx:

sudo apt-get update
sudo apt-get install nginx

Затем отредактируйте веб-страницу по умолчанию для этого сайта и добавьте текст, который поможет вам понять, что этот сайт размещен в контейнере webserver. Откройте файл /var/www/html/index.nginx-debian.html:

sudo nano /var/www/html/index.nginx-debian.html

Измените его следующим образом:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx on LXD container webserver!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...

Итак, вы отредактировали файл в двух местах и специально добавили текст о контейнере LXD («on LXD container webserver»). Сохраните файл и выйдите из редактора.

Теперь выйдите из контейнера и вернитесь на главный сервер:

logout

С помощью curl проверьте, работает ли веб-сервер в контейнере. Вам понадобятся IP-адреса веб-контейнеров, которые были найдены ранее с помощью команды lxd list.

curl http://10.10.10.100/

Команда вернет:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx on LXD container webserver!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...

Веб-сервер работает, но получить доступ к нему только через внутренний IP-адрес. Направьте внешние запросы в этот контейнер, чтобы другие пользователи могли получить доступ к веб-сайту.

5: Перенаправление входящих соединений в контейнер Nginx

Последний этап настройки – подключение контейнера webserver к Интернету. Веб-сервер Nginx установлен в контейнер и по умолчанию недоступен из Интернета. Нужно настроить сервер для перенаправления всех подключений по порту 80 в контейнер webserver. Для этого создайте правило iptables.

Читайте также:

Команда iptables требует два IP-адреса: внешний IP-адрес сервера (your_server_ip) и внутренний IP-адрес контейнера nginx (your_webserver_container_ip), который вы можете получить с помощью команды lxc list. Выполните эту команду, чтобы создать правило.

PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip \
sudo -E bash -c 'iptables -t nat -I PREROUTING -i eth0 -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 определяет интерфейс eth0, который является общедоступным интерфейсом по умолчанию.
  • -p TCP определяет протокол TCP.
  • -d $PUBLIC_IP определяет целевой IP-адрес этого правила.
  • —dport $PORT: указывает целевой порт (например, 80).
  • -j DNAT указывает, что нужно выполнить переход к целевому NAT (DNAT).
  • —to-destination $CONTAINER_IP:$PORT сообщает, что запрос должен перейти на IP-адрес конкретного контейнера и целевой порт.

Примечание: Позже вы можете повторно использовать эту команду для настройки правил переадресации, установив переменные PORT, PUBLIC_IP и CONTAINER_IP в начале строки. Просто измените выделенные значения.

Просмотреть список правил IPTables можно с помощью команды:

sudo iptables -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

DNAT       tcp  --  anywhere             your_server_ip       tcp dpt:http /* forward to this container */ to:your_container_ip:80

...

Теперь убедитесь, что веб-сервер действительно доступен из Интернета, обратившись к нему с локального компьютера с помощью команды curl:

curl --verbose  'http://your_server_ip'

Вы увидите заголовки, за которыми следует содержимое веб-страницы, созданной в контейнере:

*   Trying your_server_ip...
* Connected to your_server_ip (your_server_ip) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.0 (Ubuntu)
...
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
...

Это значит, что запросы действительно перенаправляются в контейнер.

Чтобы сохранить это правило брандмауэра, установите пакет iptables-persistent.

sudo apt-get install iptables-persistent

При установке пакета будет предложено сохранить текущие правила брандмауэра. Примите и сохраните все текущие правила.

Теперь правила брандмауэра будут сохраняться даже после перезагрузки сервера. Кроме того, сервис Nginx в контейнере LXD будет автоматически перезагружен.

6: Остановка и удаление контейнера

В дальнейшем вы можете захотеть остановить контейнер и заменить его.

Чтобы остановить контейнер, используйте:

lxc stop webserver

Чтобы проверить состояние контейнера, введите

lxc list
+-----------+---------+------+------+------------+-----------+
|   NAME    |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
+-----------+---------+------+------+------------+-----------+
| webserver | STOPPED |      |      | PERSISTENT | 0         |
+-----------+---------+------+------+------------+-----------+

Удалить контейнер можно с помощью этой команды:

lxc delete webserver

Снова запустите lxc list, и вы увидите, что в системе нет запущенного контейнера:

+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+

Используйте команду lxc help, чтобы просмотреть дополнительные параметры.

Чтобы удалить правило брандмауэра, которое направляет трафик в контейнер, сначала найдите правило в списке с помощью этой команды, которая связывает номер строки с каждым правилом:

sudo iptables -t nat -L PREROUTING --line-numbers

Вы увидите правило, перед которым будет указан номер строки:

Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  --  anywhere             your_server_ip      tcp dpt:http /* forward to the Nginx container */ to:your_container_ip

Чтобы удалить правило, укажите номер строки:

sudo iptables -t nat -D PREROUTING 1

Убедитесь, что правила больше нет:

`sudo iptables -t nat -L PREROUTING --line-numbers`
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination

Сохраните изменения, чтобы правило не восстановилось после перезапуска сервера:

sudo netfilter-persistent save

Теперь вы можете запустить еще один контейнер веб-сервера и добавить новое правило брандмауэра для пересылки трафика на него.

Заключение

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

Читайте также: Обслуживание нескольких сайтов с помощью Nginx, HAProxy и LXD в Ubuntu 16.04

LXD также позволяет делать снапшоты полного состояния контейнеров, что упрощает создание резервных копий и откатывание контейнеров. Если вы установите LXD на двух разных серверах, вы сможете подключить их и мигрировать контейнеры между серверами через Интернет.

Больше информации о LXD можно найти здесь.

Также вы можете попробовать работать с LXD онлайн и выполнить пару руководств, чтобы попрактиковаться.

Tags: , ,