company_banner

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

    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).
    Метки:
    Яндекс 665,72
    Как мы делаем Яндекс
    Поделиться публикацией
    Комментарии 10
    • +2
      Про самое интересное забыли — v8 ustack helper для dtrace. Без него смысла запускать node.js на smartos особо и нет.
      • +1
        Честно признаюсь, что опыта работы с Node.js у меня значительно меньше, чем с Solaris/SmartOS/DTrace, поэтому в этой статье я решил в детали Node.js не вдаваться. Про v8 ustack helper есть хороший пост Дейва Пачеко (на англ.)
      • +2
        Уже с пол года интересуюсь и пытаюсь внедрять решение от Joyent.
        Довольно прогрессивная, но одновременно простая штука.
        Очень жаль что документация не столь обширна как хотелось бы.
        И спасибо что освещаете эту тему.
        • +1
          Почему бы не воспользоваться графическим режимом в консоли и не запустить там нужное количество xterm или gnome-terminal? Дело в том, что графика («иксы» — X) в SmartOS не установлена. Существует проект по переносу поддержки X11 в SmartOS, но пока он не завершен, и Джонатан Перкин (Jonathan Perkin), ведущий этот проект на общественных началах, сообщил мне, что срок окончания работы над ним неизвестен. Поэтому, если я хочу открыть пять окон с ssh к своему SmartOS, то понадобится доступ по TCP с моей хост-системы к SmartOS в VirtualBox.


          Оу, матерые специалисты по Solaris для того, чтобы иметь несколько шеллов, ставят на серваки X? Ясненько, ясненько, будем держаться от специалистов подальше.

          screen и tmux, как минимум, есть.
          • 0
            Ваша ирония понятна и весьма мила, спасибо, что добавили немного перца в дискуссию, далекую от бурного обсуждения :) По сути имею сообщить, что матерые специалисты по Solaris, как и все остальные люди, используют в работе самые привычные из адекватных задаче инструментов. В Solaris, сколько я его помню, графический рабочий стол был всегда, а screen я последний раз использовал в середине 90-х под FreeBSD, в которой отродясь никаких иксов я не ставил.

            Так как SmartOS — это прямой наследник OpenSolaris, в котором X ставились по умолчанию, я ожидал, что и здесь они будут, а не обнаружив, воспользовался первым пришедшим в голову решением. Заодно решение позволило посмотреть, как настраивать по два интерфейса на зону — в документации этот момент хоть и описан, но есть некоторые противоречия в реализации. Я придумал конкретную задачу, решил ее и написал, как — чтобы пригодилось тем, кто решает такую же.

            Разумеется, ее можно решить и другими способами.

            А если бы то, на что я ставил SmartOS, было сервером для промышленной эксплуатации, я бы определенно ставил туда не X для нескольких шеллов, а ровно то, что требуется по задаче. Собственно, и на тестовую виртуалку X ставить надобности не было, так что этот процесс здесь не описан.

            А за ссылку — спасибо :)
            • 0
              screen использую повседневно для поддержания сессий по сети.
              Так что ваша ирония так же некорректна.
              • 0
                Здесь не было никакой иронии, я просто признался, что для моих задач его не требовалось использовать с давних пор. Разумеется, я знаю, что screen — полезная программа, и давно ее использовал.
              • –1
                Эта ссылка ведет на joyent-овский pkgsrc-репозиторий SmartOS. Неужто и она специалисту в новинку?
                • +1
                  Статья написана для всех, а не только для специалистов. И ваш ответ читаю не только я. Ваш предыдущий комментарий, с моей точки зрения, содержал: оверквотинг, иронию (я надеюсь, связанную лишь с тем, что вы не поняли причин, по которым я упомянул X), ссылку. Я поблагодарил вас за то конструктивное, что было в комментарии.

                  Если вам кажется, что статья слишком проста, значит, она была написана для людей, пока еще не имеющих вашей квалификации. Попробуйте воспользоваться старым добрым принципом ПДН, и предположить, что ваши собеседники тоже разбираются в том, о чем идет речь ;)
                  • 0
                    Ок :)

                    Ирония на самом деле вызвана некоторым несоответствием уровня статьи и целевой аудитории. Если не ставить целью создание облачной платформы для предоставления услуг node.js-хостинга, то есть не требовать четкого учета ресурсов, необходимого для биллинга, прекрасно подходит любая контейнерная виртуализация на всем знакомых ОС (linux, bsd).

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

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