Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Categories:

Огороженный хероку без говна для ноды

Это очередные мысли о том, как нам реорганизовать https://github.com/nponeccop/vz

Во-первых, OpenVZ (и в значительной мере Xen) в значительной степени умерли на рынке говнохостингов http://lowendbox.com/ и заменились на KVM.

Во-вторых, появился CentOS 8 c systemd

В-третьих, выросла инфраструктура для альтернативных докеров - типа runc и соответствующей инфраструктуры имиджей

В-четвертых, Redhat отдался IBM, то есть по идее со временем станет ещё более дубовым.

В связи с этим нужно портировать vz c CentOS 6 на CentOS 8

Если кто не помнит, суть vz токова: это система для запуска контейнеров, устойчивая ко взлому. Устойчивость достигается отсутствием каких-либо демонов, реестров и менеджмент-соединений. Система почти airgapped - вся менеджмент-активность идёт через Ansible, который работает через SSH.

а) нет ни входящих ни исходящих соединений
б) нет постоянно запущенного говнокода - запущены только приложения и systemd, который запускает sshd по требованию

Ну то есть в некотором смысле это возврат к старому подходу (до devops и автодеплоймента), при которой всё конфигурирование выполняется только админом и только вручную, за исключением того, что у нас не вручную, а посредством Ansible. Ansible выбран по 4 причинам:
- Redhat/IBM
- работоспособность на голом CentOS
- работа только в момент реконфигурации
- работа только через входящее SSH-соединение

В частности:
- отсутствие какой-либо активности, если реконфигурации не происходит и админ спит (условно, отсутствие пулла манифестов по таймеру)
- как следствие, отсутствие демонов и management-related servers,
- отсутствие отдельных входящих и исходящих коннекшенов и

Ну то есть нет говносервера, написанного нами, который можно хакнуть. И нет возможности украсть какие-либо секреты, связанные с менеджментом, из онлайна - SSH-ключ у админа на флешке в сейфе, у серверов нет ключей друг от друга или от мастера и т.п. То есть взлом сервера вообще никакой дополнительной информации о кластере не даёт, кроме содержимого этого единственного сервера.

1. В отличие от условной CoreOS, в которой есть etcd. И где можно взломать сам etcd c вероятностью большей чем взлом OpenSSH, после чего рут на всём кластере, или взломать любой сервер, у которого by design есть доступ к etcd то есть легко получить список всех серверов и имиджей на них запущенных.

2. В отличие от докера, где есть реестры и dockerd голой жопой в ынете, прикрытые только написанной мальчиками-дебилами схемой авторизации вокруг HTTPS (недебилами аутентификация и крипта, я надеюсь, но всё равно говно-го не так непробиваем, как OpenSSH). Взлом реестра в случае ноды позволяет получить сорцы всей системы как на ладони. Не говоря о возможности подменить имиджи своими (я надеюсь, схема подписей имиджей оффлайн-ключами там есть, но скажем, реестра с end-to-end шифрованием имиджей, который был бы не менее устойчив, чем моя схема с пушем, нету).

Кстати о пушах. В связи с тем, что соединения запрещены, мы можем только передавать имиджи через SSH в момент обновления, что не исключает схем с SSH port forwarding на машину админа, но варианта с аплоадом тарболлов через SFTP средствами Ansible оказалось достаточно.

Ортогональна к схеме работы с имиджами-контейнерами-релизами схема с парсингом вывода strace и созданием "минимальных" имиджей, что делает скажем, пуш на десяток серверов через мегабитное соединение, реальностью. Селф-контейнед тарболл без использования уменьшенных libc, стат.линковки или дельта-слоёв выходит в 17 метров (правда i686). Думаю можно отказаться от этого в пользу стандартных имиджей и-или сделать гибридную модель с пуллом базового имиджа с докер-хаба.

Но по большому счёту в сборке имиджей конь не валялся и там есть где фантазии разгуляться. Так что можно считать это отдельным подпроектом и первое время не париться (но например, вытягивать наши сорцы с реестра ни в коем случае нельзя). В любом случае, какой-то черновой вариант имиджей-без-реестров у нас есть, и можно его и оставить на первое время.

Далее ввиду требования к отсутствию демонов хорошо бы использовать не докер, а какого-то из его младших братьев, типа runc. Текущие имиджи (точнее, бандлы в которые имиджи распаковываются) у меня соответствуют спецификации, которую требует runc, так что он их прекрасно запускает (не считая потенциальных проблем с PID 1 zombie reaping).

Основной объём работ - это перевод vzexec на рельсы systemd и замена ручной работы с vzmaster push/vzmaster start/vzmaster kill, который внутри дёргает ansible, на полноценную ansible-конфигурацию. Ну то есть, надо писать кастом-роли ансибла, которые сами будут пушить то, что нужно. Сейчас иногда доходит до абсурда - vzmaster не понимает групп серверов, и выполняет операцию для всех серверов из /etc/ansible/hosts, так что я постоянно комменчу одни и раскомментирую другие. Что на практике оказывается не error prone, но утомительно и концептуально детский сад и/или ад.

Заодно полечится отсутствие персистенса - сейчас, если сервер перезагружается, то все контейнеры падают и надо раскомментировать этот сервер в hosts и делать на нём vzmaster start для примерно 5 контейнеров. Тьфу!

Помимо этого назрела необходимость в некоем server lifecycle management. По причинам, не связанным с дешевизной серверов, у нас небольшая текучка хостингов. И трудно привязать биллинговые имейлы к текущей конфигурации приложения.

"Я тут нашёл имейл от августа там нас биллят за 2.3.4.5. Мы это ещё используем?"

Это можно решить, используя конфиг ансибла для конфигурации приложения (DRY) и положив конфиг под сурс-контрол, дабы было понятно, что в нём мы переставляли и с какой целью (конфиг приложения сейчас под сорс контролом, но он независим от vz). Но для этого надо отказаться от ада с vzmaster, см. выше.

Ещё назрела система автоматических билдов - сейчас vzbuild просто собирает базовый имидж по списку файлов, собранному strace. Хорошо бы сделать типа хероковских релизов - ну то есть чтобы vzbuild release привязывал имиджи к ревизии, из которой они были собраны, и работал через pull - то есть чтобы нельзя было зарелизить что-то незакоммиченое.

Ну и я постоянно посматриваю на https://github.com/openshift/source-to-image в надежде на то, чтобы весь билд выполнять в изолированных имиджах, а не на хост-тачке. Я начал было это лепить, используя docker hub в качестве соплей, но застрял на том, что на докерхабе нету нужной для работы strace капабилити. Но если отказаться от говноедства с strace, или отказаться от докерхаба, или заниматься трассировкой после сборки имиджа, в отдельной фазе "облегчения", может получиться.

Ещё одна необходимая фича - это апгрейд и даунгрейд релизов. Ну то есть сейчас все имиджи независимые - и можно пустить (на одном хосте) несколько разных версий одного имиджа параллельно. Ну и при апгрейде надо помнить id старого и нового имиджа. Что на практике более error prone, чем раскомментирование хостов. Соответственно в ansible надо будет сделать, что если мы хотим версию foo имиджа bar - то все остальные версии надо тушить, или как-то так.
Tags: programming, все пидарасы а я
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 34 comments