Цель

Заметки ИТ которые я не хочу потерять

menu_navigation

Kubernetes create cluster with kubespray

- Введение
  - Предварительная подготовка хранилищ на worker нодах.
  - Установка кластера
  - Установка elasticsearch и curator

      Установка elasticsearch
      Тюнинг elasticsearch
      Установка curator
  - Установка fluent-bit и kibana
      Установка fluent-bit
      Установка kibana
      Настройка kibana 
  - Установка prometheus и grafana
      Установка prometheus
      Настройка prometheus-server
      Уведомления prometheus-alertmanager

      Установка и настройка elasticsearch-exporter
  - Установка grafana
      Настройка grafana
      Уведомления в grafana
  - Установка утилиты kubectl на windows, для управления кластером
  - Добавление новой ноды в кластер

Введение


Kubernetes - это открытое программное обеспечение для автоматизации развёртывания, масштабирования и оркестрации контейнеров Docker. В СШ все сервисы являются docker-контейнерами, kubernetes был выбран как среда выполнения контейнеров. Данная среда может быть изменена, например, на кластер Openshift. Инсталляция кластера kubernetes осуществляется различными способами, здесь рассмотрен вариант установки с помощью kubespray. А также установка стека EFK+prometheus+grafana с помощью helm.
Схема HA кластера с тремя мастер нодами и тремя вычислительными нодами , количество вычислительных нод может быть увеличено. 
Минимальные требования для запуска кластера:
3 masters node
6 cpu core
sda disk 40G (lvm)
12G memory

3 workers node
8 cpu core
sda disk 40G (lvm)
sdb disk 120G (
без разметки)
16G memory

Минимальные требования подразумевают запуск кластера с сервисами СШ, prometheus, grafana, fluent-bit и kibana (Elasticsearch установлен отдельно), с возможностью запуска всех перечисленных сервисов при отказе одной вычислительной ноды.


Предварительная подготовка хранилищ на worker нодах.


Для использования prometheus, grafana, fluent-bit и kibana на каждой worker ноде необходимо смонтировать несколько дополнительных дисков.
Рекомендуемый объём дисков:
БД Prometheus не менее 12Гб
БД alertmanager не менее 12Гб
БД grafana не менее 12Гб
В нашем случае используется один физический диск sdb разбитый на логические диски.

Создаем физический том
pvcreate /dev/sdb
создаем группу томов из одного физического тома
vgcreate vg_kube /dev/sdb
создаем логические тома
lvcreate -L 12G -n lv_prometheus vg_kube
lvcreate -L 12G -n lv_alertmanager vg_kube
lvcreate -L 12G -n lv_grafana vg_kube
Создаем файловую систему ext4 на этих дисках
mkfs.ext4 /dev/vg_kube/lv_prometheus
mkfs.ext4 /dev/vg_kube/lv_alertmanager
mkfs.ext4 /dev/vg_kube/lv_grafana
создаем каталоги в /mnt
mkdir -p /mnt/disks/lv_prometheus
mkdir -p /mnt/disks/lv_alertmanager
mkdir -p /mnt/disks/lv_grafana
монтируем диски
mount /dev/vg_kube/lv_prometheus /mnt/disks/lv_prometheus
mount /dev/vg_kube/lv_alertmanager /mnt/disks/lv_alertmanager
mount /dev/vg_kube/lv_grafana /mnt/disks/lv_grafana
проверяем
mount | grep mnt
добавляем монтирование при автозагрузке
vi /etc/fstab
/dev/mapper/vg_kube-lv_prometheus /mnt/disks/lv_prometheus ext4 rw,seclabel,relatime,data=ordered 0 0
/dev/mapper/vg_kube-lv_alertmanager /mnt/disks/lv_alertmanager ext4 rw,seclabel,relatime,data=ordered 0 0
/dev/mapper/vg_kube-lv_grafana /mnt/disks/lv_grafana ext4 rw,seclabel,relatime,data=ordered 0 0


Установка кластера


Установка выполняется на любой машине с CentOS, не относящейся к будущему кластеру.
клонируем репозиторий Kubespray и перейдем в его каталог
yum -y install git
cd ~
git clone https://github.com/kubernetes-incubator/kubespray.git
cd kuberspray/
добавим репозитарий дополнительных пакетов
yum -y install epel-release
установим систему управления python пакетами
yum -y install python-pip
отредактируем файл requirements.txt
vi requirements.txt
ansible=2.8.1
установим необходимые python пакеты для kubespray
pip install -r requirements.txt
скопируем директорию inventory и перейдем в нее
cp -rfp inventory/sample inventory/mycluster
cd inventory/mycluster
отредактируем файл inventory.ini
vi inventory.ini
содержимое файла inventory.ini
[all]
k8s-02-node01 ansible_host=10.100.1.10 ip=10.100.1.10 ansible_user=centos
k8s-02-node02 ansible_host=10.100.1.11 ip=10.100.1.11 ansible_user=centos
k8s-02-node03 ansible_host=10.100.1.12 ip=10.100.1.12 ansible_user=centos
k8s-02-node04 ansible_host=10.100.1.13 ip=10.100.1.13 ansible_user=centos
k8s-02-node05 ansible_host=10.100.1.14 ip=10.100.1.14 ansible_user=centos
k8s-02-node06 ansible_host=10.100.1.15 ip=10.100.1.15 ansible_user=centos
 
[kube-master]
k8s-02-node01
k8s-02-node02
k8s-02-node03
 
[etcd]
k8s-02-node01
k8s-02-node02
k8s-02-node03
 
[kube-node]
k8s-02-node04
k8s-02-node05
k8s-02-node06
 
[k8s-cluster:children]
kube-master
kube-node
откроем файл group_vars/all/all.yml
В YAML файлах не поддерживается табуляция, только пробелы.
vi group_vars/all/all.yml
и включим возможность kubelet загружать модули ядра (раскомментировать и убрать отступ)
kubelet_load_modules: true
откроем файл /group_vars/k8s-cluster/addons.yml
vi /group_vars/k8s-cluster/addons.yml
и включим необходимые дополнительные сервисы, по умолчанию включен только dashboard (обратите внимание на отступы в yml файлах, модули должны быть без отступов)
dashboard_enabled: true
helm_enabled: true
metrics_server_enabled: true
local_volume_provisioner_enabled: true
ingress_nginx_enabled: true
ingress_nginx_host_network: true
ingress_nginx_nodeselector:
  beta.kubernetes.io/os: "linux"
ingress_nginx_tolerations:
  - key: "node-role.kubernetes.io/master"
    operator: "Equal"
    value: ""
    effect: "NoSchedule"
