Развертывание копий Zabbix на Ansible

от автора

Недавно выпала задача по развертке копий основного Zabbix-server на несколько машин, дабы хранить конфиги на разных серверах, да и еще всунуть это в CI/CD GitLab. Взял Ansible и начал писать плейбук.

Работа с установками на хосты Zabbix’а через Ansible

Сначала написал файл хостов с переменными, чтобы разделять установщики на разных семействах Linux(Debian, Ubuntu, RedHat):

[remote_zabbix:children] os_family_Debian os_family_RedHat os_family_Ubuntu py_script  ## current_host - переменная, значение = самому хосту(да, хост два раза прописать)  [py_script] #Скрипт, на котором будет запускаться скрипт для экспорта/импорта гита# current_host=  [os_family_Debian] #Хост на ОС Debian# current_host=  [os_family_RedHat] #Хост на ОС ReHat# current_host=  [os_family_Ubuntu] #Хост на ОС Ubuntu# current_host=  [os_family_Debian:vars] os_family_type=debian  [os_family_RedHat:vars] os_family_type=redhat  [os_family_Ubuntu:vars] os_family_type=ubuntu 

Написал обычный пинг серверов:

- name: Test Connection   hosts: remote_zabbix   become: yes    tasks:     - name: Ping server       ping:   tags:     - test_connection

После того, как я удостоверился, что хосты доступны, создал типичный шаблон для развертывания Zabbix (web, server и БД timescaledb на PostgreSQL) и вызвал его с ролью(run_docker-compose), где стопятся контейнеры со старым Zabbix’ом и БД, если они были подняты, и поднимаются заново в docker-compose:

- name: rm zabbix-containers   ansible.builtin.shell: docker ps --filter name=zabbix* -aq | xargs docker stop | xargs docker rm   ignore_errors: True - name: rm timescale container   ansible.builtin.shell: docker ps --filter name=timescale* -aq | xargs docker stop | xargs docker rm   ignore_errors: True - name: run zabbix-server   ansible.builtin.shell: cd /home && docker-compose up -d 

*Дабы не занимать много вашего времени и не делать длиннопост, прикреплю ссылку на репозиторий с файлами.

Далее я накатываю Zabbix-agent2, скачивая его пакеты с репозиториев, роль — install_agent2.service:

- name: Download agent2.service debian   get_url:     url: https://repo.zabbix.com/zabbix/6.2/debian/pool/main/z/zabbix-release/zabbix-release_6.2-4+debian10_all.deb     dest: ./zabbix-release_6.2-4+debian10_all.deb   when: os_family_type == "debian"  - name: Download agent2.service debian   shell: |      dpkg -i ./zabbix-release_6.2-4+debian10_all.deb     apt update   when: os_family_type == "debian"  - name: Install agent2.service debian   apt:     name: zabbix-agent2     update_cache: yes   when: os_family_type == "debian"  - name: Download agent2 redhat   yum:     name: https://repo.zabbix.com/zabbix/6.2/rhel/7/x86_64/zabbix-release-6.2-3.el7.noarch.rpm   when: os_family_type == "redhat"  - name: Yum clean all   shell: yum clean all   when: os_family_type == "redhat"  - name: Install agent2.service redhat   yum:     name: zabbix-agent2   when: os_family_type == "redhat" 

Накидываю уже шаблон для конфига агента вместо дефолтного файла конфигурации (тег configure_zabbix-agent2) и перезапустил службу этого агента ролью restart_agent2.service.

Скрипт для импорта/экспорта конфигурации

Далее наступила интересная часть, где я думал, как все-таки можно сделать импорт/экспорт конфигурации самого Zabbix, когда уже все поднято. Поискав в интернете, я уже почти расстроился, что придется делать либо запросами, либо писать самодельный API. Но, к счастью, я отыскал библиотеку для Python pyzabbix, где можно спокойно сделать экспорт конфига (как потом, спустя время, оказалось, что можно и импорт).

На вход два аргумента: host_from(откуда берем конфиг) и host_to(куда импортируем, подставляется в роли Ansible).

Написал функции для аутентификации (логин-пароль или токен):

# Auth Zabbix API to export def zabbix_auth_from(host_from):     zapi = ZabbixAPI("http://" + host_from)     zapi.login("Admin", "zabbix")     print("Connected to Zabbix API Version %s" % zapi.api_version())     return zapi   # Auth Zabbix API to import def zabbix_auth_to(url_link):     zapi = ZabbixAPI('http://' + url_link + ':8080')     zapi.login("Admin", "zabbix")     print("Connected to Zabbix API Version %s" % zapi.api_version())     return zapi

При успешном выполнении скрипта нам выведется в консоль отчет об успешном входе и выведет версию Zabbix:

Connected to Zabbix API Version %version%

Все хорошо, далее пишем функции для экспорта хостов, групп хостов и шаблонов:

# Func for make export files def write_export(name, config, export_format):     if config is not None:         print("Writing %s.%s" % (name, export_format))         with open("%s.%s" % (name, export_format), "w") as f:             f.write(config)   # Func for export hosts from main zabbix def export_hosts(zapi, namefile = "export_zabbix_hosts"):     hosts_ids = []     for item in zapi.host.get(output="extend"):         hosts_ids.append(int(item['hostid']))      config = zapi.configuration.export(         format="yaml", prettyprint=True, options={"hosts": hosts_ids}     )     write_export(namefile, config, "yml")   # Func for export templates from main zabbix def export_templates(zapi, namefile = "export_zabbix_templates"):     hosts_ids = []     for item in zapi.template.get(output="extend"):         hosts_ids.append(int(item['templateid']))      config = zapi.configuration.export(         format="yaml", prettyprint=True, options={"templates": hosts_ids}     )     write_export(namefile, config, "yml")   # Func for export host groups from main zabbix def export_host_groups(zapi, namefile = "export_zabbix_hostgroups"):     hosts_groups_ids = []     for item in zapi.hostgroup.get(output="extend"):         hosts_groups_ids.append(int(item["groupid"]))      config = zapi.configuration.export(         format="yaml", prettyprint=True, options={"groups": hosts_groups_ids}     )     write_export(namefile, config, "yml") 

Далее мы просто вызываем поочередно функции экспорта, куда передаем объект с аутентифицированным Zabbix по API:

def export_zabbix_conf(zapi):     export_templates(zapi)     export_hosts(zapi)     export_host_groups(zapi)

Все, что осталось — это импортировать созданные файлы экспорта в другие хосты Zabbix(здесь zapi — уже хост, на который копируем):

# Func for import config to copy of zabbix def import_config(zapi, filename, rules):     print("Import " + filename.split('_')[-1].split('.')[0])     export_file = open(filename, "r").read()     zapi.configuration['import'](format="yaml", source=export_file, rules=rules)   def import_zabbix_conf(zapi):     import_config(zapi, "export_zabbix_templates.yml", { "templates": { "createMissing": True, "updateExisting": True }})     import_config(zapi, "export_zabbix_hostgroups.yml", { "host_groups": {"createMissing": True }})     import_config(zapi, "export_zabbix_hosts.yml", {"hosts": { "createMissing": True, "updateExisting": True }})

Все хорошо, скопировался конфиг, но остается последняя проблема — агент не видит свой же хост и нам нужно в настройках заббикса переименовать наш хост с «Zabbix Server» на наш DNS, IP (я переключил на чтение DNS, мне так удобнее было):

# Func for rename localhost on zabbix-server, for find it by zabbix-agent2 def rename_local_host(zapi, remote_host):     try:         hid=zapi.host.get(search={'host': remote_host})[0]['hostid']     except:         hid=zapi.host.get(search={'host': 'Zabbix server'})[0]['hostid']     print('Change name')     zapi.host.update(hostid=hid, host=remote_host, name=remote_host)     print('Change DNS name')     iid = zapi.hostinterface.get(hostids=hid)[0]['interfaceid']     zapi.hostinterface.update(interfaceid=iid, dns=remote_host, useip=0, ip='сюда вписать наш IP')  

Внедрение в CI/CD GitLab

Ну здесь уже просто. Мы при создании заданий в плейбуке прописываем теги, которые уже вызываем в .gitlab-ci.yml:

image: ### Ansible 6.5.1 image  stages: - install/update_zabbix - configure_zabbix-agent2 - run_script  Install/update_Zabbix:   stage: install/update_zabbix   script:     - ansible-playbook ansible/zabbix_playbook.yml -i ansible/hosts/hosts.txt -vvvv -t install/update_zabbix   when: manual  Configure_Zabbix-Agent2:   stage: configure_zabbix-agent2   script:     - ansible-playbook ansible/zabbix_playbook.yml -i ansible/hosts/hosts.txt -vvvv -t configure_zabbix-agent2   when: manual  Export/import_zabbix_config:   stage: run_script   script:     - ansible-playbook ansible/zabbix_playbook.yml -i ansible/hosts/hosts.txt -vvvv -t run_sript -t restart-agent2   when: manual 

Итоги

Мы смогли через Ansible развернуть много копий Zabbix-server и Zabbix-agent2 со своими настройками, а также скопировать конфиг с основного Zabbix на другие хосты с помощью одной библиотеки pyzabbix.

Репозиторий: https://github.com/mksmp/export-config-zabbix-ansible


ссылка на оригинал статьи https://habr.com/ru/post/717814/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *