Всем добрый день.
В связи с растущей нагрузкой на один из сайт компании, в которой я числюсь системным администратором, было принято решение воспользоваться балансировщиком Keepalived. Останавливаться на этом продукте не буду, опишу возникшую проблему.
Раскладка происходит из gitlaba. Для того, чтобы отдел тестирование был в курсе того, что он вообще тестирует, давным давно на каждый отдельный сайт был добавлен файл. Обычный txt файл, который генерировался при раскладке. В себе этот файл содержал информацию о текущей версии (бранч, ревизию, хэш последнего коммита и список последних 300 коммитов.) То есть благодаря этому файлу, тестировщик знает, что именно он тестирует. Выглядит это примерно так:
Так как этот файл находится на всех нодах, было принято решение сравнивать версии по нему.
Взяли 2 ноды с ubuntu. На каждой keepalived, nginx, php5-fpm. Виртуальный ip скачет между нодами.
Так как у меня был карт-бланш на решение, я выбрал то к чему лежит душа.
Не буду приводить много кода, так как я не программист и писать его не есть моя обязанность.
Решение следующее:
— bash скрипт для генерации файла на скриншоте выше;
— go для построения вэб-морды и проверки;
— python для nagios.
Первым делом была написана функция для для получения хэша.
func get_release(revall string) (string){
i := strings.Index(revall, "commit ")
chars := revall[i:]
i = strings.Index(chars, "n")
returned := chars[:i]
return returned
}
В этой блоке я, как видно, получаю из текстового файла строку вида «commit 65f58976c71651c91ba641d43930f07a3d55c244».
Так же был добавлен конфиг и функция его чтения. Для динамичности, конфигов может быть несколько, чтение идет папки в стиле conf.d. Конфиг представлял из себя следующее:
{
"HeaderHost": "somehost.org",
"ips": ["192.168.1.1", "192.168.1.2"],
"Hostname": ["somehost.org-1", "somehost.org-2"]
}
Тут тоже все понятно, так как nginx настроен на *:80, то можно смело биться в прописанный в interfaces адрес с нужным именем. Собственно, так же этот самый адрес в конфиге и hostname просто для вывода в форму.
Функция реквеста.
func reqrev(urlic string, host string) string {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
req, _ := http.NewRequest("GET", urlic, nil)
req.Host = host
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
return string(body)
}
На сайте стоит реврайт с http на https. Так что в функцию был добавлен кусок об игнорирование сертификата и коннект идет сразу в https. Кусок выше скорее тестовый чем боевой, поэтому обработка ошибок не учтена.
На самом деле я привираю, что это было первое, что сделано. Первым делом был найден шаблон bootstrap и переделан под конкретную нужду.
Далее шел набор всевозможных функций, структур и шаблонов html (с которыми go работает, на мой взгляд, очень просто и удобно), для получения желаемого результата. В итоге я получил нечто следующее.
Тут мы видим разницу, если она есть. В случае если последний коммит совпадает — все зеленое спокойное, если нет — цвета становятся красными и вверху страницы будет написано что и где расходится.
Для агрегации информации была добавлена эта страница
По нажатию на кнопку REV получаем тот самый тектовый файлик.
Далее при помощи все тех же функций и добавления одной новой, вешаем на го-вэб-сервер по uri /nagios, например, json.
В этом случае наш питоноскрипт приходит на все готовое. Тут вы в массиве выводим проверямые сайты (конфиги которых находятся в папке conf.d), статус для нагиоса (0-ОК), и описание. В случае если расхождения будут в описании будет массив из коммитов и изменится статус.
Очевидно, что можно было найти более простое решение и реализовать, например, в один питоноскрипт, но так делать было веселее и интереснее. Если будут заинтересовавшиеся, могу причесать код и выложить. Прошу простить за косо замазанные скриншоты.
Автор: mesyancev