ingress_nginx_namespace: "ingress-nginx"
ingress_nginx_insecure_port: 80
ingress_nginx_secure_port: 443
откроем файл /group_vars/k8s-cluster/k8s-cluster.yml
vi k8s-cluster.yml
и включим все варианты аутентификации (обратите внимание на отступы в yml файлах, модули должны быть без отступов)
kube_oidc_auth: true
kube_basic_auth: true
kube_token_auth: true
конфигурация для установки готова, теперь необходимо подготовить ноды
создадим ключи ssh, утилита требует указать имя, путь файла и парольную фразу (есть возможность, оставить все по умолчанию и просто нажимать enter - продолжить)
ssh-keygen
перейдем в каталог ssh
cd ~/.ssh
скопируем публичные ключи на наши сервера (понадобится подтверждение на подключение и пароль от удаленного сервера)
ssh-copy-id centos@10.100.1.10
ssh-copy-id centos@10.100.1.11
ssh-copy-id centos@10.100.1.12
ssh-copy-id centos@10.100.1.13
ssh-copy-id centos@10.100.1.14
ssh-copy-id centos@10.100.1.15
вернемся в каталог inventory/mycluster
cd ~/kubespray/inventory/mycluster
создадим playbook для подготовки системы на всех нодах
vi prerequisites.yml 
содержимое файла prerequisites.yml
---
- name: setup node
  hosts: all
  tasks:
  - name: update all packages
    yum:
      name: '*'
      state: latest
      lock_timeout: 180
    become: yes
 
  - name: Disabling Swap on all nodes
    shell: swapoff -a
    become: yes
 
  - name: Commenting Swap entries in /etc/fstab
    replace:
     path: /etc/fstab
     regexp: '(.*swap*)'
     replace: '#\1'
    become: yes
 
  - name: install network tools
    yum:
      name: net-tools
    become: yes
 
  - name: install ntp
    yum:
      name: ntp
    become: yes
 
  - name: check ntpd service is running
    command: systemctl status ntpd
    register: result
    ignore_errors: True
    become: yes
 
  - name: configure and sync ntp
    command: "{{item}}"
    with_items:
      - systemctl enable ntpd
      - ntpdate -u pool.ntp.org
    when: result is failed
    ignore_errors: True
    become: yes
 
  - name: start service ntp, if not running
    service:
      name: ntpd
      state: started
    become: yes
 
  - name: enable IP forwarding, kernel br_netfilter, bridge firewall rule
    command: "{{item}}"
    with_items:
      - sysctl -w net.ipv4.ip_forward=1
      - modprobe br_netfilter
      - sysctl -p
      - sysctl -w net.bridge.bridge-nf-call-iptables=1
    become: yes
 
  - name: Enable IP Forwarding
    command: sysctl -w net.ipv4.ip_forward=1
    become: yes
 
  - name: Enabling bridge network filter
    command: sysctl -w net.bridge.bridge-nf-call-iptables=1
    become: yes
 
  - name: Enabling Bridge Firewall Rule
    command: sysctl -w net.bridge.bridge-nf-call-iptables=1
    become: yes
 
  - name: turn off firewall
    shell: "systemctl stop firewalld; systemctl disable firewalld"
    become: yes
 
  - name: add path to global path
    command: export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin/
    become: yes
 
  - replace:
      path: /etc/sudoers
      regexp: '^#\s*%wheel\s*ALL=\(ALL\)\s*NOPASSWD:\s*ALL$'
      replace: '%wheel        ALL=(ALL)       NOPASSWD: ALL'
    become: yes
 
  - replace:
      path: /etc/sudoers
      regexp: '^%wheel\s*ALL=\(ALL\)\s*ALL$'
      replace: '# %wheel  ALL=(ALL)       ALL'
    become: yes
 
  - lineinfile:
      path: /etc/sysconfig/network
      state: present
      line: 'HOSTNAME={{inventory_hostname}}.local'
    become: yes
 
  - lineinfile:
      path: /etc/hosts
      state: present
      line: '{{ansible_default_ipv4.address}}   {{inventory_hostname}}.local   {{inventory_hostname}}'
    become: yes
 
  - name: restart server
    command: /sbin/shutdown -r +1
    async: 0
    poll: 0
    ignore_errors: true
    become: yes
запустим подготовительный playbook
после ввода команды, будет запрос паролей ssh и sudo удаленных машин
время выполнения команды зависит от кол-ва хостов, пропускной способности канала, и вычислительных мощностей
ansible-playbook -u centos -i inventory.ini prerequisites.yml -b --ask-become-pass
запустим playbook установки кластера kubernetes
ansible-playbook -i inventory.ini --become --become-user=root ~/kubespray/cluster.yml --timeout=30 
если выполнение команды завершается с ошибками timeout, то увеличьте его, логирование настраивается в /kubespray/ansible.cfg
[defaults]
log_path=/var/log/ansible/kubespray.log
после успешного выполнения перейдите на страницу dashboard
Логин для входа: kube
Случайно сгенерированный пароль находится на любом мастере в /etc/kubernetes/users/known_users.csv

