Thank you for reading this post, don't forget to subscribe!
что у нас имеется.
1 тачка с ansible
3 тачки под мастеров
1 тачка под воркер
192.168.1.177 - ansible
192.168.1.201 - kub-master-201
192.168.1.202 - kub-master-202
192.168.1.203 - kub-master-203
192.168.1.204 - kub-worker-204
Клонируем репо Kubespray на сервер, где у нас стоит ansible:
[root@ansible ~]# git clone https://github.com/kubernetes-incubator/kubespray.git
Доставляем пакеты на ansible:
[root@ansible ~]# cd kubespray/
[root@ansible kubespray]# pip install -r requirements.txt
[root@ansible kubespray]# pip install -U jinja2
Идем в скачанную директорию kubespray и создаем следующий файл:
vim inventory/sample/hosts.ini
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[root@ansible kubespray]# <strong>cat inventory/sample/hosts.ini</strong> # ## Configure 'ip' variable to bind kubernetes services on a # ## different ip than the default iface # ## We should set etcd_member_name for etcd cluster. The node that is not a etcd member do not need to set the value, or can set the empty string value. [all] kub-master-201 ansible_host=192.168.1.201 ip=192.168.1.201 kub-master-202 ansible_host=192.168.1.202 ip=192.168.1.202 kub-master-203 ansible_host=192.168.1.203 ip=192.168.1.203 kub-worker-204 ansible_host=192.168.1.204 ip=192.168.1.204 # node1 ansible_host=95.54.0.12 # ip=10.3.0.1 etcd_member_name=etcd1 # node2 ansible_host=95.54.0.13 # ip=10.3.0.2 etcd_member_name=etcd2 # node3 ansible_host=95.54.0.14 # ip=10.3.0.3 etcd_member_name=etcd3 # node4 ansible_host=95.54.0.15 # ip=10.3.0.4 etcd_member_name=etcd4 # node5 ansible_host=95.54.0.16 # ip=10.3.0.5 etcd_member_name=etcd5 # node6 ansible_host=95.54.0.17 # ip=10.3.0.6 etcd_member_name=etcd6 # ## configure a bastion host if your nodes are not directly reachable # bastion ansible_host=x.x.x.x ansible_user=some_user [kube-master] kub-master-201 kub-master-202 kub-master-203 [etcd] kub-master-201 kub-master-202 kub-master-203 [kube-node] kub-worker-204 [calico-rr] [k8s-cluster:children] kube-master kube-node calico-rr |
[/codesyntax]
Далее устанавливаем необходимые нам параметры в
vim inventory/sample/group_vars/k8s-cluster/addons.yml
1 2 3 4 |
dashboard_enabled: true # включаем dasboard helm_enabled: true local_volume_provisioner_enabled: true ingress_nginx_enabled: true |
Далее правим
vim inventory/sample/group_vars/all/all.yml
1 2 3 4 5 |
upstream_dns_servers - 8.8.8.8 - 8.8.4.4 #тут указываем наши днс сервера, я использую гугловые, можно оставить по умолчанию. ниже указываем наш прокси если он используется http_proxy: "http://proxy_ip:3128" https_proxy: "http://proxy_ip:3128" |
Здесь можно почитать про переменные для Kubespray:
https://github.com/kubernetes-sigs/kubespray/blob/master/docs/vars.md
теперь заходим на все ноды и ставим sshpass
yum install sshpass
в одну команду это будет так:
[root@ansible kubespray]# for i in `cat inventory/sample/hosts.ini | awk -F 'ip=' '{print $2}' | grep -v etc | grep -v ^$`; do ssh -t root@$i "yum install sshpass -y"; done
Далее запускаем плейбук:
ansible-playbook -u root -i inventory/sample/hosts.ini cluster.yml -b --ask-pass
Разворачивается от 20 до 40 минут.
После проверяем что у нас все в состоянии Ready:
kubectl get nodes
kubectl get pod -A
1 2 3 4 5 6 |
[root@kub-master-201 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION kub-master-201 Ready master 14m v1.18.4 kub-master-202 Ready master 13m v1.18.4 kub-master-203 Ready master 13m v1.18.4 kub-worker-204 Ready <none> 12m v1.18.4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
[root@kub-master-201 ~]# kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE ingress-nginx ingress-nginx-controller-ctxn8 1/1 Running 0 12m kube-system calico-kube-controllers-766d894b44-x9p6r 1/1 Running 0 12m kube-system calico-node-645pd 1/1 Running 1 12m kube-system calico-node-8vvc2 1/1 Running 1 12m kube-system calico-node-stbpk 1/1 Running 1 12m kube-system calico-node-xmfpp 1/1 Running 1 12m kube-system coredns-dff8fc7d-pfrg4 1/1 Running 0 11m kube-system coredns-dff8fc7d-rqgxn 1/1 Running 0 11m kube-system dns-autoscaler-d9fdd58df-n4xs5 1/1 Running 0 11m kube-system kube-apiserver-kub-master-201 1/1 Running 0 14m kube-system kube-apiserver-kub-master-202 1/1 Running 0 13m kube-system kube-apiserver-kub-master-203 1/1 Running 0 13m kube-system kube-controller-manager-kub-master-201 1/1 Running 0 14m kube-system kube-controller-manager-kub-master-202 1/1 Running 0 13m kube-system kube-controller-manager-kub-master-203 1/1 Running 0 13m kube-system kube-proxy-b75wx 1/1 Running 0 13m kube-system kube-proxy-pm7bh 1/1 Running 0 13m kube-system kube-proxy-tm6jj 1/1 Running 0 12m kube-system kube-proxy-z9wll 1/1 Running 0 13m kube-system kube-scheduler-kub-master-201 1/1 Running 0 14m kube-system kube-scheduler-kub-master-202 1/1 Running 0 13m kube-system kube-scheduler-kub-master-203 1/1 Running 0 13m kube-system kubernetes-dashboard-57777fbdcb-7rp68 1/1 Running 0 11m kube-system kubernetes-metrics-scraper-54fbb4d595-mms6w 1/1 Running 0 11m kube-system local-volume-provisioner-bfs98 1/1 Running 0 11m kube-system local-volume-provisioner-m62cr 1/1 Running 0 11m kube-system local-volume-provisioner-tp6vs 1/1 Running 0 11m kube-system local-volume-provisioner-xv5l6 1/1 Running 0 11m kube-system nginx-proxy-kub-worker-204 1/1 Running 0 12m kube-system nodelocaldns-lnspc 1/1 Running 0 11m kube-system nodelocaldns-qh8jj 1/1 Running 0 11m kube-system nodelocaldns-v2pp2 1/1 Running 0 11m kube-system nodelocaldns-wx4qr 1/1 Running 0 11m |
Затем URL Dashboard:
kubectl cluster-info
https://192.168.1.201:6443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
Получаем токен:
kubectl describe secret $(kubectl get secret | grep cluster-admin | awk '{print $1}')
Берем который для dashboard, идем по ссылке и вставляем его в форму:
Далее может возникнуть возникнуть ошибка: kubernetes dashboard unknown server error (404)
Решается она удалением dashboard 1.10 и установкой dashboard 2.0:
kubectl delete deployments kubernetes-dashboard -n kube-system
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc2/aio/deploy/recommended.yaml
Переходим по тому же URL, вставляем токен и все работает без ошибок
======================================================================================================
Расширенная установка с prometheus, grafana, fluent-bit и kibana Elasticsearch
требования для запуска кластера:
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 разбитый на логические диски.
Создаем физический том
1 |
pvcreate /dev/sdb |
создаем группу томов из одного физического тома
1 |
vgcreate vg_kube /dev/sdb |
создаем логические тома
1 2 3 |
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 на этих дисках
1 2 3 |
mkfs.ext4 /dev/vg_kube/lv_prometheus mkfs.ext4 /dev/vg_kube/lv_alertmanager mkfs.ext4 /dev/vg_kube/lv_grafana |
создаем каталоги в /mnt
1 2 3 |
mkdir -p /mnt/disks/lv_prometheus mkdir -p /mnt/disks/lv_alertmanager mkdir -p /mnt/disks/lv_grafana |
монтируем диски
1 2 3 |
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
1 2 3 |
/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
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[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 |
[/codesyntax]
откроем файл 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 файлах, модули должны быть без отступов)
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 |
[/codesyntax]
откроем файл /group_vars/k8s-cluster/k8s-cluster.yml
vi k8s-cluster.yml
и включим все варианты аутентификации (обратите внимание на отступы в yml файлах, модули должны быть без отступов)
1 2 3 |
kube_oidc_auth: true kube_basic_auth: true kube_token_auth: true |
конфигурация для установки готова, теперь необходимо подготовить ноды
создадим ключи ssh, утилита требует указать имя, путь файла и парольную фразу (есть возможность, оставить все по умолчанию и просто нажимать enter - продолжить)
ssh-keygen
перейдем в каталог ssh
cd ~/.ssh
скопируем публичные ключи на наши сервера (понадобится подтверждение на подключение и пароль от удаленного сервера)
1 2 3 4 5 6 |
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
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
--- - 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 |
[/codesyntax]
запустим подготовительный 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
1 2 |
[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
добавим пакет
1 2 3 4 5 6 7 8 9 10 11 12 |
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
укажите путь к каталогу хранения данных и укажите интерфейс для прослушивания
1 2 |
path.data: /mnt/disks/lv_es network.host: [_eth0_, _local_] |
при использовании кластера укажите следующие параметры на каждой ноде
1 2 3 4 5 |
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
1 |
vi /etc/elasticsearch/jvm.options |
1 2 |
-Xms8g -Xmx8g |
1 |
swapoff -a |
1 |
vi /etc/fstab |
1 |
#/dev/mapper/centos-swap swap |
1 |
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
1 2 3 4 5 6 7 8 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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'] |
[/codesyntax]
содержимое файла action.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
ctions: 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 |
[/codesyntax]
применение конфигурационных файлов
/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 файлами.
все команды ниже вводить на любом мастер сервере.
1 |
<span lang="EN-US">helm init --service-account tiller</span> |
Установка 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
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
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." |
[/codesyntax]
Уведомления prometheus-alertmanager
Для настройки отправки уведомлений на почту приведите к следующему виду Config Maps prometheus-alertmanager
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 |
[/codesyntax]
Установка и настройка elasticsearch-exporter
установим его в том же namespace logging, указав http адрес elasticsearch
1 2 |
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
[codesyntax lang="php"]
1 2 3 4 |
- job_name: elasticsearch-exporter static_configs: - targets: - elasticsearch-exporter:9108 |
[/codesyntax]
туда же добавим правила оповещений для elasticsearch, в блоке "rules:". Будет создана новая группа правил с именем "elasticsearch"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
- 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 }}" |
[/codesyntax]
Установка 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]
1 2 3 4 5 6 7 |
[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 и добавить переменную
1 |
set KUBECONFIG=admin.conf |
проверка покажет ваши хосты
1 |
kubectl get nodes |
создаем прокси туннель с кластером
1 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[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 |
[/codesyntax]
запускаем подготовительный плейбук (содержимое файла 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=