Для загрузки исходников нам понадобиться загрузить некоторые файлы. Для этого в системе должны быть установлены соответствующие пакеты. В зависимости от типа системы процесс установки будет незначительно отличаться.
а) на системах Red Hat:
yum install git wget
б) для систем на основе Debian:
apt-get install git wget
Установка Go
Для компиляции исходника, нам необходимо установить Golang. Для этого переходим на страницу загрузки и копируем ссылку на архив с его последней версией:
* по умолчанию, страница предлагает загрузить Go для нашей операционной системы, поэтому, если мы открыли сайт на компьютере Windows, ниже под кнопкой загрузки выбираем Linux.
Воспользовавшись ссылкой, скачиваем архив на наш сервер:
На клиенте в настройки брандмауэра добавляем правило на разрешение порта 9080.
а) если используем iptables (Debian, Ubuntu):
iptables -I INPUT 1 -p tcp —dport 9080 -j ACCEPT
apt-get install iptables-persistent
netfilter-persistent save
б) если используем firewalld (CentOS, Red Hat):
firewall-cmd —permanent —add-port=9080/tcp
firewall-cmd —reload
После установки promtail открываем браузер и переходим на страницу http://192.168.0.25:9080/targets, где 192.168.0.25 — IP-адрес клиентского компьютера с NGINX. Мы должны увидеть страницу:
Promtail работает. Можно приступать к сбору логов.
Для работы с хостинг-провайдером нам заранее понадобятся авторизационные данные и идентификаторы ресурсов. Их мы будем прописывать в сценариях terraform.
Нам нужно зарегистрироваться на сервисе Yandex.Cloud (в нашем примере, мы будем работать, именно, с ним). После этого, нам нужно получить:
1. OAuth-токен. Используется в процедуре аутентификации для получения IAM-токена и нужен нам для прохождения авторизации при подключении terraform. Выдается на 1 год. Получить можно, отправив запрос со страницы документации Яндекс.
2. Идентификатор облака. После регистрации на хостинге мы заходим в контроль-панель. Мы должны увидеть наши ресурсы, в частности, облако:
А справа от него будет идентификатор.
3. Идентификатор каталога. На той же странице контроль панели, ниже облака мы увидим каталог:
Также, справа мы можем скопировать его идентификатор.
После получения нужных данных просто сохраняем их в отдельный файл. После установки terraform они нам понадобятся.
Установка Terraform
Terraform является клиентом и необходимо выполнить установку на компьютер, с которого планируется управление инфраструктурой. Актуальная инструкция по развертыванию представлена на официальном сайте. На текущий момент клиент может быть установлен из репозитория, с использованием бинарника, собран из исходников, а также с помощью choco на Windows или brew на Mac OS. В нашем примере будут рассмотрены установка на Ubuntu и Rocky Linux из репозитория, а также загрузка бинарника.
Ubuntu (Debian)
Обновляем список пакетов:
apt update
Установим дополнительные пакеты:
apt install gnupg software-properties-common curl
* где:
gnupg — программа для шифровки и дешифровки цифровых подписей. Нужна для работы с репозиториями.
software-properties-common — утилита для работы с репозиториями.
Убедимся, что terraform работает. Для этого вводим команду:
terraform -version
Мы должны получить что-то на подобие:
Terraform v1.1.7 on linux_amd64
Также рекомендуется установить автоподстановки:
terraform -install-autocomplete
Это позволит нам завершать команды terraform с помощью клавиши Tab.
Теперь создадим каталог, в котором будем работать со сценариями для тераформа:
mkdir -p /opt/terraform/yandex
* в моем примере я решил работать в каталоге /opt/terraform/yandex.
Перейдем в созданный каталог:
cd /opt/terraform/yandex
Мы готовы приступить непосредственно к работе с terraform.
Установка провайдера
Чтобы terraform мог корректно взаимодействовать с инфраструктурой провайдера, необходимо использовать набор инструкций, которые будет использовать наша утилита. В терминологии terraform это называется провайдер.
На сайте Hashicorp можно найти все поддерживаемые провайдеры. Как говорилось выше, мы будем работать с Yandex.Cloud. Рассмотрим подробнее установку провайдера для работы с ним.
terraform required_version — версия клиента terraform, для которого должен запускаться сценарий. Параметр не обязательный, но является правилом хорошего тона и может помочь избежать некоторых ошибок, которые возникнут из-за несовместимости при работе в команде.
required_providers version — версия провайдера. Мы можем указать, как в данном примере, необходимость использовать конкретную версию, а можно с помощью знака >= или <= указать не выше или не ниже определенной.
token — OAuth-токен для прохождения авторизации. Был нами получен после регистрации на хостинге
cloud_id — идентификатор для облака, в котором будут создаваться ресурсы. Также получен был нами заранее.
folder_id — идентификатор каталога, который также был получен в начале инструкции.
zone — ресурсы, которые хранятся на мощностях Яндекс разделены по зонам. Каждая зона — это определенная географическая локация центра обработки данных. Список доступных зон можно посмотреть на странице Зоны доступности.
Теперь выполним команду:
terraform init
Система загрузит нужные файлы и установит провайдер:
Initializing the backend...
Initializing provider plugins...
- Finding latest version of yandex-cloud/yandex...
- Installing yandex-cloud/yandex v0.73.0...
- Installed yandex-cloud/yandex v0.73.0 (self-signed, key ID E40F590B50BB8E40)
...
Terraform has been successfully initialized!
...
Мы готовы двигаться дальше.
Работа с ресурсами
Мы рассмотрим небольшие примеры по созданию, редактированию и удалению ресурсов. В большей степени мы будем работать с виртуальными машинами. Большую часть информации по написанию сценариев можно найти на официальном сайте хостинга или самого terraform.
Создание ресурсов
В нашем рабочем каталоге создадим новый файл:
vi infrastructure1.tf
Напишем минимально необходимый сценарий для создания виртуальной машины:
data — позволяет запрашивать данные. В данном примере мы обращаемся к ресурсу yandex_compute_image с целью поиска идентификатора образа, с которого должна загрузиться наша машина.
yandex_compute_image — ресурс образа. Его название определено провайдером.
ubuntu_image — произвольное название ресурса. Его мы определили сами и будем использовать в нашем сценарии.
ubuntu-2004-lts — в нашем примере мы запрашиваем данные ресурса, который ищем по family с названием ubuntu-2004-lts. Данное название можно посмотреть в контроль панели хостинга — нужно выбрать образ и кликнуть по нему. Откроется страница с дополнительной информацией. В данном случае ubuntu-2004-lts соответствуем Ubuntu 20.04 LTS.
resource — позволяет создавать различные ресурсы.
yandex_compute_instance — ресурс виртуальной машины. Его название определено провайдером.
vm-test1 — наше название ресурса для виртуальной машины.
subnet_terraform — наше название для ресурса подсети.
metadata — обратите особое внимание на передачу метеданных. В данном примере мы передаем содержимое файла, а сам файл рассмотрим ниже.
** в нашем примере будет создана виртуальная машина с названием test1, 2 CPU, 2 Gb RAM в сети 192.168.15.0/24 на базе Ubuntu 20.04 LTS. *** обратите внимание, что мы указали идентификатор той подсети для виртуальной машины, которую создали также с помощью нашего сценария terraform.
* в данном файле мы опишем пользователя, под которым мы сможем подключиться к нашему серверу по SSH:
#cloud-config — как выяснилось, этот комментарий обязательный.
name — имя пользователя, который будет создан на виртуальной машине.
groups — в какую группу добавить пользователя.
shell — оболочка shell по умолчанию.
sudo — правило повышения привилений.
ssh-authorized-keys — список ключей, которые будут добавлены в authorized_keys.
Попробуем испытать наш сценарий. Сначала вводим:
terraform plan
Если мы не ошиблись, утилита покажет, что terraform сделает в нашей облачной инфраструктуре. Очень важно внимательно просматривать изменения.
После того, как мы убедимся в корректности действий, применяем настройку:
terraform apply
Мы еще раз увидим, что будет выполнено, а также получим запрос на подтверждение действий — вводим yes:
Enter a value: yes
Terraform выполнит необходимые действия. Мы можем перейти в контроль-панель хостинга и убедиться, что наша виртуальная машина создалась.
Редактирование данных
Если необходимо внести изменения в нашу инфраструктуру, то достаточно просто открыть наш файл со сценарием:
vi infrastructure1.tf
Внести нужные изменения, например:
...
resources {
cores = 4
memory = 4
}
...
* в нашем конкретном случае, мы увеличили количество процессоров и объем памяти для созданной виртуальной машины.
Однако, некоторые изменения требуют остановки виртуальной машины. В этом случае мы получим ошибку при попытке применить новые настройки с текстом:
Error: Changing the `secondary_disk`, `resources`, `platform_id`, `network_acceleration_type` or `network_interfaces` on an instance requires stopping it. To acknowledge this action, please set allow_stopping_for_update = true in your config file.
Мы должны явно разрешить для конкретных ресурсов выполнение остановки их работы для внесения изменений. В нашем файле для конкретного ресурса добавим:
* для нашей машины test1 мы указали опцию allow_stopping_for_update, которая говорит о том, что работу ресурса можно останавливать для внесения изменений.
Строим план:
terraform plan
Мы должны увидеть, что будет изменено в нашей инфраструктуре. В моем случае:
Задача – добавить дашборд для отображения различной статистики с бекенда.
Ниже описывается процесс создания дашборды, рассматриваются примеры запросов из Grafana к Prometheus для получения данных, настройки различных типов панелей, примеры метрик, которые можно использовать.
Соответственно – в дашборде хочется выводить статистику и того, и другого. Для этого – добавим переменную, с помощью которой сможем переключаться между ними.
Переходим в Variables:
в Name задаём имя, которое будет использоваться в запросах
Type – оставляем Query
Label – имя, как оно будет отображаться в дашборде для выбора
Data source – Prometheus
Refresh – при загрузке дашборда
Query – собственно, сам запрос, который вернёт нам значения, и из которого будем получать список окружений в данном случае Prometheus-сервер, который запущен на EC2, добавляет external_label в виде env=mobilebackend-dev, его и используем для получения значений – используем метрику node_boot_time_seconds, фильтруем вывод по метке job="node-exporter" запрос получается: label_values(node_boot_time_seconds{job="node-exporter"}, env)
Сохраняем – Add внизу.
Статусы хоста
Первым добавим блок, в котором убдут выводить % использования CPU, Load Avareage, память и диски.
CPU Busy
node_cpu_seconds_total
Прежде, чем заниматься настройкой отображения CPU Busy – давайте вспомним /proc/stats.
Сначала – получим время с момента запуска системы:
Выполняем сложение всех счётчиков, делим на 100 – получаем общее кол-во секунд.
Потом, аналогично вычислениям с uptime – получаем кол-во дней, вышло 24 – один день (точнее 4 часа) “потерялся”, но не критично – в целом значения сошлись.
Теперь выведем метрики node_exporter, и сравним их с данными из /proc/stat (на самом деле метрики я вывел немного раньше, поэтому будет разница):
root@bm-backed-app-dev:/opt/prometheus-client# curl -s localhost:9100/metrics | grep node_cpu_seconds_total
HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 2.13035164e+06
node_cpu_seconds_total{cpu="0",mode="iowait"} 579.98
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 11.88
node_cpu_seconds_total{cpu="0",mode="softirq"} 298.71
node_cpu_seconds_total{cpu="0",mode="steal"} 1340.68
node_cpu_seconds_total{cpu="0",mode="system"} 4660.78
node_cpu_seconds_total{cpu="0",mode="user"} 14346.37
И сравниваем с stat:
user: stat = 14351.56, exporter = 14346.37
system: stat = 4662.32, exporter = 4660.78
Окей – тут тоже всё более-менее сходится, и значение данных из node_cpu_seconds_total понятно.
Запрос
Теперь рассмотрим запрос, который будем использовать для получения CPU Busy %:
(((count(count(node_cpu_seconds_total{env="$environment"}) by (cpu))) - avg(sum by (mode)(irate(node_cpu_seconds_total{mode='idle',env="$environment"}[5m])))) * 100) / count(count(node_cpu_seconds_total{env="$environment"}) by (cpu))
Тут:
count – считаем кол-во элементов, полученных из запроса
irate – считает значение в секунду, основываясь на двух последних данных
node_cpu_seconds_total – секунды в каждом режиме (system, user, idle etc)
{env=~"$environment"} – выборка по значению переменной $environment
Подсчёт кол-ва ядер
Кол-во ядер мы получаем запросом ((count(count(node_cpu_seconds_total{env="$environment"}) by (cpu))).
Рассмотрим его детальнее.
Сначала сделаем выборку по node_cpu_seconds_total{env=~"mobilebackend-dev"}:
Так мы получим значения node_cpu_seconds_total по каждому типу – iowait, user, system, nice etc.
В count(node_cpu_seconds_total{env=~"mobilebackend-dev"}) считаем общее кол-во элементов (iowait, user, system, nice etc), хотя оно нам не надо – мы просто используем этот массив для следующего запроса.
А следующий запрос – count(node_cpu_seconds_total{env=~"mobilebackend-dev"}) by (cpu) возвращает нам общее кол-во node_cpu_seconds_total по типам для каждого ядра:
Например для Production это будет выглядеть так:
И в конце-концов добавив ещё один счётчик – count, и превратив запрос в count(count(node_cpu_seconds_total{env=~"mobilebackend-dev"}) by (cpu)) – мы получим кол-во ядер:
Coloring – включаем красивую подсветку по значениям, и в Thresholds задаём значения, при которых цвет будет меняться – на оранжевый при 75%, и на красный – при 90%
Stat – Current
Unit – выбираем None > percent 1-100
Получается такое:
Возвращаемся к дашборе, добавляем ещё один елемент – Row:
Задаём имя, меняем размер панельки с CPU Busy:
Load Average
Следующая панелька будет выводить Load Average.
Можно было бы вывести просто значение node_load1{env=~"$environment"} – но на Dev сервере одно ядро, и значение node_load1 == 1 будет являться условными 100% для одного ядра, а на Production с его 8 ядрами node_load1 == 1 будет всего:
>>> 1.0 / 8 * 100
12.5
12.5%
Значит, что бы корректно отрисовывать шкалу – нам потребуется получить значение LA, поделить его на кол-во ядер и умножить на 100 – получим % от “максимального” (в кавычках, потому что LA может быть и выше 1 для 1 ядра или 8 для 8 ядер) значения.
Следовательно – используем такой запрос:
avg(node_load1{env=~"$environment"}) / count(count(node_cpu_seconds_total{env=~"$environment"}) by (cpu)) * 100
в (node_memory_MemTotal_bytes{env="$environment"} - node_memory_MemFree_bytes{env="$environment"}) считаем общее кол-во занятой памяти (active + cache), назовём её busy
и считаем busy / total * 100 – получаем % от свободной памяти
В Options включаем шкалу, настраиваем аналогично примерам выше:
Повторяем для второго диска – /rootfs/data, получаем такую картинку в дашборде:
Текущеее время
Следующим – добавим отображение текущего времени. Во-первых – просто удобно на экране (в комнате висит большой телевизор, на котором выводится борда) видеть текущее время, во-вторых – такая себе проверка на то, что браузер/дашборда не зависли, и обновляются.
Для вывода времени – опять используем Singlestat панели, и функцию timestamp(), которой передадим метрику up (можно любую – нам только требуется получить из метрики время).
Добавим ещё несколько графиков – статистику с AWS Application Load Balancer.
Тут надо добавить ещё одну переменную – Load balancer.
К сожалению – cloudformation_exporter не умеет получать теги, поэтому пока придётся использовать просто имена ALB (надо будет посмотреть – может на стороне Prometheus можно будет сделать им relabel).
Переходим в Axes, и включаем отображение шкалы Y справа, в юнитах используем милисекунды:
Далее переходим в Display > Series overrides > Add override, и в Alias or regex указываем алиас метрики, в данном случае мы хотим выводить время, основываясь на данных из `aws_applicationelb_target_response_time_sum`, который в метриках указывается как response_time ms:
Кликаем на “+” – добавляем желамое действие. Тут указываем отображание времени в Y Right и заодно – можно поиграть со цветом:
И всё вместе теперь выглядит так:
EC2 statistics
И последним – добавим графики EC2.
В принципе – тут ничего такого, что уже не рассматривалось выше.
CPU
Сначала – статистика использования CPU – System, User, IOwait, idle.
В самом простом виде запросы выглядел бы так:
sum by (instance)(rate(node_cpu_seconds_total{mode="system",env="$environment"}[5m])) * 100
Получаем % от времени, которое CPU проёвл в режиме system/user/idle и т.д.
Но в случае, когда у нас несколько ядер – добавляем вычисление % от кол-ва ядер, аналоигчно тому, как мы это делали для отрисовки шкалы с % LA и CPU Busy:
(avg(sum by (instance)(rate(node_cpu_seconds_total{mode="idle",env="$environment"}[5m])) * 100)) / count(count(node_cpu_seconds_total{env="$environment",instance="localhost:9100"}) by (cpu))
1.Установка prometheus 2.exporter nginx(ingress-controller) 3.exporter elasticsearch 4.exporter rabbitmq 5.exporter redis 6.настройка оповещений в telegram 6.1 настройка оповещений в telegram в различные чаты(группы) 6.2. настройка оповещений в telegram разграничение оповещений по группам (исключения уведомлений) 7.Проблема с prometheus-kube-proxy 8.Настройка алерта для определённого неймспейса 9.Добавление оповещений и по email 10. Настройка графиков в grafana
/newbot — отправляем ему и бот просит придумать имя нашему новому боту. Единственное ограничение на имя — оно должно оканчиваться на «bot». В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты, иначе придется поломать голову над именем.
всё мы зарегались, теперь этот токен можно использовать при подключении нашего алертменеджера к телеграму
cat default.tmpl
{{ define "telegram.default" }}
{{ range .Alerts }}
{{ if eq .Status "firing"}}? <b>{{ .Status | toUpper }}</b> ? {{ else }}<b>{{ .Status | toUpper }}</b>{{ end }}
<b>{{ .Labels.alertname }}</b>
{{ .Annotations.message }} {{ .Annotations.description }}
<b>Duration:</b> {{ duration .StartsAt .EndsAt }}{{ if ne .Status "firing"}}
<b>Ended:</b> {{ .EndsAt | since }}{{ end }}
{{ end }}
{{ end }}
cat Dockerfile
FROM metalmatze/alertmanager-bot:0.4.2
COPY ./default.tmpl /templates/default.tmpl
admin1 — тут указываю хэши id пользователей которые будут заходить token — тут указываем токен нашего телеграм бота (хэш) namespace — тут указываем неймспейс в котором у нас запущен prometheus image — тут указываем образ телеграмбота пересобранного и загруженного в наш гитлаб — —telegram.admin — тут id пользователей в открытом виде
имеет настройку continue: true (по дефолту false) благодаря которой уведомления попав под первое правило не прекращаются а отправляются дальше по route и отправляются по другим receiver (когда совпадают по label)
правила совпадения работают не как OR а как AND (т.е. должны совпасть ВСЕ лейблы)
Задача, исключить из чата админов сообщения отправляемые в чат разрабочиков, чтобы админам прилетали все дефолтные
Решение — возможно тупенькое но я другого не нашёл, работать будет так:
прилетает сообщение, с лейблами: severity: «critical» team: «terminal-soft»
значит оно должно попасть только в группу terminal-soft, поэтому для receiver: «telegram-terminal-soft» оставляем match_re: team: «terminal-soft»
но так как в уведомлении будет прителать лейбл severity: «critical» то он будет попадать под совпадение receiver: «telegram-admins» у которого match_re: severity: «critical|warning»
нам этого не нужно поэтому для receiver: «telegram-terminal-soft» ставим continue: false и тогда обработка следующих routes не будет происходить.
вывод перед админским чатом правило должно быть с условием: continue: false а админский чат последний в списке.
# base image
FROM alpine:3.14
# set consul version
ENV CONSUL_VERSION 1.10.2
# create a new directory
RUN mkdir /consul
# download dependencies
RUN apk --no-cache add
bash
ca-certificates
wget
# download and set up consul
RUN wget --quiet --output-document=/tmp/consul.zip https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip &&
unzip /tmp/consul.zip -d /consul &&
rm -f /tmp/consul.zip &&
chmod +x /consul/consul
# update PATH
ENV PATH="PATH=$PATH:$PWD/consul"
# add the config file
COPY ./config/consul-config.json /consul/config/config.json
# expose ports
EXPOSE 8300 8400 8500 8600
# run consul
ENTRYPOINT ["consul"]
Если у вас есть веб-приложение с соответствующим файлом Dockerfile, теперь вы можете перейти к следующему шагу и использовать GitLab для автоматического развертывания вашего приложения в кластере kubernetes. Вот как…
Для этого поста в блоге вам понадобится:
ваш исходный код и файл Dockerfile размещены в проекте GitLab
бегун GitLab с исполнителем docker-in-docker
доступ к кластеру kubernetes
Процесс на самом деле состоит из 2 этапов:
создайте образ Docker и перейдите во встроенный реестр Docker в GitLab
используйте kubectl apply для развертывания новой версии