Архив автора: admin

Grafana Loki

Установка пакетов




Для загрузки исходников нам понадобиться загрузить некоторые файлы. Для этого в системе должны быть установлены соответствующие пакеты. В зависимости от типа системы процесс установки будет незначительно отличаться.




а) на системах Red Hat:




yum install git wget




б) для систем на основе Debian:




apt-get install git wget




Установка Go




Для компиляции исходника, нам необходимо установить Golang. Для этого переходим на страницу загрузки и копируем ссылку на архив с его последней версией:




* по умолчанию, страница предлагает загрузить Go для нашей операционной системы, поэтому, если мы открыли сайт на компьютере Windows, ниже под кнопкой загрузки выбираем Linux.




Воспользовавшись ссылкой, скачиваем архив на наш сервер:




wget https://golang.org/dl/go1.15.6.linux-amd64.tar.gz




* на момент написания инструкции, последняя версия была 1.15.6.




Распаковываем архив в каталог /usr/local:




tar -v -C /usr/local -xzf go*.tar.gz




Открываем файл:




vi /etc/profile




Добавляем в самый низ строку:




export PATH=$PATH:/usr/local/go/bin




Один раз выполняем данную команду:




export PATH=$PATH:/usr/local/go/bin




Проверяем, что go установлен и готов выполнять команды:




go version




Мы должны увидеть версию скачанного пакета.




Настройка безопасности




1. Брандмауэр




В зависимости от используемого брандмауэра, необходимо выполнить следующие настройки.




а) если используем iptables (по умолчанию, в системах на базе Debian):




iptables -I INPUT 1 -p tcp —dport 3100 -j ACCEPT




* данная команда добавит правило на разрешение порта 3100 (на котором, по умолчанию, запускается Grafana Loki).




Для сохранения правил устанавливаем пакет:




apt-get install iptables-persistent




Сохранение правил теперь можно выполнить командой:




netfilter-persistent save




б) если используем firewalld (по умолчанию, в системах на базе Red Hat):




firewall-cmd —permanent —add-port=3100/tcp




firewall-cmd —reload




* данная команда добавит правило на разрешение порта 3100 (на котором, по умолчанию, запускается Grafana Loki).




2. SELinux




Как правило, в системах на базе Red Hat активирована дополнительная система безопасности. В нашей инструкции мы ее отключаем командами:




setenforce 0




sed -i ‘s/^SELINUX=.*/SELINUX=disabled/g’ /etc/selinux/config




* первая команда вводится до разового отключения SELinux. Вторая не дает ему запуститься после перезагрузки.




Установка




Установка Grafana Loki сводится к загрузке готового бинарника или исходника с последующей компиляцией. Также мы настроим юнит в systemd для работы приложения в качестве сервиса.




Копирование бинарника и конфигурационного файла




Переходим в каталог:




cd /usr/src/




Загружаем исходные файлы проекта:




git clone https://github.com/grafana/loki




Переходим в каталог loki:




cd loki/




Запускаем компиляцию бинарника:




go build ./cmd/loki




В текущем каталоге появится файл loki — перенесем его в каталог /usr/local/bin:




mv loki /usr/local/bin/




Создадим каталог:




mkdir /etc/loki




… и перенесем в него конфигурационный файл:




mv cmd/loki/loki-local-config.yaml /etc/loki/




В конфиге, который идет в исходнике в качестве рабочего каталога для Grafana Loki используется /tmp — мы это исправим двумя командами:




sed -i ‘s//tmp/wal//opt/loki/wal/g’ /etc/loki/loki-local-config.yaml




* первой командой мы меняем настройку dir для wal (журнала предзаписи). 




sed -i ‘s//tmp/loki//opt/loki/g’ /etc/loki/loki-local-config.yaml




* в данном примере мы заменили путь для storage_configworking_directory и ruler storage на /opt/loki.




Создаем каталог:




mkdir /opt/loki




Выполним первый тестовый запуск сервиса:




/usr/local/bin/loki -config.file=/etc/loki/loki-local-config.yaml




Открываем браузер и переходим по адресу http://192.168.0.15:3100/metrics, где 192.168.0.15 — IP-адрес нашего сервера Grafana Loki. Мы должны увидеть страницу с метриками:





Значит наш сервис запустился и нормально работает. Можно прервать его работу на сервере комбинацией клавиш Ctrl + С и продолжать настройку.




Автозапуск




Чтобы сервис мог автоматически запускаться при старте системы, добавим его в systemd.




Для начала, создадим пользователя, под которым будет работать сервис:




useradd —no-create-home —shell /bin/false loki




* данной командой мы создадим пользователя loki. Ему нельзя будет входить в систему в качестве интерактивного пользователя, также для него не будет создана домашняя директория.




Делаем владельцем loki бинарник для запуска сервиса:




chown loki:loki /usr/local/bin/loki




Задаем владельца для рабочих каталогов Loki:




chown -R loki:loki /etc/loki




chown -R loki:loki /opt/loki




Создаем юнит в systemd:




vi /etc/systemd/system/loki.service




[Unit]

Description=Grafana Loki Service

After=network.target



[Service]

User=loki

Group=loki

Type=simple

ExecStart=/usr/local/bin/loki -config.file=/etc/loki/loki-local-config.yaml

ExecReload=/bin/kill -HUP $MAINPID

Restart=on-failure



[Install]

WantedBy=multi-user.target




Перечитываем конфигурацию systemd:




systemctl daemon-reload




Теперь можно разрешить и стартовать наш сервис:




systemctl enable loki —now




Проверить, что он запустился и работает можно командой:




systemctl status loki




Установка серверной части завершена.




Отправка логов на сервер




В нашем примере мы передадим логи веб-сервера NGINX в нашу Grafana Loki. Для этого переходим на сервер с NGINX и выполним следующие действия.




Установка Promtail




Promtail — агент, который читает и отправляет логи на сервер. Его установка во многом напоминает установку сервера — получаем бинарник и добавляем его в автозагрузку. В нашем примере мы загрузим уже скомпилированный файл для запуска.




Для начала, установим следующие пакеты:




yum install unzip wget




unzip нужен для распаковки архива с бинарником; wget — для скачивания архива.




Загружаем последнюю версию promtail для Linux:




wget https://github.com/grafana/loki/releases/latest/download/promtail-linux-amd64.zip




* в нашем примере загружается бинарник на систему 64-бит. На странице https://github.com/grafana/loki/releases можно скачать файлы для установки под Linux и Windows.




Распаковываем скачанный архив:




unzip promtail-linux-amd64.zip




Переносим бинарник в каталог /usr/local/bin:




mv promtail-linux-amd64 /usr/local/bin/promtail




* обратите внимание, что мы его сразу переименовали в promtail.




Создаем каталог для конфигурационных файлов promtail:




mkdir /etc/promtail




Создаем конфигурационный файл:




vi /etc/promtail/promtail.yaml




server:

  http_listen_port: 9080

  grpc_listen_port: 0



positions:

  filename: /tmp/positions.yaml



clients:

  - url: http://192.168.0.15:3100/loki/api/v1/push




* где 9080 — номер порта, на котором будет слушать promtail; 192.168.0.15 — IP-адрес нашего сервера Loki, куда нужно отправлять данные.




Создаем юнит в systemd для promtail:




vi /etc/systemd/system/promtail.service




[Unit]

Description=Promtail Service

After=network.target



[Service]

Type=simple

ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail/promtail.yaml

ExecReload=/bin/kill -HUP $MAINPID

Restart=on-failure



[Install]

WantedBy=multi-user.target




Перечитываем конфигурацию systemd:




systemctl daemon-reload




Разрешаем запуск сервиса promtail и стартуем его:




systemctl enable promtail —now




Проверяем статус:




systemctl status promtail




На клиенте в настройки брандмауэра добавляем правило на разрешение порта 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 работает. Можно приступать к сбору логов.




Настройка сбора логов




Открываем конфигурационный файл promtail:




vi /etc/promtail/promtail.yaml




...



scrape_configs:

- job_name: nginx

  static_configs:

  - targets:

      - localhost

    labels:

      job: nginxlogs

      __path__: /var/log/nginx/*log




* где:







Перезапускаем сервис promtail:




systemctl restart promtail




Снова заходим по адресу http://192.168.0.25:9080/targets — мы должны увидеть настроенное нами задание:





Сбор логов настроен.




Настройка Grafana




Переходим к серверу с Grafana. Он может быть установлен на отдельном сервере или на том же сервере с Loki.




Заходим в веб-интерфейс и переходим в Configuration — Data Sources:





Добавляем новый источник, кликая по Add data source:





Среди списка возможных источников выбираем Loki:





В настройках задаем имя и указываем IP-адрес сервера Loki:





* в нашем примере задается имя Loki и подключение к серверу 192.168.0.15.




Нажимаем на Save & Test:




Если мы увидели сообщение «Data source connected and labels found.»:значит подключение выполнено и можно двигаться дальше.




Переходим в раздел Create — Dashboard:





Кликаем по кнопке Add new panel:





В открывшемся окне выбираем в качестве источника данных Loki, затем кликаем по Log labels — выбираем job и nginxlogs:





Мы увидим Unable to graph data (так как логи представляют из себя данные, на основе которых нельзя постоить график) — кликаем по Switch to table view:





Мы должны увидеть строки из логов:





Логи NGINX отображаются в Grafana.




Парсинг лога




Мы увидели логи в графане, но они представленны в неудобном для отбора и фильрации виде. Попробуем это исправить с помощью парсинга логов на стороне promtail.




Открываем файл для редактирования:




vi /etc/promtail/promtail.yaml




Дополним нашу задачу для сбора логов NGINX:




...



scrape_configs:

- job_name: nginx

  static_configs:

  - targets:

      - localhost

    labels:

      job: nginxlogs

      __path__: /var/log/nginx/*log

  pipeline_stages:

    - match:

        selector: '{job="nginxlogs"}'

        stages:

        - regex:

            expression: '^(?P<remote_addr>[w.]+) - (?P<remote_user>[^ ]*) [(?P<time_local>.*)] "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<protocol>[^ ]*)" (?P<status>[d]+) (?P<body_bytes_sent>[d]+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)"?'

        - labels:

            remote_addr:

            remote_user:

            time_local:

            method:

            request:

            protocol:

            status:

            body_bytes_sent:

            http_referer:

            http_user_agent:




* обратите внимание, что к имеющейся настройки мы добавили pipeline_stages:







Перезапускаем сервис для promtail:




systemctl restart promtail




Идем в Grafana — в Log labels мы должны увидеть новые критерии для фильтра по тегам:





Пробуем добавить, например, фильтр по статусу ответа веб-сервера:





Источник: https://sidmid.ru/grafana-loki-2/



Работать с Terraform в yandex облаке

Регистрация на хостинге




Для работы с хостинг-провайдером нам заранее понадобятся авторизационные данные и идентификаторы ресурсов. Их мы будем прописывать в сценариях 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 — утилита для работы с репозиториями.



  • curl — отправка GET, POST и других запросов.




Установим в систему ключ для репозитория:




curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add —




Добавляем репозиторий:




apt-add-repository «deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main»




Обновляем список пакетов, чтобы загрузить списки с нового репозитория:




apt update




Можно устанавливать terraform:




apt install terraform




Rocky Linux




Устанавливаем утилиту для работы с репозиториями:




yum install yum-utils




Добавляем репозиторий:




yum-config-manager —add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo




Устанавливаем terraform:




yum install terraform




Скачиваем бинарник




Суть данного метода — скачать бинарный файл и перенести его в каталог /usr/local/bin.




Таким же образом устанавливаем terraform на Windows.




Для начала нам понадобятся утилиты unzip и wget. Устанавливаются они по-разному, в зависимости от дистрибутива Linux.




а) Ubuntu / Debian:




apt install unzip wget




б) Rocky Linux:




yum install unzip wget




Переходим к загрузке бинарного файла. Посмотреть ссылку на него можно на странице официального сайта:





Воспользуемся ссылкой, чтобы скачать архив:




wget https://releases.hashicorp.com/terraform/1.1.7/terraform_1.1.7_linux_amd64.zip




* в нашем примере будет загружена версия 1.1.7.




Распакуем архив командой:




unzip terraform_*_linux_amd64.zip




Перенесем распакованный бинарник в каталог:




mv terraform /usr/local/bin/




После установки




Убедимся, что 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. Рассмотрим подробнее установку провайдера для работы с ним.




В нашем рабочем каталоге создаем первый файл:




vi main.tf




terraform {

  required_version = "= 1.1.7"



  required_providers {

    yandex = {

      source  = "yandex-cloud/yandex"

      version = "= 0.73"

    }

  }

}



provider "yandex" {

  token     = "<OAuth>"

  cloud_id  = "<идентификатор облака>"

  folder_id = "<идентификатор каталога>"

  zone      = "<зона доступности по умолчанию>"

}




* где:




  • 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" "ubuntu_image" {

  family = "ubuntu-2004-lts"

}



resource "yandex_compute_instance" "vm-test1" {

  name = "test1"



  resources {

    cores  = 2

    memory = 2

  }



  boot_disk {

    initialize_params {

      image_id = data.yandex_compute_image.ubuntu_image.id

    }

  }



  network_interface {

    subnet_id = yandex_vpc_subnet.subnet_terraform.id

    nat       = true

  }



  metadata = {

    user-data = "${file("./meta.yml")}"

  }



}



resource "yandex_vpc_network" "network_terraform" {

  name = "net_terraform"

}



resource "yandex_vpc_subnet" "subnet_terraform" {

  name           = "sub_terraform"

  zone           = "ru-central1-a"

  network_id     = yandex_vpc_network.network_terraform.id

  v4_cidr_blocks = ["192.168.15.0/24"]

}




* где:




  • 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 — наше название ресурса для виртуальной машины.



    • yandex_vpc_network — ресурс сети, определенный провайдером.



    • network_terraform — наше название для ресурса сети.



    • yandex_vpc_subnet — ресурс подсети, определенный провайдером.



    • subnet_terraform — наше название для ресурса подсети.



    • metadata — обратите особое внимание на передачу метеданных. В данном примере мы передаем содержимое файла, а сам файл рассмотрим ниже.




** в нашем примере будет создана виртуальная машина с названием test1, 2 CPU, 2 Gb RAM в сети 192.168.15.0/24 на базе Ubuntu 20.04 LTS.
*** обратите внимание, что мы указали идентификатор той подсети для виртуальной машины, которую создали также с помощью нашего сценария terraform.




Создаем файл с метеданными:




meta.yml




#cloud-config

users:

  - name: test

    groups: sudo

    shell: /bin/bash

    sudo: ['ALL=(ALL) NOPASSWD:ALL']

    ssh-authorized-keys:

      - ssh-rsa AAAAB3Nza..................UXFDCb/ujrK4KbpCyvk=




* в данном файле мы опишем пользователя, под которым мы сможем подключиться к нашему серверу по 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.




Мы должны явно разрешить для конкретных ресурсов выполнение остановки их работы для внесения изменений. В нашем файле для конкретного ресурса добавим:




...

resource "yandex_compute_instance" "vm-test1" {

  name = "test1"

  allow_stopping_for_update = true



...




* для нашей машины test1 мы указали опцию allow_stopping_for_update, которая говорит о том, что работу ресурса можно останавливать для внесения изменений.




Строим план:




terraform plan




Мы должны увидеть, что будет изменено в нашей инфраструктуре. В моем случае:




      ~ resources {

          ~ cores         = 2 -> 4

          ~ memory        = 2 -> 4

            # (2 unchanged attributes hidden)

        }




Применяем настройки:




terraform apply




Проверяем через контроль-панель, что изменения вступили в силу.




Удаление ресурсов




Для удаления ресурса можно использовать разные приемы.




1. Например, можно указать count = 0:




resource "yandex_compute_instance" "vm-test1" {

  count = 0

  ...




2. Можно закомментировать или удалить строки ресурса из файла tf.




3. Если мы хотим оставить содержимое файлов нетронутым, но при этом удалить все ресурсы, вводим:




terraform destroy




Утилита пройдет по всем файлам tf в директории, найдет ресурсы и выполнит их удаление.




Файл state




Очень важно уметь работать с файлом состояния terraform, а также понять, что это. Данный файл появляется после первого применения сценария в том же рабочем каталоге:




ls




terraform.tfstate




В нем содержатся все изменения, которые происходили с применением terraform. Без него последний не будет знать, что уже было сделано — на практике это приведет к дублированию инфраструктуры, то есть, если мы создали сервер, потеряли файл состояния и снова запустили terraform, он создаст еще один сервер. Для больших инфраструктур с большой историей все намного критичнее.




И так, файл состояния важен с точки зрения понимания инфраструктуры самим terraform. Также у него есть еще одна функция — блокировка параллельных выполнений. Это важно для работы в командах, где одновременные действия могут привести к неожиданным последствиям. Чтобы этого не произошло, terraform создает блокировку, которая запрещает выполнения, если уже идет процесс применения плана.




Из вышесказанного делаем выводы:







Рассмотрим возможность хранения данного файла состояния на облачном хранилище Яндекс.




Сначала мы должны создать хранилище. Это можно сделать через веб-интерфейс, но мы это сделаем в terraform.




Но сначала мы сделаем файл:




vi variables.tf




variable "yandex_folder_id" {

  type        = string

  default     = "<идентификатор каталога>"

}




* где yandex_folder_id — название для нашей переменной; <идентификатор каталога> — тот идентификатор, который мы указали в файле main под аргументом folder_id.




Теперь откроем файл main:




vi main.tf




И отредактируем значение folder_id на:




  ...

  folder_id = var.yandex_folder_id

  ...




* в данном примере мы теперь задаем folder_id не явно, а через созданную переменную.




Теперь создадим файл:




vi yandex_storage_bucket.tf




resource "yandex_iam_service_account" "sa" {

  folder_id = var.yandex_folder_id

  name      = "sa-test"

}



resource "yandex_resourcemanager_folder_iam_member" "sa-editor" {

  folder_id = var.yandex_folder_id

  role      = "storage.editor"

  member    = "serviceAccount:${yandex_iam_service_account.sa.id}"

}



resource "yandex_iam_service_account_static_access_key" "sa-static-key" {

  service_account_id = yandex_iam_service_account.sa.id

  description        = "Static access key for object storage"

}



resource "yandex_storage_bucket" "state" {

  bucket     = "tf-state-bucket-test"

  access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key

  secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key

}




* рассмотрим файл немного подробнее:







Создаем еще один файл:




vi outputs.tf




output "access_key" {

  value = yandex_iam_service_account_static_access_key.sa-static-key.access_key

  sensitive = true

}

output "secret_key" {

  value = yandex_iam_service_account_static_access_key.sa-static-key.secret_key

  sensitive = true

}




* это делается для получения значений аргументов access_key и secret_key и сохранения данных значений в файле состояния. Если access_key можно посмотреть в панели Яндекса, то secret_key мы увидеть не можем.




Строим план и применяем настройки:




terraform plan




terraform apply




Заходим в контроль-панель Яндекса и видим, что у нас создалось хранилище. Его мы будем использовать для хранения файлов состояний terraform.




Открываем наш файл main:




vi main.tf




Добавляем:




terraform {

  ...



  backend "s3" {

    endpoint   = "storage.yandexcloud.net"

    bucket     = "tf-state-bucket-test"

    region     = "ru-central1-a"

    key        = "terraform/infrastructure1/terraform.tfstate"

    access_key = "<access_key>"

    secret_key = "<secret_key >"



    skip_region_validation      = true

    skip_credentials_validation = true

  }

}




* в раздел terraform мы добавили инструкцию для хранения файла state. В нашем примере он будет размещен на бакете tf-state-bucket-test по пути terraform/infrastructure1/terraform.tfstate.
** особое внимание обратите на access_key и secret_key. В разделе terraform мы не можем указать переменные, как это делали при создании хранилища. Сами значения можно найти в нашем локальном файле state.




Используем команду:,




terraform init




Система снова инициализирует состояние текущего каталога и создаст файл state на удаленном хранилище. Чтобы убедиться, можно зайти в контроль панель, найти наше хранилище, а в нем — файл terraform/infrastructure1/terraform.tfstate.




Реальный пример




Мы развернем 2 веб-сервера и поместим их за Network load balancer.




Для этого мы создадим новый рабочий каталог:




mkdir -p /opt/terraform/yandex-network-load balancer




И перейдем в него:




cd /opt/terraform/yandex-network-load balancer




Подразумевается, что все инфраструктура создается с нуля, поэтому нужно либо удалить предыдущие наработки, либо создать новый сервисный аккаунт для storage.




Мы создадим 5 файлов:




  1. main.tf — в нем мы опишем инструкции для init, а именно требования к версии клиента terraform, провайдера.



  2. web-servers.tf — сценарий для создания 2-х веб-серверов.



  3. network-load-balancer.tf — создание Network Load Balancer.



  4. variables.tf — описание переменных.



  5. outputs.tf — вывод значений после отработки terraform на экран и в файл состояния.




1. Создаем файл main.tf:




vi main.tf




terraform {

  required_version = "= 1.1.7"



  required_providers {

    yandex = {

      source  = "yandex-cloud/yandex"

      version = "= 0.73"

    }

  }

}

provider "yandex" {

  token     = "<OAuth>"

  cloud_id  = "<идентификатор облака>"

  folder_id = "<идентификатор каталога>"

  zone      = "<зона доступности по умолчанию>"

}




* это стандартный вариант файла main.tf, который мы разбирали в начале.




2. web-servers.tf:




vi web-servers.tf




data "yandex_compute_image" "lamp" {

  family = "lamp"

}



data "yandex_compute_image" "lemp" {

  family = "lemp"

}



resource "yandex_compute_instance" "vm-test1" {

  name                      = "vm-test1"

  allow_stopping_for_update = true



  resources {

    cores  = 2

    memory = 2

  }



  boot_disk {

    initialize_params {

      image_id = data.yandex_compute_image.lamp.id

    }

  }



  network_interface {

    subnet_id = yandex_vpc_subnet.subnet_terraform.id

    nat       = true

  }



}



resource "yandex_compute_instance" "vm-test2" {

  name                      = "vm-test2"

  allow_stopping_for_update = true



  resources {

    cores  = 2

    memory = 2

  }



  boot_disk {

    initialize_params {

      image_id = data.yandex_compute_image.lemp.id

    }

  }



  network_interface {

    subnet_id = yandex_vpc_subnet.subnet_terraform.id

    nat       = true

  }



}



resource "yandex_vpc_network" "network_terraform" {

  name = "network_terraform"

}



resource "yandex_vpc_subnet" "subnet_terraform" {

  name           = "subnet_terraform"

  zone           = "ru-central1-a"

  network_id     = yandex_vpc_network.network_terraform.id

  v4_cidr_blocks = ["192.168.15.0/24"]

}




* в данном примере мы создадим 2 виртуальные машины — одну с образом lamp (Apache), вторую на lemp (NGINX).




3. network-load-balancer.tf:




vi network-load-balancer.tf




resource "yandex_lb_network_load_balancer" "lb-test" {

  name = "lb-test"



  listener {

    name = "listener-web-servers"

    port = 80

    external_address_spec {

      ip_version = "ipv4"

    }

  }



  attached_target_group {

    target_group_id = yandex_lb_target_group.web-servers.id



    healthcheck {

      name = "http"

      http_options {

        port = 80

        path = "/"

      }

    }

  }

}



resource "yandex_lb_target_group" "web-servers" {

  name = "web-servers-target-group"



  target {

    subnet_id = yandex_vpc_subnet.subnet_terraform.id

    address   = yandex_compute_instance.vm-test1.network_interface.0.ip_address

  }



  target {

    subnet_id = yandex_vpc_subnet.subnet_terraform.id

    address   = yandex_compute_instance.vm-test2.network_interface.0.ip_address

  }

}




* в данном сценарии мы:







4. variables.tf:




vi variables.tf




variable "yandex_folder_id" {

  type        = string

  default     = "<folder_id>"

}




* создадим переменную с folder_id, в котором мы должны работать. Выше мы уже делали такую переменную.




5. outputs.tf:




vi outputs.tf




output "lb_ip_address" {

  value = yandex_lb_network_load_balancer.lb-test.*

}




* на самом деле, это не обязательно — информацию о созданном балансировщике можно посмотреть в контроль панели, но для примера мы решили это рассмотреть.




Готово. После применения данного сценария мы получим то, что хотели — две виртуальные машины + балансировщик сети, который будет распределять запросы между данными серверами.




Источник: https://sidmid.ru/работать-с-terraform-в-yandex-облаке/



Grafana: создание dashboard

Задача – добавить дашборд для отображения различной статистики с бекенда.




Ниже описывается процесс создания дашборды, рассматриваются примеры запросов из Grafana к Prometheus для получения данных, настройки различных типов панелей, примеры метрик, которые можно использовать.




Для примеров запросов использовалась в основном борда Node Exporter Full 0.16 для метрик EC2, и борда AWS ELB Application Load Balancer для ALB.




Добавлять будем:




  • вверху – статусы хоста:

    • часы (время с момента получения последней метрики)



    • CPU usage %



    • Load Average %



    • memory usage %



    • root, /data disks % usage




  • статусы сервисов:

    • nginx



    • php-fpm



    • rabbitmq status



    • memcached status



    • redis status



    • RDS статус




  • статистика EC2 (node_exporter):

    • CPU

      • CPU System/User/IOwait/Idle




    • Memory:

      • RAM total



      • RAM used



      • RAM free




    • Disk

      • IO time




    • Processes

      • Blocked I/O



      • Running




  • статистика Load Balancer

    • RequestCount / Latency

      • TargetResponseTime_Average



      • ActiveConnectionCount_Average




    • HTTPCode

      • HTTPCode_Target_2XX_Count_Average



      • HTTPCode_Target_3XX_Count_Average



      • HTTPCode_Target_4XX_Count_Average



      • HTTPCode_Target_5XX_Count_Average




Настройки dashboard




Переходим в Settings, задаём имя дашборды:





Переменные




Документация – тут>>> и тут>>>.




У нас есть два бекеда – Dev и Production.




Соответственно – в дашборде хочется выводить статистику и того, и другого. Для этого – добавим переменную, с помощью которой сможем переключаться между ними.




Переходим в 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.




Сначала – получим время с момента запуска системы:




root@bm-backed-app-dev:/opt/prometheus-client# cat /proc/uptime

2168671.61 2147672.65




Тут:




  • первая колонка – аптйам системы в секундах



  • вторая – время в сукундах, проведённое в IDLE




Проверяем:




root@bm-backed-app-dev:/opt/prometheus-client# uptime

14:21:45 up 25 days,  2:37




Считаем – кол-во секунд из /proc/uptime делим на часы и кол-во часов в сутках:




root@bm-backed-app-dev:/opt/prometheus-client# echo 2168671 / 3600 / 24 | bc

25




Хорошо, тут всё сходится.




Теперь считаем stats:




root@bm-backed-app-dev:/opt/prometheus-client# cat /proc/stat

...

cpu0 1435156 1188 466232 213091141 58015 0 29879 134098 0 0

...

btime 1529657067




Тут колонки:




  • user: normal processes executing in user mode



  • nice: niced processes executing in user mode



  • system: processes executing in kernel mode



  • idle: twiddling thumbs



  • iowait: waiting for I/O to complete



  • irq: servicing interrupts



  • softirq: servicing softirqs




Время в сотых секунды.




btime – время загрузки системы в секундах с момента January 1, 1970 (UNIX epoch).




Теперь попробуем посчитать:




root@bm-backed-app-dev:/opt/prometheus-client# echo "(1435156+1188+466232+213091141+58015+0+29879+134098) / 100 / 3600 / 24" | bc

24




Выполняем сложение всех счётчиков, делим на 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 – считаем кол-во элементов, полученных из запроса



  • avg: общее среднее значение, документация тут>>>



  • irate –  считает значение в секунду, основываясь на двух последних данных



  • node_cpu_seconds_total – секунды в каждом режиме (systemuseridle 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 по каждому типу – iowaitusersystemnice 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)) – мы получим кол-во ядер:





Production





Для наглядности – проверяем на серверах:




root@bm-backed-app-dev:/opt/prometheus-client# grep -c ^processor /proc/cpuinfo

1




И прод:




root@mobilebackend-production:/data/projects# grep -c ^processor /proc/cpuinfo

8




Время ядер в idle




По теме – Understanding Machine CPU usage.




Следующая часть запроса – avg(sum by (mode) (irate(node_cpu_seconds_total{mode='idle',env="$environment"}[5m]))).




Сначала выполняем irate(node_cpu_seconds_total{mode='idle',env="mobilebackend-dev"}[5m]):





Так мы получаем среднее значение времени в секундах, которое cpu0 провёл в статусе idle, т.е. бездельничал.




А “завернув” этот запрос в avg(sum by (mode)() – получим среднее значение для всех ядер:





И если для Dev разницы нет, то на Prod с его 8-ю ядрами значение будет более наглядным:





Т.е. вместе все 8 ядер провели 7.95 секунд в режиме idle.




Если принять 8 за 100%, то вычислим %, который ядра провели не в idle за 1 секунду:




>>> (8.0 - 7.95) * 100 / 8.0

0.6249999999999978




0.6% времени проведено в других режимах – systemuser etc.




Если бы, к примеру, все ядра вместе провели 8 секунд в idle (т.е. каждое ядро за 1 целую секунду провело 1 целую секунду в idle):




>>> (8.0 - 8.0) * 100 / 8.0

0.0




То нагрузка на ЦПУ была бы 0%.




И наоборот, если бы половина времени, т.е. 4 секунды в общем, были бы потрачены в idle, то результат:




>>> (8.0 - 4.0) * 100 / 8.0

50.0




50% idle, 50% – остальные режимы.




Вообще есть хорошая страничка тут – Как найти процент от числа для тех, кто как я не силён в математике 




Настройка панели




Теперь переходим к панели.




Жмём на зголовок панели – Edit:





В General задаём имя:





В Metrics добавляем наш запрос:





В Options настраиваем вид:




  • Gauge – включаем отображение шкалы



  • Spark lines – строка “истории”



  • 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





Настраиваем шкалу аналогично CPU Busy:





Перетаскиваем её в Row, меняем размер:





Проверим поведение.




Устанавливаем стресс-тест для CPU:




root@bm-backed-app-dev:/opt/prometheus-client# apt install stress




Запускаем его:




root@bm-backed-app-dev:/opt/prometheus-client# stress —cpu 8 —timeout 20





И данные из uptime:




root@bm-backed-app-dev:/opt/prometheus-client# uptime

18:03:18 up 25 days,  6:18,  1 user,  load average: 1.65, 1.13, 0.64




Memory usage




Далее добавим шкалу с отображением занятой памяти.




Проверим free на проде:




root@mobilebackend-production:/data/projects# free -h

total        used        free      shared  buff/cache   available

Mem:            15G        2.8G        7.5G         93M        4.8G         11G




15 ГБ всего, 2.8 занято активными процессами, 4.8 – кеш, свободной памяти 7.5. ОК.




Составим запрос:




((node_memory_MemTotal_bytes{env="$environment"} - node_memory_MemFree_bytes{env="$environment"}) / (node_memory_MemTotal_bytes{env="$environment"} )) * 100




  • в (node_memory_MemTotal_bytes{env="$environment"} - node_memory_MemFree_bytes{env="$environment"})  считаем общее кол-во занятой памяти (active + cache), назовём её busy



  • и считаем busy / total * 100 – получаем % от свободной памяти




В Options включаем шкалу, настраиваем аналогично примерам выше:





Получается теперь:





Disk usage




В Prometheus выполняем запрос для проверки:




node_filesystem_avail_bytes{env="mobilebackend-dev",fstype="ext4"}





Добавляем панель, добавляем в неё запрос на получение метрик о /rootfs и вычисляем % занятого места:




100 - ((node_filesystem_avail_bytes{env="$environment",mountpoint="/rootfs",fstype="ext4"} * 100) / node_filesystem_size_bytes{env="$environment",mountpoint="/rootfs",fstype="ext4"})





Настраиваем шкалу аналогично предыдущим:





Повторяем для второго диска – /rootfs/data, получаем такую картинку в дашборде:





Текущеее время




Следующим – добавим отображение текущего времени. Во-первых – просто удобно на экране (в комнате висит большой телевизор, на котором выводится борда) видеть текущее время, во-вторых – такая себе проверка на то, что браузер/дашборда не зависли, и обновляются.




Для вывода времени – опять используем Singlestat панели, и функцию timestamp(), которой передадим метрику up (можно любую – нам только требуется получить из метрики время).




Создаём панель, в Metrics указываем:




timestamp(up{instance="localhost:9090",job="prometheus"}) * 1000




В Options в Units выбираем YYYY-MM-DD HH:mm:ss и получаем текущее время (правда дата не выводится, но она и не нужна):





Сортируем по желанию, и получаем первую часть дашборды:





Статусы сервисов




Теперь – добавим простое отображение стаусов Up/Down для сервисов, которые работают на хосте и необходимы для работы приложения.




У нас это:




  • nginx



  • php-fpm



  • memcahed



  • redis



  • rabbitmq



  • AWS RDS



  • AWS ALB




Memcahed статус




Начнём с вывода статуса memcahed.




Создаём новую Row, в ней – новую Singlestat панель.




На сервере запущен quay.io/prometheus/memcached-exporter, который среди прочих метрик возвращает memcahed_up:




...

  memcached-exporter:

    image: quay.io/prometheus/memcached-exporter

    network_mode: "host"

...




memcahed на сервере один, потому можем создать простой запрос на получение кол-ва сервисов в up:




memcached_up{env="$environment",instance="localhost:9150",job="memcached-exporter"}




В Value mappings добавляем отображение статуса – Up, если memcahed_up == 1, или DOWN – если ноль:





В Options > Threshold задаём значения 1,1 (меньше одного – сразу красным) и Stat Current, получаем симпатичный статус:





RabbitMQ статус




Запущен https://github.com/kbudde/rabbitmq_exporter.




Создаём пользователя для доступа експортёра:




root@bm-backed-app-dev:/opt/prometheus-client# rabbitmqctl add_user prometheus password

Creating user "prometheus" ...




Добавляем ему тег “мониторинг”:




root@bm-backed-app-dev:/opt/prometheus-client# rabbitmqctl set_user_tags prometheus monitoring




Добавим его в переменные контейнера:




...

  rabbitmq-exporter:

    image: kbudde/rabbitmq-exporter

    network_mode: "host"

    environment:

    - PUBLISH_PORT=9419

    - RABBIT_USER=prometheus

    - RABBIT_PASSWORD=password

...




Перезапускаем сервис:




root@bm-backed-app-dev:/opt/prometheus-client# systemctl restart prometheus-client.service




Проверяем метрики:




root@bm-backed-app-dev:/home/admin# curl -s localhost:9419/metrics | grep -v # | grep _up

rabbitmq_up 1




И добавляем ещё одну Singlestat панель:





PHP-FPM stats




Повторяем для NGINX – для него всё, как в примерах выше, и добавляем ещё один статус – для PHP-FPM.




Единственное отличие тут – это количество.




Если все сервисы запущены по одному на дев/прод сервер, то php-fpm запущено 6 пулов:




root@bm-backed-app-dev:/opt/prometheus-client# ps aux | grep fpm: | grep -v grep | grep -v master | awk '{print $11, $12, $13}' | uniq

php-fpm: pool dev.admin.domain1.com

php-fpm: pool dev.admin.domain2.com

php-fpm: pool dev.domain1.com

php-fpm: pool dev.domain2.com

php-fpm: pool dev.domain3.com

php-fpm: pool dev.admin.domain3.com





Соответственно, php_fpm_up вернёт не 1, а 6 результатов – по 1 на каждый пул.




Учитывая это – формируем запрос в Metrics и используем count():




count(php_fpm_up{env="$environment",instance="localhost:9253",job="php-fpm-exporter"})




В Value mappings в Type вместо Value to text выбираем range to text:





MySQL stats




Т.к. mysql_exporter ещё не запущен – то тут кратенько пример его запуска.




В роли серверов баз данных используется AWS RDS, два мастер-инстанса.




Значит – надо запустить два експортёра, по одному на каждый RDS. В Ansible шаблон Compose файл добавляем их:




...

  mysql_exporter_db1:

    image: prom/mysqld-exporter

    networks:

    - prometheus-client

    ports:

    - 9104:9104

    environment:

    - DATA_SOURCE_NAME={{ mysql_monitoring_db1_user }}:{{ mysql_monitoring_db1_pass }}@({{ mysql_monitoring_db1_host }}:3306)/



  mysql_exporter_db2:

    image: prom/mysqld-exporter

    networks:

    - prometheus-client

    ports:

    - 9105:9104

    environment:

    - DATA_SOURCE_NAME={{ mysql_monitoring_db2_user }}:{{ mysql_monitoring_db2_pass }}@({{ mysql_monitoring_db2_host }}:3306)/




Переменные берутся из Ansible vault с зашифрованными паролями.




Добавляем джобы в конфиг Прометеус сервера:




...

  - job_name: 'mysql_exporter_db1'

    static_configs:

      - targets:

        - 'localhost:9104'



  - job_name: 'mysql_exporter_db2'

    static_configs:

      - targets:

        - 'localhost:9105'




Деплоим, проверяем DB1:




root@mobilebackend-dev:/opt/prometheus-client# curl -s localhost:9104/metrics | grep -v # | grep -w mysql_up

mysql_up 1




И DB2 (второй екпортёр слушает на порту 9105):




root@mobilebackend-dev:/opt/prometheus-client# curl -s localhost:9105/metrics | grep -v # | grep -w mysql_up

mysql_up 1




Добавляем в Grafana:




mysql_up{env="$environment",instance="localhost:9104",job="mysql_exporter_db1"}





Load Balancer statistics




Добавим ещё несколько графиков – статистику с AWS Application Load Balancer.




Тут надо добавить ещё одну переменную – Load balancer.




К сожалению – cloudformation_exporter не умеет получать теги, поэтому пока придётся использовать просто имена ALB (надо будет посмотреть – может на стороне Prometheus можно будет сделать им relabel).




Добавляем переменную, в запросе указываем:




aws_applicationelb_request_count_sum{job="aws_applicationelb"}




В регулярном выражении – получаем только имя ALB:




/.*app/(.*)"/





Добавляем Row, и в ней – новую панель, но на этот раз типа Graph, в Metrics добавим четыре запроса – на коды 2хх, 3хх, 4хх и 5хх от targets:




aws_applicationelb_httpcode_target_2_xx_count_sum{load_balancer="app/$load_balancer"}





Аналогично можно добавить статистику по времени ответа бекенда.




Добавляем панель Connections/response time – тут будем выводить кол-во активный сессий и время ответа targets.




Добавляем метрики:




aws_applicationelb_target_response_time_sum{load_balancer="app/$load_balancer"}




И активные сессии:




aws_applicationelb_active_connection_count_sum{load_balancer="app/$load_balancer"}




Series overrides




Сейчас на графике отображаются юниты по оси Y слева и внизу.




Но – на этом графике используются метрики двух типов – в одном выводится count – кол-во сессий, а на втором – время ответа от бекенда до ALB в мс.




Хочется, что слева в шкале выводились числа, снизу время получения метрики, а слева – кол-во милисекнуд ответа бекенда.




Для этого – используем ещё одну интересную возможность Grafana – Series overrides. Интересный пост на эту тему есть тут – Advanced Graphing (Part1): Style Overrides.




Переходим в 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))





Memory




Добавляем панель RAM.




Выводим память всего:




https://sidmid.ru/wp-content/uploads/2021/12/41-1024x494.png




Использованной памяти:




node_memory_MemTotal_bytes{env="$environment"} - node_memory_MemFree_bytes{env="$environment"} - (node_memory_Cached_bytes{env="$environment"} + node_memory_Buffers_bytes{env="$environment"})




Свободной памяти:




node_memory_MemFree_bytes{env="$environment"}





Диск




Добавим отображение времени на read-write операции:




irate(node_disk_read_time_seconds_total{env="$environment"}[5m])

irate(node_disk_write_time_seconds_total{env="$environment"}[5m])




В Legend используем {{device}}, куда будет подставлено значение из label “device“:






Получается так: 




Процессы




И последняя уже таблица – процессы в системе.




Выводим кол-во процессов в статусе run:




node_procs_running{env="$environment"}




И blocked:




node_procs_blocked{env="$environment"}





И всё вместе теперь выглядит так:





Источник: https://sidmid.ru/grafana-создание-dashboard/



2023-01-02T04:09:01
DevOps

Kubernetes. Запуск prometheus/grafana/alertmanager — запуск exporter для ingress-nginx-controller

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




Качаем репозиторий




git clone https://github.com/prometheus-community/helm-charts.git
cd helm-charts/charts/kube-prometheus-stack/
докачиваем чарты:
helm dep update




создаём namescpase в котором будет всё крутиться:
kubectl create ns monitoring




теперь рассмотрим что правим в переменных у helm chart:




[root@prod-vsrv-kubemaster1 charts]# vim kube-prometheus-stack/values.yaml




namespaceOverride: «monitoring»




для работы telegram бота:




  ## Alertmanager configuration directives

  ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file

  ##      https://prometheus.io/webtools/alerting/routing-tree-editor/

  ##

  config:

    global:

      resolve_timeout: 5m

    route:

        receiver: 'telegram'

        routes:

        - match:

            severity: critical

          repeat_interval: 48h

          continue: true

          receiver: 'telegram'

        - match:

            alertname: Watchdog

          repeat_interval: 48h

          continue: true

          receiver: 'telegram'

    receivers:

        - name: 'telegram'

          webhook_configs:

              - send_resolved: true

                url: 'http://alertmanager-bot:8080'

    templates:

    - '/etc/alertmanager/config/*.tmpl'




настраиваем ingress у alertmanager:




  ingress:                                                    

    enabled: true                                             

    hosts:                                                    

      - alertmanager.prod.test.local                       

    paths:                                                    

     - /




настраиваем volume для Alertmanager отмечу что в кластере настроен nfs-provisioner — nfs-storageclass




  ingress:                                                    

    enabled: true                                             

    hosts:                                                    

      - alertmanager.prod.test.local                       

    paths:                                                    

     - /




теперь настроим grafana




тут указываем ingress а также добавляем хранение dashboard в nfs storage-class




grafana:

  enabled: true

  namespaceOverride: "monitoring"

  ## Deploy default dashboards.

  ##

  defaultDashboardsEnabled: true

  adminPassword: prom-operator

  ingress:

    ## If true, Grafana Ingress will be created

    ##

    enabled: true

     labels: {}

    ## Hostnames.

    ## Must be provided if Ingress is enable.

    ##

    hosts:

      - grafana.prod.test.local

    #hosts: []

    ## Path for grafana ingress

    path: /

    ## TLS configuration for grafana Ingress

    ## Secret must be manually created in the namespace

    ##

    tls: []

    # - secretName: grafana-general-tls

    #   hosts:

    #   - grafana.example.com

  persistence:

    type: pvc

    enabled: true

    storageClassName: nfs-storageclass

    accessModes:

      - ReadWriteMany

    size: 5Gi

    # annotations: {}

    finalizers:

      - kubernetes.io/pvc-protection




  ## If using kubeControllerManager.endpoints only the port and targetPort are used

  ##

  service:

    port: 10252

    targetPort: 10252

    selector:

      k8s-app: kube-controller-manager

    #   component: kube-controller-manager




  ## If using kubeScheduler.endpoints only the port and targetPort are used

  ##

  service:

    port: 10251

    targetPort: 10251

    selector:

      k8s-app: kube-scheduler

    #   component: kube-scheduler




## Configuration for kube-state-metrics subchart

##

kube-state-metrics:

  namespaceOverride: "monitoring"

  rbac:

    create: true

  podSecurityPolicy:

    enabled: true




## Configuration for prometheus-node-exporter subchart

##

prometheus-node-exporter:

  namespaceOverride: "monitoring"




теперь настраиваем ingress для prometheus




  ingress:                                         

    enabled: true                                  

    annotations: {}                                

    labels: {}                                     

    ## Hostnames.                                  

    ## Must be provided if Ingress is enabled.     

    ##                                             

    hosts:                                         

      - prometheus.prod.test.local             

                                         

    ## Paths to use for ingress rules -            

    ##                                             

    paths:                                         

     - /




а так же volume:




    ## Prometheus StorageSpec for persistent data

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md

    ##

    storageSpec:                                              

      volumeClaimTemplate:                                    

        spec:                                                 

          storageClassName: nfs-storageclass                  

          accessModes: ["ReadWriteMany"]                      

          resources:                                          

            requests:                                         

              storage: 10Gi




и теперь важная фишка, добавление label который надо будет добавить на все неймспейсы:




    ## Namespaces to be selected for ServiceMonitor discovery.

    ##

    serviceMonitorNamespaceSelector:

       matchLabels:

         prometheus: enabled




    ## Log level for Alertmanager to be configured with.

    ##

    logLevel: info



    ## Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the

    ## running cluster equal to the expected size.

    replicas: 3




также правим:




    ## Enable scraping /metrics/resource from kubelet's service

    ## This is disabled by default because container metrics are already exposed by cAdvisor

    ##

    resource: true




для выставления срока хранения данных можем поменять следующее значение:




    ## Time duration Alertmanager shall retain data for. Default is '120h', and must match the regular expression

    ## [0-9]+(ms|s|m|h) (milliseconds seconds minutes hours).

    ##

    retention: 120h




запускаем теперь helm chart




[root@prod-vsrv-kubemaster1 charts]# helm upgrade —install -name prometheus kube-prometheus-stack/ -f kube-prometheus-stack/values.yaml —namespace monitoring




Release "prometheus" does not exist. Installing it now.

NAME: prometheus

LAST DEPLOYED: Thu Mar  4 13:25:07 2021

NAMESPACE: monitoring

STATUS: deployed

REVISION: 1

NOTES:

kube-prometheus-stack has been installed. Check its status by running:

  kubectl --namespace monitoring get pods -l "release=prometheus"



Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.




видим что при запуске добавился label release=prometheus — проверяем:
kubectl describe pod prometheus-kube-prometheus-operator-659d5f8674-qxrf5 -n monitoring | grep -i release
release=prometheus




смотрим label на всех неймсмейсах:
kubectl get ns —show-labels




NAME                     STATUS   AGE     LABELS

default                  Active   192d    <none>

elk                      Active   63d     <none>

ingress-nginx            Active   192d    name=ingress-nginx

keda                     Active   86d     <none>

kube-node-lease          Active   192d    <none>

kube-public              Active   192d    <none>

kube-system              Active   192d    name=kube-system

m-logstash-megabuilder   Active   12d     <none>

monitoring               Active   3h15m   <none>

terminal-soft            Active   176d    <none>




проставим на них label release=prometheus
kubectl label namespace —all «prometheus=enabled»




проверяем:
kubectl get ns —show-labels




NAME                     STATUS   AGE     LABELS

default                  Active   192d    prometheus=enabled

elk                      Active   63d     prometheus=enabled

ingress-nginx            Active   192d    name=ingress-nginx,prometheus=enabled

keda                     Active   86d     prometheus=enabled

kube-node-lease          Active   192d    prometheus=enabled

kube-public              Active   192d    prometheus=enabled

kube-system              Active   192d    name=kube-system,prometheus=enabled

m-logstash-megabuilder   Active   12d     prometheus=enabled

monitoring               Active   3h16m   prometheus=enabled

terminal-soft            Active   176d    prometheus=enabled




теперь настроим сбор метрик с ingress controller,




создаём сервис для ingress. Указываем namespace в котором работает ingress, так же необходим label app.kubernetes.io/name: ingress-nginx данный лейб смотрим так:
kubectl describe pod -n ingress-nginx ingress-nginx-controller-vqjkl | grep -A3 Labels




Labels:               app.kubernetes.io/name=ingress-nginx

                      app.kubernetes.io/part-of=ingress-nginx

                      controller-revision-hash=bd6d56f49

                      pod-template-generation=1




mkdir exporter-ingres




cat exporter-ingres/service.yaml




apiVersion: v1

kind: Service

metadata:

  labels:

    app.kubernetes.io/name: ingress-nginx

    release: prometheus

  name: ingress-nginx

  namespace: ingress-nginx

spec:

  ports:

  - name: http

    port: 80

    protocol: TCP

    targetPort: 80

  - name: https

    port: 443

    protocol: TCP

    targetPort: 443

  - name: prometheus

    port: 10254

    protocol: TCP

    targetPort: 10254

  selector:

    app.kubernetes.io/name: ingress-nginx




В данном файле так же обращаем внимание на:
name: prometheus
на это имя будет натравлен port у ServiceMonitor




теперь создаём ServiceMonitor, он будет создавать в prometheus target с метриками ingress controller:




cat exporter-ingres/service-monitor.yaml




apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

  labels:

    app: ingress-nginx

    release: prometheus

  name: ingress-nginx

  namespace: monitoring

spec:

  endpoints:

  - honorLabels: true

    interval: 10s

    path: /metrics

    port: prometheus

    scheme: http

    scrapeTimeout: 10s

  namespaceSelector:

     any: true

  selector:

    matchLabels:

      app.kubernetes.io/name: ingress-nginx

      release: prometheus




также правим:




    ## Enable scraping /metrics/resource from kubelet's service

    ## This is disabled by default because container metrics are already exposed by cAdvisor

    ##

    resource: true




применяем:




[root@prod-vsrv-kubemaster1 charts]# kubectl apply -f exporter-ingres/service.yaml -f exporter-ingres/service-monitor.yaml




через пару минуток проверяем в prometheus





общий  вид у файла values.yaml будет следующий:




cat helm-charts/charts/kube-prometheus-stack/values.yaml




# Default values for kube-prometheus-stack.

# This is a YAML-formatted file.

# Declare variables to be passed into your templates.



## Provide a name in place of kube-prometheus-stack for `app:` labels

##

nameOverride: ""



## Override the deployment namespace

##

namespaceOverride: "monitoring"



## Provide a k8s version to auto dashboard import script example: kubeTargetVersionOverride: 1.16.6

##

kubeTargetVersionOverride: ""



## Provide a name to substitute for the full names of resources

##

fullnameOverride: ""



## Labels to apply to all resources

##

commonLabels: {}

# scmhash: abc123

# myLabel: aakkmd



## Create default rules for monitoring the cluster

##

defaultRules:

  create: true

  rules:

    alertmanager: true

    etcd: true

    general: true

    k8s: true

    kubeApiserver: true

    kubeApiserverAvailability: true

    kubeApiserverError: true

    kubeApiserverSlos: true

    kubelet: true

    kubePrometheusGeneral: true

    kubePrometheusNodeAlerting: true

    kubePrometheusNodeRecording: true

    kubernetesAbsent: true

    kubernetesApps: true

    kubernetesResources: true

    kubernetesStorage: true

    kubernetesSystem: true

    kubeScheduler: true

    kubeStateMetrics: true

    network: true

    node: true

    prometheus: true

    prometheusOperator: true

    time: true



  ## Runbook url prefix for default rules

  runbookUrl: https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/runbook.md#

  ## Reduce app namespace alert scope

  appNamespacesTarget: ".*"



  ## Labels for default rules

  labels: {}

  ## Annotations for default rules

  annotations: {}



  ## Additional labels for PrometheusRule alerts

  additionalRuleLabels: {}



## Deprecated way to provide custom recording or alerting rules to be deployed into the cluster.

##

# additionalPrometheusRules: []

#  - name: my-rule-file

#    groups:

#      - name: my_group

#        rules:

#        - record: my_record

#          expr: 100 * my_record



## Provide custom recording or alerting rules to be deployed into the cluster.

##

additionalPrometheusRulesMap: {}

#  rule-name:

#    groups:

#    - name: my_group

#      rules:

#      - record: my_record

#        expr: 100 * my_record



##

global:

  rbac:

    create: true

    pspEnabled: true

    pspAnnotations: {}

      ## Specify pod annotations

      ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor

      ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp

      ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl

      ##

      # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'

      # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'

      # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'



  ## Reference to one or more secrets to be used when pulling images

  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

  ##

  imagePullSecrets: []

  # - name: "image-pull-secret"



## Configuration for alertmanager

## ref: https://prometheus.io/docs/alerting/alertmanager/

##

alertmanager:



  ## Deploy alertmanager

  ##

  enabled: true



  ## Api that prometheus will use to communicate with alertmanager. Possible values are v1, v2

  ##

  apiVersion: v2



  ## Service account for Alertmanager to use.

  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

  ##

  serviceAccount:

    create: true

    name: ""

    annotations: {}



  ## Configure pod disruption budgets for Alertmanager

  ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget

  ## This configuration is immutable once created and will require the PDB to be deleted to be changed

  ## https://github.com/kubernetes/kubernetes/issues/45398

  ##

  podDisruptionBudget:

    enabled: false

    minAvailable: 1

    maxUnavailable: ""



  ## Alertmanager configuration directives

  ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file

  ##      https://prometheus.io/webtools/alerting/routing-tree-editor/

  ##



  config:

    global:

      resolve_timeout: 5m

    route:

        receiver: 'telegram'

        routes:

        - match:

            severity: critical

          repeat_interval: 48h

          continue: true

          receiver: 'telegram'

        - match:

            alertname: Watchdog

          repeat_interval: 48h

          continue: true

          receiver: 'telegram'

    receivers:

        - name: 'telegram'

          webhook_configs:

              - send_resolved: true

                url: 'http://alertmanager-bot:8080'







#  config:

#    global:

#      resolve_timeout: 5m

#    route:

#      group_by: ['job']

#      group_wait: 30s

#      group_interval: 5m

#      repeat_interval: 12h

#      receiver: 'null'

#      routes:

#      - match:

#          alertname: Watchdog

#        receiver: 'null'

#    receivers:

#    - name: 'null'



    templates:

    - '/etc/alertmanager/config/*.tmpl'



  ## Pass the Alertmanager configuration directives through Helm's templating

  ## engine. If the Alertmanager configuration contains Alertmanager templates,

  ## they'll need to be properly escaped so that they are not interpreted by

  ## Helm

  ## ref: https://helm.sh/docs/developing_charts/#using-the-tpl-function

  ##      https://prometheus.io/docs/alerting/configuration/#tmpl_string

  ##      https://prometheus.io/docs/alerting/notifications/

  ##      https://prometheus.io/docs/alerting/notification_examples/

  tplConfig: false



  ## Alertmanager template files to format alerts

  ## By default, templateFiles are placed in /etc/alertmanager/config/ and if

  ## they have a .tmpl file suffix will be loaded. See config.templates above

  ## to change, add other suffixes. If adding other suffixes, be sure to update

  ## config.templates above to include those suffixes.

  ## ref: https://prometheus.io/docs/alerting/notifications/

  ##      https://prometheus.io/docs/alerting/notification_examples/

  ##

  templateFiles: {}

  #

  ## An example template:

  #   template_1.tmpl: |-

  #       {{ define "cluster" }}{{ .ExternalURL | reReplaceAll ".*alertmanager\.(.*)" "$1" }}{{ end }}

  #

  #       {{ define "slack.myorg.text" }}

  #       {{- $root := . -}}

  #       {{ range .Alerts }}

  #         *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`

  #         *Cluster:*  {{ template "cluster" $root }}

  #         *Description:* {{ .Annotations.description }}

  #         *Graph:* <{{ .GeneratorURL }}|:chart_with_upwards_trend:>

  #         *Runbook:* <{{ .Annotations.runbook }}|:spiral_note_pad:>

  #         *Details:*

  #           {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`

  #           {{ end }}

  #       {{ end }}

  #       {{ end }}



  ingress:

    enabled: true



    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName

    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress

    # ingressClassName: nginx



    annotations: {}



    labels: {}



    ## Hosts must be provided if Ingress is enabled.

    ##

    hosts:

      - alertmanager.prod.test.local



    ## Paths to use for ingress rules - one path should match the alertmanagerSpec.routePrefix

    ##

    paths:

     - /



    ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched)

    ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types

    # pathType: ImplementationSpecific



    ## TLS configuration for Alertmanager Ingress

    ## Secret must be manually created in the namespace

    ##

    tls: []

    # - secretName: alertmanager-general-tls

    #   hosts:

    #   - alertmanager.example.com



  ## Configuration for Alertmanager secret

  ##

  secret:

    annotations: {}



  ## Configuration for creating an Ingress that will map to each Alertmanager replica service

  ## alertmanager.servicePerReplica must be enabled

  ##

  ingressPerReplica:

    enabled: false



    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName

    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress

    # ingressClassName: nginx



    annotations: {}

    labels: {}



    ## Final form of the hostname for each per replica ingress is

    ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }}

    ##

    ## Prefix for the per replica ingress that will have `-$replicaNumber`

    ## appended to the end

    hostPrefix: ""

    ## Domain that will be used for the per replica ingress

    hostDomain: ""



    ## Paths to use for ingress rules

    ##

    paths: []

    # - /



    ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched)

    ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types

    # pathType: ImplementationSpecific



    ## Secret name containing the TLS certificate for alertmanager per replica ingress

    ## Secret must be manually created in the namespace

    tlsSecretName: ""



    ## Separated secret for each per replica Ingress. Can be used together with cert-manager

    ##

    tlsSecretPerReplica:

      enabled: false

      ## Final form of the secret for each per replica ingress is

      ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }}

      ##

      prefix: "alertmanager"



  ## Configuration for Alertmanager service

  ##

  service:

    annotations: {}

    labels: {}

    clusterIP: ""



    ## Port for Alertmanager Service to listen on

    ##

    port: 9093

    ## To be used with a proxy extraContainer port

    ##

    targetPort: 9093

    ## Port to expose on each node

    ## Only used if service.type is 'NodePort'

    ##

    nodePort: 30903

    ## List of IP addresses at which the Prometheus server service is available

    ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips

    ##



    ## Additional ports to open for Alertmanager service

    additionalPorts: []



    externalIPs: []

    loadBalancerIP: ""

    loadBalancerSourceRanges: []

    ## Service type

    ##

    type: ClusterIP



  ## Configuration for creating a separate Service for each statefulset Alertmanager replica

  ##

  servicePerReplica:

    enabled: false

    annotations: {}



    ## Port for Alertmanager Service per replica to listen on

    ##

    port: 9093



    ## To be used with a proxy extraContainer port

    targetPort: 9093



    ## Port to expose on each node

    ## Only used if servicePerReplica.type is 'NodePort'

    ##

    nodePort: 30904



    ## Loadbalancer source IP ranges

    ## Only used if servicePerReplica.type is "loadbalancer"

    loadBalancerSourceRanges: []

    ## Service type

    ##

    type: ClusterIP



  ## If true, create a serviceMonitor for alertmanager

  ##

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    selfMonitor: true



    ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS.

    scheme: ""



    ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS.

    ## Of type: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#tlsconfig

    tlsConfig: {}



    bearerTokenFile:



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



  ## Settings affecting alertmanagerSpec

  ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#alertmanagerspec

  ##

  alertmanagerSpec:

    ## Standard object’s metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata

    ## Metadata Labels and Annotations gets propagated to the Alertmanager pods.

    ##

    podMetadata: {}



    ## Image of Alertmanager

    ##

    image:

      repository: quay.io/prometheus/alertmanager

      tag: v0.21.0

      sha: ""



    ## If true then the user will be responsible to provide a secret with alertmanager configuration

    ## So when true the config part will be ignored (including templateFiles) and the one in the secret will be used

    ##

    useExistingSecret: false



    ## Secrets is a list of Secrets in the same namespace as the Alertmanager object, which shall be mounted into the

    ## Alertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/.

    ##

    secrets: []



    ## ConfigMaps is a list of ConfigMaps in the same namespace as the Alertmanager object, which shall be mounted into the Alertmanager Pods.

    ## The ConfigMaps are mounted into /etc/alertmanager/configmaps/.

    ##

    configMaps: []



    ## ConfigSecret is the name of a Kubernetes Secret in the same namespace as the Alertmanager object, which contains configuration for

    ## this Alertmanager instance. Defaults to 'alertmanager-' The secret is mounted into /etc/alertmanager/config.

    ##

    # configSecret:



    ## AlertmanagerConfigs to be selected to merge and configure Alertmanager with.

    ##

    alertmanagerConfigSelector: {}

    ## Example which selects all alertmanagerConfig resources

    ## with label "alertconfig" with values any of "example-config" or "example-config-2"

    # alertmanagerConfigSelector:

    #   matchExpressions:

    #     - key: alertconfig

    #       operator: In

    #       values:

    #         - example-config

    #         - example-config-2

    #

    ## Example which selects all alertmanagerConfig resources with label "role" set to "example-config"

    # alertmanagerConfigSelector:

    #   matchLabels:

    #     role: example-config



    ## Namespaces to be selected for AlertmanagerConfig discovery. If nil, only check own namespace.

    ##

    alertmanagerConfigNamespaceSelector: {}

    ## Example which selects all namespaces

    ## with label "alertmanagerconfig" with values any of "example-namespace" or "example-namespace-2"

    # alertmanagerConfigNamespaceSelector:

    #   matchExpressions:

    #     - key: alertmanagerconfig

    #       operator: In

    #       values:

    #         - example-namespace

    #         - example-namespace-2



    ## Example which selects all namespaces with label "alertmanagerconfig" set to "enabled"

    # alertmanagerConfigNamespaceSelector:

    #   matchLabels:

    #     alertmanagerconfig: enabled



    ## Define Log Format

    # Use logfmt (default) or json logging

    logFormat: logfmt



    ## Log level for Alertmanager to be configured with.

    ##

    logLevel: info



    ## Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the

    ## running cluster equal to the expected size.

    replicas: 3



    ## Time duration Alertmanager shall retain data for. Default is '120h', and must match the regular expression

    ## [0-9]+(ms|s|m|h) (milliseconds seconds minutes hours).

    ##

    retention: 120h



    ## Storage is the definition of how storage will be used by the Alertmanager instances.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md

    ##

    storage:

     volumeClaimTemplate:

       spec:

         storageClassName: nfs-storageclass

         accessModes: ["ReadWriteMany"]

         resources:

           requests:

             storage: 10Gi

    #   selector: {}





    ##  The external URL the Alertmanager instances will be available under. This is necessary to generate correct URLs. This is necessary if Alertmanager is not served from root of a DNS name.     string  false

    ##

    externalUrl:



    ##  The route prefix Alertmanager registers HTTP handlers for. This is useful, if using ExternalURL and a proxy is rewriting HTTP routes of a request, and the actual ExternalURL is still true,

    ## but the server serves requests under a different route prefix. For example for use with kubectl proxy.

    ##

    routePrefix: /



    ## If set to true all actions on the underlying managed objects are not going to be performed, except for delete actions.

    ##

    paused: false



    ## Define which Nodes the Pods are scheduled on.

    ## ref: https://kubernetes.io/docs/user-guide/node-selection/

    ##

    nodeSelector: {}



    ## Define resources requests and limits for single Pods.

    ## ref: https://kubernetes.io/docs/user-guide/compute-resources/

    ##

    resources: {}

    # requests:

    #   memory: 400Mi



    ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node.

    ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided.

    ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node.

    ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured.

    ##

    podAntiAffinity: ""



    ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity.

    ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone

    ##

    podAntiAffinityTopologyKey: kubernetes.io/hostname



    ## Assign custom affinity rules to the alertmanager instance

    ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

    ##

    affinity: {}

    # nodeAffinity:

    #   requiredDuringSchedulingIgnoredDuringExecution:

    #     nodeSelectorTerms:

    #     - matchExpressions:

    #       - key: kubernetes.io/e2e-az-name

    #         operator: In

    #         values:

    #         - e2e-az1

    #         - e2e-az2



    ## If specified, the pod's tolerations.

    ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/

    ##

    tolerations: []

    # - key: "key"

    #   operator: "Equal"

    #   value: "value"

    #   effect: "NoSchedule"



    ## If specified, the pod's topology spread constraints.

    ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/

    ##

    topologySpreadConstraints: []

    # - maxSkew: 1

    #   topologyKey: topology.kubernetes.io/zone

    #   whenUnsatisfiable: DoNotSchedule

    #   labelSelector:

    #     matchLabels:

    #       app: alertmanager



    ## SecurityContext holds pod-level security attributes and common container settings.

    ## This defaults to non root user with uid 1000 and gid 2000.       *v1.PodSecurityContext  false

    ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

    ##

    securityContext:

      runAsGroup: 2000

      runAsNonRoot: true

      runAsUser: 1000

      fsGroup: 2000



    ## ListenLocal makes the Alertmanager server listen on loopback, so that it does not bind against the Pod IP.

    ## Note this is only for the Alertmanager UI, not the gossip communication.

    ##

    listenLocal: false



    ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to an Alertmanager pod.

    ##

    containers: []



    # Additional volumes on the output StatefulSet definition.

    volumes: []



    # Additional VolumeMounts on the output StatefulSet definition.

    volumeMounts: []



    ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes

    ## (permissions, dir tree) on mounted volumes before starting prometheus

    initContainers: []



    ## Priority class assigned to the Pods

    ##

    priorityClassName: ""



    ## AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster.

    ##

    additionalPeers: []



    ## PortName to use for Alert Manager.

    ##

    portName: "web"



    ## ClusterAdvertiseAddress is the explicit address to advertise in cluster. Needs to be provided for non RFC1918 [1] (public) addresses. [1] RFC1918: https://tools.ietf.org/html/rfc1918

    ##

    clusterAdvertiseAddress: false



    ## ForceEnableClusterMode ensures Alertmanager does not deactivate the cluster mode when running with a single replica.

    ## Use case is e.g. spanning an Alertmanager cluster across Kubernetes clusters with a single replica in each.

    forceEnableClusterMode: false





## Using default values from https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml

##

grafana:

  enabled: true

  namespaceOverride: "monitoring"



  ## Deploy default dashboards.

  ##

  defaultDashboardsEnabled: true



  adminPassword: prom-operator



  ingress:

    ## If true, Grafana Ingress will be created

    ##

    enabled: true



    ## Annotations for Grafana Ingress

    ##

    annotations: {}

      # kubernetes.io/ingress.class: nginx

      # kubernetes.io/tls-acme: "true"



    ## Labels to be added to the Ingress

    ##

    labels: {}



    ## Hostnames.

    ## Must be provided if Ingress is enable.

    ##

    hosts:

      - grafana.prod.test.local

    #hosts: []



    ## Path for grafana ingress

    path: /



    ## TLS configuration for grafana Ingress

    ## Secret must be manually created in the namespace

    ##

    tls: []

    # - secretName: grafana-general-tls

    #   hosts:

    #   - grafana.example.com



  sidecar:

    dashboards:

      enabled: true

      label: grafana_dashboard



      ## Annotations for Grafana dashboard configmaps

      ##

      annotations: {}

      multicluster: false

    datasources:

      enabled: true

      defaultDatasourceEnabled: true



      # If not defined, will use prometheus.prometheusSpec.scrapeInterval or its default

      # defaultDatasourceScrapeInterval: 15s



      ## Annotations for Grafana datasource configmaps

      ##

      annotations: {}



      ## Create datasource for each Pod of Prometheus StatefulSet;

      ## this uses headless service `prometheus-operated` which is

      ## created by Prometheus Operator

      ## ref: https://git.io/fjaBS

      createPrometheusReplicasDatasources: false

      label: grafana_datasource



  extraConfigmapMounts: []

  # - name: certs-configmap

  #   mountPath: /etc/grafana/ssl/

  #   configMap: certs-configmap

  #   readOnly: true



  ## Configure additional grafana datasources (passed through tpl)

  ## ref: http://docs.grafana.org/administration/provisioning/#datasources

  additionalDataSources: []

  # - name: prometheus-sample

  #   access: proxy

  #   basicAuth: true

  #   basicAuthPassword: pass

  #   basicAuthUser: daco

  #   editable: false

  #   jsonData:

  #       tlsSkipVerify: true

  #   orgId: 1

  #   type: prometheus

  #   url: https://{{ printf "%s-prometheus.svc" .Release.Name }}:9090

  #   version: 1



  ## Passed to grafana subchart and used by servicemonitor below

  ##

  service:

    portName: service



  ## If true, create a serviceMonitor for grafana

  ##

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    selfMonitor: true



    # Path to use for scraping metrics. Might be different if server.root_url is set

    # in grafana.ini

    path: "/metrics"



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Component scraping the kube api server

##

kubeApiServer:

  enabled: true

  tlsConfig:

    serverName: kubernetes

    insecureSkipVerify: false



  ## If your API endpoint address is not reachable (as in AKS) you can replace it with the kubernetes service

  ##

  relabelings: []

  # - sourceLabels:

  #     - __meta_kubernetes_namespace

  #     - __meta_kubernetes_service_name

  #     - __meta_kubernetes_endpoint_port_name

  #   action: keep

  #   regex: default;kubernetes;https

  # - targetLabel: __address__

  #   replacement: kubernetes.default.svc:443



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    jobLabel: component

    selector:

      matchLabels:

        component: apiserver

        provider: kubernetes



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



## Component scraping the kubelet and kubelet-hosted cAdvisor

##

kubelet:

  enabled: true

  namespace: kube-system



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ## Enable scraping the kubelet over https. For requirements to enable this see

    ## https://github.com/prometheus-operator/prometheus-operator/issues/926

    ##

    https: true



    ## Enable scraping /metrics/cadvisor from kubelet's service

    ##

    cAdvisor: true



    ## Enable scraping /metrics/probes from kubelet's service

    ##

    probes: true



    ## Enable scraping /metrics/resource from kubelet's service

    ## This is disabled by default because container metrics are already exposed by cAdvisor

    ##

    resource: true

    # From kubernetes 1.18, /metrics/resource/v1alpha1 renamed to /metrics/resource

    resourcePath: "/metrics/resource/v1alpha1"

    ## Metric relabellings to apply to samples before ingestion

    ##

    cAdvisorMetricRelabelings: []

    # - sourceLabels: [__name__, image]

    #   separator: ;

    #   regex: container_([a-z_]+);

    #   replacement: $1

    #   action: drop

    # - sourceLabels: [__name__]

    #   separator: ;

    #   regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)

    #   replacement: $1

    #   action: drop



    ## Metric relabellings to apply to samples before ingestion

    ##

    probesMetricRelabelings: []

    # - sourceLabels: [__name__, image]

    #   separator: ;

    #   regex: container_([a-z_]+);

    #   replacement: $1

    #   action: drop

    # - sourceLabels: [__name__]

    #   separator: ;

    #   regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)

    #   replacement: $1

    #   action: drop



    #   relabel configs to apply to samples before ingestion.

    #   metrics_path is required to match upstream rules and charts

    ##

    cAdvisorRelabelings:

      - sourceLabels: [__metrics_path__]

        targetLabel: metrics_path

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



    probesRelabelings:

      - sourceLabels: [__metrics_path__]

        targetLabel: metrics_path

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



    resourceRelabelings:

      - sourceLabels: [__metrics_path__]

        targetLabel: metrics_path

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



    metricRelabelings: []

    # - sourceLabels: [__name__, image]

    #   separator: ;

    #   regex: container_([a-z_]+);

    #   replacement: $1

    #   action: drop

    # - sourceLabels: [__name__]

    #   separator: ;

    #   regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)

    #   replacement: $1

    #   action: drop



    #   relabel configs to apply to samples before ingestion.

    #   metrics_path is required to match upstream rules and charts

    ##

    relabelings:

      - sourceLabels: [__metrics_path__]

        targetLabel: metrics_path

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Component scraping the kube controller manager

##

kubeControllerManager:

  enabled: true



  ## If your kube controller manager is not deployed as a pod, specify IPs it can be found on

  ##

  endpoints: []

  # - 10.141.4.22

  # - 10.141.4.23

  # - 10.141.4.24



  ## If using kubeControllerManager.endpoints only the port and targetPort are used

  ##

  service:

    port: 10252

    targetPort: 10252

    selector:

      k8s-app: kube-controller-manager

    #   component: kube-controller-manager



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ## Enable scraping kube-controller-manager over https.

    ## Requires proper certs (not self-signed) and delegated authentication/authorization checks

    ##

    https: false



    # Skip TLS certificate validation when scraping

    insecureSkipVerify: null



    # Name of the server to use when validating TLS certificate

    serverName: null



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Component scraping coreDns. Use either this or kubeDns

##

coreDns:

  enabled: true

  service:

    port: 9153

    targetPort: 9153

    # selector:

    #   k8s-app: kube-dns

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Component scraping kubeDns. Use either this or coreDns

##

kubeDns:

  enabled: false

  service:

    dnsmasq:

      port: 10054

      targetPort: 10054

    skydns:

      port: 10055

      targetPort: 10055

    # selector:

    #   k8s-app: kube-dns

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace

    dnsmasqMetricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    dnsmasqRelabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Component scraping etcd

##

kubeEtcd:

  enabled: true



  ## If your etcd is not deployed as a pod, specify IPs it can be found on

  ##

  endpoints: []

  # - 10.141.4.22

  # - 10.141.4.23

  # - 10.141.4.24



  ## Etcd service. If using kubeEtcd.endpoints only the port and targetPort are used

  ##

  service:

    port: 2379

    targetPort: 2379

    # selector:

    #   component: etcd



  ## Configure secure access to the etcd cluster by loading a secret into prometheus and

  ## specifying security configuration below. For example, with a secret named etcd-client-cert

  ##

  ## serviceMonitor:

  ##   scheme: https

  ##   insecureSkipVerify: false

  ##   serverName: localhost

  ##   caFile: /etc/prometheus/secrets/etcd-client-cert/etcd-ca

  ##   certFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client

  ##   keyFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key

  ##

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    scheme: http

    insecureSkipVerify: false

    serverName: ""

    caFile: ""

    certFile: ""

    keyFile: ""



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace





## Component scraping kube scheduler

##

kubeScheduler:

  enabled: true



  ## If your kube scheduler is not deployed as a pod, specify IPs it can be found on

  ##

  endpoints: []

  # - 10.141.4.22

  # - 10.141.4.23

  # - 10.141.4.24



  ## If using kubeScheduler.endpoints only the port and targetPort are used

  ##

  service:

    port: 10251

    targetPort: 10251

    selector:

      k8s-app: kube-scheduler

    #   component: kube-scheduler



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    ## Enable scraping kube-scheduler over https.

    ## Requires proper certs (not self-signed) and delegated authentication/authorization checks

    ##

    https: false



    ## Skip TLS certificate validation when scraping

    insecureSkipVerify: null



    ## Name of the server to use when validating TLS certificate

    serverName: null



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace





## Component scraping kube proxy

##

kubeProxy:

  enabled: true



  ## If your kube proxy is not deployed as a pod, specify IPs it can be found on

  ##

  endpoints: []

  # - 10.141.4.22

  # - 10.141.4.23

  # - 10.141.4.24



  service:

    port: 10249

    targetPort: 10249

    # selector:

    #   k8s-app: kube-proxy



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ## Enable scraping kube-proxy over https.

    ## Requires proper certs (not self-signed) and delegated authentication/authorization checks

    ##

    https: false



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]





## Component scraping kube state metrics

##

kubeStateMetrics:

  enabled: true

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    ## Override serviceMonitor selector

    ##

    selectorOverride: {}



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Configuration for kube-state-metrics subchart

##

kube-state-metrics:

  namespaceOverride: "monitoring"

  rbac:

    create: true

  podSecurityPolicy:

    enabled: true



## Deploy node exporter as a daemonset to all nodes

##

nodeExporter:

  enabled: true



  ## Use the value configured in prometheus-node-exporter.podLabels

  ##

  jobLabel: jobLabel



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""



    ## How long until a scrape request times out. If not set, the Prometheus default scape timeout is used.

    ##

    scrapeTimeout: ""



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - sourceLabels: [__name__]

    #   separator: ;

    #   regex: ^node_mountstats_nfs_(event|operations|transport)_.+

    #   replacement: $1

    #   action: drop



    ##  relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



## Configuration for prometheus-node-exporter subchart

##

prometheus-node-exporter:

  namespaceOverride: "monitoring"

  podLabels:

    ## Add the 'node-exporter' label to be used by serviceMonitor to match standard common usage in rules and grafana dashboards

    ##

    jobLabel: node-exporter

  extraArgs:

    - --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/)

    - --collector.filesystem.ignored-fs-types=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$



## Manages Prometheus and Alertmanager components

##

prometheusOperator:

  enabled: true



  ## Prometheus-Operator v0.39.0 and later support TLS natively.

  ##

  tls:

    enabled: true

    # Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants

    tlsMinVersion: VersionTLS13

    # The default webhook port is 10250 in order to work out-of-the-box in GKE private clusters and avoid adding firewall rules.

    internalPort: 10250



  ## Admission webhook support for PrometheusRules resources added in Prometheus Operator 0.30 can be enabled to prevent incorrectly formatted

  ## rules from making their way into prometheus and potentially preventing the container from starting

  admissionWebhooks:

    failurePolicy: Fail

    enabled: true

    ## A PEM encoded CA bundle which will be used to validate the webhook's server certificate.

    ## If unspecified, system trust roots on the apiserver are used.

    caBundle: ""

    ## If enabled, generate a self-signed certificate, then patch the webhook configurations with the generated data.

    ## On chart upgrades (or if the secret exists) the cert will not be re-generated. You can use this to provide your own

    ## certs ahead of time if you wish.

    ##

    patch:

      enabled: true

      image:

        repository: jettech/kube-webhook-certgen

        tag: v1.5.0

        sha: ""

        pullPolicy: IfNotPresent

      resources: {}

      ## Provide a priority class name to the webhook patching job

      ##

      priorityClassName: ""

      podAnnotations: {}

      nodeSelector: {}

      affinity: {}

      tolerations: []

    # Use certmanager to generate webhook certs

    certManager:

      enabled: false

      # issuerRef:

      #   name: "issuer"

      #   kind: "ClusterIssuer"



  ## Namespaces to scope the interaction of the Prometheus Operator and the apiserver (allow list).

  ## This is mutually exclusive with denyNamespaces. Setting this to an empty object will disable the configuration

  ##

  namespaces: {}

    # releaseNamespace: true

    # additional:

    # - kube-system



  ## Namespaces not to scope the interaction of the Prometheus Operator (deny list).

  ##

  denyNamespaces: []



  ## Filter namespaces to look for prometheus-operator custom resources

  ##

  alertmanagerInstanceNamespaces: []

  prometheusInstanceNamespaces: []

  thanosRulerInstanceNamespaces: []



  ## The clusterDomain value will be added to the cluster.peer option of the alertmanager.

  ## Without this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated:9094 (default value)

  ## With this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated.namespace.svc.cluster-domain:9094

  ##

  # clusterDomain: "cluster.local"



  ## Service account for Alertmanager to use.

  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

  ##

  serviceAccount:

    create: true

    name: ""



  ## Configuration for Prometheus operator service

  ##

  service:

    annotations: {}

    labels: {}

    clusterIP: ""



  ## Port to expose on each node

  ## Only used if service.type is 'NodePort'

  ##

    nodePort: 30080



    nodePortTls: 30443



  ## Additional ports to open for Prometheus service

  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services

  ##

    additionalPorts: []



  ## Loadbalancer IP

  ## Only use if service.type is "loadbalancer"

  ##

    loadBalancerIP: ""

    loadBalancerSourceRanges: []



  ## Service type

  ## NodePort, ClusterIP, loadbalancer

  ##

    type: ClusterIP



    ## List of IP addresses at which the Prometheus server service is available

    ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips

    ##

    externalIPs: []



  ## Labels to add to the operator pod

  ##

  podLabels: {}



  ## Annotations to add to the operator pod

  ##

  podAnnotations: {}



  ## Assign a PriorityClassName to pods if set

  # priorityClassName: ""



  ## Define Log Format

  # Use logfmt (default) or json logging

  # logFormat: logfmt



  ## Decrease log verbosity to errors only

  # logLevel: error



  ## If true, the operator will create and maintain a service for scraping kubelets

  ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/helm/prometheus-operator/README.md

  ##

  kubeletService:

    enabled: true

    namespace: kube-system



  ## Create a servicemonitor for the operator

  ##

  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    ## Scrape timeout. If not set, the Prometheus default scrape timeout is used.

    scrapeTimeout: ""

    selfMonitor: true



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



  ## Resource limits & requests

  ##

  resources: {}

  # limits:

  #   cpu: 200m

  #   memory: 200Mi

  # requests:

  #   cpu: 100m

  #   memory: 100Mi



  # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico),

  # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working

  ##

  hostNetwork: false



  ## Define which Nodes the Pods are scheduled on.

  ## ref: https://kubernetes.io/docs/user-guide/node-selection/

  ##

  nodeSelector: {}



  ## Tolerations for use with node taints

  ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/

  ##

  tolerations: []

  # - key: "key"

  #   operator: "Equal"

  #   value: "value"

  #   effect: "NoSchedule"



  ## Assign custom affinity rules to the prometheus operator

  ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

  ##

  affinity: {}

    # nodeAffinity:

    #   requiredDuringSchedulingIgnoredDuringExecution:

    #     nodeSelectorTerms:

    #     - matchExpressions:

    #       - key: kubernetes.io/e2e-az-name

    #         operator: In

    #         values:

    #         - e2e-az1

    #         - e2e-az2

  dnsConfig: {}

    # nameservers:

    #   - 1.2.3.4

    # searches:

    #   - ns1.svc.cluster-domain.example

    #   - my.dns.search.suffix

    # options:

    #   - name: ndots

    #     value: "2"

  #   - name: edns0

  securityContext:

    fsGroup: 65534

    runAsGroup: 65534

    runAsNonRoot: true

    runAsUser: 65534



  ## Prometheus-operator image

  ##

  image:

    repository: quay.io/prometheus-operator/prometheus-operator

    tag: v0.45.0

    sha: ""

    pullPolicy: IfNotPresent



  ## Prometheus image to use for prometheuses managed by the operator

  ##

  # prometheusDefaultBaseImage: quay.io/prometheus/prometheus



  ## Alertmanager image to use for alertmanagers managed by the operator

  ##

  # alertmanagerDefaultBaseImage: quay.io/prometheus/alertmanager



  ## Prometheus-config-reloader image to use for config and rule reloading

  ##

  prometheusConfigReloaderImage:

    repository: quay.io/prometheus-operator/prometheus-config-reloader

    tag: v0.45.0

    sha: ""



  ## Set the prometheus config reloader side-car CPU limit

  ##

  configReloaderCpu: 100m



  ## Set the prometheus config reloader side-car memory limit

  ##

  configReloaderMemory: 50Mi



  ## Set a Field Selector to filter watched secrets

  ##

  secretFieldSelector: ""



## Deploy a Prometheus instance

##

prometheus:



  enabled: true



  ## Annotations for Prometheus

  ##

  annotations: {}



  ## Service account for Prometheuses to use.

  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

  ##

  serviceAccount:

    create: true

    name: ""



  # Service for thanos service discovery on sidecar

  # Enable this can make Thanos Query can use

  # `--store=dnssrv+_grpc._tcp.${kube-prometheus-stack.fullname}-thanos-discovery.${namespace}.svc.cluster.local` to discovery

  # Thanos sidecar on prometheus nodes

  # (Please remember to change ${kube-prometheus-stack.fullname} and ${namespace}. Not just copy and paste!)

  thanosService:

    enabled: false

    annotations: {}

    labels: {}

    portName: grpc

    port: 10901

    targetPort: "grpc"



  ## Configuration for Prometheus service

  ##

  service:

    annotations: {}

    labels: {}

    clusterIP: ""



    ## Port for Prometheus Service to listen on

    ##

    port: 9090



    ## To be used with a proxy extraContainer port

    targetPort: 9090



    ## List of IP addresses at which the Prometheus server service is available

    ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips

    ##

    externalIPs: []



    ## Port to expose on each node

    ## Only used if service.type is 'NodePort'

    ##

    nodePort: 30090



    ## Loadbalancer IP

    ## Only use if service.type is "loadbalancer"

    loadBalancerIP: ""

    loadBalancerSourceRanges: []

    ## Service type

    ##

    type: ClusterIP



    sessionAffinity: ""



  ## Configuration for creating a separate Service for each statefulset Prometheus replica

  ##

  servicePerReplica:

    enabled: false

    annotations: {}



    ## Port for Prometheus Service per replica to listen on

    ##

    port: 9090



    ## To be used with a proxy extraContainer port

    targetPort: 9090



    ## Port to expose on each node

    ## Only used if servicePerReplica.type is 'NodePort'

    ##

    nodePort: 30091



    ## Loadbalancer source IP ranges

    ## Only used if servicePerReplica.type is "loadbalancer"

    loadBalancerSourceRanges: []

    ## Service type

    ##

    type: ClusterIP



  ## Configure pod disruption budgets for Prometheus

  ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget

  ## This configuration is immutable once created and will require the PDB to be deleted to be changed

  ## https://github.com/kubernetes/kubernetes/issues/45398

  ##

  podDisruptionBudget:

    enabled: false

    minAvailable: 1

    maxUnavailable: ""



  # Ingress exposes thanos sidecar outside the cluster

  thanosIngress:

    enabled: false



    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName

    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress

    # ingressClassName: nginx



    annotations: {}

    labels: {}

    servicePort: 10901



    ## Port to expose on each node

    ## Only used if service.type is 'NodePort'

    ##

    nodePort: 30901



    ## Hosts must be provided if Ingress is enabled.

    ##

    hosts: []

      # - thanos-gateway.domain.com



    ## Paths to use for ingress rules

    ##

    paths: []

    # - /



    ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched)

    ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types

    # pathType: ImplementationSpecific



    ## TLS configuration for Thanos Ingress

    ## Secret must be manually created in the namespace

    ##

    tls: []

    # - secretName: thanos-gateway-tls

    #   hosts:

    #   - thanos-gateway.domain.com



  ingress:

    enabled: true



    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName

    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress

    # ingressClassName: nginx



    annotations: {}

    labels: {}



    ## Hostnames.

    ## Must be provided if Ingress is enabled.

    ##

    hosts:

      - prometheus.prod.test.local

    #hosts: []



    ## Paths to use for ingress rules - one path should match the prometheusSpec.routePrefix

    ##

    paths:

     - /



    ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched)

    ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types

    # pathType: ImplementationSpecific



    ## TLS configuration for Prometheus Ingress

    ## Secret must be manually created in the namespace

    ##

    tls: []

      # - secretName: prometheus-general-tls

      #   hosts:

      #     - prometheus.example.com



  ## Configuration for creating an Ingress that will map to each Prometheus replica service

  ## prometheus.servicePerReplica must be enabled

  ##

  ingressPerReplica:

    enabled: false



    # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName

    # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress

    # ingressClassName: nginx



    annotations: {}

    labels: {}



    ## Final form of the hostname for each per replica ingress is

    ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }}

    ##

    ## Prefix for the per replica ingress that will have `-$replicaNumber`

    ## appended to the end

    hostPrefix: ""

    ## Domain that will be used for the per replica ingress

    hostDomain: ""



    ## Paths to use for ingress rules

    ##

    paths: []

    # - /



    ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched)

    ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types

    # pathType: ImplementationSpecific



    ## Secret name containing the TLS certificate for Prometheus per replica ingress

    ## Secret must be manually created in the namespace

    tlsSecretName: ""



    ## Separated secret for each per replica Ingress. Can be used together with cert-manager

    ##

    tlsSecretPerReplica:

      enabled: false

      ## Final form of the secret for each per replica ingress is

      ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }}

      ##

      prefix: "prometheus"



  ## Configure additional options for default pod security policy for Prometheus

  ## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/

  podSecurityPolicy:

    allowedCapabilities: []

    allowedHostPaths: []

    volumes: []



  serviceMonitor:

    ## Scrape interval. If not set, the Prometheus default scrape interval is used.

    ##

    interval: ""

    selfMonitor: true



    ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS.

    scheme: ""



    ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS.

    ## Of type: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#tlsconfig

    tlsConfig: {}



    bearerTokenFile:



    ##  metric relabel configs to apply to samples before ingestion.

    ##

    metricRelabelings: []

    # - action: keep

    #   regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'

    #   sourceLabels: [__name__]



    #   relabel configs to apply to samples before ingestion.

    ##

    relabelings: []

    # - sourceLabels: [__meta_kubernetes_pod_node_name]

    #   separator: ;

    #   regex: ^(.*)$

    #   targetLabel: nodename

    #   replacement: $1

    #   action: replace



  ## Settings affecting prometheusSpec

  ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#prometheusspec

  ##

  prometheusSpec:

    ## If true, pass --storage.tsdb.max-block-duration=2h to prometheus. This is already done if using Thanos

    ##

    disableCompaction: false

    ## APIServerConfig

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#apiserverconfig

    ##

    apiserverConfig: {}



    ## Interval between consecutive scrapes.

    ## Defaults to 30s.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/release-0.44/pkg/prometheus/promcfg.go#L180-L183

    ##

    scrapeInterval: ""



    ## Number of seconds to wait for target to respond before erroring

    ##

    scrapeTimeout: ""



    ## Interval between consecutive evaluations.

    ##

    evaluationInterval: ""



    ## ListenLocal makes the Prometheus server listen on loopback, so that it does not bind against the Pod IP.

    ##

    listenLocal: false



    ## EnableAdminAPI enables Prometheus the administrative HTTP API which includes functionality such as deleting time series.

    ## This is disabled by default.

    ## ref: https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis

    ##

    enableAdminAPI: false



    ## Image of Prometheus.

    ##

    image:

      repository: quay.io/prometheus/prometheus

      tag: v2.24.0

      sha: ""



    ## Tolerations for use with node taints

    ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/

    ##

    tolerations: []

    #  - key: "key"

    #    operator: "Equal"

    #    value: "value"

    #    effect: "NoSchedule"



    ## If specified, the pod's topology spread constraints.

    ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/

    ##

    topologySpreadConstraints: []

    # - maxSkew: 1

    #   topologyKey: topology.kubernetes.io/zone

    #   whenUnsatisfiable: DoNotSchedule

    #   labelSelector:

    #     matchLabels:

    #       app: prometheus



    ## Alertmanagers to which alerts will be sent

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#alertmanagerendpoints

    ##

    ## Default configuration will connect to the alertmanager deployed as part of this release

    ##

    alertingEndpoints: []

    # - name: ""

    #   namespace: ""

    #   port: http

    #   scheme: http

    #   pathPrefix: ""

    #   tlsConfig: {}

    #   bearerTokenFile: ""

    #   apiVersion: v2



    ## External labels to add to any time series or alerts when communicating with external systems

    ##

    externalLabels: {}



    ## Name of the external label used to denote replica name

    ##

    replicaExternalLabelName: ""



    ## If true, the Operator won't add the external label used to denote replica name

    ##

    replicaExternalLabelNameClear: false



    ## Name of the external label used to denote Prometheus instance name

    ##

    prometheusExternalLabelName: ""



    ## If true, the Operator won't add the external label used to denote Prometheus instance name

    ##

    prometheusExternalLabelNameClear: false



    ## External URL at which Prometheus will be reachable.

    ##

    externalUrl: ""



    ## Define which Nodes the Pods are scheduled on.

    ## ref: https://kubernetes.io/docs/user-guide/node-selection/

    ##

    nodeSelector: {}



    ## Secrets is a list of Secrets in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods.

    ## The Secrets are mounted into /etc/prometheus/secrets/. Secrets changes after initial creation of a Prometheus object are not

    ## reflected in the running Pods. To change the secrets mounted into the Prometheus Pods, the object must be deleted and recreated

    ## with the new list of secrets.

    ##

    secrets: []



    ## ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods.

    ## The ConfigMaps are mounted into /etc/prometheus/configmaps/.

    ##

    configMaps: []



    ## QuerySpec defines the query command line flags when starting Prometheus.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#queryspec

    ##

    query: {}



    ## Namespaces to be selected for PrometheusRules discovery.

    ## If nil, select own namespace. Namespaces to be selected for ServiceMonitor discovery.

    ## See https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#namespaceselector for usage

    ##

    ruleNamespaceSelector: {}



    ## If true, a nil or {} value for prometheus.prometheusSpec.ruleSelector will cause the

    ## prometheus resource to be created with selectors based on values in the helm deployment,

    ## which will also match the PrometheusRule resources created

    ##

    ruleSelectorNilUsesHelmValues: true



    ## PrometheusRules to be selected for target discovery.

    ## If {}, select all ServiceMonitors

    ##

    ruleSelector: {}

    ## Example which select all prometheusrules resources

    ## with label "prometheus" with values any of "example-rules" or "example-rules-2"

    # ruleSelector:

    #   matchExpressions:

    #     - key: prometheus

    #       operator: In

    #       values:

    #         - example-rules

    #         - example-rules-2

    #

    ## Example which select all prometheusrules resources with label "role" set to "example-rules"

    # ruleSelector:

    #   matchLabels:

    #     role: example-rules



    ## If true, a nil or {} value for prometheus.prometheusSpec.serviceMonitorSelector will cause the

    ## prometheus resource to be created with selectors based on values in the helm deployment,

    ## which will also match the servicemonitors created

    ##

    serviceMonitorSelectorNilUsesHelmValues: true



    ## ServiceMonitors to be selected for target discovery.

    ## If {}, select all ServiceMonitors

    ##

    serviceMonitorSelector: {}

    ## Example which selects ServiceMonitors with label "prometheus" set to "somelabel"

    # serviceMonitorSelector:

    #   matchLabels:

    #     prometheus: somelabel



    ## Namespaces to be selected for ServiceMonitor discovery.

    ##

    serviceMonitorNamespaceSelector:

       matchLabels:

         prometheus: enabled



    ## Example which selects ServiceMonitors in namespaces with label "prometheus" set to "somelabel"

    # serviceMonitorNamespaceSelector:

    #   matchLabels:

    #     prometheus: somelabel



    ## If true, a nil or {} value for prometheus.prometheusSpec.podMonitorSelector will cause the

    ## prometheus resource to be created with selectors based on values in the helm deployment,

    ## which will also match the podmonitors created

    ##

    podMonitorSelectorNilUsesHelmValues: true



    ## PodMonitors to be selected for target discovery.

    ## If {}, select all PodMonitors

    ##

    podMonitorSelector: {}

    ## Example which selects PodMonitors with label "prometheus" set to "somelabel"

    # podMonitorSelector:

    #   matchLabels:

    #     prometheus: somelabel



    ## Namespaces to be selected for PodMonitor discovery.

    ## See https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#namespaceselector for usage

    ##

    podMonitorNamespaceSelector: {}



    ## If true, a nil or {} value for prometheus.prometheusSpec.probeSelector will cause the

    ## prometheus resource to be created with selectors based on values in the helm deployment,

    ## which will also match the probes created

    ##

    probeSelectorNilUsesHelmValues: true



    ## Probes to be selected for target discovery.

    ## If {}, select all Probes

    ##

    probeSelector: {}

    ## Example which selects Probes with label "prometheus" set to "somelabel"

    # probeSelector:

    #   matchLabels:

    #     prometheus: somelabel



    ## Namespaces to be selected for Probe discovery.

    ## See https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#namespaceselector for usage

    ##

    probeNamespaceSelector: {}



    ## How long to retain metrics

    ##

    retention: 10d



    ## Maximum size of metrics

    ##

    retentionSize: ""



    ## Enable compression of the write-ahead log using Snappy.

    ##

    walCompression: false



    ## If true, the Operator won't process any Prometheus configuration changes

    ##

    paused: false



    ## Number of replicas of each shard to deploy for a Prometheus deployment.

    ## Number of replicas multiplied by shards is the total number of Pods created.

    ##

    replicas: 1



    ## EXPERIMENTAL: Number of shards to distribute targets onto.

    ## Number of replicas multiplied by shards is the total number of Pods created.

    ## Note that scaling down shards will not reshard data onto remaining instances, it must be manually moved.

    ## Increasing shards will not reshard data either but it will continue to be available from the same instances.

    ## To query globally use Thanos sidecar and Thanos querier or remote write data to a central location.

    ## Sharding is done on the content of the `__address__` target meta-label.

    ##

    shards: 1



    ## Log level for Prometheus be configured in

    ##

    logLevel: info



    ## Log format for Prometheus be configured in

    ##

    logFormat: logfmt



    ## Prefix used to register routes, overriding externalUrl route.

    ## Useful for proxies that rewrite URLs.

    ##

    routePrefix: /



    ## Standard object’s metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata

    ## Metadata Labels and Annotations gets propagated to the prometheus pods.

    ##

    podMetadata: {}

    # labels:

    #   app: prometheus

    #   k8s-app: prometheus



    ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node.

    ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided.

    ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node.

    ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured.

    podAntiAffinity: ""



    ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity.

    ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone

    ##

    podAntiAffinityTopologyKey: kubernetes.io/hostname



    ## Assign custom affinity rules to the prometheus instance

    ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

    ##

    affinity: {}

    # nodeAffinity:

    #   requiredDuringSchedulingIgnoredDuringExecution:

    #     nodeSelectorTerms:

    #     - matchExpressions:

    #       - key: kubernetes.io/e2e-az-name

    #         operator: In

    #         values:

    #         - e2e-az1

    #         - e2e-az2



    ## The remote_read spec configuration for Prometheus.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#remotereadspec

    remoteRead: []

    # - url: http://remote1/read



    ## The remote_write spec configuration for Prometheus.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#remotewritespec

    remoteWrite: []

    # - url: http://remote1/push



    ## Enable/Disable Grafana dashboards provisioning for prometheus remote write feature

    remoteWriteDashboards: false



    ## Resource limits & requests

    ##

    resources: {}

    # requests:

    #   memory: 400Mi



    ## Prometheus StorageSpec for persistent data

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md

    ##

    storageSpec:

    ## Using PersistentVolumeClaim

    ##

      volumeClaimTemplate:

        spec:

          storageClassName: nfs-storageclass

          accessModes: ["ReadWriteMany"]

          resources:

            requests:

              storage: 10Gi

    #    selector: {}



    ## Using tmpfs volume

    ##

    #  emptyDir:

    #    medium: Memory



    # Additional volumes on the output StatefulSet definition.

    volumes: []



    # Additional VolumeMounts on the output StatefulSet definition.

    volumeMounts: []



    ## AdditionalScrapeConfigs allows specifying additional Prometheus scrape configurations. Scrape configurations

    ## are appended to the configurations generated by the Prometheus Operator. Job configurations must have the form

    ## as specified in the official Prometheus documentation:

    ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. As scrape configs are

    ## appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility

    ## to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible

    ## scrape configs are going to break Prometheus after the upgrade.

    ##

    ## The scrape configuration example below will find master nodes, provided they have the name .*mst.*, relabel the

    ## port to 2379 and allow etcd scraping provided it is running on all Kubernetes master nodes

    ##

    additionalScrapeConfigs: []

    # - job_name: kube-etcd

    #   kubernetes_sd_configs:

    #     - role: node

    #   scheme: https

    #   tls_config:

    #     ca_file:   /etc/prometheus/secrets/etcd-client-cert/etcd-ca

    #     cert_file: /etc/prometheus/secrets/etcd-client-cert/etcd-client

    #     key_file:  /etc/prometheus/secrets/etcd-client-cert/etcd-client-key

    #   relabel_configs:

    #   - action: labelmap

    #     regex: __meta_kubernetes_node_label_(.+)

    #   - source_labels: [__address__]

    #     action: replace

    #     targetLabel: __address__

    #     regex: ([^:;]+):(d+)

    #     replacement: ${1}:2379

    #   - source_labels: [__meta_kubernetes_node_name]

    #     action: keep

    #     regex: .*mst.*

    #   - source_labels: [__meta_kubernetes_node_name]

    #     action: replace

    #     targetLabel: node

    #     regex: (.*)

    #     replacement: ${1}

    #   metric_relabel_configs:

    #   - regex: (kubernetes_io_hostname|failure_domain_beta_kubernetes_io_region|beta_kubernetes_io_os|beta_kubernetes_io_arch|beta_kubernetes_io_instance_type|failure_domain_beta_kubernetes_io_zone)

    #     action: labeldrop



    ## If additional scrape configurations are already deployed in a single secret file you can use this section.

    ## Expected values are the secret name and key

    ## Cannot be used with additionalScrapeConfigs

    additionalScrapeConfigsSecret: {}

      # enabled: false

      # name:

      # key:



    ## additionalPrometheusSecretsAnnotations allows to add annotations to the kubernetes secret. This can be useful

    ## when deploying via spinnaker to disable versioning on the secret, strategy.spinnaker.io/versioned: 'false'

    additionalPrometheusSecretsAnnotations: {}



    ## AdditionalAlertManagerConfigs allows for manual configuration of alertmanager jobs in the form as specified

    ## in the official Prometheus documentation https://prometheus.io/docs/prometheus/latest/configuration/configuration/#<alertmanager_config>.

    ## AlertManager configurations specified are appended to the configurations generated by the Prometheus Operator.

    ## As AlertManager configs are appended, the user is responsible to make sure it is valid. Note that using this

    ## feature may expose the possibility to break upgrades of Prometheus. It is advised to review Prometheus release

    ## notes to ensure that no incompatible AlertManager configs are going to break Prometheus after the upgrade.

    ##

    additionalAlertManagerConfigs: []

    # - consul_sd_configs:

    #   - server: consul.dev.test:8500

    #     scheme: http

    #     datacenter: dev

    #     tag_separator: ','

    #     services:

    #       - metrics-prometheus-alertmanager



    ## AdditionalAlertRelabelConfigs allows specifying Prometheus alert relabel configurations. Alert relabel configurations specified are appended

    ## to the configurations generated by the Prometheus Operator. Alert relabel configurations specified must have the form as specified in the

    ## official Prometheus documentation: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs.

    ## As alert relabel configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the

    ## possibility to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible alert relabel

    ## configs are going to break Prometheus after the upgrade.

    ##

    additionalAlertRelabelConfigs: []

    # - separator: ;

    #   regex: prometheus_replica

    #   replacement: $1

    #   action: labeldrop



    ## SecurityContext holds pod-level security attributes and common container settings.

    ## This defaults to non root user with uid 1000 and gid 2000.

    ## https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md

    ##

    securityContext:

      runAsGroup: 2000

      runAsNonRoot: true

      runAsUser: 1000

      fsGroup: 2000



    ##  Priority class assigned to the Pods

    ##

    priorityClassName: ""



    ## Thanos configuration allows configuring various aspects of a Prometheus server in a Thanos environment.

    ## This section is experimental, it may change significantly without deprecation notice in any release.

    ## This is experimental and may change significantly without backward compatibility in any release.

    ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#thanosspec

    ##

    thanos: {}



    ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to a Prometheus pod.

    ##  if using proxy extraContainer  update targetPort with proxy container port

    containers: []



    ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes

    ## (permissions, dir tree) on mounted volumes before starting prometheus

    initContainers: []



    ## PortName to use for Prometheus.

    ##

    portName: "web"



    ## ArbitraryFSAccessThroughSMs configures whether configuration based on a service monitor can access arbitrary files

    ## on the file system of the Prometheus container e.g. bearer token files.

    arbitraryFSAccessThroughSMs: false



    ## OverrideHonorLabels if set to true overrides all user configured honor_labels. If HonorLabels is set in ServiceMonitor

    ## or PodMonitor to true, this overrides honor_labels to false.

    overrideHonorLabels: false



    ## OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs.

    overrideHonorTimestamps: false



    ## IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from the podmonitor and servicemonitor

    ## configs, and they will only discover endpoints within their current namespace. Defaults to false.

    ignoreNamespaceSelectors: false



    ## PrometheusRulesExcludedFromEnforce - list of prometheus rules to be excluded from enforcing of adding namespace labels.

    ## Works only if enforcedNamespaceLabel set to true. Make sure both ruleNamespace and ruleName are set for each pair

    prometheusRulesExcludedFromEnforce: false



    ## QueryLogFile specifies the file to which PromQL queries are logged. Note that this location must be writable,

    ## and can be persisted using an attached volume. Alternatively, the location can be set to a stdout location such

    ## as /dev/stdout to log querie information to the default Prometheus log stream. This is only available in versions

    ## of Prometheus >= 2.16.0. For more details, see the Prometheus docs (https://prometheus.io/docs/guides/query-log/)

    queryLogFile: false



    ## EnforcedSampleLimit defines global limit on number of scraped samples that will be accepted. This overrides any SampleLimit

    ## set per ServiceMonitor or/and PodMonitor. It is meant to be used by admins to enforce the SampleLimit to keep overall

    ## number of samples/series under the desired limit. Note that if SampleLimit is lower that value will be taken instead.

    enforcedSampleLimit: false



    ## AllowOverlappingBlocks enables vertical compaction and vertical query merge in Prometheus. This is still experimental

    ## in Prometheus so it may change in any upcoming release.

    allowOverlappingBlocks: false



  additionalRulesForClusterRole: []

  #  - apiGroups: [ "" ]

  #    resources:

  #      - nodes/proxy

  #    verbs: [ "get", "list", "watch" ]



  additionalServiceMonitors: []

  ## Name of the ServiceMonitor to create

  ##

    #- name: ""



    ## Additional labels to set used for the ServiceMonitorSelector. Together with standard labels from

    ## the chart

    ##

    # additionalLabels: {}



    ## Service label for use in assembling a job name of the form <label value>-<port>

    ## If no label is specified, the service name is used.

    ##

    # jobLabel: ""



    ## labels to transfer from the kubernetes service to the target

    ##

    # targetLabels: []



    ## labels to transfer from the kubernetes pods to the target

    ##

    # podTargetLabels: []



    ## Label selector for services to which this ServiceMonitor applies

    ##

    # selector: {}



    ## Namespaces from which services are selected

    ##

    # namespaceSelector: []

      ## Match any namespace

      ##

      # any: false



      ## Explicit list of namespace names to select

      ##

      # matchNames: []



    ## Endpoints of the selected service to be monitored

    ##

    # endpoints: []

      ## Name of the endpoint's service port

      ## Mutually exclusive with targetPort

      # - port: ""



      ## Name or number of the endpoint's target port

      ## Mutually exclusive with port

      # - targetPort: ""



      ## File containing bearer token to be used when scraping targets

      ##

      #   bearerTokenFile: ""



      ## Interval at which metrics should be scraped

      ##

      #   interval: 30s



      ## HTTP path to scrape for metrics

      ##

      #   path: /metrics



      ## HTTP scheme to use for scraping

      ##

      #   scheme: http



      ## TLS configuration to use when scraping the endpoint

      ##

      #   tlsConfig:



          ## Path to the CA file

          ##

          # caFile: ""



          ## Path to client certificate file

          ##

          # certFile: ""



          ## Skip certificate verification

          ##

          # insecureSkipVerify: false



          ## Path to client key file

          ##

          # keyFile: ""



          ## Server name used to verify host name

          ##

          # serverName: ""



  additionalPodMonitors: []

  ## Name of the PodMonitor to create

  ##

  # - name: ""



    ## Additional labels to set used for the PodMonitorSelector. Together with standard labels from

    ## the chart

    ##

    # additionalLabels: {}



    ## Pod label for use in assembling a job name of the form <label value>-<port>

    ## If no label is specified, the pod endpoint name is used.

    ##

    # jobLabel: ""



    ## Label selector for pods to which this PodMonitor applies

    ##

    # selector: {}



    ## PodTargetLabels transfers labels on the Kubernetes Pod onto the target.

    ##

    # podTargetLabels: {}



    ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.

    ##

    # sampleLimit: 0



    ## Namespaces from which pods are selected

    ##

    # namespaceSelector:

      ## Match any namespace

      ##

      # any: false



      ## Explicit list of namespace names to select

      ##

      # matchNames: []



    ## Endpoints of the selected pods to be monitored

    ## https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmetricsendpoint

    ##

    # podMetricsEndpoints: []





Настроим Elasticsearch-exporter




он есть в том же репозитории:
https://github.com/prometheus-community/helm-charts.git с которого мы запускали сам prometheus, лежит он тут:




helm-charts/charts/prometheus-elasticsearch-exporter




!!!!!!!!!!!!сам elasticsearch уже должен быть установлен.




смотрим нужные нам данные:




правим переменные:




vim helm-charts/charts/prometheus-elasticsearch-exporter/values.yaml




ранее мы добавляли лейбл командой:
проставим на них label release=prometheus
kubectl label namespace —all «prometheus=enabled»




проверяем что всё ок




kubectl get ns --show-labels | grep elk

elk                      Active   71d    prometheus=enabled





теперь смотрим на какое имя нам надо будет ссылаться:




kubectl get service -n elk | grep 9200

elasticsearch-master            ClusterIP   13.100.200.219   <none>        9200/TCP,9300/TCP   28d

elasticsearch-master-headless   ClusterIP   None             <none>        9200/TCP,9300/TCP   28d




в конфиге будем указывать elasticsearch-master




смотрим какие есть лейблы на этом сервисе:




kubectl describe service -n elk elasticsearch-master | grep -A4 Labels

Labels:            app=elasticsearch-master

                   app.kubernetes.io/managed-by=Helm

                   chart=elasticsearch

                   heritage=Helm

                   release=elasticsearch




нас интересует app=elasticsearch-master




правим конфиг:




vim prometheus-elasticsearch-exporter/values.yaml




es:

  uri: http://elasticsearch-master:9200



serviceMonitor:

  ## If true, a ServiceMonitor CRD is created for a prometheus operator

  ## https://github.com/coreos/prometheus-operator

  ##

  enabled: true

  namespace: monitoring

  labels:

    app: elasticsearch-master

    release: prometheus

  interval: 10s

  scrapeTimeout: 10s

  scheme: http

  relabelings: []

  targetLabels:

    app: elasticsearch-master

    release: prometheus

  metricRelabelings: []

  sampleLimit: 0






в полном виде конфиг выглядит так:




## number of exporter instances

##

replicaCount: 1



## restart policy for all containers

##

restartPolicy: Always



image:

  repository: justwatch/elasticsearch_exporter

  tag: 1.1.0

  pullPolicy: IfNotPresent

  pullSecret: ""



## Set enabled to false if you don't want securityContext

## in your Deployment.

## The below values are the default for kubernetes.

## Openshift won't deploy with runAsUser: 1000 without additional permissions.

securityContext:

  enabled: true  # Should be set to false when running on OpenShift

  runAsUser: 1000



# Custom DNS configuration to be added to prometheus-elasticsearch-exporter pods

dnsConfig: {}

# nameservers:

#   - 1.2.3.4

# searches:

#   - ns1.svc.cluster-domain.example

#   - my.dns.search.suffix

# options:

#   - name: ndots

#     value: "2"

#   - name: edns0



log:

  format: logfmt

  level: info



resources: {}

  # requests:

  #   cpu: 100m

  #   memory: 128Mi

  # limits:

  #   cpu: 100m

  #   memory: 128Mi



priorityClassName: ""



nodeSelector: {}



tolerations: []



podAnnotations: {}



podLabels: {}



affinity: {}



service:

  type: ClusterIP

  httpPort: 9108

  metricsPort:

    name: http

  annotations: {}

  labels: {}



## Extra environment variables that will be passed into the exporter pod

## example:

## env:

##   KEY_1: value1

##   KEY_2: value2

env: {}



## The name of a secret in the same kubernetes namespace which contain values to be added to the environment

## This can be useful for auth tokens, etc

envFromSecret: ""



## A list of environment variables from secret refs that will be passed into the exporter pod

## example:

## This will set ${ES_PASSWORD} to the 'password' key from the 'my-secret' secret

## extraEnvSecrets:

##   ES_PASSWORD:

##     secret: my-secret

##     key: password

extraEnvSecrets: {}



# A list of secrets and their paths to mount inside the pod

# This is useful for mounting certificates for security

secretMounts: []

#  - name: elastic-certs

#    secretName: elastic-certs

#    path: /ssl



# A list of additional Volume to add to the deployment

# this is useful if the volume you need is not a secret (csi volume etc.)

extraVolumes: []

#  - name: csi-volume

#    csi:

#      driver: secrets-store.csi.k8s.io

#      readOnly: true

#      volumeAttributes:

#        secretProviderClass: my-spc



#  A list of additional VolumeMounts to add to the deployment

#  this is useful for mounting any other needed resource into

#  the elasticsearch-exporter pod

extraVolumeMounts: []

#  - name: csi-volume

#    mountPath: /csi/volume

#    readOnly: true



es:

  ## Address (host and port) of the Elasticsearch node we should connect to.

  ## This could be a local node (localhost:9200, for instance), or the address

  ## of a remote Elasticsearch server. When basic auth is needed,

  ## specify as: <proto>://<user>:<password>@<host>:<port>. e.g., http://admin:pass@localhost:9200.

  ##

  uri: http://elasticsearch-master:9200



  ## If true, query stats for all nodes in the cluster, rather than just the

  ## node we connect to.

  ##

  all: true



  ## If true, query stats for all indices in the cluster.

  ##

  indices: true



  ## If true, query settings stats for all indices in the cluster.

  ##

  indices_settings: true



  ## If true, query stats for shards in the cluster.

  ##

  shards: true



  ## If true, query stats for snapshots in the cluster.

  ##

  snapshots: true



  ## If true, query stats for cluster settings.

  ##

  cluster_settings: false



  ## Timeout for trying to get stats from Elasticsearch. (ex: 20s)

  ##

  timeout: 30s



  ## Skip SSL verification when connecting to Elasticsearch

  ## (only available if image.tag >= 1.0.4rc1)

  ##

  sslSkipVerify: false





  ssl:

    ## If true, a secure connection to ES cluster is used

    ##

    enabled: false



    ## If true, certs from secretMounts will be need to be referenced instead of certs below

    ##

    useExistingSecrets: false



    ca:



      ## PEM that contains trusted CAs used for setting up secure Elasticsearch connection

      ##

      # pem:



      # Path of ca pem file which should match a secretMount path

      path: /ssl/ca.pem

    client:

      ## if true, client SSL certificate is used for authentication

      ##

      enabled: true



      ## PEM that contains the client cert to connect to Elasticsearch.

      ##

      # pem:



      # Path of client pem file which should match a secretMount path

      pemPath: /ssl/client.pem



      ## Private key for client auth when connecting to Elasticsearch

      ##

      # key:



      # Path of client key file which should match a secretMount path

      keyPath: /ssl/client.key

web:

  ## Path under which to expose metrics.

  ##

  path: /metrics



serviceMonitor:

  ## If true, a ServiceMonitor CRD is created for a prometheus operator

  ## https://github.com/coreos/prometheus-operator

  ##

  enabled: true

  namespace: monitoring

  labels:

    app: elasticsearch-master

    release: prometheus

  interval: 10s

  scrapeTimeout: 10s

  scheme: http

  relabelings: []

  targetLabels:

    app: elasticsearch-master

    release: prometheus

  metricRelabelings: []

  sampleLimit: 0



prometheusRule:

  ## If true, a PrometheusRule CRD is created for a prometheus operator

  ## https://github.com/coreos/prometheus-operator

  ##

  ## The rules will be processed as Helm template, allowing to set variables in them.

  enabled: false

  #  namespace: monitoring

  labels: {}

  rules: []

    # - record: elasticsearch_filesystem_data_used_percent

    #   expr: |

    #     100 * (elasticsearch_filesystem_data_size_bytes{service="{{ template "elasticsearch-exporter.fullname" . }}"} - elasticsearch_filesystem_data_free_bytes{service="{{ template "elasticsearch-exporter.fullname" . }}"})

    #     / elasticsearch_filesystem_data_size_bytes{service="{{ template "elasticsearch-exporter.fullname" . }}"}

    # - record: elasticsearch_filesystem_data_free_percent

    #   expr: 100 - elasticsearch_filesystem_data_used_percent{service="{{ template "elasticsearch-exporter.fullname" . }}"}

    # - alert: ElasticsearchTooFewNodesRunning

    #   expr: elasticsearch_cluster_health_number_of_nodes{service="{{ template "elasticsearch-exporter.fullname" . }}"} < 3

    #   for: 5m

    #   labels:

    #     severity: critical

    #   annotations:

    #     description: There are only {{ "{{ $value }}" }} < 3 ElasticSearch nodes running

    #     summary: ElasticSearch running on less than 3 nodes

    # - alert: ElasticsearchHeapTooHigh

    #   expr: |

    #     elasticsearch_jvm_memory_used_bytes{service="{{ template "elasticsearch-exporter.fullname" . }}", area="heap"} / elasticsearch_jvm_memory_max_bytes{service="{{ template "elasticsearch-exporter.fullname" . }}", area="heap"}

    #     > 0.9

    #   for: 15m

    #   labels:

    #     severity: critical

    #   annotations:

    #     description: The heap usage is over 90% for 15m

    #     summary: ElasticSearch node {{ "{{ $labels.node }}" }} heap usage is high



# Create a service account

# To use a service account not handled by the chart, set the name here

# and set create to false

serviceAccount:

  create: false

  name: default



# Creates a PodSecurityPolicy and the role/rolebinding

# allowing the serviceaccount to use it

podSecurityPolicies:

  enabled: false





можем устанавливать:




helm install elasticsearch-exporter —values prometheus-elasticsearch-exporter/values.yaml prometheus-elasticsearch-exporter/ -n elk




через какое-то время появится target





4.exporter rabbitmq




прогоняем label по всем namespace
kubectl label namespace —all «prometheus=enabled»




у меня уже установлен rabbitmq в кластере в namespace rabbitmq, прометеус в namespace monitoring




пароль от rabbitmq у меня закрыт в секрете:




kubectl get secrets -n rabbitmq  | grep pass

secret-admin-password            Opaque                                1      4d22h





vim prometheus-rabbitmq-exporter/values.yaml




loglevel: info

rabbitmq:

  url: http://rabbitmq-headless.rabbitmq.svc.test.local:15672

  user: admin

  password: secret-admin-password

  # If existingPasswordSecret is set then password is ignored

  existingPasswordSecret: ~







prometheus:

  monitor:

    enabled: true

    additionalLabels:

      release: prometheus

    interval: 15s

    namespace: []




helm install rabbitmq-exporter prometheus-rabbitmq-exporter/ -n monitoring —values prometheus-rabbitmq-exporter/values.yaml




5. exporter redis




прогоняем label по всем namespace
kubectl label namespace —all «prometheus=enabled»




у меня уже установлен redis в кластере в namespace redis, прометеус в namespace monitoring




пароль от redis у меня закрыт в секрете:




[root@prod-vsrv-kubemaster1 charts]# kubectl get secrets -n redis  | grep -E 'NAME|password'

NAME                                                   TYPE                                  DATA   AGE

redis-password                                         Opaque                                1      27h





vim prometheus-redis-exporter/values.yaml




redisAddress: redis://redis-cluster-headless.redis.svc.test.local:6379



serviceMonitor:

  enabled: true

  namespace: monitoring

  # Set labels for the ServiceMonitor, use this to define your scrape label for Prometheus Operator

  labels:

    release: prometheus



auth:

  # Use password authentication

  enabled: true

  # Use existing secret (ignores redisPassword)

  secret:

    name: redis-password

    key: redis-password





helm install redis-exporter prometheus-redis-exporter/ -n redis —values prometheus-redis-exporter/values.yaml




6. настройка оповещений в telegram




Для начала создадим telegram bot





идём на  @BotFather




нажимаем start и получаем список команд:





 /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




собираем образ пушим в наш гитлаб




далее идём в телеграмм в канал:




userinfobot
печатаем старт и получаем наш id




далее выполняем:




echo -n «4196184» | base64
получаем хэш
NDE5NjE4NA==




а так же получаем хэш нашего телеграм токена:




echo -n «1788359733:AAFf3cK6dfEPHV5e7ePXnHP6x6GHWzEQoSw» | base64
MTc4ODM1OTczMzpBQUZmM2NLNmRmRVBIVjVlN2VQWG5IUDZ4NkdIV3pFUW9Tdw==




создаём deployment




cat telegrambot.yml




apiVersion: v1

items:

- apiVersion: v1

  data:

    admin1: NDE5NjE4NA

    admin2: NTY

    admin3: NDE5

    token: MTc4ODM1OTczMzpBQUZmM2NLNmRmRVBIVjVlN2VQWG5IUDZ4NkdIV3pFUW9Tdw==

  kind: Secret

  metadata:

    labels:

      app.kubernetes.io/name: alertmanager-bot

    name: alertmanager-bot

    namespace: monitoring

  type: Opaque

- apiVersion: v1

  kind: Service

  metadata:

    labels:

      app.kubernetes.io/name: alertmanager-bot

    name: alertmanager-bot

    namespace: monitoring

  spec:

    ports:

    - name: http

      port: 8080

      targetPort: 8080

    selector:

      app.kubernetes.io/name: alertmanager-bot

- apiVersion: apps/v1

  kind: StatefulSet

  metadata:

    labels:

      app.kubernetes.io/name: alertmanager-bot

    name: alertmanager-bot

    namespace: monitoring

  spec:

    podManagementPolicy: OrderedReady

    replicas: 1

    selector:

      matchLabels:

        app.kubernetes.io/name: alertmanager-bot

    serviceName: alertmanager-bot

    template:

      metadata:

        labels:

          app.kubernetes.io/name: alertmanager-bot

        name: alertmanager-bot

        namespace: monitoring

      spec:

        containers:

        - args:

          - --alertmanager.url=http://alertmanager-operated:9093

          - --log.level=info

          - --store=bolt

          - --bolt.path=/data/bot.db

          - --telegram.admin=4196184

          - --telegram.admin=56

          - --telegram.admin=41

          env:

     #     - name: TELEGRAM_ADMIN

     #       valueFrom:

     #         secretKeyRef:

     #           key: admin

     #           name: alertmanager-bot

          - name: TELEGRAM_TOKEN

            valueFrom:

              secretKeyRef:

                key: token

                name: alertmanager-bot

          image: gitlab.test.local:4567/monitoring/alertbot

          imagePullPolicy: IfNotPresent

          name: alertmanager-bot

          ports:

          - containerPort: 8080

            name: http

          resources:

            limits:

              cpu: 100m

              memory: 128Mi

            requests:

              cpu: 25m

              memory: 64Mi

          volumeMounts:

          - mountPath: /data

            name: alertmanager-bot

        restartPolicy: Always

        imagePullSecrets:

        - name: regcred



    volumeClaimTemplates:

    - metadata:

        labels:

          app.kubernetes.io/name: alertmanager-bot

        name: alertmanager-bot

        namespace: monitoring

      spec:

        accessModes:

        - ReadWriteMany

        resources:

          requests:

            storage: 1Gi

        storageClassName: nfs-storageclass

kind: List





admin1 — тут указываю хэши id пользователей которые будут заходить
token — тут указываем токен нашего телеграм бота (хэш)
namespace — тут указываем неймспейс в котором у нас запущен prometheus
image — тут указываем образ телеграмбота пересобранного и  загруженного в наш гитлаб
— —telegram.admin — тут id пользователей в открытом виде




можем запускать:
kubectl apply -f telegrambot.yml




всё можно проверять:
пишем /start
и бот отвечает:





6.1 настройка оповещений в telegram, в различные чаты(группы)




Задача — настроить оповещения в разные чаты телеграмма




за основу будет взят телеграм бот:
https://github.com/inCaller/prometheus_bot
который был заточен под helm chart
https://github.com/gvych/telegram-bot-helm-chart
отмечу сразу что его надо дописывать в values так как с нуля он не стартует.




приступим, создаём в телеграм новую группу:





добавляем нашего бота которого мы создали в предыдущем пункте, так как я дополняю статью позже, то имя бота у меня другое:






далее добавляем к группе бота который позволит увидеть chatid








вот мы получили chatid запомним его.




Выкачиваем репозиторий:




git clone https://github.com/gvych/telegram-bot-helm-chart.git




cd telegram-bot-helm-chart




правим версию для deployment и выславляем selector изначально их нету в гите, общий вид будет такой:




cat telegram-bot/templates/deployment.yaml




{{- if not .Values.application.initializeCommand -}}

apiVersion: apps/v1

kind: Deployment

metadata:

  name: {{ template "trackableappname" . }}

  labels:

    app: {{ template "appname" . }}

    track: "{{ .Values.application.track }}"

    tier: "{{ .Values.application.tier }}"

    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"

    release: {{ .Release.Name }}

    heritage: {{ .Release.Service }}

spec:

  replicas: {{ .Values.replicaCount }}

  selector:

    matchLabels:

      app: {{ template "appname" . }}

  template:

    metadata:

      annotations:

        checksum/application-secrets: "{{ .Values.application.secretChecksum }}"

      labels:

        app: {{ template "appname" . }}

        track: "{{ .Values.application.track }}"

        tier: "{{ .Values.application.tier }}"

        release: {{ .Release.Name }}

    spec:

      imagePullSecrets:

{{ toYaml .Values.image.secrets | indent 10 }}

      volumes:

      - configMap:

          defaultMode: 420

          name: {{ template "trackableappname" . }}.config

        name: config-volume



      containers:

      - name: {{ .Chart.Name }}

        image: "moghaddas/prometheus_bot"

        imagePullPolicy: {{ .Values.image.pullPolicy }}

        volumeMounts:

        - mountPath: /config.yaml

          name: config-volume

          subPath: config.yaml

        - mountPath: /alert.tmpl

          name: config-volume

          subPath: alert.tmpl

        ports:

        - name: "{{ .Values.service.name }}"

          containerPort: {{ .Values.service.internalPort }}

        livenessProbe:

          tcpSocket:

            port: {{ .Values.service.internalPort }}

          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}

          timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}

        readinessProbe:

          tcpSocket:

            port: {{ .Values.service.internalPort }}

          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}

          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}

        resources:

{{ toYaml .Values.resources | indent 12 }}

{{- end -}}





также правим конфиг, чтобы в уведомлении видно было alertname, description,  message — по умолчанию их нету в дефолте.




telegram-bot-helm/templates/configmap.yaml




apiVersion: v1

kind: ConfigMap

metadata:

  name: {{ template "trackableappname" . }}.config

  labels:

    app: {{ template "appname" . }}

    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"

    release: {{ .Release.Name }}

    heritage: {{ .Release.Service }}

data:

  config.yaml: |-

    telegram_token: "{{ .Values.telegram.token }}"

    template_path: "/alert.tmpl"

    time_zone: "UTC"

    split_token: "|"

    split_msg_byte: 4000

  alert.tmpl: |-

    {{ "{{" }} if eq .Status "firing" {{ "}}" }} <b>[PROBLEM]</b> {{ "{{" }} else {{ "}}" }} <b>[RECOVERY]</b> {{ "{{" }} end {{ "}}" }}

    {{ "{{" }} index (index .Alerts 0).Labels "alertname" {{ "}}" }}

    {{ "{{" }} index (index .Alerts 0).Annotations "description"{{ "}}" }}

    {{ "{{" }} index (index .Alerts 0).Annotations "message"{{ "}}" }}





теперь правим файл с переменными:




cat telegram-bot/values.yaml




# Default values for chart.

# This is a YAML-formatted file.

# Declare variables to be passed into your templates.

replicaCount: 1

telegram:

  token: "139453456058954:AAFaZIepDdfggTql0dfgdfPT6dq1Edqu5dfggxFD6Wr08j0g"

  chat_id: "-567616984" #not used at the moment



releaseOverride: alertmanager-bot-chat-id

image:

  pullPolicy: Always

application:

  track: stable

  tier: web

  migrateCommand:

  initializeCommand:

  secretName:

  secretChecksum:

service:

  enabled: true

  name: web

  type: ClusterIP

  url: http://alertmanager-operated:9093

  additionalHosts:

  commonName:

  externalPort: 9087

  internalPort: 9087



livenessProbe:

  initialDelaySeconds: 15

readinessProbe:

  initialDelaySeconds: 5





resources:

  limits:

    cpu: 100m

    memory: 128Mi

  requests:

    cpu: 10m

    memory: 8Mi





здесь token — это токен нашего телеграм бота мы его получаем при его регистрации в botfather




chat_id — это id нашей группы




url: http://alertmanager-operated:9093  это наш адрес alermanager увидеть его можно следующим образом:




kubectl get service -n monitoring | grep alertmanager-operated

alertmanager-operated                            ClusterIP   None             <none>        9093/TCP,9094/TCP,9094/UDP   57d





для каждой группы мы будем запускать свой телеграмбот, вот второй:




cat telegram-bot/values-test.yaml




# Default values for chart.

# This is a YAML-formatted file.

# Declare variables to be passed into your templates.

replicaCount: 1

telegram:

  token: "139453456058954:AAFaZIepDdfggTql0dfgdfPT6dq1Edqu5dfggxFD6Wr08j0g"

  chat_id: "-480100545" #not used at the moment



releaseOverride: alertmanager-bot-test

image:

  pullPolicy: Always

application:

  track: stable

  tier: web

  migrateCommand:

  initializeCommand:

  secretName:

  secretChecksum:

service:

  enabled: true

  name: web

  type: ClusterIP

  url: http://alertmanager-operated:9093

  additionalHosts:

  commonName:

  externalPort: 9087

  internalPort: 9087



livenessProbe:

  initialDelaySeconds: 15

readinessProbe:

  initialDelaySeconds: 5





resources:

  limits:

    cpu: 100m

    memory: 128Mi

  requests:

    cpu: 10m

    memory: 8Mi





ставим первый:
helm upgrade —install -name telegram-bot-chat-id telegram-bot/ -f telegram-bot/values.yaml —namespace monitoring
и второй:
helm upgrade —install -name telegram-bot-test telegram-bot/ -f telegram-bot/values-test.yaml —namespace monitoring




далее создаём своё кастомное правило:




cat prometheus-alert-rule.yaml




apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

  annotations:

    meta.helm.sh/release-name: prometheus

    meta.helm.sh/release-namespace: monitoring

    prometheus-operator-validated: "true"

  labels:

    app: kube-prometheus-stack

    release: prometheus

  name: my-test-prometheus-alertmanager.rules

  namespace: monitoring

  selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/prometheusrules/my-test-prometheus-alertmanager.rules

spec:

  groups:

  - name: my-test-alertmanager.rules

    rules:

    - alert: EBNULSA_CONTAINER

      annotations:

        message: |

          CONTAINER_UMER

          Namespace: {{ $labels.namespace }} and

          Podname: {{ $labels.pod }}

      expr: sum_over_time(kube_pod_container_status_ready{namespace="my-site"}[5m])

        <1

      for: 1m

      labels:

        severity: critical

        team: namespace-my-site





и второе:




cat prometheus-alert-rule-test.yaml




apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

  annotations:

    meta.helm.sh/release-name: prometheus

    meta.helm.sh/release-namespace: monitoring

    prometheus-operator-validated: "true"

  labels:

    app: kube-prometheus-stack

    release: prometheus

  name: test-prometheus-alertmanager.rules

  namespace: monitoring

  selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/prometheusrules/test-prometheus-alertmanager.rules

spec:

  groups:

  - name: test-alertmanager.rules

    rules:

    - alert: EBNULSA_CONTAINER-namespace-test

      annotations:

        message: |

          CONTAINER_UMER

          Namespace: {{ $labels.namespace }} and

          Podname: {{ $labels.pod }}

      expr: sum_over_time(kube_pod_container_status_ready{namespace="test"}[5m])

        <1

      for: 1m

      labels:

        severity: critical

        team: namespace-test





тут обращаем внимание на разное название лейблов




team: namespace-my-site




и




team: namespace-test




согласно данным лейблам алертменеджер будет раскидывать в нужные группы.




смотрим что данные правила создались:




kubectl -n monitoring get prometheusrules.monitoring.coreos.com




NAME                                                              AGE

my-test-prometheus-alertmanager.rules                             19h

prometheus-kube-prometheus-alertmanager.rules                     57d

prometheus-kube-prometheus-etcd                                   57d

prometheus-kube-prometheus-general.rules                          57d

prometheus-kube-prometheus-k8s.rules                              57d

prometheus-kube-prometheus-kube-apiserver-availability.rules      57d

prometheus-kube-prometheus-kube-apiserver-slos                    57d

prometheus-kube-prometheus-kube-apiserver.rules                   57d

prometheus-kube-prometheus-kube-prometheus-general.rules          57d

prometheus-kube-prometheus-kube-prometheus-node-recording.rules   57d

prometheus-kube-prometheus-kube-scheduler.rules                   57d

prometheus-kube-prometheus-kube-state-metrics                     57d

prometheus-kube-prometheus-kubelet.rules                          57d

prometheus-kube-prometheus-kubernetes-apps                        57d

prometheus-kube-prometheus-kubernetes-resources                   57d

prometheus-kube-prometheus-kubernetes-storage                     57d

prometheus-kube-prometheus-kubernetes-system                      57d

prometheus-kube-prometheus-kubernetes-system-apiserver            57d

prometheus-kube-prometheus-kubernetes-system-controller-manager   57d

prometheus-kube-prometheus-kubernetes-system-kubelet              57d

prometheus-kube-prometheus-kubernetes-system-scheduler            57d

prometheus-kube-prometheus-node-exporter                          57d

prometheus-kube-prometheus-node-exporter.rules                    57d

prometheus-kube-prometheus-node-network                           57d

prometheus-kube-prometheus-node.rules                             57d

prometheus-kube-prometheus-prometheus                             57d

prometheus-kube-prometheus-prometheus-operator                    57d

test-prometheus-alertmanager.rules                                18h






далее правим конфиг алертменеджера, не забываем что в нашем случае это гит:
https://github.com/prometheus-community/helm-charts.git




правим файл:
helm-charts/charts/kube-prometheus-stack/values.yaml




alertmanager:

  ## Deploy alertmanager

  enabled: true

  apiVersion: v2

  serviceAccount:

    create: true

    name: ""

    annotations: {}

  podDisruptionBudget:

    enabled: false

    minAvailable: 1

    maxUnavailable: ""



  config:

    global:

      resolve_timeout: 5m

      smtp_smarthost: 10.230.144.56:25

    route:

       # receiver: 'telegram'

        receiver: 'email_unixadmins'

        routes:

        - receiver: "telegram"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            severity: "critical|warning"

          continue: true

        - receiver: "telegram"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            alertname: "Watchdog"

          continue: true

        - receiver: "email_unixadmins"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            severity: "critical"

          continue: true

        - receiver: "telegram-my-site"

          match_re:

            severity: "critical"

            team: "namespace-my-site"

        - receiver: "telegram-test"

          match_re:

            severity: "critical"

            team: "namespace-test"



    receivers:

        - name: 'telegram'

          webhook_configs:

              - send_resolved: true

#                url: 'http://alertmanager-bot:8080'

                url: 'http://alertmanager-bot-chat-id:9087/alert/-567616984'



        - name: 'telegram-my-site'

          webhook_configs:

              - send_resolved: true

                url: 'http://alertmanager-bot-for-my-site:9087/alert/-581835428'



        - name: 'telegram-test'

          webhook_configs:

              - send_resolved: true

                url: 'http://alertmanager-bot-test:9087/alert/-480100545'





        - name: 'email_unixadmins'

          email_configs:

              - to: 'admin1@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true

              - to: 'admin2@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true









обращаю внимание, что установить несколько типов severity можно в таком виде:




severity: «critical|warning»




запись вида:
continue: true
(по умолчанию она false) означает что после первого совпадения надо продолжать роутить сообщения




всё дальше можно апдейтить:




helm upgrade —install -name prometheus kube-prometheus-stack/ -f kube-prometheus-stack/values.yaml —namespace monitoring




6.2. настройка оповещений в telegram разграничение оповещений по группам (исключения уведомлений)




Вводная: есть админский чат и есть чат разработчиков. при настройке как в пункте 6.1 уведомления приходящие в чат разрабочиков дублируются и в чат админов.




данная ситуация происходит вообще потому, что alertmanager  со следующим конфигом:




  config:

    global:

      resolve_timeout: 5m

      smtp_smarthost: 10.230.144.56:25

    route:

       # receiver: 'telegram'

        receiver: 'email_unixadmins'

        routes:

        - receiver: "telegram-admins"

          group_wait: 10s

          repeat_interval: 1h

          match_re:

            severity: "critical|warning"

          continue: true

        - receiver: "telegram-admins"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            alertname: "Watchdog"

          continue: true



        - receiver: "telegram-terminal-soft"

          group_wait: 10s

          repeat_interval: 1h

          match_re:

            severity: "critical"

            team: "terminal-soft"

          continue: true





имеет настройку
continue: true  (по дефолту false)
благодаря которой уведомления попав под первое правило не прекращаются а отправляются дальше по route и отправляются по другим receiver (когда совпадают по label)




ВАЖНО!!!!!!!!!!!!!!  в записи:




          match_re:

            severity: "critical"

            team: "terminal-soft"




правила совпадения работают не как 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
а админский чат последний в списке.




теперь рассмотрим всё это по конфигам:




правило по которому будет срабатывать алерт:




test.rule.yml




apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

  annotations:

    meta.helm.sh/release-name: prometheus

    meta.helm.sh/release-namespace: monitoring

    prometheus-operator-validated: "true"

  labels:

    app: kube-prometheus-stack

    release: prometheus

  name: mega-mega24-cloud-prometheus-alertmanager.rules

  namespace: monitoring

  selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/prometheusrules/mega-mega24-cloud-prometheus-alertmanager.rules

spec:

  groups:

  - name: mega-mega24-cloud-alertmanager.rules

    rules:

    - alert: EBNULSA_CONTAINER

      annotations:

        message: |

          CONTAINER_UMER

          Namespace: {{ $labels.namespace }} and

          Podname: {{ $labels.pod }}

      expr: sum_over_time(kube_pod_container_status_ready{namespace="mega-mega24-cloud"}[2m])

        <1

      for: 1m

      labels:

        team: "terminal-soft"





тут обращаем внимание на наличие лейбла team: «terminal-soft» и отсутствие лейбла severity: critical




конфиг алерт менеджера:




cat helm-charts/charts/kube-prometheus-stack/values.yaml




  ## Alertmanager configuration directives

  ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file

  ##      https://prometheus.io/webtools/alerting/routing-tree-editor/

  ##



  config:

    global:

      resolve_timeout: 5m

      smtp_smarthost: 10.230.144.56:25

    route:

       # receiver: 'telegram'

        receiver: 'email_unixadmins'

        routes:



        - receiver: "email_unixadmins"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            severity: "critical"

          continue: true



        - receiver: "telegram-admins"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            alertname: "Watchdog"

          continue: true



        - receiver: "telegram-terminal-soft"

          group_wait: 10s

          repeat_interval: 1h

          match_re:

            team: "terminal-soft"

          continue: false



        - receiver: "telegram-admins"

          group_wait: 10s

          repeat_interval: 1h

          match_re:

            severity: "critical|warning"

          continue: true





    receivers:

        - name: 'telegram-admins'

          webhook_configs:

              - send_resolved: true

                url: 'http://telegram-admins-group:9087/alert/-1001441100259'



        - name: 'telegram-terminal-soft'

          webhook_configs:

              - send_resolved: true

                url: 'http://telegram-terminal-soft:9087/alert/-597056946'





        - name: 'email_unixadmins'

          email_configs:

              - to: 'user1@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true

              - to: 'user2@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true





тут видим что предпоследнее правило имеет вид:




— receiver: «telegram-terminal-soft»
group_wait: 10s
repeat_interval: 1h
match_re:
team: «terminal-soft»
continue: false




а последнее правило для работы дефолтных правил (которые есть в prometheus  по умолчанию)




— receiver: «telegram-admins»
group_wait: 10s
repeat_interval: 1h
match_re:
severity: «critical|warning»
continue: true




7.Проблема с prometheus-kube-proxy




столкнулся со следующей проблемой, после запуска прометеуса не отображаются метрики с kube-proxy





прикол в следующем, сам kube-proxy стартанул на 127,0,0,1




[root@kub-worker-2 ~]# netstat -ntpl | grep 10249

tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      2537/kube-proxy





а прометеус лезет на айпишник т.е. щимится на ноды а там ни кто не отвечает:
[root@kub-master-1 charts]# telnet 192.168.1.205 10249
Trying 192.168.1.205…
telnet: connect to address 192.168.1.205: Connection refused




что для исправления делаем, НА ВСЕХ НОДАХ правим:




[root@kub-master-1 charts]# vim /etc/kubernetes/kube-proxy-config.yaml
c
metricsBindAddress: 127.0.0.1:10249
на
metricsBindAddress: 0.0.0.0:10249




общий вид у файла такой:




apiVersion: kubeproxy.config.k8s.io/v1alpha1

kind: KubeProxyConfiguration

bindAddress: 0.0.0.0

clientConnection:

 acceptContentTypes:

 burst: 10

 contentType: application/vnd.kubernetes.protobuf

 kubeconfig: /etc/kubernetes/kube-proxy-kubeconfig.yaml

 qps: 5

clusterCIDR: 10.0.0.0/16

configSyncPeriod: 15m0s

conntrack:

 maxPerCore: 32768

 min: 131072

 tcpCloseWaitTimeout: 1h0m0s

 tcpEstablishedTimeout: 24h0m0s

enableProfiling: False

healthzBindAddress: 127.0.0.1

hostnameOverride: kub-master-1

iptables:

 masqueradeAll: False

 masqueradeBit: 14

 minSyncPeriod: 0s

 syncPeriod: 30s

ipvs:

 excludeCIDRs: []

 minSyncPeriod: 0s

 scheduler: rr

 syncPeriod: 30s

 strictARP: False

metricsBindAddress: 0.0.0.0:10249

mode: iptables

nodePortAddresses: []

oomScoreAdj: -999

portRange:

udpIdleTimeout: 250ms




далее перезапускаем:




[root@kub-master-1 charts]# kubectl delete pod -n kube-system kube-proxy-kub-master-1 kube-proxy-kub-master-2 kube-proxy-kub-master-3 kube-proxy-kub-worker-1 kube-proxy-kub-worker-2
pod «kube-proxy-kub-master-1» deleted
pod «kube-proxy-kub-master-2» deleted
pod «kube-proxy-kub-master-3» deleted
pod «kube-proxy-kub-worker-1» deleted
pod «kube-proxy-kub-worker-2» deleted




Проверяем доступность:




[root@kub-master-1 charts]# telnet 192.168.1.205 10249
Trying 192.168.1.205…
Connected to 192.168.1.205.
Escape character is ‘^]’.
^]
telnet> quit
Connection closed.




и как видим метрики теперь отображаются:





8.Настройка алерта для определённого namespace




У меня есть тестовый сервис:




cat my-site-ingress.yaml




---

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: my-ingress

  namespace: my-site

spec:

  rules:

  - host: test.ru  #тут указывается наш домен

    http:

      paths:  #список путей которые хотим обслуживать(он дефолтный и все запросы будут отправляться на бэкенд, т.е. на сервис my-service-apache)

      - backend:

          serviceName: my-service-apache  #тут указывается наш сервис

          servicePort: 80 #порт на котором сервис слушает

#        path: /  все запросы на корень '/' будут уходить на наш сервис





cat my-site-service.yaml




---

apiVersion: v1

kind: Service

metadata:

  name: my-service-apache # имя сервиса

  namespace: my-site

spec:

  ports:

  - port: 80  # принимать на 80

    targetPort: 80 # отправлять на 80

  selector:

    app: apache  #отправлять на все поды с данным лейблом

  type: ClusterIP





cat my-site.yaml




---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: my-deployment-apache

  namespace: my-site

spec:

  replicas: 1

  selector:

    matchLabels:

      app: apache # по вот этому лейблу репликасет цепляет под

# тут описывается каким мокаром следует обновлять поды

  strategy:

    rollingUpdate:

      maxSurge: 1  # указывает на какое количество реплик можно увеличить

      maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить

#т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под)

    type: RollingUpdate

## тут начинается описание контейнера

  template:

    metadata:

      labels:

        app: apache  # по вот этому лейблу репликасет цепляет под

    spec:

      containers:

        - image: httpd:2.4.43

          name: apache

          ports:

            - containerPort: 80

# тут начинаются проверки по доступности

          readinessProbe: # проверка готово ли приложение

            failureThreshold: 3 #указывает количество провалов при проверке

            httpGet:  # по сути дёргает курлом на 80 порт

              path: /

              port: 80

            periodSeconds: 10 #как часто должна проходить проверка (в секундах)

            successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок

            timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда

          livenessProbe: #проверка на жизнь приложения, живо ли оно

            failureThreshold: 3

            httpGet:

              path: /

              port: 80

            periodSeconds: 10

            successThreshold: 1

            timeoutSeconds: 1

            initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд



# тут начинается описание лимитов для пода

          resources:

            requests: #количество ресурсов которые резервируются для pod на ноде

              cpu: 60m

              memory: 200Mi

            limits: #количество ресурсов которые pod может использовать(верхняя граница)

              cpu: 120m

              memory: 300Mi





применяем
kubectl create ns my-site
kubectl apply -f my-site-ingress.yaml -f my-site-service.yaml -f my-site.yaml
проверяем




[root@kub-master-1 ~]# kubectl get pod -n my-site

NAME                                    READY   STATUS    RESTARTS   AGE

my-deployment-apache-859486bd8c-zk99f   1/1     Running   0          11m





как видим всё ок.
теперь сделаем так чтобы сервис постоянно падал и перезапускался, для этого подправим в деплойменте проверки(readinessProbe/livenessProbe) порта не 80 а 81:




cat my-site.yaml

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: my-deployment-apache

  namespace: my-site

spec:

  replicas: 1

  selector:

    matchLabels:

      app: apache # по вот этому лейблу репликасет цепляет под

# тут описывается каким мокаром следует обновлять поды

  strategy:

    rollingUpdate:

      maxSurge: 1  # указывает на какое количество реплик можно увеличить

      maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить

#т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под)

    type: RollingUpdate

## тут начинается описание контейнера

  template:

    metadata:

      labels:

        app: apache  # по вот этому лейблу репликасет цепляет под

    spec:

      containers:

        - image: httpd:2.4.43

          name: apache

          ports:

            - containerPort: 80

# тут начинаются проверки по доступности

          readinessProbe: # проверка готово ли приложение

            failureThreshold: 3 #указывает количество провалов при проверке

            httpGet:  # по сути дёргает курлом на 80 порт

              path: /

              port: 81

            periodSeconds: 10 #как часто должна проходить проверка (в секундах)

            successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок

            timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда

          livenessProbe: #проверка на жизнь приложения, живо ли оно

            failureThreshold: 3

            httpGet:

              path: /

              port: 81

            periodSeconds: 10

            successThreshold: 1

            timeoutSeconds: 1

            initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд



# тут начинается описание лимитов для пода

          resources:

            requests: #количество ресурсов которые резервируются для pod на ноде

              cpu: 60m

              memory: 200Mi

            limits: #количество ресурсов которые pod может использовать(верхняя граница)

              cpu: 120m

              memory: 300Mi





и применим:




kubectl apply -f my-site.yaml




как видим pod перезапускается:




[root@kub-master-1 ~]# kubectl get pod -n my-site

NAME                                    READY   STATUS    RESTARTS   AGE

my-deployment-apache-85978bf68f-mbwlm   0/1     Running   1          41s





но не может пройти проверки.




посмотрим что в метриках на prometheus:




применим promql запрос:




kube_pod_container_status_ready{namespace=»my-site»}[5m]




который смотрит статус контейнеров по namespace my-site за последние 5 минут.





как видим у нас 2 разных имени контейнера:
my-deployment-apache-859486bd8c-zk99f   (который был запущен ранее и с ним было всё нормально)
и
my-deployment-apache-85978bf68f-mbwlm (текущий, который был специально сломан через неправильные проверки)




теперь нам надо получить результат, были ли за последние 5 минуть незапущенные контейнеры, для этого используем следующий запрос:




sum_over_time(kube_pod_container_status_ready{namespace=»my-site»}[5m]) <1




который смотрит были ли контейнеры со статусом МЕНЬШЕ 1 (т.е. не запущенные) за 5 минут





для проверки можем увеличить время до 900 минут и глянем что он выведет:





как видим таких было 3 контейнера




возвращаем проверки в деплойменте ждём 5 минут и проверяем статус:





как видим за 5 минут упавших контейнеров не было.




теперь привяжем это к alertmanager.




правим имеющееся правила прометеуса:




kubectl -n monitoring edit prometheusrules prometheus-kube-prometheus-alertmanager.rules




и в общий список где перечисляются правила:




spec:

  groups:

  - name: alertmanager.rules

    rules:

    - alert: AlertmanagerConfigInconsistent

      annotations:

        message: |

          The configuration of the instances of the Alertmanager cluster `{{ $labels.namespace }}/{{ $labels.service }}` are out of sync.

          {{ range printf "alertmanager_config_hash{namespace="%s",service="%s"}" $labels.namespace $labels.service | query }}

          Configuration hash for pod {{ .Labels.pod }} is "{{ printf "%.f" .Value }}"

          {{ end }}

      expr: count by(namespace,service) (count_values by(namespace,service) ("config_hash",

        alertmanager_config_hash{job="prometheus-kube-prometheus-alertmanager",namespace="monitoring"}))

        != 1

      for: 5m

      labels:

        severity: critical

    - alert: AlertmanagerFailedReload

      annotations:

        message: Reloading Alertmanager's configuration has failed for {{ $labels.namespace

          }}/{{ $labels.pod}}.

      expr: alertmanager_config_last_reload_successful{job="prometheus-kube-prometheus-alertmanager",namespace="monitoring"}

        == 0

      for: 10m

      labels:

        severity: warning

    - alert: AlertmanagerMembersInconsistent

      annotations:

        message: Alertmanager has not found all other members of the cluster.

      expr: |-

        alertmanager_cluster_members{job="prometheus-kube-prometheus-alertmanager",namespace="monitoring"}

          != on (service) GROUP_LEFT()

        count by (service) (alertmanager_cluster_members{job="prometheus-kube-prometheus-alertmanager",namespace="monitoring"})

      for: 5m

      labels:

        severity: critical





добавляем наше:




    - alert: EBNULSA_CONTAINER

      annotations:

        message: CONTAINER_UMER

      expr: sum_over_time(kube_pod_container_status_ready{namespace="my-site"}[5m])

        <1

      for: 1m

      labels:

        severity: critical




выходим сохраняемся.




в прометеусе переходим на вкладку alerts и видим наше правило:





всё теперь можно снова ломать проверки в нашем деплойменте и проверять полетел ли алерт:





как видим полетел.




проверяем наш телеграм бот и видим:





в таком вот виде настраивается алертинг.




Теперь рассмотрим как нам добавлять свой алертинг а не править имеющийся.




смотрим имеющие правила:




[root@kub-master-1 ~]# kubectl -n monitoring get prometheusrules.monitoring.coreos.com

NAME                                                              AGE

prometheus-kube-prometheus-alertmanager.rules                     3d

prometheus-kube-prometheus-etcd                                   3d

prometheus-kube-prometheus-general.rules                          3d

prometheus-kube-prometheus-k8s.rules                              3d

prometheus-kube-prometheus-kube-apiserver-availability.rules      3d

prometheus-kube-prometheus-kube-apiserver-slos                    3d

prometheus-kube-prometheus-kube-apiserver.rules                   3d

prometheus-kube-prometheus-kube-prometheus-general.rules          3d

prometheus-kube-prometheus-kube-prometheus-node-recording.rules   3d

prometheus-kube-prometheus-kube-scheduler.rules                   3d

prometheus-kube-prometheus-kube-state-metrics                     3d

prometheus-kube-prometheus-kubelet.rules                          3d

prometheus-kube-prometheus-kubernetes-apps                        3d

prometheus-kube-prometheus-kubernetes-resources                   3d

prometheus-kube-prometheus-kubernetes-storage                     3d

prometheus-kube-prometheus-kubernetes-system                      3d

prometheus-kube-prometheus-kubernetes-system-apiserver            3d

prometheus-kube-prometheus-kubernetes-system-controller-manager   3d

prometheus-kube-prometheus-kubernetes-system-kubelet              3d

prometheus-kube-prometheus-kubernetes-system-scheduler            3d

prometheus-kube-prometheus-node-exporter                          3d

prometheus-kube-prometheus-node-exporter.rules                    3d

prometheus-kube-prometheus-node-network                           3d

prometheus-kube-prometheus-node.rules                             3d

prometheus-kube-prometheus-prometheus                             3d

prometheus-kube-prometheus-prometheus-operator                    3d





добавляем наше:




cat prometheus-alert-rule.yaml




apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

  annotations:

    meta.helm.sh/release-name: prometheus

    meta.helm.sh/release-namespace: monitoring

    prometheus-operator-validated: "true"

  labels:

    app: kube-prometheus-stack

    release: prometheus

  name: my-test-prometheus-alertmanager.rules

  namespace: monitoring

  selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/prometheusrules/my-test-prometheus-alertmanager.rules

spec:

  groups:

  - name: my-test-alertmanager.rules

    rules:

    - alert: EBNULSA_CONTAINER

      annotations:

        message: |

          CONTAINER_UMER

          Namespace: {{ $labels.namespace }} and

          Podname: {{ $labels.pod }}

      expr: sum_over_time(kube_pod_container_status_ready{namespace="my-site"}[5m])

        <1

      for: 1m

      labels:

        severity: critical





применяем:
[root@kub-master-1 ~]# kubectl apply -f prometheus-alert-rule.yaml




проверяем:




[root@kub-master-1 ~]# kubectl -n monitoring get prometheusrules.monitoring.coreos.com | grep my

my-test-prometheus-alertmanager.rules                             91m






как видим наше правило добавилось.




запись вида:
Namespace: {{ $labels.namespace }}
Podname: {{ $labels.pod }}




выведет имя неймспейса и имя пода.




в телеграме это будет отображаться следующим образом:





9.Добавление оповещений и по email




правим файл:
vim charts/kube-prometheus-stack/values.yaml




  ## Alertmanager configuration directives

  ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file

  ##      https://prometheus.io/webtools/alerting/routing-tree-editor/

  ##



  config:

    global:

      resolve_timeout: 5m

      smtp_smarthost: 10.20.44.56:25

    route:

       # receiver: 'telegram'

        receiver: 'email_unixadmins'

        routes:

        - receiver: "telegram"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            severity: "critical"

          continue: true

        - receiver: "telegram"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            alertname: "Watchdog"

          continue: true

        - receiver: "email_unixadmins"

          group_wait: 10s

          repeat_interval: 48h

          match_re:

            severity: "critical"

          continue: true

    receivers:

        - name: 'telegram'

          webhook_configs:

              - send_resolved: true

                url: 'http://alertmanager-bot:8080'



        - name: 'email_unixadmins'

          email_configs:

              - to: 'admin1@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true

              - to: 'admin2@test.ru'

                from: 'prod-vsrv-kuber-alertmanager@test.ru'

                require_tls: false

                send_resolved: true




smtp_smarthost: 10.20.44.56:25  это наш smtp хост через который мы шлём почту.




receiver: ’email_unixadmins’  — на него будут идти оповещения вне зависимости от критичности алерта, для остальных можно выставлять уровень критичности.




и применяем:




helm upgrade —install -name prometheus kube-prometheus-stack/ -f kube-prometheus-stack/values.yaml —namespace monitoring




10. Настройка графиков в grafana




создаём новый дашборд






переходим к созданию панели




она будет отображать только наш неймспейс terminal-soft
создадим панель которая будет отображать сколько процессорного времени использует namespace
запрос выглядит следующим образом:




sum(rate(container_cpu_usage_seconds_total{namespace=»terminal-soft»}[5m]))





настраиваем отображение:





сохраняем:





теперь добавим panel по использованию оперативной памяти в namespace terminal-soft




также создаём новую панель, и используем запрос:




sum(rate(container_memory_usage_bytes{namespace=»terminal-soft»}[5m]))





в левой колонке ставим параметр, в чём измеряем (в нашем случае в байтах)





и настраиваем отображаему легенду а именно минимальные максимальные значение и т.д.





всё можно сохраняться





как видим 2 графика у нас уже отображаются нормально:





теперь отобразим занятое дисковое пространство persistantvolume




создаём новую панель




запрос будет выглядеть следующим образом:
(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim=»$volume»} — kubelet_volume_stats_available_bytes{persistentvolumeclaim=»$volume»}) / kubelet_volume_stats_capacity_bytes{persistentvolumeclaim=»$volume»} * 100




у нас повилась переменная volume  рассмотрим как её создать:




переходим в настройки dasboard






добавим несколько переменных,
первая cluster  запрос:
label_values(kubelet_volume_stats_capacity_bytes, cluster)




не забываем ставить Hide Variables чтобы в панели он не отображался





вторая namespace, запрос:




label_values(kubelet_volume_stats_capacity_bytes{cluster=»$cluster», job=»kubelet», metrics_path=»/metrics»}, namespace)





и третья volume запрос:




label_values(kubelet_volume_stats_capacity_bytes{cluster=»$cluster», job=»kubelet», metrics_path=»/metrics», namespace=»$namespace»}, persistentvolumeclaim)





вот наши 3 переменные:





теперь смотрим на нашу панель:





добавляем legend в описании пишем {{namespace}} (чтоб отображался наш неймспейс)




также видим что вверху появились НЕ СКРЫТЫЕ переменные которые мы можем выбирать.




Отображение сети (входящий/исходящий трафик)




используем 2 метрики:
входящий трафик для namespace terminal soft:
sum(rate(container_network_receive_bytes_total{pod=~»deployment.+»,namespace=»terminal-soft»}[1m]))




исходящий трафик для namespace terminal soft:
sum(rate(container_network_transmit_bytes_total{pod=~»deployment.+»,namespace=»terminal-soft»}[1m]))







Отображение кодов ответа на nginx ingress controller




создаём ещё одну панель.




дёргаем метрику:




sum(increase(nginx_ingress_controller_request_duration_seconds_count{namespace=»terminal-soft»}[1m])) by (status) > 0




в качестве legend ставим
{{status}} code





можно сохранять.





ещё добавим несколько графиков для отображения количества ответов по статусам

200(2**)
300(3**)
400(4**)
500(5**)




создаём панель и добавляем запрос:
sum(increase(nginx_ingress_controller_requests{namespace=»terminal-soft»,status=~»2.*»}[1m]))





добавляем ещё несколько панелей запросы будут аналогичны первому:




sum(increase(nginx_ingress_controller_requests{namespace=»terminal-soft»,status=~»3.*»}[1m]))




sum(increase(nginx_ingress_controller_requests{namespace=»terminal-soft»,status=~»4.*»}[1m]))




sum(increase(nginx_ingress_controller_requests{namespace=»terminal-soft»,status=~»5.*»}[1m]))




по итогу у нас получился вот такой dasboard





рассмотрим ещё один дашборд где при выборе namespace будут отображаться Проц/оперативка/сеть  как на весь неймспейс так и на каждый под в отдельности





вот так оно будет выглядеть по итогу




переходим в настройки:





далее создаём переменные:





cluster
label_values(kube_pod_info, cluster)





namespace
label_values(kube_pod_info{cluster=»$cluster»}, namespace)





перейдём к настройке самих дашбордов — первый по перативке:





sum(rate(container_memory_usage_bytes{namespace=»$namespace»}[5m]))
all MEMORY in $namespace




sum(rate(container_memory_working_set_bytes{namespace=»$namespace», container!=»», image!=»»}[5m])) by (pod)
{{pod}}




далее проц





sum(rate(container_cpu_usage_seconds_total{namespace=»$namespace»}[5m]))
all CPU in $namespace




sum(rate(container_cpu_usage_seconds_total{namespace=»$namespace», container!=»», image!=»»}[5m])) by (pod)
{{pod}}




далее рассмотрим сеть:






sum(rate(container_network_receive_bytes_total{namespace=»$namespace»}[1m]))
INPUT in ALL $namespace




sum(rate(container_network_transmit_bytes_total{namespace=»$namespace»}[1m]))
OUTPUT in ALL $namespace




sum(rate(container_network_receive_bytes_total{namespace=»$namespace», container!=»», image!=»»}[5m])) by (pod)
input in {{pod}}




sum(rate(container_network_transmit_bytes_total{namespace=»$namespace», container!=»», image!=»»}[5m])) by (pod)
output in {{pod}}







Источник: https://sidmid.ru/kubernetes-запуск-prometheus-grafana-alertmanager-запуск-exporter-для-ingress-nginx-controller/#grafana



SRWare Iron: интересный кроссплатформенный веб-браузер

SRWare Iron: интересный кроссплатформенный веб-браузер

SRWare Iron: интересный кроссплатформенный веб-браузер

2022 год почти закончился, и между последние новости декабря связано с выпуски новой версии приложений, полезных и доступных для использования в GNU/Linux, мы обнаружили наличие Версия 108.0.5500.0 из Веб-браузер SRWare Iron.

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



Читать