Начало работы с LXC на сервере Ubuntu 13.04

LXC (или Linux Containers) – это система, разработанная на основе некоторых функций ядра Linux, которая позволяет создавать и управлять несколькими виртуализированными системами Linux на одной родительской машине. Однако, в отличие от некоторых других решений виртуализации, LXC не эмулирует аппаратные средства, а контейнер и хост совместно используют одно ядро, благодаря чему система LXC невероятно проста в работе.

Главными преимуществами LXC считаются:

  • Безопасность; основные сервисы запускаются в отдельных контейнерах, а потому дефекты безопасности какого-либо сервиса никак не повлияют на работу других сервисов (или же это влияние будет минимальным). Это чем-то напоминает chroot jail, но система LXC предлагает нечто большее, чем простая изоляция файловой системы.
  • Портативность; контейнеры LXC можно архивировать и перемещать на любой другой хост с аналогичной архитектурой процессора. Это важно при масштабировании приложения, поскольку отдельные сервисы можно просто дублировать и переместить.
  • Настройка ограничений; благодаря использованию cgroups контейнеры LXC можно ограничивать по ресурсам. При запуске большого количества контейнеров эта функция позволяет установить их приоритетность и обеспечить самые важные контейнеры необходимым объемом ресурсов.

Примечание: Все команды руководства следует выполнять как root.

Внимание! Не пытайтесь выполнить данное руководство в системе Debian. Несмотря на сходство этих систем, пакеты LXC для Debian имеют ряд недостатков, которые нарушают изоляцию контейнеров.

Установка LXC

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

apt-get install lxc

Эта команда устанавливает LXC и настраивает структуру сети для контейнеров. После завершения установки можно проверить, готовы ли ядро и конфигурация. Для этого запустите:

$ lxc-checkconfig
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.8.0-19-generic
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: missing
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

Вы наверняка заметили, что поле User namespace обозначено как missing.

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

Создание нового контейнера

Для создания новых контейнеров LXC существует команда lxc-create. Для примера попробуйте создать контейнер по шаблону ubuntu (в руководств он условно называется test-container).

lxc-create -n test-container -t ubuntu

При первом запуске этой команды на её выполнение может уйти несколько минут, поскольку она загружает и кэширует все необходимые компоненты. В результате команда создаст в новом контейнере минимальную установку Ubuntu через debootstrap.

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

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

Чтобы проверить состояние контейнеров, используйте команду lxc-ls –fancy; на данный момент она должна сообщить о том, что контейнеры не запущены:

# lxc-ls --fancy
NAME            STATE    IPV4  IPV6  AUTOSTART
----------------------------------------------
test-container  STOPPED  -     -     NO

Сохраните конфигурационный файл и запустите контейнер:

lxc-start -n test-container -d

Эта команда запустит контейнер в фоновом режиме. Подождите несколько секунд и снова запустите  lxc-ls –fancy, чтобы узнать состояние контейнера:

# lxc-ls --fancy
NAME            STATE    IPV4        IPV6  AUTOSTART
----------------------------------------------------
test-container  RUNNING  10.0.3.143  -     NO

Обратите внимание: теперь контейнеру присвоен IP-адрес; сам контейнер не доступен по внешнему IP-адресу, но имеет доступ к интернету.

Получить доступ к контейнеру можно при помощи команды:

lxc-console -n test-container

На экране появится стандартная форма входа. Предоставьте имя пользователя и пароль, полученные во время создания контейнера (в данном случае это ubuntu/ubuntu). В дальнейшем рекомендуется изменить стандартные учётные данные и выбрать более надёжные и уникальные.

После аутентификации на экране появится простая командная строка bash для управления хост-машиной. Обратите внимание, что в этой минимальной установке отсутствуют некоторые из общих инструментов, при необходимости их можно получить при помощи apt.

Чтобы закрыть консоль контейнера и вернуться в стандартную сессию, нажмите Ctrl-A и Q.

Установка сервисов

