Мониторинг 3PAR с помощью скриптов в Zabbix

от автора

Привет! На связи Андрей Лебедев, системный администратор Cloud4Y. Хочу с вами поделиться одним из вариантов настройки мониторинга СХД.

На СХД 3PAR, к сожалению, отсутствует мониторинг по SNMP, так как на FTS, к примеру. Часть проблем можно отлавливать с помощью SNM Trap, но в целом собирать так метрики нельзя. Зато можно использовать авторизацию по SSH и официальный модуль от HPE. В данной статье покажу пример использование модулей Posh‑SSH + HPE3PARToolKit через скрипт для сбора различных метрик, вывод их в файл и дальнейшую передачу на Zabbix Server.

Помимо мониторинга с помощью скриптов существует ещё как минимум два способа мониторинга 3PAR:

  • Grafana + официальный скрипт HPE

  • SNMP Trap

Предлагаю разобрать мониторинг через скрипты в Zabbix. Для такого мониторинга необходимо установить модули PowerShell: PoshSSH и HPE3PARToolKit. Минимально необходимая версия PowerShell — 5.1. Проверить версию PowerShell можно командой host или $PSVersionTable

Установка модулей

Install-Module -Name Posh-SSH  Install-Module -Name HPEStoragePowerShellToolkit

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

Save-Module –Name Posh-SSH –Path C:\PS\

Копируем модули по пути C:\Program Files\WindowsPowerShell\Modules и проверяем, что модули установлены:

Get-Module -Name Posh-SSH,HPEStoragePowerShellToolkit -ListAvailable

На примере скрипта по мониторингу VLUN рассмотрим составляющие скрипта. Для получения данных через PS необходима УЗ на 3PAR с минимальной ролью «Browse». В первой части скрипта выполняется сбор суммы всех томов под одним и тем же VV:

$Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress ip_адрес_3PAR -SANUserName «Имя пользователя 3PAR» -SANPassword «пароль»     $dataVlun = Get-StatVlun -SANConnection $Connection1 -Iteration 1 -vvSum     $removessh = ($Connection1 | Close-Connection)      $data = @()      $dataVlun | ForEach-Object {          $3parexport = @{}          $3parexport["{#NAMEVLUN}"] = $_.VVName                  $data += $3parexport      }      $exportdata = @{}     $exportdata["data"] = $data      $exportdata | ConvertTo-Json -Compress -Depth 10 | Out-File -FilePath "Вывод в файл" 

Скрипт подсоединяется на 3PAR через SSH, выполняет команду Get-StatVlun в 1 итерацию и записывает сумму всех томов одного и того же Virtual Volume в переменную. Далее через цикл идёт сбор томов в пустую переменную, и в конце данные сжимаются а вывод записывается в файл.

Вторая часть скрипта выполняет сбор метрик по каждому тому 3PAR. При сравнении вывода через CLI и непосредственно на самом 3PAR была обнаружена небольшая несостыковка в данных. Из-за того, что в вывод через CLI добавляются столбцы r/w_Cur, r/w_Avg и r/w_Max, происходит смещение столбцов. 

Так значение операций ввода-вывода будет равняться столбцу r/w_Cur, а не I/O_Cur, KB_Cur равняется I/O_Cur, Svt_Cur = KB_Cur.

$Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress ip_адрес_3PAR -SANUserName «Имя пользователя 3PAR» -SANPassword «пароль»     $dataVlun = Get-StatVlun -SANConnection $Connection1 -Iteration 1 -vvSum -rw      $removessh = ($Connection1 | Close-Connection)       $3parexport = @{}     $3parexport_write = @{}     $3parexport_read = @{}     $3parexport_total = @{}      $dataVlun | ForEach-Object {         $exportport = ($_.Host)+($_.Port)+($_.VVName)         If ($_."r/w" -eq "t"){             If (-Not $3parexport.ContainsKey($exportport)) {             $3parexport_total[$exportport] = @{                 "RW" = $_."r/w"                 "KBCur" = $_.KB_Cur                 "SVTCur" = $_.Svt_Cur                 "IOCur" = $_."I/O_Cur"                 "RWCur" = $_."r/w_Cur"             }           }         }                        If ($_."r/w" -eq "r"){            If (-Not $3parexport.ContainsKey($exportport)) {             $3parexport_read[$exportport] = @{                 "RW" = $_."r/w"                 "KBCur" = $_.KB_Cur                 "SVTCur" = $_.Svt_Cur                 "IOCur" = $_."I/O_Cur"                 "RWCur" = $_."r/w_Cur"             }           }         }                        If ($_."r/w" -eq "w"){            If (-Not $3parexport.ContainsKey($exportport)) {             $3parexport_write[$exportport] = @{                 "RW" = $_."r/w"                 "KBCur" = $_.KB_Cur                 "SVTCur" = $_.Svt_Cur                 "IOCur" = $_."I/O_Cur"                 "RWCur" = $_."r/w_Cur"             }           }         }                             }     $3parexport_read | ConvertTo-Json -Compress -Depth 10 | Out-File -FilePath "Вывод в файл"     $3parexport_write | ConvertTo-Json -Compress -Depth 10 | Out-File -FilePath "Вывод в файл"     $3parexport_total | ConvertTo-Json -Compress -Depth 10 | Out-File -FilePath "Вывод в файл" 

