Pull to refresh
501.5
Яндекс
Как мы делаем Яндекс

Филипп Торчинский из Semonix: установка SmartOS и использование Node.js на ней

Reading time 9 min
Views 10K
29 ноября в офисе Яндекса в Питере я буду проводить научный семинар «DTrace — проверочная работа для вашего кода». Те, кто на YaC 2012 слушал мой доклад «Инфраструктура облачных вычислений на основе ядра Illumos» — да и многие другие — знают, что в Semonix я занимаюсь облачными технологиями, тесно связанными со SmartOS. На семинаре я расскажу, как с помощью технологии DTrace проводить глубокий анализ производительности и детально изучать работу приложения. Поиск по Хабру находит только одну статью про SmartOS, и чтобы на семинар пришло больше тех, кто уже знаком с ней, я решил заранее написать про установку SmartOS и использование Node.js на ней.

Для начала расскажу, для чего нужна SmartOS. Если коротко, её предназначение – быть хост-системой для виртуальных машин. Она часто используется как основа для публичных и частных облаков, например, облачных служб Joyent и MITAC. Службой Joyent пользуется LinkedIn: вся его мобильная серверная часть сделана на Node.js, который запущен в облаке Joyent. Мы подробно писали об этом в блоге компании Semonix в статьях о SmartOS и об облаках, основанных на illumos, а я рассказывал в докладе на YaC 2012, который уже упоминал.

Типичные случаи применения SmartOS – системы для ЦОДов, системы для разработки и эксплуатации нагруженного веб-приложения, платформа для создания приватного или публичного облака. При работе над этой статьей я активно использовал статью Сту Радниджа, который проделывал примерно такой же путь установки SmartOS, как и я, но с использованием VMware вместо VirtualBox.

Планируем тестовую установку


Допустим, вы оказались одним из тех, кому интересно попробовать SmartOS. Как это проще сделать? Я пошел по самому простому пути, который не даст запустить Windows или Linux в вирутальной машине, зато позволит воспользоваться готовым образом SmartOS + Node.js. Запускать буду SmartOS в VirtualBox. Понятно, что KVM в виртуалке под VirtualBox не заработает, а остальное – должно заработать на ура.

SmartOS может быть хост-системой для гостей под управлением Windows, Linux и самой SmartOS. В этой статье я рассматриваю только вариант с гостевыми системами под управлением SmartOS. В них реализуется легковесная виртуализация (то же самое, что зоны в Solaris и нечто похожее на клетки во FreeBSD), и, стало быть, для их работы не требуется KVM, который поддерживается только на физических компьютерах. Вся конфигурация показана на рисунке ниже. SmartOS (host) – это система, которая является гостем по отношению к Windows на моем ноутбуке, и хостом — по отношению к системам SmartOS, запущенным в зонах внутри этой SmartOS.



SmartOS будем ставить в виртуальную машину с двумя сетевыми интерфейсами. Зачем? Очень просто: я хочу из своей хост-системы (в данном случае – Windows) подсоединяться обычным ssh к SmartOS, чтобы можно было открыть несколько окон — хотя бы по одной штуке для каждой гостевой системы внутри моей SmartOS.

Почему бы не воспользоваться графическим режимом в консоли и не запустить там нужное количество xterm или gnome-terminal? Дело в том, что графика («иксы» — X) в SmartOS не установлена. Существует проект по переносу поддержки X11 в SmartOS, но пока он не завершен, и Джонатан Перкин (Jonathan Perkin), ведущий этот проект на общественных началах, сообщил мне, что срок окончания работы над ним неизвестен. Поэтому, если я хочу открыть пять окон с ssh к своему SmartOS, то понадобится доступ по TCP с моей хост-системы к SmartOS в VirtualBox.

Кроме этого, в гостевую машину SmartOS нельзя установить VirtualBox Guest Additions, позволяющие выполнять cut-and-paste между гостевой системой и хост-системой, в которой я пишу статью (и хочу в нее копировать тексты из терминала). Теоретически, я думаю, установить Guest Additions можно (там по сути нужно установить модули ядра), но для Solaris-подобных систем Guest Additions поставляется в виде пакета формата .pkg, который в SmartOS не поддерживается. Я решил, что мороки с распаковкой пакета и ручным прикручиванием модуля к ядру будет больше, чем с доступом по ssh из хост-системы.

