А что если ваши приложения будут обрабатывать самостоятельно свои собственные операционные системы? Это вроде как окончательная форма DevOps, верно? Его окончательная эволюция? Чаризард для DevOps, если хотите.
Вдохновение, чтобы написать об этом, пришло от Kelsey Hightower, который прекрасно рассказал о саморазвитии приложений Kubernetes. https://www.youtube.com/watch?v=XPC-hFL-4lU Рекомендую к просмотру.
Вот вам и TLDR; myapp --kubernetes --replicas=5
myapp сам статирует для Linux, монтирует себя и развертывает себя в кластер Kubernetes с 5 репликами. Никаких файлов конфигурации не требуются.
Я подумала, что это было бы очень круто, и тут же отправился проверять Kubernetes, чтобы посмотреть, могу ли я добавить что-то подобное Pilosa( https://github.com/pilosa/pilosa). В документации Kubernetes есть такая страница, посвященная «выбору правильного решения», которая имеет более 40 различных способов общения с Kubernetes, ни один из которых не «запускал этот двоичный файл». Я не хочу копаться в сомне страниц документации только для одного маленького быстрого эксперимента! Я знаю что Kubernetes это отличное программное обеспечение, и я готова поспорить, что скоро мы будем развертывать Pilosa в нашем собственном кластере Kubernetes. Однако в этот конкретный момент меня действительно поразила идея «саморазвертывания приложений», а не рутинная часть «на Kubernetes».
На самом деле я осознала, что уже проделала определенную работу в этом направлении для бенчмаркинга Pilosa. Первоначальная идея заключалась в том, чтобы создать инструмент, который с помощью одной команды смог бы: Предоставлять облачную инфраструктуру различным провайдерам Устанавливать и запускать кластер Pilosa на удаленных хостах Позволит определить высоко настраиваемые тесты Устанавливать и запускать тесты на удаленных «агентовских» хостов Собирать результаты тестов Собирать метрики хоста (процессор, память и т.д.) Хранить все данные каждого теста в согласованном формате Готовить и подавать вкусняшки(шутка) В любом случае мы фактически достигли некоторых из этих целей с помощью нового инструмента Pi. Pi — это инструмент, специально предназначенный для бенчмаркинга Pilosa, но я думаю, что он содержит некоторые многоразовые библиотеки, которые могут быть полезны для сообщества с открытым исходным кодом в целом (с возможностью его улучшения).
Это всё хорошо, но давайте вернемся к развертыванию приложений. Давайте отложим часть предоставления ресурсов из облака на данный момент, и скажем что у нас есть набор свежих, чистых, Linux-хостов, к которым есть ssh-доступ, и мы хотим непосредственно протестировать Pilosa. Допустим у вас есть локальная кодовая база Pilos (в вашем GOPATH), а также мифический инструмент Pi. Какова минимальная сумма работы, которую вы могли бы ожидать, чтобы запустить тест против кластера Pilosa и собрать результаты? Как насчет запуска одной команды на вашем ноутбуке в каком-нибудь переполненном кафе?
pi spawn --pilosa-hosts=<...> --agent-hosts=<...> --spawn-file=~/my.benchmark
Нажимаете на enter, и через несколько минут у вас данные бенчмаркинга прямо перед вами. Многоузловой кластер Pilosa был создан вместе с несколькими узлами агентов для отправки запросов к нему. Агенты извергли огромное количество реалистично распределенных случайных данных в кластер, а затем последовали за ним с помощью комплекса сложных запросов.
Имейте в виду, что до того, как вы запустили Pi, этот пул удаленных хостов знать не знает о Go, Pilosa, Pi или о чем либо еще. Это были просто изображения Linux с AWS или GCP или что-то подобное. Как мы это сделаем? Давайте разобьем процесс на этапы: во-первых, нам нужно иметь возможность подключаться к удаленным хостам через ssh изнутри программы Go. Приятный сюрприз, оказывается у Go есть довольно большой пакет ssh(https://godoc.org/golang.org/x/crypto/ssh), который обрабатывает большую часть этого вместо нас.
Как только мы подключаемся к удаленным хостам, мы можем выполнять команды в оболочке как с терминала! Мы получаем стандартные интерфейсы Reader и Writer для получения данных в этих командах и из них, поэтому всё очень хорошо. Но что мы собираемся запустить? У этих хостов нет установленных Pilosa или Pi, которые нам понадобятся, если мы хотим запустить кластер и протестировать его. Ну, давайте просто запустим dog — у этих хостов определенно есть это, не так ли? В частности, мы будем запускать dog > pilosa — помните про Writer? Это на самом деле io.WriteCloser, и он идет прямо на stdin dog. Поэтому мы просто пишем весь бинарный файл Pilosa прямо там, закрываем его, и данные магическим образом переносятся в файл на удаленном хосте! «Подождите», скажете вы. «Какой бинарный? Мой ноутбук в этой кофейне не имеет бинарного файла Linux для Pilosa.» Как вы, возможно, догадались, Go экономит день, сделав его легким для перекрестного компилирования для других платформ. Теперь я знаю, что вы думаете: «Он собирается импортировать пакеты для компилятора Go, строить новый диск Pilosa непосредственно в памяти и передавать его прямо в dog, работающую на удаленном хосте. Я НЕ МОГУ ЖДАТЬ! " Да, нет, извините — это тот самый парень, который не мог потрудиться, чтобы запустить виртуальную машину, чтобы испытать Kubernetes. Я посмотрела на источник для инструментальной цепочки в течение минуты и решила использовать os / exec для запуска сборки go в подпроцессе.
com := exec.Command("go", "build", "-o", "someTempFile", "https://github.com/pilosa/pilosa") Ах да нам ведь нужно настроить среду, чтобы убедиться, что мы всё это дело создаем для Linux: com.Env = append(os.Environ(), "GOOS=linux")
Откройте временный файл dog,поместите его на удаленный хост, с помощью chmod, чтобы сделать его исполняемым, и … работаем! Давайте уделим минутку для обдумывания того как много Go помогло нам там — не только придал легкость перекрестной компиляции, а еще учтем тот факт, что мы можем скомпилировать автономный бинарный файл, который довольно легковесный, и это пожалуй всё, что нам нужно для запуска нашего приложения на другом хосте. Никакой JVM, никакого переводчика — это действительно просто очень освежает — как добротный лимонад. Хорошо, бинарный файл Pilosa на своем месте. Мы можем создать файл конфигурации и скопировать его таким же образом или просто запустить Pilosa с аргументами командной строки. После того, как он будет запущен, мы сможем передать любые логи обратно нам или оставить их в файле на удаленном хосте.
Теперь настало время обратить внимание на поставленную задачу — бенчмаркинг. Говоря формально, мы еще не создали самораспространяющееся приложение, мы создали приложение для развертывания Pilosa — помните, что это Pi, который делает всё это дело. Но нам нужно запускать Pi на удаленных хостах, потому что у Pi есть все инструменты для бенчмаркинга, и нет никакой причины, по которым этот кросс-компиляционный dog не будет работать так же, как в исходном коде самой программы, которая его запускает. Мы перекрестно скомпилируем Pi, копируем его на каждый из «агентов» и выясним, какие тесты мы должны запускать, и запускаем их! Бенчмаркинг Pi сообщают о своих результатах в формате JSON на stdout, который мы счастливо собираем. Это немного странно, но опять же, мы обязаны за предоставленные нам модели параллелизма, которые делает всё очень простым. Мы запускаем несколько разных программ на нескольких удаленных хостах, которые бросают огромные объемы данных друг на друга и делают массовые вычисления. И всё это из одной программы на одном обычном ноутбуке с хиленьким Wi-Fi-соединением. Не говоря уже о том, что мы передаем потоки и объединяем результаты всех этих удаленных программ в единую сплоченную структуру результатов, которая полностью описывает бенчмаркинг. Это было бы кошмаром наяву для большинства языков! Вот, у вас на руках самораспространяющееся приложение без использования Kubernetes. Всё, что вам нужно, это куча хостов, к которым у вас есть доступ через SSH, и вы тоже можете создавать сложные флоты самораспространяющихся программ. Изучите исходный код для Pi (особенно пакеты build и ssh) и прочитайте документацию, если вы действительно хотите их использовать. Возможно, вы тоже сможете подкинуть пару патчей проекту.