Установка elasticsearch и curator


Elasticsearch - это поисковый движок, с открытым исходным кодом, написанный на java.
Установка производится на отдельную машину, т.к. elasticsearch очень требователен к ресурсам. Рекомендуется не менее 16Gb RAM, кол-во CPU не менее 4.
подготовим диск для данных, в данном случае это второй физический диск sdb на 100Gb, обьем диска зависит от кол-ва поступающих данных, заложите возможность увеличения диска.
pvcreate /dev/sdb
создаем группу томов из физического тома
vgcreate vg_es /dev/sdb
создаем логический том
lvcreate -L 100G -n lv_es vg_es
Создаем файловую систему ext4 на этих дисках
mkfs.ext4 /dev/vg_es/lv_es
создаем каталоги в /mnt
mkdir -p /mnt/disks/lv_es
монтируем диски
mount /dev/vg_es/lv_es /mnt/disks/lv_es
проверяем
mount | grep mnt
добавляем монтирование при автозагрузке
vi /etc/fstab
/dev/mapper/vg_es-lv_es /mnt/disks/lv_es ext4 rw,seclabel,relatime,data=ordered 0 0
установим java
yum install -y java-1.8.0-openjdk
добавим пакет
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
cat > /etc/yum.repos.d/elasticsearch.repo<
[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF

Установка elasticsearch


установка пакета
yum install -y elasticsearch
запуск сервиса и добавление его в автозагрузку
systemctl start elasticsearch.service
systemctl enable elasticsearch.service
настройка elasticsearch производится в файле /etc/elasticsearch/elasticsearch.yml
vi /etc/elasticsearch/elasticsearch.yml
укажите путь к каталогу хранения данных и укажите интерфейс для прослушивания
path.data: /mnt/disks/lv_es
network.host: [_eth0_, _local_]
при использовании кластера укажите следующие параметры на каждой ноде
cluster.name: production
node.name: ${HOSTNAME}
node.master=true
node.data=true
discovery.zen.ping.unicast.hosts: ["ip_ ноды_1", " ip_ноды_2 "," ip_ноды_3 "]
сменим владельца каталога на elasticsearch
chown elasticsearch:elasticsearch /mnt/disks/lv_es
после внесения изменений перезапускаем сервис
systemctl restart elasticsearch.service


Тюнинг elasticsearch


Изменение размера JVM heap, рекомендуется 50% от физического размера RAM. Параметры использования памяти при инициализации и максимального количества памяти должны быть одинаковыми. 
vi /etc/elasticsearch/jvm.options
-Xms8g
-Xmx8g
отключение swap файла
swapoff -a
откройте файл загрузки томов
vi /etc/fstab
и закомментируйте строчку содержащую swap
#/dev/mapper/centos-swap swap
увеличение виртуальной памяти
sysctl -w vm.max_map_count=262144


Установка curator


curator - это сервис для периодической очистки индексов elasticsearch.
добавим пакет
rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
cat > /etc/yum.repos.d/curator.repo<
[curator-5]
name=CentOS/RHEL 7 repository for Elasticsearch Curator 5.x packages
baseurl=https://packages.elastic.co/curator/5/centos/7
gpgcheck=1
gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1
EOF
непосредственно установка
yum install -y elasticsearch-curator
создание каталога и конфигурационных файлов
mkdir /etc/curator
touch /etc/curator/config.yml
touch /etc/curator/action.yml
содержимое файла config.yml
client:
  hosts:
    - 127.0.0.1
  port: 9200
  url_prefix:
  use_ssl: False
  certificate:
  client_cert:
  client_key:
  ssl_no_validate: False
  http_auth:
  timeout: 30
  master_only: False
 
logging:
  loglevel: INFO
  logfile:
  logformat: default
  blacklist: ['elasticsearch', 'urllib3']
содержимое файла action.yml
actions:
  1:
    action: close
    description: >-
      Close indices older than 14 days (based on index name).
    options:
      ignore_empty_list: True
      delete_aliases: False
      disable_action: False
    filters:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 14
 
  2:
    action: delete_indices
    description: >-
      Delete indices older than 14 days (based on index name).
    options:
      ignore_empty_list: True
      disable_action: False
    filters:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 14
применение конфигурационных файлов
/usr/bin/curator --config /etc/curator/config.yml /etc/curator/action.yml
Добавим задание в cron, каждый день в час ночи
crontab -e
0 1 * * * /usr/bin/curator --config /etc/curator/config.yml /etc/curator/action.yml
откроем порт 9200 в firewall
firewall-cmd --zone=public --permanent --add-port=9200/tcp


Установка fluent-bit и kibana


Инициализируем Helm - это пакетный менеджер для kubernetes, по большей части используется для оркестровки yaml файлами.
все команды ниже вводить на любом мастер сервере.
helm init --service-account tiller


Установка fluent-bit


fluent-bit - это сервер пересылки журналов и обработчик журналов, который помогает собирать данные из разных источников, объединять их и затем отправлять их в elasticsearch.
необходимо указать ip адрес elasticsearch (в данном случае 10.100.1.101) 
helm install --namespace logging stable/fluent-bit --name fluent-bit \
--set backend.type=es \
--set backend.es.host=10.100.1.101,backend.es.tls_verify=off,backend.es.replace_dots=off


Установка kibana


kibana - это веб-приложение для визуализации и поиска логов.
необходимо указать DNS имя, в примере указан wildcard домен. И ip адрес elasticsearch (в данном случае 10.100.1.101) 
helm install --namespace logging stable/kibana --name kibana \
--set ingress.enabled=true,ingress.hosts[0]=kibana.10.100.1.13.nip.io \
--set env.ELASTICSEARCH_HOSTS=http://10.100.1.101:9200

Настройка kibana

переходим на адрес kibana.10.100.1.13.nip.io (ip адрес вычислительной ноды с wildcard доменом) выбираем "Managment"-"Create Index Patterns", вводим в поле паттерн logstash-*, на следующем шаге выбираем в поле “Time Filter field name” – @timestamp и жмем кнопку "Create Index pattern".
Поиск логов. На вкладке Discover в строке поиска введите название сервиса или запрос подобного формата: log-name AND start NOT 408893030505 (должно присутствовать слово log-name и start, но без числа 408893030505 в сообщении логов).

Сохранение логов. В kibana есть возможность сохранять результат запросов в csv формате, один из них создание визуализации в виде таблицы и последующее сохранение. На вкладке Visualize создайте визуализацию Data Table, выберите индекс logstash-*, выберите временной период, укажите необходимый запрос (например имя сервиса) и приведите метрики к следующему виду:
после внесения изменений нажмите кнопку Apply changes (выглядит как кнопка play) и Save (в верхнем части окна) для сохранения визуализации. В нижней части таблицы появится ссылки на загрузку, в форматах Raw или Formatted. Formatted загружает данные в формате таблицы. Raw загружает данные как представлено - дата, как unix time и т.д.


Установка prometheus и grafana


Установка prometheus


prometheus - это система мониторинга docker-контейнеров., она состоит из различных компонентов, в нашем случае используются следующие:
prometheus-server - считывает метрики и сохраняет их в темпоральной базе данных
prometheus-alertmanager - менеджер уведомлений
prometheus-pushgateway - компонент для приема метрик кратковременных процессов
prometheus-kube-state-metrics - снимает метрики с подов, сервисов и т.д.
prometheus-node-exporter - снимает метрики с хостов kubernetes
elasticsearch-exporter - агент который собирает метрики из elasticsearch и передает их prometheus
в helm чарте, необходимо указать DNS имя, в примере указан wildcard домен. и два персистентных хранилища (обьем диска зависит от кол-ва поступающих данных, заложите возможность увеличения диска), для prometheus и alertmanager (сервис уведомлений).

helm install --namespace logging stable/prometheus --name prometheus \
--set server.ingress.enabled=true,server.ingress.hosts[0]=prometheus.10.100.1.13.nip.io \
--set alertmanager.persistentVolume.enabled=true \
--set alertmanager.persistentVolume.storageClass=local-storage,alertmanager.persistentVolume.size=10Gi \
--set server.persistentVolume.enabled=true,server.persistentVolume.storageClass=local-storage,server.persistentVolume.size=10Gi
Настройка prometheus-server
Правила для отправки уведомлений настраиваются в Config Maps prometheus-server в блоке "rules:", в примере настроено несколько правил оповещений, при отказе хоста и при load average выше 1.5 и т.д.
Config Maps в интерфейсе kubernetes использует JSON формат, который не допускает разрыв строк и использует для переноса строки "\n", а в YAML синтаксе для многострочного текста используется пайп "|". Для удобства редактирования и конвертации JSON<->YAML можно использовать онлайн конвертор, например https://www.json2yaml.com/convert-yaml-to-json
groups:
- name: kubernetes
  rules:
  - alert: InstanceDown
    expr: up == 0
    for: 5m
    labels:
      severity: warning
    annotations:
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
      summary: "Instance {{ $labels.instance }} down"
  - alert: high_cpu_load_node
    expr: node_load15 > 1.5
    for: 30s
    labels:
      severity: warning
    annotations:
      summary: "Server under high load"
      description: "Host is under high load, the avg load 1m is at {{ $value}}. Reported by instance {{ $labels.instance }}."
  - alert: container_memory_above_1024
    expr: sum (container_memory_working_set_bytes{image!="",name=~"^k8s_.*"}) by (pod_name) > 1073741824
    for: 5m
    labels:
      severity: warning
    annotations:
      description: "Pod name {{ $labels.pod_name }} uses more than 1024Mb of RAM."
      summary: "Pod name {{ $labels.pod_name }} uses too much RAM."
  - alert: container_cpu_above_1
    expr:  sum(rate(container_cpu_usage_seconds_total{image!="",name=~"^k8s_.*"}[5m])) by (pod_name) > 1
    for: 5m
    labels:
      severity: warning
    annotations:
      description: "Pod name {{ $labels.pod_name }} uses more than 1 CPU."
      summary: "Pod name {{ $labels.pod_name }} uses too much CPU."

Уведомления prometheus-alertmanager

Для настройки отправки уведомлений на почту приведите к следующему виду Config Maps prometheus-alertmanager 
global: {}
receivers:
- name: default-receiver
  email_configs:
  - to: control@nafanasev.ru
    from: control@nafanasev.ru
    smarthost: mail.nafanasev.ru:465
    auth_username: control@nafanasev.ru
    auth_password: пароль
    auth_identity: control@nafanasev.ru
    require_tls: false
route:
  group_interval: 5m
  group_wait: 10s
  receiver: default-receiver
  repeat_interval: 3h



Установка и настройка elasticsearch-exporter


установим его в том же namespace logging, указав http адрес elasticsearch
helm install --namespace logging stable/elasticsearch-exporter --name elasticsearch-exporter \
--set es.uri=http://10.100.1.101:9200
в Config Maps для prometheus-server добавим в блок "prometheus.yml:" еще один scrape_configs
- job_name: elasticsearch-exporter
  static_configs:
  - targets:
    - elasticsearch-exporter:9108
туда же добавим правила оповещений для elasticsearch, в блоке "rules:". Будет создана новая группа правил с именем "elasticsearch"
- name: elasticsearch
  rules:
  - alert: Elastic_node_DOWN
    expr: elasticsearch_node_stats_up != 1
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "Elasticsearch instance status is not ready"
      description: "This server's Elasticsearch instance status DOWN"
  - alert: Elastic_Cluster_Health_RED
    expr: elasticsearch_cluster_health_status{color="red"} == 1
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Instance not all primary and replica shards are allocated in elasticsearch cluster"
      description: "Instance not all primary and replica shards are allocated in elasticsearch cluster"
  - alert: Elasticsearch_JVM_Heap_Too_High
    expr: elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} > 0.8
    for: 15m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node heap usage is high"
      description: "The heap in is over 80% for 15m."
  - alert: Elasticsearch_health_up
    expr: elasticsearch_cluster_health_up != 1
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "ElasticSearch node reports last scrape of the ElasticSearch cluster health failed"
      description: "ElasticSearch node reports last scrape of the ElasticSearch cluster health failed"
  - alert: Elasticsearch_Count_of_JVM_GC_Runs
    expr: rate(elasticsearch_jvm_gc_collection_seconds_count{}[5m]) > 5
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node reports count of JVM garbage collector runs > 5 per sec and has a value of {{ $value }}"
      description: "ElasticSearch node reports count of JVM garbage collector runs > 5 per sec and has a value of {{ $value }}"
  - alert: Elasticsearch_GC_Run_Time
    expr: rate(elasticsearch_jvm_gc_collection_seconds_sum[5m]) > 0.3
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node reports garbage collector run time in seconds > 0.3 sec and has a value of {{ $value }}"
      description: "ElasticSearch node reports garbage collector run time in seconds > 0.3 sec and has a value of {{ $value }}"
  - alert: Elasticsearch_json_parse_failures
    expr: elasticsearch_cluster_health_json_parse_failures > 0
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node reports json parse failures > 0 and has a value of {{ $value }}"
      description: "ElasticSearch node reports json parse failures > 0 and has a value of {{ $value }}"
  - alert: Elasticsearch_breakers_tripped
    expr: rate(elasticsearch_breakers_tripped{}[5m]) > 0
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node reports breakers tripped > 0 and has a value of {{ $value }}"
      description: "ElasticSearch node reports breakers tripped > 0 and has a value of {{ $value }}"
  - alert: Elasticsearch_health_timed_out
    expr: elasticsearch_cluster_health_timed_out > 0
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "ElasticSearch node reports Number of cluster health checks timed out > 0 and has a value of {{ $value }}"
      description: "ElasticSearch node reports Number of cluster health checks timed out > 0 and has a value of {{ $value }}"