Зачем же нужен второй интерфейс? Чтобы SmartOS мог через NAT выйти за пакетами в интернет. Это ограничение на условия задачи накладывает VirtualBox – сделать в нем доступную из хост-системы виртуалку с NAT/DHCP иначе можно только через bridged network, а это не всегда удобно. Обсуждение случаев, когда не очень удобно (или не поддерживается в определенных хост-системах или версиях VirtualBox), выходит за рамки этой статьи, но поверьте – такое бывает. Самые простые варианты: кончились DHCP-адреса в той сети, куда у вас подключен физический компьютер, или не хочется каждый раз смотреть, какой адрес в этот раз выдан системе перед тем, как к ней цепляться ssh.

Как сделать два сетевых интерфейса в VirtualBox


Настроить виртуальную машину так, чтобы в ней было 2 сетевых адаптера – элементарно: на закладке «Сеть» надо просто указать, что активен не только первый адаптер в режиме host adapter, но и второй — в режиме NAT (см. рисунок ниже). Обратите внимание, что для SmartOS имеет смысл выбрать тип виртуальной машины Solaris 10 10/09 or later (64 bit). Возможно, что вариант Solaris 11 подойдет лучше. У меня без проблем и задержек заработало и так.

Что еще надо настроить?



К CD-ROM виртуальной машины надо подсоединить файл latest.iso — из него будет грузиться SmartOS.



После загрузки в первый раз система задаст несколько вопросов про настройки (в частности, пароль root’a), отформатирует диск, создаст пул ZFS на диске и запишет настройки на диск. После перезагрузки вы должны увидеть нечто, подобное рисунку ниже.



Войдите как root, используя пароль, который вы задали раньше. Уже сейчас можно подсоединиться к SmartOS с помощью ssh, для этого только надо узнать, какой у сервера адрес:

ipadm show-addr


Как сделать два сетевых интерфейса в SmartOS


Конфигурация системы в SmartOS хранится в файле /usbkey/config. Файловая система /usbkey монтируется с диска, в отличие от /etc, которая всегда загружается с LiveCD или LiveUSB и монтируется на RAM-диск. Поэтому изменения, внесенные в файлы из /etc будут потеряны при перезагрузке, а в /usbkey – сохранятся.
Файл /usbkey/config создается при первом запуске SmartOS на компьютере, и по умолчанию он описывает только первый интерфейс в системе. Для того чтобы видел и второй, надо немного изменить файл. Для его модификации нам потребуется узнать MAC-адреса интерфейсов. Для этого можно использовать команду
dladm  show-phys -m


LINK         SLOT     ADDRESS            INUSE CLIENT
e1000g0      primary  8:0:27:f7:e9:a3    yes  e1000g0
e1000g1      primary  8:0:27:d0:35:3b    no   --


Теперь изменим файл /usbkey/config, чтобы он выглядел вот так:


#
# This file was auto-generated and must be source-able by bash.
#
 
# admin_nic is the nic admin_ip will be connected to for headnode zones.
admin_nic=8:0:27:f7:e9:a3
admin_ip=dhcp
admin_netmask=
admin_network=...
admin_gateway=dhcp
 
external_nic=8:0:27:d0:35:3b
external_ip=dhcp
external_netmask=255.255.255.0
external_gateway=dhcp
 
dns_resolvers=8.8.8.8,8.8.4.4
dns_domain=
ntp_hosts=pool.ntp.org
compute_node_ntp_hosts=dhcp
 

Создание виртуальной машины внутри SmartOS


Вначале надо скачать образ виртуальной машины. Для этого надо обновить список образов:
imgadm update

А теперь посмотрим, какие готовые образы есть в репозитории:
imgadm avail



UUID                                 OS      PUBLISHED  URN
78ab4d60-2610-11e2-b3f7-b3bd2c369427 linux   2012-11-04 sdc:jpc:ubuntu-12.04:2.1.2
6a67c702-2083-11e2-b4fa-03f9d1d64ef0 linux   2012-10-28 sdc:jpc:ubuntu-12.04:2.1.1
b00acc20-14ab-11e2-85ae-4f03a066e93e smartos 2012-10-12 sdc:sdc:mongodb:1.4.0
1fc068b0-13b0-11e2-9f4e-2f3f6a96d9bc smartos 2012-10-11 sdc:sdc:nodejs:1.4.0
8700b668-0da4-11e2-bde4-17221283a2f4 linux   2012-10-03 sdc:jpc:centos-6:1.3.0
55330ab4-066f-11e2-bd0f-434f2462fada smartos 2012-09-25 sdc:sdc:base:1.8.1
60a3b1fa-0674-11e2-abf5-cb82934a8e24 smartos 2012-09-25 sdc:sdc:base64:1.8.1
...


Теперь перед нами – список образов, доступных для установки. Здесь приведена только часть списка – он значительно длиннее. На момент написания статьи в репозитории были доступны 96 образов. Нас интересует образ base64 – минимальная система, включающая в себя node.js. В данный момент самая свежая версия этого образа — 1.8.1 (включает node 0.8.9), и его UUID — 60a3b1fa-0674-11e2-abf5-cb82934a8e24.

Скачаем образ виртуальной машины:

imgadm import 60a3b1fa-0674-11e2-abf5-cb82934a8e24


Теперь сделаем описание виртуальной машины, которую мы создадим на основе только что загруженного образа и запустим ее внутри хоста SmartOS.

Описание делается в виде файла JSON (подробности процесса описаны в документации на smartos.org, я здесь просто положу работающий пример – пусть у нас он лежит в /zones/template.json). Файл должен лежать в файловой системе, которая размещается на диске и сохраняется между перезагрузками, удобнее всего – в /zones.
Обратите внимание на dataset_uuid – это тот самый UUID, который принадлежит только что полученному из репозитория образу. В зоне тоже будет два сетевых интерфейса — «внутренний» и «внешний». Такая настройка используется в ЦОДах в реальной жизни: к внутреннему интерфейсу подключается внутренняя сеть, в которой работают администраторы ЦОДа, к внешнему — интернет, откуда приходят клиенты.

{
  "brand": "joyent",
  "dataset_uuid": "60a3b1fa-0674-11e2-abf5-cb82934a8e24",
  "max_physical_memory": 1024,
  "nics": [
    {
      "nic_tag": "admin",
      "ip": "dhcp",
      "gateway": "dhcp"
    },
    {
      "nic_tag": "external",
      "ip": "dhcp",
      "gateway": "10.0.3.2"
    }
  ]
}


Теперь создаем новую виртуальную машину SmartOS (для краткости будем дальше ее назвать «зона»):

vmadm create -f /zones/ template.json


Если все получилось нормально, можно увидеть запущенную новую зону, дав команду

vmadm list
UUID                                  TYPE  RAM      STATE             ALIAS
570cccb2-0511-400b-9143-7616b2ca8a3d  OS    1024     running           -


Теперь можно подключиться к новой зоне либо из консоли SmartOS, либо через ssh:

zlogin 570cccb2-0511-400b-9143-7616b2ca8a3d

Обратите внимание: UUID зоны отличается от UUID образа зоны, потому что из одного и того же образа можно создать много зон. Одновременно в одной хост-системе SmartOS может быть запущено до 8191 виртуальных машин.

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

zlogin 570cccb2-0511-400b-9143-7616b2ca8a3d
ipadm show-addr

Управление пакетами


Теперь можно установить любые нужные нам в зоне пакеты. Для этого надо обновить информацию о доступных пакетах с помощью pkgin update, получить их список pkgin list или искать требуемое с помощью pkgin search. Для установки пакета следует использовать pkgin install.

Как запустить Node.js


Предположим, вы не были знакомы с Node.js ранее. Тогда для начала можно сделать очень простое веб-приложение, выдающее банальное Hello, World! Освоение Node.js можно начать с чтения широко известного руководства. Следуя ему, создаем наш Hello, World.

Для этого соединяемся с зоной

zlogin 570cccb2-0511-400b-9143-7616b2ca8a3d

и создаем, например, в каталоге /home/node файл server.js с таким содержимым:

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(80);

Теперь запускаем node /home/node/server.js и обращаемся к нашей зоне из обычного браузера. В моем случае это потребовало настройки маршрутизации между зоной и хост-системой Windows:

В зоне: route add 192.168.56.1 192.168.56.101
В Windows: route add 192.168.56.102 192.168.56.101

Адрес 192.168.56.1 – это интерфейс VirtualBox в Windows, 192.168.56.101 – хост-система SmartOS, 192.168.56.102 – зона в ней.


Как использовать DTrace с Node.js?


Провайдер DTrace для node называется (сюрприз!) node. Так как это провайдер типа USDT, то его датчики надо указывать либо в виде node*:::<название датчика>, либо с указанием конкретного PID процесса node, например, node3297:::<название датчика>.

Живой пример использования DTrace для наблюдения за работой вашего сервера под Node.js — протоколирование обращений к нему. Чтобы узнать, какие запросы получают серверы из разных зон (типичный случай для хостинг-провайдера), запускаем короткий скрипт:

# dtrace -L /var/lib/dtrace -n 'node*:::http-server-request{printf("%s: %s of %s\n",zonename, args[0]->method, args[0]->url)}' -q
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /favicon.ico
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /favicon.ico
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /
570cccb2-0511-400b-9143-7616b2ca8a3d: GET of /favicon.ico

Чтобы посмотреть, с каких адресов приходят запросы, можно слегка модифицировать скрипт:

# dtrace -L /var/lib/dtrace -n 'node*:::http-server-request{printf("%s: %s of %s\n",args[1]->remoteAddress, args[0]->method, args[0]->url)}' -q
192.168.56.1: GET of /
192.168.56.1: GET of /
192.168.56.1: GET of /favicon.ico
192.168.56.1: GET of /
192.168.56.1: GET of /favicon.ico
192.168.56.1: GET of /
192.168.56.1: GET of /

Для node в DTrace доступны следующие датчики:

gc-start
gc-done
http-client-request
http-client-response
http-server-request
http-server-response
net-server-connection
net-socket-read
net-socket-write
net-stream-end

Если вы обнаруживаете, что какие-то датчики недоступны, это – верный признак того, что файла /usr/lib/dtrace/node.d у вас нет. Тогда надо создать каталог /var/lib/dtrace/, скачать туда файл (он лежит по адресу https://raw.github.com/joyent/node/master/src/node.d) и запускать dtrace с ключом –L /var/lib/dtrace/ (он означает «включить в путь поиска библиотек DTrace указанный после ключа L каталог).

Подробное описание датчиков с примерами кода (на английском) есть на странице dtrace.org/blogs/rm/2011/03/01/dtrace-probes-for-node-v0-4-x/#httpd (там, правда, речь идет об устаревшей версии Node.js).

Заключение


Особая прелесть настроек SmartOS в том, что единожды установив, их не надо повторять после выхода обновления. Можно скачать очередной latest.iso, заменить им прежний и загрузиться с нового. Все настройки, виртуальные машины и файлы внутри них будут подхвачены автоматически, так как в них никто и ничего не меняет — изменяется только загружаемый образ, а настройки существуют отдельно от него.

Тех, кому интересно послушать мой рассказ про DTrace, буду ждать 29 ноября в 19:00 в петербургском офисе Яндекса. Семинар совершенно бесплатный, но количество мест ограничено, поэтому нужно зарегистрироваться. Для тех, кто не попадёт на него, организаторы обеспечат онлайн-трансляцию. А тем, кто собирается, скажу, что нужно взять с собой ноутбуки с установленной SmartOS под VirtualBox, потому что важной частью семинара будет решение практических задач.

Встреча будет полезна всем, кто интересуется анализом производительности приложений в UNIX-подобных системах, особенно разработчикам ПО под Solaris, разработчикам ПО под Node.js, системным администраторам и другим ответственным за производительность (если они работают с системами FreeBSD, Solaris, QNX, OpenIndiana, SmartOS и другими, поддерживающими DTrace).
Tags:
Hubs:
+19
Comments 10
Comments Comments 10

Articles

Information

Website
www.ya.ru
Registered
Founded
Employees
over 10,000 employees
Location
Россия
Representative