Происходит авторизация по SSH, выполнение команды Get-StatVlun -Iteration 1 -vvSum -rw
Ключи:

-rw выводит данные по каждому тому на чтение, запись и суммарно
RW – записывает в себя чтение\запись или сумму. В данном примере записывает сумму чтения + запись по каждому тому.
KBcur – текущее время обслуживания в мс
IOCur – текущее количество КБ в секунду
RWcur – текущее количество операций ввода-вывода в секунду

В конце получаем 3 файла – на чтение, на запись и суммарно.

Добавление в Zabbix

По ссылке можно найти готовый шаблон для Zabbix, где собраны некоторые элементы данных и автообнаружение (CPU, VLUN, VV, PortCheck, Disk). Шаблон под версию 7.0 и выше.

А ниже — примеры скриптов мониторинга:

CPU
    ####################################################     ################## 3PAR CPU Node #################     ####################################################  $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS $dataCPU = Get-StatCPU -SANConnection $Connection1 -Iteration 1  $removessh = ($Connection1 | Close-Connection)  $data = @()  $dataCPU | ForEach-Object {      $3parexport = @{}      $3parexport["{#NODENUM}"] = $_."node"              $data += $3parexport      }  $exportdata = @{} $exportdata["data"] = $data  $exportdata | ConvertTo-Json -Compress -Depth 10 | Out-File -FilePath "Вывод в файл"    #################################################### ################## 3PAR CPU  ################# ####################################################      $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataCPU = Get-StatCPU -SANConnection $Connection1 -Iteration 1     $removessh = ($Connection1 | Close-Connection)     $3parCPU = @{}     $dataCPU | ForEach-Object {         $NodeCPU = $_.node         If ($_.cpu -eq "total"){          If (-Not $3parCPU.ContainsKey($NodeCPU)) {             $3parCPU[$NodeCPU] = @{                 "cpu" = $_.cpu                 "user" = $_.user                 "system" = $_.sys                 "idle" = $_.idle             }         }       }    }       $3parCPU | ConvertTo-Json -Depth 10 -Compress | Out-File -FilePath "Вывод в файл" 

Ports
    ####################################################     ################## 3PAR port Check #################     ####################################################      $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataPort = Get-HostPorts | Select-Object -SkipLast 1      $removessh = ($Connection1 | Close-Connection)      $data = @()      $dataPort | ForEach-Object {          $3parexport = @{}          $3parexport["{#DEVICE}"] = $_.Device         $3parexport["{#MODE}"] = $_.Mode         $3parexport["{#STATE}"] = $_.State         $3parexport["{#NODEWWN}"] = $_.Node_WWN         $3parexport["{#PORTWWN}"] = $_.Port_WWN         $3parexport["{#TYPE}"] = $_.Type         $3parexport["{#PROTOCOL}"] = $_.Protocol         $3parexport["{#LABEL}"] = $_.Label         $3parexport["{#PARTNER}"] = $_.Partner                   $data += $3parexport      }      $exportdata = @{}     $exportdata["data"] = $data      $exportdata | ConvertTo-Json -Depth 10 | Out-File -FilePath "Вывод в файл"       ####################################################     ################## 3PAR port Data ##################     ####################################################      $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataPort = Get-HostPorts | Select-Object -SkipLast 1     $removessh = ($Connection1 | Close-Connection)      $3parStatPort = @{}     $dataPort | ForEach-Object {         $portname = $_.Device         If (-Not $3parStatPort.ContainsKey($portname)) {             $3parStatPort[$portname] = @{                 "MODE" = $_.Mode                 "STATE" = $_.State                 "NODEWWN" = $_.Node_WWN                 "PORTWWN" = $_.Port_WWN                 "TYPE" = $_.Type                 "PROTOCOL" = $_.Protocol                 "LABEL" = $_.Label                 "PARTNER" = $_.Partner             }         }     }     $3parStatPort | ConvertTo-Json -Depth 10 | Out-File -FilePath "Вывод в файл"      ####################################################     ################## 3PAR stat port ##################     ####################################################      $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $data = Get-StatPort -SANConnection $Connection1 -Iteration 1     $removessh = ($Connection1 | Close-Connection)     $3parStatPort = @{}     $data | ForEach-Object {         $portname = $_.Port         If (-Not $3parStatPort.ContainsKey($portname)) {             $3parStatPort[$portname] = @{                 "KBCur" = $_.KB_Cur                 "SvtCur" = $_.Svt_Cur                 "IOCur" = $_."I/O_Cur"                 "IOSzCur" = $_.IOSz_Cur             }         }     }     $3parStatPort | ConvertTo-Json -Depth 10 | Out-File -FilePath "Вывод в файл" 

VV
    ####################################################     ################## 3PAR VV check #################     ####################################################       $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataVV = Get-VVList     $removessh = ($Connection1 | Close-Connection)      $data = @()      $dataVV | ForEach-Object {          $3parexport = @{}          $3parexport["{#ID}"] = $_.Id         $3parexport["{#PROV}"] = $_.Prov         $3parexport["{#NAME}"] = $_.Name         $3parexport["{#TYPE}"] = $_.Type         $3parexport["{#COPYOF}"] = $_.CopyOf         $3parexport["{#BSID}"] = $_.BsId         $3parexport["{#RD}"] = $_.Rd         $3parexport["{#STATE}"] = $_."-Detailed_State-"         $3parexport["{#SNP}"] = $_.Snp         $3parexport["{#USR}"] = $_.Usr         $3parexport["{#VSIZE}"] = $_.VSize                   $data += $3parexport      }      $exportdata = @{}     $exportdata["data"] = $data      $exportdata | ConvertTo-Json -Depth 10 -Compress | Out-File -FilePath "Вывод в файл"           ####################################################         ################## 3PAR VV stat #################         ####################################################        $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataVV = Get-StatVv -SANConnection $Connection1 -Iteration 1     $removessh = ($Connection1 | Close-Connection)     $3parStatVV = @{}     $3parStatVV = @{}     $dataVV | ForEach-Object {         $VVname = $_.VVname         If (-Not $3parStatVV.ContainsKey($VVname)) {             $3parStatVV[$VVname] = @{                 "KBCUR" = $_.KB_Cur                 "SVTCUR" = $_.Svt_Cur                 "IOSZCUR" = $_.IOSz_Cur                 "IOCUR" = $_."I/O_Cur"             }         }     }     $3parStatVV | ConvertTo-Json -Depth 10 -Compress | Out-File -FilePath "Вывод в файл"           ####################################################         ################## 3PAR VV List #################         ####################################################       $Connection1 = New-PoshSshConnection -ArrayNameOrIPAddress $3paripaddress -SANUserName $VC_USER -SANPassword $VC_PASS     $dataVVList = Get-VVList     $removessh = ($Connection1 | Close-Connection)     $3parVVList = @{}     $dataVVList | ForEach-Object {         $VVname = $_.Name         If (-Not $3parVVList.ContainsKey($VVname)) {             $3parVVList[$VVname] = @{                 "ID" = $_.Id                 "PROV" = $_.Prov                 "USED" = $_.Usr                 "TOTAL" = $_.VSize                 "ADM" = $_.Adm                 "SNP" = $_.Snp                 "STATE" = $_."-Detailed_State-"                 "RD" = $_.Rd             }         }     }     $3parVVList | ConvertTo-Json -Depth 10 -Compress | Out-File -FilePath "Вывод в файл" 

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

UserParameter=3par1StatVlunNewTotal[*],type Путь_до_файла  UserParameter=3par1StatVlunNewRead[*],type Путь_до_файла UserParameter=3par1StatVlunNewWrite[*],type Путь_до_файла UserParameter=3par1StatVlunCheck[*],type Путь_до_файла

После перезапускаем агента, добавляем шаблон 3PAR на Zabbix server и пользуемся.

Это довольно простое решение, оно не оптимально, но работает. Если у вас есть идеи, как ещё можно реализовать процессы мониторинга, с интересом послушаю.

Спасибо за внимание!


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


Комментарии

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

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