Для примера попробуйте установить в контейнер nginx открыть к нему доступ в интернете. На данный момент в контейнере успешно запущен сервер Ubuntu; процесс установки сервиса во многом схож с установкой самого хоста.

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

Подключившись к lxc-console, установите nginx:

sudo apt-get install nginx
sudo service nginx start

Теперь веб-сервер nginx установлен и запущен, но пока что не доступен из открытого интерфейса хоста. В этом можно убедиться, посетив ссылку http://ip-адрес-сервера.

Каждому контейнеру присваивается отдельный диапазон IP-адресов, работающих вне NAT и, следовательно, недоступных из интернета. Подобным образом работает большинство домашних сетей, в которых все компьютеры совместно используют один IP.

Узнать о настройках NAT на хосте можно при помощи iptables:

# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24

Эта настройка открывает всем контейнерам доступ к внешней сети, но для корректной работы сервисов в таких условиях требуется настройка переадресации портов.

В выводе команды lxc-ls –fancy (см. выше) говорится, что контейнеру был присвоен IP-адрес 10.0.3.143 (ваш адрес, вероятнее всего, будет отличаться). Добавьте правило iptables в таблицу prerouting, чтобы настроить переадресацию пакетов с порта 80 на тот же порт контейнера nginx.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 10.0.3.143:80

Примечание: Если порт 80 на хосте уже занят другим сервисом, это правило перенаправит все пакеты в контейнер (даже если он не запущен), и, следовательно, сервис хоста окажется недоступным.

Если теперь перейти по ссылке:

http://ip-адрес-сервера

на экране появится стандартная страница nginx; если это так – настройка переадресации прошла успешно.

Этот процесс можно повторить в других контейнерах для любых других сервисов. Преимущество такого метода состоит в том, что при обнаружении лазейки или уязвимости в контейнере nginx злоумышленник не сможет повлиять на другие сервисы (например, БД), пока не найдёт способ выбраться из контейнера.

Ограничение ресурсов

Кроме изолирования сервисов LXC позволяет использовать в контейнерах  ограничения cgroup.

Эти ограничения настраиваются в конфигурационном файле /var/lib/lxc/test-container/config.

К примеру, при помощи memory.limit можно настроить максимальный объём RAM для конкретного контейнера. К примеру, чтобы ограничить память до 50MB, используйте:

lxc.cgroup.memory.limit_in_bytes = 50000000

Ограничения ресурсов CPU устанавливаются немного иначе. В отличие от памяти, CPU не имеет физических границ и измеряется в shares:

lxc.cgroup.cpu.shares = 100

Shares не привязаны к какому-либо физическому количеству, а представляют относительное распределение ресурсов CPU; проще говоря, это значит, что контейнер с большим количеством shares имеет больше ресурсов CPU. Используемые здесь числа совершенно произвольны; например, вы можете установить 10 для одного контейнера и 20 для другого, а можете в такой же ситуации установить для них 1000 и 2000 соответственно, и это лишь скажет, что приоритет второго контейнера в два раза выше.

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

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

lxc-cgroup -n test-container cpu.shares 100

Автозапуск

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

Для настройки автозапуска контейнера нужно создать символьную ссылку между его конфигурационным файлом и каталогом /etc/lxc/auto:

ln -s /var/lib/lxc/test-container/config /etc/lxc/auto/test-container.conf

Убедитесь, что автозапуск контейнера  настроен:

# lxc-ls --fancy
NAME            STATE    IPV4        IPV6  AUTOSTART
----------------------------------------------------
test-container  RUNNING  10.0.3.143  -     YES

Удаление контейнера

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

Остановите контейнер:

lxc-shutdown -n test-container

Эта команда попытается выполнить безопасное отключение контейнера. Для мгновенного прекращения работы  контейнера (что может повредить данные) существует команда lxc-stop; её рекомендуется использовать только в случаях, если не сработала команда lxc-shutdown.

Остановив контейнер, убедитесь, что он не содержит важных данных, и удалите его:

lxc-destroy -n test-container

Tags: , ,

Добавить комментарий