Table of Contents

Настройка хоста LXC на Ubuntu 16.04

Выключаем IPv6

Чтобы выключить IPv6 правим файлик /etc/sysctl.conf и добавляем туда строки:

##Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Настраиваем hostname

В файликах /etc/hostname и /etc/hosts нужно прописать имя хоста.

Устанавливаем LXC

sudo apt-get install lxc

Проверить, что все установилось хорошо можно командой:

lxc-checkconfig

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

Для контейнеров LXC как правило используются два варианта подключения. Первый - когда контейнеры подключаются к сети через NAT и второй - когда контейнеры подключены к физическому интерфейсу через bridge. По-умолчанию в Ubuntu конфигурируется первый вариант и подключены к сети через NAT. Контейнеры получают адреса по DHCP из диапазона 10.0.x.2-10.0.x.254, а мост на хосте LXC получсет адрес 10.0.3.1.

Настройки сети LXC хранятся в файле /etc/default/lxc-net. Там можно включить или выключить lxcbr0, а также задать другие параметры.

https://habrahabr.ru/company/ua-hosting/blog/305184/
Для того чтобы включить bridge непосредственно на физический интерфейс нужно сделать так. На всякий случай проверяем что у нас установлены bridge-utils. По идее они должны были поставиться вместе с lxc:

sudo apt-get install bridge-utils

Теперь в файлике /etc/network/interfaces нужно выключить (закомментировать) eth0 (или другой физический интерфейс) и прописать вместо него br0, который будет указывать на eth0. В самом простом случае c DHCP это будет как-то так:

# The primary network interface
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_fd 0

Или как-то так со статическим адресом:

auto br0
iface br0 inet static
        address x.x.x.x
        network x.x.x.0
        netmask 255.255.255.0
        broadcast x.x.x.255
        gateway x.x.x.x
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0
        dns-nameserver x.x.x.x x.x.x.x

Выключаем lxcbr0. Для этого в файлике /etc/default/lxc-net устанавливаем

USE_LXC_BRIDGE="false"

и перезагружаем хост.

Теперь чтобы в новых контейнерах по-умолчанию создавался интерфейс, использующий br0 нужно в файлике /etc/lxc/default.conf заменить

lxc.network.link = lxcbr0 

на

lxc.network.link = br0

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

Установка лимитов памяти

При дефолтной установке LXC после попытке сконфигурировать лимиты потребления памяти контейнер перестает старовать с ошибкой:

Permission denied - Error setting memory.memsw.limit_in_bytes 

Лечится это добавлением к строке запуска ядра параметров:

cgroup_enable=memory swapaccount=1

Для этого открываем файлик /etc/default/grub и в строке GRUB_CMDLINE_LINUX_DEFAULT= пишем:

  GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"

Файлик сохраняем и обновляем конфимгурацию Grub:

sudo update-grub

И перезагружаем хост.

Монтируем директорию хоста в контейнер

Это может понадобиться для того, чтобы одни и те же файлы были видны в нескольких контейнерах.

По-умолчанию в контейнер монтируется файловая система из директории /var/lib/lxc/mycontainer/rootfs. Для того, чтобы подмонтировать к корневой файловой системе контейнера директорию хоста нужно отредактировать файлик /var/lib/lxc/mycontainer/config и добавить туда:

lxc.mount.entry=/path/in/host/mount_point /var/lib/lxc/mycontainer/rootfs/mount_point none bind 0 0

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

lxc.mount.entry=/path/in/host/mount_point mount_point none bind 0 0

При монтировании, система смотрит, есть ли слеш “/” в начале пути точки монтирования в контейнере. Если слеша нет, то путь считается относительным.
Точку монтирования в контейнере нужно создавать вручную. При монтировании она автоматически не создается, а при отсутствии точки монтирования контейнер не стартует.

Устанавливаем LXC-WebPanel

Логично использовать форк LXC-webpanel, который умеет делать бекап контейнера из web-интерфейса и поддерживает LXC 1.0. Запускаем скрипт, который пропишет нужный репозиторий:

curl -s https://packagecloud.io/install/repositories/claudyus/LXC-Web-Panel/script.deb.sh | sudo bash 

На момент написания заметки скрипт прописывает репозиторий для Ubuntu 16.04, однако сущестует только репозиторий для “Ubuntu 14.04”. Исправить это можно отредактировав файл:

sudo nano /etc/apt/sources.list.d/claudyus_LXC-Web-Panel.list

и заменив в нем xenial на trusty. После этой процедуры устанавдиваем lwp:

sudo apt-get update && sudo apt-get -y install lwp

теперь можно сконфигурировать, запустить панель и протестировать

sudo cp /etc/lwp/lwp.example.conf /etc/lwp/lwp.conf
sudo nano /etc/lwp/lwp.conf #change it to your liking
sudo systemctl enable lwp
sudo service lwp start

заходим на http://x.x.x.x:5000 с логином admin и паролем admin

Вход с доменной учеткой

В LWP собственный модуль авторизации с помощью LDAP сломан. Судя по всему из-за несовместимости с новыми версиями Python. Однако, можно ввести хост в домен (например с помощью PBIS - как описано тут, а в файлике /etc/lwp/lwp.conf указать:

auth = pam

Пользователя нужно добавить в файлик /etc/sudoers.

Включаем SSL на LWP

Поддержка SSL в LWP была выпилена и рекомендовано использовать nginx в качестве reverse-proxy. Устанаваливаем и настраиваем nginx:

sudo apt-get install nginx 

nginx.conf:

server {
    listen   443; ## listen for ipv4; this line is default and implied
    #listen   [::]:443 default ipv6only=on; ## listen for ipv6

    # logs
    error_log /var/log/nginx/lwp.yourdomain.com.error.log error;
    access_log /var/log/nginx/lwp.yourdomain.com.access.log;

    # Make site accessible from hostanme
    # change this according to your domain/hostanme
    server_name lwp.yourdomain.com;

    # set client body size #
    client_max_body_size 5M;

    ssl on;
    ssl_certificate ssl/server.cert;
    ssl_certificate_key ssl/server.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:5000;
    }
}

server {
    listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6

    # Make site accessible from hostanme on port 80
    # change this according to your domain/hostanme
    server_name lwp.yourdomain.com;

    # redirect all requests to https
    return 301 https://$host$request_uri;
}

Работа с контейнерами

После создания контейнера можно его запустить командой lxc-start, указав имя - test:

lxc-start -n test

Для того, чтобы попасть в консоль контейнера в коммандной строке выполнить:

lxc-console -n test

Так как хостовая система Ubuntu, то логин и пароль для входа в контейнер по-умолчанию:

username: ubuntu
password: ubuntu

Чтобы выйти из консоли контейнера нужно нажачать Ctrl+a и затем q (без Ctrl).
Для того чтобы создать пользователя в контейнере не заходя в него нужно либо сделать chroot в папку с файловой системой контейнера, либо выполнить lxc-attach, а затем addduser:

lxc-attach -n test
adduser username

Настраиваем ZFS-pool

Замечательным свойством LXC является поддержка ZFS.
Использование ZFS позволяет использовать снепшоты для бекапа, а также дедупликацию и компрессию для экономии места.
Если на хосте LXC есть ZFS volume, то контейнеры можно создавать как в нем, так и по старому в директории. Просто при создании контейнера нужно указывать имя zfs pool, в котором будет создан dataset

sudo zpool create -f lxc /dev/xvdb
sudo zpool status
sudo zfs list
sudo zfs set dedup=on lxc
sudo zfs set compression=on lxc
sudo zdb -S lxc

Миграция контейнера из OpenVZ

https://github.com/cdown/openvz-to-lxc/blob/master/openvz-to-lxc https://l3net.wordpress.com/2012/10/26/easy-lxc-running-openvz-containers-in-lxc-2/

Эксперимент проводится на контейнере с Debian 7.0.
На хосте OpenVZ я распаковал dump контейнера, смонтировал образ ploop, затем сжал файлики, перенес их на хост LXC, создал новый контейнер и распаковал в него содержимое архива.
На хосте OpenVZ:

tar -xvf ./ve-dump.103.1492091356.tar 
mkdir /mnt/hdd
mount -t ploop ./DiskDescriptor.xml /mnt/hdd 
tar -cvpf ./hdd.tar.gz /mnt/hdd

Передаем на хост LXC:

 dd if=./hdd.tar.gz | ssh mike@lxc.host dd of=/mnt/hdd.tar.gz

На хосте LXC:

cd /mnt/
sudo tar -xvf ./hdd.tar.gz

Чистим контейнер:

rm -Rf /var/lib/lxc/new_container/rootfs/*

И переносим туда файлики:

cp -aR /mnt/hdd/hdd/* /var/lib/lxc/new_container/rootfs/

Пробуем запустить контейнер:

lxc-start -n new_container

Контейнер стартует, однако консоль не отдает. :(