Покрокова інструкція налаштування LXD на Ubuntu 16.04

Дана інструкція містить покроковий алгоритм встановлення та налаштування LXD. Інструкція розглядає наступні теми:
— Установка і запуск контейнера.
— Налаштування мережі.
— Налаштування статичних IP-адрес для контейнерів.
— Налаштування NAT і Iptables.
— Створення резервних копій і відновлення з них.
— Відмінні особливості від Docker.
Введення
LXD — це гіпервізор контейнерів, який базується на LXС[1]. Основна відмінність від LXC полягає в тому, що LXD вводить поняття образу контейнера, і будує інфраструктуру навколо цих двох понять.
Простіше кажучи, LXD – це Docker для віртуальних ОС. Принцип такий же: образ ОС можна скачувати з репозиторіїв і розгортати примірники на хості як контейнери. Один образ можна «клонувати» на кілька віртуальних машин.
Відмінності від Docker:
  1. Docker – віртуалізація додатків, а LXD – віртуалізація операційних систем.
  2. При старті контейнера запускається повноцінне linux оточення: запускаються скрипти в init.d і різні встановлені сервіси (mysql, apache, nginx, cron тощо).
  3. Є можливість задати статичний ip адреса контейнера.
  4. Після запуску контейнера можна змінювати конфігурацію контейнера ("прокинути" папки тощо).
  5. При виході з контейнера командою
    exit
    він продовжує свою роботу.
  6. Можна отримати безпосередньо доступ до файлової системи контейнера з машини хоста. Коренева система контейнера знаходиться в папці
    /var/lib/lxd/containers/<назва контейнера>/rootfs
    .
  7. За замовчуванням сервіс LXD працює через unix-сокет, але його можна відкрити в зовнішню мережу і роздавати свої образи. Іншими словами можна підняти персональний сервер з образами.
Інші можливості LXD:
  1. Можна інтегрувати з OpenStack через плагін nova-lxd.
  2. Є можливість сплячого режиму (гібернація) контейнера.
  3. Є API управлінням контейнерами[4].
  4. Можна запускати Docker всередині LXD[5].
Установка LXD
LXD на поточний момент нормально працює на Ubuntu 16.04 LTS. Можна запустити і на інших системах, але можуть виникнути складності або щось буде працювати не так, як треба. Приміром, на Centos 7 контейнери запускаються тільки в привілейованому режимі, відсутні готові збірки lxd і потрібно компілювати їх вручну.
У свіжій версії Ubuntu, за замовчуванням, вже вбудований lxd. Якщо він не встановлений, то можна поставити так:
aptitude install lxd

Налаштування LXD
Оновити систему та встановіть необхідні для роботи пакети:
aptitude update
aptitude upgrade
aptitude install lxd zfs zfsutils-linux

Ініціалізація LXD
Ініціалізацію LXD потрібно робити до того як ви почнете користуватися контейнерами.
Перед тим як робити ініціалізацію потрібно вирішити, яке backend сховище буде використовуватися. Backend сховищ – це місце, де знаходяться всі контейнери і образи. Виділяють два основних типів сховища: ZFS і Dir.
  • ZFS дозволяє моментально створювати і відновлювати знімки контейнерів, створювати контейнери з образів. Завдяки ZFS, знімки LXD займають значно менше місця, ніж сам контейнер.
  • Dir зберігає образи звичайним способом на диску. Кожен знімок буде займати стільки ж, як і сам контейнер.
ZFS монтується в файл як loop device, тому потрібно стежити за розміром сховища і збільшувати місце, якщо його мало залишилося. ZFS має сенс використовувати, якщо у вас є приватне віддалене сховище образів, куди ви відправляєте, час від часу, знімки контейнерів в якості бекапів, а потім завантажуєте їх від туди для установки нових версій або для відновлення контейнерів з бекапів.
Я на продакшн сервер вирішив поставити Dir. ZFS протестую у себе на локалці. Бекапи буду робити звичайними скриптами упаковувати їх в tar і відправляти їх на Amazon S3.
Після того як ви вирішили яке backend сховище використовувати, починайте процес ініціалізації. Робиться це командою:
lxd init

Утиліта буде задавати питання, на які вам потрібно буде відповісти. Першим питанням утиліта запитає: який тип сховища використовувати?
Name of the storage backend to use (dir or zfs): dir