Установка grafana


grafana - инструмент визуализации для prometheus.
необходимо указать DNS имя, в примере указан wildcard домен. и персистентное хранилище для grafana (обьем диска зависит от кол-ва поступающих данных, заложите возможность увеличения диска).
helm install --namespace logging stable/grafana --name grafana \
--set ingress.enabled=True,ingress.hosts[0]=grafana.10.100.1.13.nip.io \
--set rbac.create=true \
--set persistence.enabled=true,persistence.storageClassName=local-storage,persistence.size=10Gi
получить пароль для admin можно в свойствах контейнера, или в терминале контейнера в переменой GF_SECURITY_ADMIN_PASSWORD или командой на мастере
kubectl get secret --namespace logging grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

Настройка grafana

Войдите в веб-интерфейс grafana.10.100.1.13.nip.io, выберете "Add data source" - "Prometheus", введите URL - http://prometheus-server.logging.svc.cluster.local и нажмите "Save & Test", появится сообщение "Data source is working"
Далее выберете вкладку "Dashboard" и импортируйте все предложенные дашборды.
Для добавления новых дашбордов выберете "Dashboards" - Manage - Import и вставьте ссылку или id дашборда или json файл, полученные на сайте https://grafana.com/grafana/dashboards
Популярный dashboard для мониторинга kubernetes - Cluster Monitoring for Kubernetes by Pivotal Observability - https://grafana.com/grafana/dashboards/10000 
Dashboard для мониторинга подов в kubernetes - Pod Stats & Info by karstensiemer https://grafana.com/grafana/dashboards/10518
Dashboard для мониторинга elasticsearch - ElasticSearch by infinity https://grafana.com/grafana/dashboards/2322
Любой дашборд можно отредактировать, для этого зайдите в его "Dashboard setting" и выберете "Make editable" и сохраните изменения. После чего в панелях появится кнопка Edit.
Уведомления в grafana
в Config Maps для grafana добавьте следующие строки для блока [smtp]
[smtp]
enabled = true
host = mail.nafanasev.ru:465
user = control
password = пароль
skip_verify = true
from_address = control@nafanasev.ru
пароль не должен содержать символы "#" и ";"
в веб-интерфейсе последовательно нажмите Alerting - Notification channels - Add New channel и добавьте имя канала и email адреса получателей.


Установка утилиты kubectl на windows, для управления кластером


после установки кластера необходимо забрать файл из любой мастер ноды /etc/kubernetes/admin.conf
скачать https://storage.googleapis.com/kubernetes-release/release/v1.14.0/bin/windows/amd64/kubectl.exe
в командной строке перейти в папку куда вы скопировали файл admin.conf и добавить переменную
set KUBECONFIG=admin.conf 
проверка покажет ваши хосты
kubectl get nodes 
создаем прокси туннель с кластером
kubectl proxy


Добавление новой ноды в кластер


на новой ноде меняем имя хоста
hostnamectl set-hostname k8s-02-node07
systemctl restart systemd-hostnamed
на любой linux машине, не относящейся к кластеру, с установленным ansible, создаем ssh ключ и копируем на новую ноду
ssh-keygen
cd ~/.ssh
ssh-copy-id centos@10.100.1.16
редактируем ansible файл inventory.ini
[all]
k8s-02-node01 ansible_host=10.100.1.10 ip=10.100.1.10 ansible_user=centos
k8s-02-node02 ansible_host=10.100.1.11 ip=10.100.1.11 ansible_user=centos
k8s-02-node03 ansible_host=10.100.1.12 ip=10.100.1.12 ansible_user=centos
k8s-02-node04 ansible_host=10.100.1.13 ip=10.100.1.13 ansible_user=centos
k8s-02-node05 ansible_host=10.100.1.14 ip=10.100.1.14 ansible_user=centos
k8s-02-node06 ansible_host=10.100.1.15 ip=10.100.1.15 ansible_user=centos
k8s-02-node07 ansible_host=10.100.1.16 ip=10.100.1.16 ansible_user=centos
 
[kube-master]
k8s-02-node01
k8s-02-node02
k8s-02-node03
 
[etcd]
k8s-02-node01
k8s-02-node02
k8s-02-node03
 
[kube-node]
k8s-02-node04
k8s-02-node05
k8s-02-node06
k8s-02-node07
 
[k8s-cluster:children]
kube-master
kube-node
запускаем подготовительный плейбук (содержимое файла prerequisites.yml выше)
sudo ansible-playbook -i inventory.ini -u centos -k prerequisites.yml -b --ask-become-pass 
запускаем playbook ~/kuberspray/scale.yml
sudo ansible-playbook -i inventory.ini -u centos -k scale.yml --ask-become-pass 
на мастере создаем token доступа
kubeadm token create --print-join-command 
вывод команды
kubeadm join 10.100.1.10:6443 --token 9tgd0g.90hwyjiafe6267mm --discovery-token-ca-cert-hash 
sha256:a568507ac9b2ca4735b2b2d63b4464694f410f3d711a78dc829a3ba808f54bb7 
на ноде выполняем
kubeadm join 10.100.1.10:6443 --token 9tgd0g.90hwyjiafe6267mm --discovery-token-ca-cert-hash \
sha256:a568507ac9b2ca4735b2b2d63b4464694f410f3d711a78dc829a3ba808f54bb7 
ставим label для новой ноды
kubectl label node k8s-02-node07 node-role.kubernetes.io/node= 


2 комментария: