Linux-vserver или каждому сервису по песочнице

  • Tutorial
Недавно на хабре публиковались статьи о openvz и lxc. Это напомнило мне, что эта статья всё еще валяется в sandbox'е…

Для целей размещения проектов я применяю такую схему: каждый сервис запускается в изолированной среде: боевой — отдельно, тестовый — отдельно, телефония — отдельно, веб — отдельно. Это снижает риски взлома систем, позволяет бакапить всё и вся одним rsync'ом на соседний сервер по крону, а в случае слёта железа просто поднять на соседнем железе. (А использование drbd + corosync позволяет это делать еще и автоматически)

Для создания изолированной среды есть два подхода, именуемые VDS (виртуализация аппаратуры) и VPS/jail (виртуализация процессного пространства).

Для создания VDS изоляций применяют XEN, VirtualBox, VMWare и прочие виртуальные машины.
Для создания VPS на linux используется либо linux-vserver, либо openvz, либо lxc.

Плюсы VDS: система внутри может быть совершенно любой, можно держать разные версии ядер, можно ставить другую ОС.
Минусы VDS: высокие потери производительности на IO, избыточное потребление CPU и RAM на сервисы, дублирующие запущенные на серверной ОС.

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

Так как мне не нужны разные ОС, то всюду применяю linux-vserver (так уж сложилось исторически, применяю с 2004го года, а openvz вышел в открытый доступ в 2005м), а lxc в моём понимании еще не дорос до продакшена (хотя и очень близок уже).

Приведу цитату из FAQ:
«What is the status of Linux-VServer?
Linux-VServer has more than a decade of maturity and is actively developed. Two projects are similar to Linux-VServer, [LXC], and [OpenVZ]. Of the two, OpenVZ is the more mature and offers some similar functionality to Linux-VServer. LXC is solely based on the kernel mechanisms such as cgroups that are present in modern kernels. These kernel mechanisms will continue to be refined and isolation will mature. As that occurs, Linux-VServer will take advantage of those new features separately from LXC and continue to provide the same robust user interface that it does currently. Currently, LXC offers significantly less functionality and isolation than Linux-vserver. LXC will eventually be a robust wrapper around kernel mechanisms but is still under heavy development and not considered ready for production use.»

Ниже я опишу базовые операции по запуску LAMP сервера в изолированном окружении.

ОС: debian-stable, 64bit
Начиная с Wheezy поддержка vserver командой debian убрана, поэтому использую ядра с repo.psand.net/info

Настройка корневой системы для запуска linux-vserver


  echo "deb http://repo.psand.net/ wheezy main" > /etc/apt/sources.list.d/psand.list
  wget -O - http://repo.psand.net/pubkey.txt | sudo apt-key add -
  aptitude update
  aptitude search linux-image-vserver # Ищем тут последнюю версию ядра
  aptitude install linux-image-vserver-3.13-beng util-vserver curl bzip2 # заменить 3.13 на актуальную для вас версию
  curl http://dev.call2ru.com/vs/nss_vserver_64.tar.bz2 | tar xfj -
  cd nss_vserver_64
  make
  make install
  ln -s var/lib/vservers /
  curl http://dev.call2ru.com/vs/vserverauth.tar.gz | tar xfz -
  cd vserverauth/vslogin/
  make
  cp vslogin /sbin/
  chmod u+s /sbin/vslogin
  echo /sbin/vslogin >> /etc/shells
  echo -e "auto dummy0\niface dummy0 inet static\n\taddress 192.168.1.250\n\tnetmask 255.255.255.0\n" >> /etc/network/interfaces
  echo -e "\tpre-up /sbin/iptables -t nat -A POSTROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MASQUERADE\n"  >> /etc/network/interfaces
  echo -e "\tpost-down /sbin/iptables -t nat -D POSTROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MASQUERADE\n"  >> /etc/network/interfaces

После установки — ребут в новое ядро.

Что мы сделали:
  • Установили ядро с поддержкой linux-vserver, установили утилиты для создания/управления vserver'ами.
  • Установили мой модуль nss_vserver[1] и vslogin, который позволяет логиниться по ssh напрямую внутрь vserver'а
  • Настроили интерфейс dummy0, чтобы создать «приватную» сеть для виртуальных машин.


Это позволяет использовать один IP сервера для запуска различных сервисов, разделяя их по логину (например, чтобы войти рутом в виртуальную машину web надо просто логиниться как web-root либо как root@web).

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

Для решения этого, на руте нам понадобится еще nginx:
  aptitude install nginx
  cat > /etc/nginx/sites-available/proxy <<END
server {
        listen 80; # Либо IP:PORT
        proxy_set_header Host  $host; 
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-SSL  no;

        if ($http_host ~ "(?i)(somesite\.ru)$") {
                rewrite ^(.*)   /web/$1 last;
        }
        # Тут добавить дополнительные if'ы для раскидывания по другим виртуалкам

        # Тут catch-all для всех прочих
        rewrite ^(.*)     /web/$1    last;

        # Определяем форварды внутрь виртуалок
        location /web// {
                proxy_pass http://192.168.1.57/;
                proxy_read_timeout 500;
        }
}
END
  ln -s ../sites-available/proxy /etc/nginx/sites-enabled/
  /etc/init.d/nginx reload


Это позволяет все приходящие запросы на 80й порт раскидывать по разным виртуальным машинам в зависимости от имени.
При необходимости, можно использовать proxy_pass на другой внешний IP, что позволяет перемещать виртуальные сервера по разным машинам без необходимости ожидать полного обновления DNS записей, но это тема для отдельного разговора.

Теперь нам надо создать новую виртуальную машину (номер 57, имя web) в которой установим LAMP.

Создание нового vserver'а


  MIRROR=http://ftp.de.debian.org/debian
  NAME=web
  DOMAIN=mydom.ru
  CONTEXT=57
  vserver $NAME build -m debootstrap --context $CONTEXT --hostname $NAME.$DOMAIN --interface dummy0:192.168.1.$CONTEXT/24 -- -d squeeze -m $MIRROR
  echo default > /etc/vservers/$NAME/app/init/mark
  vserver $NAME start
  vserver $NAME enter
  aptitude update
  aptitude install locales
  echo -e "en_US.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\n" >> /etc/locale.gen
  locale-gen
  echo -e "127.0.0.1 localhost.localdomain localhost vhost\n192.168.1.250 vroot\n" > /etc/hosts

Это устанавливает базовую систему, делает её автозапускаемой при ребуте корневой системы.

Теперь виртуалка готова к установке в неё необходимого софта. Например, обычный LAMP:
   aptitude install apache2 libapache2-mod-php5 mysql-server php5-mysql php5-mysqli libapache2-mod-rpaf
   editor /etc/apache2/mods-available/rpaf.conf
   #  (в строке "RPAFproxy_ips 127.0.0.1" дописать еще через пробел в конце 192.168.1.57 (IP виртуалки))
  a2enmod rpaf
  /etc/init.d/apache2 restart
  exit


Всё! Теперь у вас на сервере работает апач в совершенно изолированной среде.

К проблемам этого подхода относятся:

1. Прямой вход внутрь виртуальных серверов возможен только по паролю.
2. На корневой системе никому нельзя давать доступа, поэтому на корневой системе должен стоять только проверенный минимум софта (ssh, nginx, iptables и больше ничего).
3. При необходимости прямого доступа до каких-либо портов внутри виртуальных машин, проброс нужно делать с помощью iptables.

Моменты, оставленные за кадром для простоты статьи

1. /var/lib/vservers/* желательно размещать на lvm, чтобы иметь возможность управлять выделением места для виртуальных машин независимо.
2. Управление ресурсами: просто созданная виртуальная машина может съесть все ресурсы машины. Подробнее о настройке лимитов linux-vserver.org/Resource_Limits
3. /tmp/. Внутри виртуалок по умолчанию /tmp/ создаётся как ramdisk в 16m размером. Либо сразу перед «vserver $NAME start» исправить /etc/vservers/$NAME/fstab
4. Полезные сведения, информацию и прочее про linux-vserver можно найти на linux-vserver.org

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

Комментарии 27

    +4
    Мне кажется, деление на VDS/VPS как разные сущности, несколько не общепринято. Обычно их используют как 100% синонимы, то есть можно увидеть 'VDS на openvz' и 'VPS на xen'е'. Термин VPS вообще более редкий.
      +1
      Статью писал давно, когда еще не успели их смешать до такой степени…
        0
        Насколько я помню, VPS и VDS всегда были синонимами, так скажем 5 лет назад, когда я работал в одной хостинговой компании — точно были. У нас было разграничение лишь в том, что для американцев привычнее понятие VPS, а для европейцев и русских в частности — VDS.
          0
          Хм. Значит, это у меня лично в голове всё смешалось. Но у меня чётко в памяти, что N лет назад я встречал их с разделением смысла.
        +1
        У меня вопрос почти по теме: что такое «облако»? Почему-то для меня облака ассоциируются с неограниченными ресурсами и оплатой за фактическое использование (да, я про Селектел). Однако, всюду встречаются «cloud hostings», где доступны жесткие конфигурации (DigitalOcean как пример). Где правду искать?)
          +2
          «Облако» по сути — это когда ресурсы не привязаны к жесткому физическому месту.
          То есть это облачко, которое летает по небосводу, где может.

          По идее HA кластер из двух машин — это уже «Облако». Только такое, бинарное…
            0
            Если совсем абстрагироваться от любой конкретики, то идеей «облака» является технологическая простота получения дополнительных ресурсов (то, что в определении называют self-serving) и сразу, как они понадобились (on-demand). А делается это скейлом виртуалки, выделения ей слотов или вообще предоставлением бареметалла (есть такая фича в openstack'е, где для инстансов выделяют реальные сервера «as is» без гипервизора) — это уже специфика конкретного решения.

            Это не точная характеристика, но скорее, количественная, переходящая в качественную. Примерно как переслать пакет курьером — это не пакетная передача данных. Слать 10 пакетов в секунду по модему — уже пакетная.
          +2
          echo «deb repo.psand.net/ wheezy main» > /etc/apt/sources.list.d/psand.list
          curl dev.call2ru.com/vs/nss_vserver_64.tar.bz2
          curl curl dev.call2ru.com/vs/vserverauth.tar.gz

          Левые репозитории, левые ядра, левые какие-то пакеты, ставящиеся через маке-макеинсталл… Автор так и не написал чем это лучше/хуже openvz или lxc. Проще уж проксмокс(или ядро от него) какой-нибудь накатить поверх дебиана.
          Можно как-нибудь статью облагородить?
            +1
            Левые репозитории — из-за выкашивания vserver из стокового debian. До squeeze это было одно из самых положительных качеств — наличие в репе и быстрый запуск. Сейчас стало хуже.
            Разницу между решениями напишу, хорошо.
            0
            aptitude install linux-image-vserver-3.13-beng util-vserver curl bzip2 # заменить 3.13 на актуальную для вас версию

            Разве там нет виртуального пакета, ссылающегося на последнюю версию ядра?
              0
              Вот нету. Пока было в дебиане в стоке — было просто установить linux-image-vserver-amd64 и всё.
              0
              Хотелось бы сравнения с Docker. Я пока не вижу, чем предложенный вариант лучше решения на Docker.
                0
                >> lxc в моём понимании еще не дорос до продакшена
                  0
                  Если сравнивать LXC с vserver, LXC, навскидку, проигрывает в тонкости управления ресурсами, но выигрывает в тонкости управления сетью.
                  0
                  Расскажите, что нового в Linux-VServer за последние несколько лет?
                    0
                    Начали переводить отдельные подсистемы на LXC. Те же resource limit, accounting.
                    А так… они просто работают, работают хорошо.
                    Случаев выхода из песочницы, несмотря за несколько взломов и использования даже рутовых дыр ядра не было.
                      0
                      А вот с LXC насколько я понимаю все не так.
                      Последний exploit который был для ядра, давал рута с возможностью создавать блочные устройства и загружать модули
                        0
                        мелочи жизни :) поэтому я и использую vserver а не lxc.
                          0
                          жаль убрали из debian :(
                            0
                            не нашлось мейнтейнера.
                    0
                    Какие на текущий момент есть наработки по выходу из гостевой системы в хост (для разных систем виртуализации естественно свои), и соответственно методы защиты?

                    Речь идет не только о получении полного root доступа (что как я понимаю дает к примеру root доступ в гостевой системе lxc или обычного chroot) но и к примеру получение информации о хост-компьютере, с целью определить, не запускается ли приложение в нескольких копиях на одной и той же физической машине.
                      0
                      Так, по _выходу_ всё хорошо — это практически невозможно. В случае linux-vserver выйти за пределы chroot barrier невозможно (я такого не слышал, и так и не смог найти эксплойта, хотя искал). Выйти из просто chroot'а если ты root — можно, причем способов масса.
                      Узнать запущен ли ты из контейнера или на физическом железе — сложнее. Например, можно проверять доступность различных ограничений…
                      В любом случае, универсального решения поиска физического железа нет.
                        +1
                        Узнать запущен ли ты из контейнера или на физическом железе — сложнее. Например, можно проверять доступность различных ограничений…

                        очень просто — выполнить echo b > /proc/sysrq-trigger от рута ;) в контейнере ничего не произойдет :)
                          0
                          кто сказал, что на руте sysfq-trigger включен в ядре?
                            0
                            И в каком дистрибутиве он не включен? Дженту не предлагать.
                              –1
                              kernel.sysrq=0?
                                +1
                                root@xxx:~# cat /proc/cmdline
                                BOOT_IMAGE=/vmlinuz-3.2.0-4-amd64 root=/dev/mapper/debian-root ro quiet sysrq=0
                                root@xxx:~# sysctl kernel.sysrq=0
                                kernel.sysrq = 0
                                root@xxx:~# sysctl -a | grep sysrq
                                kernel.sysrq = 0
                                root@xxx:~# echo s > /proc/sysrq-trigger
                                root@xxx:~# dmesg

                                [ 490.515566] SysRq: Emergency Sync
                                [ 490.517566] Emergency Sync complete

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

                    Самое читаемое