Якщо ваша відповідь Dir, то утиліта відразу перейде до налаштування мережі. Якщо ваша відповідь ZFS, то система буде ставити наступні питання:
Create a new ZFS pool (yes/no)? yes
Name of the new ZFS pool: lxd
Would you like to use an existing block device (yes/no)? no
Size in GB of the new loop device (1GB minimum): 10

«Size in GB of the new loop device» — це розмір сховища ZFS. Всі образи і контейнери будуть зберігатися в сховище, тому якщо ви збираєтеся зберігати багато образів або контейнерів, то потрібно збільшити це число.
Потім утиліта запитає: чи потрібно відкривати доступ до LXD зовні? Відповідаємо «ні». Якщо ви хочете створити публічний або приватний репозиторій, то потрібно відповісти «так».
Would you like LXD to be available over the network (yes/no)? no 

Налаштування LXD bridge
Після налаштування типу сховища, утиліта запитає: «чи Бажаєте ви сконфігурувати LXD bridge?». Відповідаємо «так».
Do you want to configure the LXD bridge (yes/no)? yes

Запуститися інтерфейс налаштування мережі. Відповідайте на питання наступним чином:
Would you like to setup a network bridge for LXD containers now? Yes
Bridge interface name: lxdbr0
Do you want to setup an IPv4 subnet? Yes
IPv4 address: 10.200.0.1
IPv4 CIDR mask: 16
First DHCP address: 10.200.100.1
Last DHCP address: 10.200.255.254
Max number of DHCP clients: 25399
Do you want to NAT the IPv4 traffic? Yes
Do you want to setup an IPv6 subnet? No

Для мережі буде використовуватися міст з інтерфейсом lxdbr0.
Маска мережі 10.200.0.0/16.
IP адреса хоста 10.200.0.1.
Автоматично DHCP буде роздавати IP для контейнерів з 10.200.100.1 за 10.200.255.254, але вручну можна встановити, починаючи з 10.200.0.2.
Протокол ip6 для контейнерів можна не включати.
повторно Запустити утиліту налаштування LXD bridge можна командою:
dpkg-reconfigure -p medium lxd

Установка статичної IP для контейнера
Відкрийте файл:
nano /etc/default/lxd-bridge

Раскоментируйте сходинку LXC_DHCP_CONFILE і пропишіть:
LXD_CONFILE="./etc/lxd-dnsmasq.conf"

Створити файл налаштувань статичних IP адрес:
nano /etc/lxd-dnsmasq.conf

Пропишіть статичний IP адреса для тестового контейнера:
dhcp-host=test,10.200.1.1

В подальшому, цей файл можна буде додавати інші статичні IP адреси для інших контейнерів.
Після кожної зміни файлу /etc/lxd-dnsmasq.conf потрібно буде перезавантажувати lxd-bridge командою:
service lxd-bridge restart

Якщо це не допомагає, то потрібно зупинити контейнери з невірними IP, видалити файл dnsmasq.lxdbr0.leases, а потім перезавантажити lxd-bridge:
lxc stop test
rm /var/lib/lxd-bridge/dnsmasq.lxdbr0.leases
service lxd-bridge restart

Налаштування NAT
Для того, щоб запрацював NAT, виконавши команди:
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

Налаштувати Grub
Відредагуйте файл
nano /etc/default/grub

Поміняйте рядок
GRUB_CMDLINE_LINUX="swapaccount=1 quiet"

Без цього рядка у мене при запуску lxd виходив warning про те що cgroup swap account не буде працювати. Я вирішив включити опцією swapaccount=1. quiet – це тиха завантаження системи (опціонально)
Додавання LXD в автозапуск
systemctl enable lxd

Перезапуск системи
Перезавантажте Ubuntu:
init 6

Установка і запуск образу віртуальної машини
Додайте репозиторій (опціонально, за замовчуванням images вже доданий):
lxc remote add images images.linuxcontainers.org:8443

Скачайте образ:
lxc image copy images:centos/6/amd64 local: --alias=centos-image

centos-image – синонім способу, щоб легше було до нього звертатися
Запустіть спосіб:
lxc launch local:centos-image test

test — назва майбутнього контейнера
Можна запускати образи у дві команди:
lxc init local:centos-image test
lxc start test

Перша команда створить контейнер, а друга його запустить. Перша команда корисна, якщо ви хочете просто створити контейнер, але не запускати його.
Подивіться статус запущених контейнерів
lxc list

Команда повинна показати наступну інформацію:
(Ubuntu)[root@ubuntu /]# lxc list
+------+---------+-------------------+------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+---------+-------------------+------+------------+-----------+
| test | RUNNING | 10.200.1.1 (eth0) | | PERSISTENT | 0 |
+------+---------+-------------------+------+------------+-----------+

Зверніть увагу, що LXD видав статичний IP для контейнера, який ви налаштували в /etc/lxc-dnsmasq.conf
Перенаправлення папки
Дана команда монтує папку /data/test/folder в контейнер test в папку /folder
mkdir -p /data/test/folder
chown 100000:100000 /data/test/folder
lxc config add device disk_name test disk path=/source folder=/data/test/folder

Монтування папок не змінює вміст папки /var/lib/lxd/containers/test, а монтується в окрему папку /var/lib/lxd/devices/test. Тому бекапи і знімки контейнера не будуть містити примонтированные папки і файли. Оновлення контейнера з бекапа або образу не буде зачіпати вміст вмонтованих папок.
Переглянути інформацію про налаштування можна через команду:
lxc config show test

Підключення до віртуальної машини
Зайдіть в запущений контейнер test:
lxc exec test -- /bin/bash

Перевірте з'єднання:
ifconfig

Висновок:
[root@test ~]# ifconfig
eth0 Link euroncap:Ethernet HWaddr 00:16:3E:23:21:3F
inet addr:10.200.1.1 Bcast:10.200.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe23:213f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:15078 errors:0 dropped:0 overruns:0 frame:0
TX packets:15320 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:28090645 (26.7 MiB) TX bytes:841975 (822.2 KiB)

lo Link euroncap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

Перевірте NAT:
ping ya.ru

Висновок:
[root@test ~]# ping ya.ru
PING ya.ru (93.158.134.3) 56(84) bytes of data.
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=1 ttl=50 time=105 ms
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=2 ttl=50 time=106 ms
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=3 ttl=50 time=105 ms
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=4 ttl=50 time=105 ms
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=5 ttl=50 time=104 ms
64 bytes from www.yandex.ru (93.158.134.3): icmp_seq=6 ttl=50 time=106 ms
^C
--- ya.ru ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 6671ms
rtt min/avg/max/mdev = 104.942/105.845/106.664/0.568 ms

Встановіть базові пакети:
yum install mc nano openssh-server epel-release wget -y
yum update -y
chkconfig sshd on
service sshd start

Встановіть пароль від рута
пароль

Відволічетесь від контейнера:
exit

Підключення через ssh
Скопіюйте ключ ssh хоста в контейнер
ssh-copy-id root@10.200.1.1

Якщо Ubuntu лається, що не може знайти ключ, то спочатку згенеруйте ключ ssh, а потім скопіюйте його командою ssh-copy-id. Якщо ключ скопировался успішно, то пропустіть цей крок (генерація ключа).
ssh-keygen

Тепер ви можете заходити в контейнер через ssh без пароля (через сертифікати):
ssh root@10.200.1.1

Кидок ssh через NAT
Часто потрібно отримати можливість підключення через ssh до контейнера безпосередньо, минаючи хост (щоб кожен раз не заходити на хост, щоб перейти в контейнер).
Для цього потрібно виконати команду:
iptables -t nat -A PREROUTING -p tcp --dport 22001 -j DNAT --to-destination 10.200.1.1:22

Автозбереження iptables після завантаження Ubuntu
за умовчанням В Ubuntu iptables втрачаються після перезавантаження хост машини. Щоб вирішити цю проблему потрібно створити файл:
nano /etc/network/if-up.d/00-iptables

Записати вміст файлу:
#!/bin/sh
iptables-restore < /etc/default/iptables
#ip6tables-restore < /etc/default/iptables6

Встановити права на запуск:
chmod +x /etc/network/if-up.d/00-iptables

Зберегти поточні параметри:
iptables-save > /etc/default/iptables

Перезавантажитися і спробувати підключитися до контейнера через ssh:
ssh root@<зовнішній ip хост машини> -p22001

Тонке налаштування iptables
Якщо використовувати відновлення iptables при завантаженні, то LXD буде додавати свої команди в iptables, і в iptables будуть міститися дублікати записів. До того ж на різних серверах потрібно заборонити вхідні з'єднання і відкрити тільки необхідні порти.
Готовий лістинг
/etc/default/iptables
, який вирішує дві задачі відразу, представлений нижче:
# Generated by iptables-save v1.6.0 on Fri Aug 19 16:21:18 2016
*mangle
:PREROUTING ACCEPT [129:9861]
:INPUT ACCEPT [129:9861]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [102:11316]
:POSTROUTING ACCEPT [102:11316]
COMMIT
# Completed on Fri Aug 19 16:21:18 2016
# Generated by iptables-save v1.6.0 on Fri Aug 19 16:21:18 2016
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# Перенаправлення ssh порту в контейнер test
-A PREROUTING -p tcp -m tcp --dport 22001 -j DNAT --to-destination 10.200.1.1:22
COMMIT
# Completed on Fri Aug 19 16:21:18 2016
# Generated by iptables-save v1.6.0 on Fri Aug 19 16:21:18 2016
*filter
:INPUT ACCEPT [128:9533]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [102:11316]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
# Дозволяємо вхідні з'єднання http і ssh
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# Забороняємо інші вхідні з'єднання
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Fri Aug 19 16:21:18 2016

Створення бекапів
Даний метод створює бекапи контейнерів LXD образи, готові до імпорту. В ідеалі потрібно створювати знімки і відправляти їх у приватний репозиторій LXD. Але іноді, цього зробити не можна. Наприклад, у невеликій компанії немає можливості купувати ще один сервер. В цьому випадку можна обійтися простим рішенням tar + Amazon S3.
Скачайте готові скрипти для створення та відновлення резервних копій:
wget https://github.com/vistoyn/lxd_backup/raw/1.1/scripts/lxc-backup -O "/usr/local/bin/lxc-backup"
wget https://github.com/vistoyn/lxd_backup/raw/1.1/scripts/lxc-restore -O "/usr/local/bin/lxc-restore"

Встановіть прапорець для виконання скриптів:
chmod +x /usr/local/bin/lxc-restore
chmod +x /usr/local/bin/lxc-backup

Перед створенням і відновленням бекапів потрібно зупинити працює контейнер. Можна, в принципі, робити бекап на працюючому контейнері, але при створенні бекапу можлива втрата деяких даних (залежить від встановлених програм в контейнері).
dir
Ця команда створить бекап контейнера test, стисне файл в архів і збереже його на диску в папці /backup/lxc/test:
lxc stop test
lxc-backup test

Відновити з бекапа знімка:
lxc-restore test /backup/lxc/test/snap-test-2016-08-19.tar.bz2

Для zfs
Для ZFS після імені контейнера потрібно додавати «.zfs»
Створення бекапа:
lxc stop test
lxc-backup test.zfs

Відновити з бекапа знімка:
lxc-stop test
lxc-restore test.zfs /backup/lxc/test/snap-test.zfs-2016-08-19.tar.bz2

Імпорт бекапа
На новому хості іноді потрібно створити контейнер з бекапа. Для цього потрібно спочатку імпортувати образ, а потім запустити його як контейнер.
Команда імпорту бекапа як способу LXD:
lxc image import /backup/lxc/test/snap-test-2016-08-19.tar.bz2 --alias my-new-image

Команда запуску образу як контейнера:
lxc launch me-new-image test2

Матеріали
Дана стаття не розглядає безліч інших питань, пов'язаних з LXD. Додаткову літературу про LXD можна почитати тут:
  1. Офіційний сайт LXD.
  2. Список доступних образів.
  3. Серія статей про LXD 2.0 російською мовою.
  4. Взаємодія безпосередньо з LXD API.
  5. Запуск Docker в LXD контейнері.
  6. Налаштування статичного адреси для LXC-контейнера в Ubuntu 16.04.
  7. Налаштування ZFS для LXD в Ubuntu.
  8. Довідкова інформація по ZFS.
  9. Як зберегти правила iptables після перезавантаження Ubuntu?
  10. Утиліта створення та відновлення резервних копій для LXD.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.