从Nagios迁移到澳大利亚的Icinga2

大家好


我是Linux系统管理员,我于2015年凭独立的专业签证从俄罗斯移居到澳大利亚,但本文不会涉及如何让小猪成为拖拉机。 这些文章已经足够了(尽管如此,如果有兴趣的话,我也会写这篇文章),所以我想谈一谈在我作为linux-ops工程师在澳大利亚工作期间如何从一个系统开始移植监视另一个。 具体来说-Nagios => Icinga2。


本文部分是技术性的,部分是关于与人之间的沟通以及与文化和工作方法的差异相关的问题。


不幸的是,“ code”标签没有突出显示Puppet和yaml代码,因此我不得不使用“ plaintext”。


2016年12月21日上午,没有任何生病的迹象。 我像往常一样,在工作日的前半小时以未经注册的匿名方式阅读Habr,吸着咖啡,读了这篇文章


由于Nagios在公司中使用过,无需三思而后行,所以我在Redmine中创建了一张票证,并将链接扔到了常规聊天中,因为我认为这很重要。 该倡议甚至在澳大利亚也应受到惩罚,因此自从我发现这个问题以来,首席工程师就把这个问题挂在我身上。


来自Redmine的屏幕

在我们的部门中,在提出意见之前,习惯上提供至少一个替代方法,即使选择很明显,因此我从谷歌搜索当前总体上与哪些监视系统相关,因为在我上次工作的最后一个地方,我有自己的个人记录系统,非常原始,但仍然可以正常工作并完成分配给它的所有任务。 Python,圣彼得堡理工学院和地铁规则。 不,地铁很烂。 这是个人的(11年的工作经验),值得单独撰写,但现在不行了。


关于在当前位置更改基础结构配置的规则。 我们使用Puppet,Gitlab和基础架构原理作为代码,因此:


  • 通过手动修改虚拟机上的任何文件,无需通过SSH进行任何手动更改。 在三年的工作中,我已经多次接受这样的工作,这是一周前的最后一次,但我认为这不是最后一次。 好吧,实际上-修复配置中的一行,重新启动服务,看看问题是否已解决-10秒。 在Gitlab中创建一个新分支,推送更改,等待r10k在Puppetmaster上运行,运行Puppet --environment = mybranch,再等待几分钟,直到所有工作都完成-最少5分钟。
  • 任何更改都可以通过在Gitlab中创建合并请求来进行,您需要至少获得一名团队成员的批准。 团队领导的重大变更需要两到三个批准。
  • 所有更改都是以一种或另一种方式进行文本更改(因为Puppet清单,Hiera脚本和数据是文本),因此不鼓励使用二进制文件,并且需要充分的理由来批准它们。

因此,我查看的选项是:


  • Munin-如果基础架构中有10台以上的服务器,那么管理就会陷入困境(从本文开始 。我并不想检查它,所以我信服了)。
  • Zabbix-长期以来一直在俄罗斯留意,但后来对于我的工作来说是多余的。 在这里-由于使用Puppet作为配置管理器以及使用Gitlab作为版本控制系统而不得不删除。 据我了解,当时Zabbix将整个配置存储在数据库中,因此目前尚不清楚如何在当前条件下管理配置以及如何跟踪更改。
  • 从部门的情绪来看,普罗米修斯是我们最终要达到的目标,但是那时我无法掌握它,也无法证明一个真正可行的样本(概念证明),因此我不得不拒绝。
  • 还有其他几种选择,或者需要完全重新设计系统,或者处于起步阶段/被放弃,并且出于相同的原因而被拒绝。

最后,出于以下三个原因,我选择了Icinga2:


1-与Nrpe兼容(客户端服务运行对来自Nagios的命令的检查)。 这一点非常重要,因为当时我们有135台虚拟机(现在到2019年有165台)带有一堆自写服务/检查的虚拟机,而重做所有这些将是一个可怕的痔疮。
2-所有配置文件均为文本,可轻松编辑此内容,创建合并请求,并能够查看已添加或删除的内容。
3是一个活跃且不断发展的OpenSource项目。 我们非常喜欢OpenSource,并通过创建Pull Requests和Issues解决问题为OpenSource做出了切实可行的贡献。


让我们走吧,Icinga2。


我首先要面对的是同事们的惰性。 每个人都习惯于Nagios / Najios(尽管即使在这里他们也不能妥协如何发音)和CheckMK界面。 icinga界面看上去完全不同(这是减号),但是可以通过过滤器根据任何参数的字面意思灵活地配置所需的内容(这是一个加号,但我为此特别努力)。


筛选器

估计滚动条的大小与滚动字段的大小之比。


其次,每个人都习惯于在一台显示器上看到整个基础架构,因为CheckMk允许您使用多台Nagios主机,但是Icinga不知道该怎么做(事实上,它确实可以做到,但下面有更多介绍)。 另一种选择是叫做Thruk的东西,但是它的设计引起了所有团队成员的呕吐,除了一个人(提出这个问题的人(不是我))。


Thruk Firebox-团队一致决定

经过几天的头脑风暴,我提出了集群监视的想法,即在生产区域中有一个主控主机,而有两个下属-一个在开发/测试中,一个外部主机位于另一个提供商处,以便从客户或外部人员的角度监视我们的服务。观察者。 这种配置使我能够在一个基于Web的界面中查看所有问题,并且对自己也有效,但是Puppet ... Puppet的问题在于,主主机现在必须了解系统中的所有主机和服务/检查,并且必须在区域之间分配它们(dev-test,staging-prod,ext),但是通过Icinga API发送更改需要花费几秒钟,但是为所有主机编译所有服务的Puppet目录则需要花费几分钟。 尽管我已经多次解释了一切的运作方式以及为何花费如此长时间的原因,但这仍然归咎于我。


第三-一堆Snowflakes(雪花)-由于它们具有某些特殊之处而被从通用系统中剔除的东西,因此通用规则不适用于它们。 它是通过正面攻击来解决的-如果有警报,但实际上一切正常,那么您需要更深入地挖掘并理解为什么它会警告我,尽管应该这样做。 反之亦然-为什么Nagios恐慌而Icinga则不然。


第四-Nagios在这里为我工作了三年,最初对他的信任比对我新潮的行家系统的信任更大,因此每次Icinga引起恐慌时,直到Nagios对同一问题感到兴奋之前,没人做任何事情。 但是,很少有Icinga早于Nagios发出真正的警报,我认为这是一个严重的问题,我将在“结论”部分中进行讨论。


结果,调试被推迟了超过5个月(实际上计划于2018年6月28日-2018年12月3日),这主要是因为“奇偶校验”-当Nagios中有几项服务没有人谈论时,它会废弃过去几年我什么都没听到,但是现在他们无缘无故发出了暴击,我不得不解释为什么他们不在我的面板上,并且不得不将它们添加到Icinga中以“完成奇偶检查”(所有服务/检查在Nagios中对应于Icinga中的服务/支票)


实现方式:
首先是代码与数据之战,例如木偶风格。 所有数据(通常是所有数据)都应存放在希拉中,而别无其他。 所有代码都位于.pp文件中。 变量,抽象,函数-一切以pp开头。
结果,我们有一堆虚拟机(在撰写本文时为165个)和68个Web应用程序,需要对其SSL证书的运行状况和有效性进行监视。 但是由于历史上的痔疮,用于监视应用程序的信息来自单独的gitlab存储库,并且自Puppet 3起数据格式就没有改变,这带来了更多的配置困难。


应用程序的伪代码,请小心
define profiles::services::monitoring::docker_apps( Hash $app_list, Hash $apps_accessible_from, Hash $apps_access_list, Hash $webhost_defaults, Hash $webcheck_defaults, Hash $service_overrides, Hash $targets, Hash $app_checks, ) { #### APPS #### $zone = $name $app_list.each | String $app_name, Hash $app_data | { $notify_group = { 'notify_group' => ($webcheck_defaults[$zone]['notify_group'] + pick($app_data['notify_group'], {} )) } # adds notifications for default group (systems) + any group defined in int/pm_docker_apps.eyaml $data = merge($webhost_defaults, $apps_accessible_from, $app_data) $site_domain = $app_data['site_domain'] $regexp = pick($app_data['check_regex'], 'html') # Pick a regex to check $check_url = $app_data['check_url'] ? { undef => { 'http_uri' => '/' }, default => { 'http_uri' => $app_data['check_url'] } } $check_regex = $regexp ?{ 'absent' => {}, default => {'http_expect_body_regex' => $regexp} } $site_domain.each | String $vhost, Hash $vdata | { # Split an app by domains if there are two or more $vhost_name = {'http_vhost' => $vhost} $vars = $data['vars'] + $vhost_name + $check_regex + $check_url $web_ipaddress = is_array($vdata['web_ipaddress']) ? { # Make IP-address an array if it's not, because askizzy has 2 ips and it's an array true => $vdata['web_ipaddress'], false => [$vdata['web_ipaddress']], } $access_from_zones = [$zone] + $apps_access_list[$data['accessible_from']] # Merge default zone (where the app is defined) and extra zones if they exist $web_ipaddress.each | String $ip_address | { # For each IP (if we have multiple) $suffix = length($web_ipaddress) ? { # If we have more than one - add IP as a suffix to this hostname to avoid duplicating resources 1 => '', default => "_${ip_address}" } $octets = split($ip_address, '\.') $ip_tag = "${octets[2]}.${octets[3]}" # Using last octet only causes a collision between nginx-vip 203.15.70.94 and ext. ip 49.255.194.94 $access_from_zones.each | $zone_prefix |{ $zone_target = $targets[$zone_prefix] $nginx_vip_name = "${zone_prefix}_nginx-vip-${ip_tag}" # If it's a host for ext - prefix becomes 'ext_' (ext_nginx-vip...) $nginx_host_vip = { $nginx_vip_name => { ensure => present, target => $zone_target, address => $ip_address, check_command => 'hostalive', groups => ['nginx_vip',], } } $ssl_vars = $app_checks['ssl'] $regex_vars = $app_checks['http'] + $vars + $webcheck_defaults[$zone] + $notify_group if !defined( Profiles::Services::Monitoring::Host[$nginx_vip_name] ) { ensure_resources('profiles::services::monitoring::host', $nginx_host_vip) } if !defined( Icinga2::Object::Service["${nginx_vip_name}_ssl"] ) { icinga2::object::service {"${nginx_vip_name}_ssl": ensure => $data['ensure'], assign => ["host.name == $nginx_vip_name",], groups => ['webchecks',], check_command => 'ssl', check_interval => $service_overrides['ssl']['check_interval'], target => $targets['services'], apply => true, vars => $ssl_vars } } if $regexp != 'absent'{ if !defined(Icinga2::Object::Service["${vhost}${$suffix} regex"]){ icinga2::object::service {"${vhost}${$suffix} regex": ensure => $data['ensure'], assign => ["match(*_nginx-vip-${ip_tag}, host.name)",], groups => ['webchecks',], check_command => 'http', check_interval => $service_overrides['regex']['check_interval'], target => $targets['services'], enable_flapping => true, apply => true, vars => $regex_vars } } } } } } } } 

主机和服务配置代码看起来也很糟糕:


监控/ config.pp
 class profiles::services::monitoring::config( Array $default_config, Array $hostgroups, Hash $hosts = {}, Hash $host_defaults, Hash $services, Hash $service_defaults, Hash $service_overrides, Hash $webcheck_defaults, Hash $servicegroups, String $servicegroup_target, Hash $user_defaults, Hash $users, Hash $oncall, Hash $usergroup_defaults, Hash $usergroups, Hash $notifications, Hash $notification_defaults, Hash $notification_commands, Hash $timeperiods, Hash $webhost_defaults, Hash $apps_access_list, Hash $check_commands, Hash $hosts_api = {}, Hash $targets = {}, Hash $host_api_defaults = {}, ) { # Profiles::Services::Monitoring::Hostgroup <<| |>> # will be enabled when we move to icinga completely #### APPS #### case $location { 'int', 'ext': { $apps_by_zone = {} } 'pm': { $int_apps = hiera('int_docker_apps') $int_app_defaults = hiera('int_docker_app_common') $st_apps = hiera('staging_docker_apps') $srs_apps = hiera('pm_docker_apps_srs') $pm_apps = hiera('pm_docker_apps') + $st_apps + $srs_apps $pm_app_defaults = hiera('pm_docker_app_common') $apps_by_zone = { 'int' => $int_apps, 'pm' => $pm_apps, } $app_access_by_zone = { 'int' => {'accessible_from' => $int_app_defaults['accessible_from']}, 'pm' => {'accessible_from' => $pm_app_defaults['accessible_from']}, } } default: { fail('Please ensure the node has $location fact set (int, pm, ext)') } } file { '/etc/icinga2/conf.d/': ensure => directory, recurse => true, purge => true, owner => 'icinga', group => 'icinga', mode => '0750', notify => Service['icinga2'], } $default_config.each | String $file_name |{ file {"/etc/icinga2/conf.d/${file_name}": ensure => present, source => "puppet:///modules/profiles/services/monitoring/default_config/${file_name}", owner => 'icinga', group => 'icinga', mode => '0640', } } $app_checks = { 'ssl' => $services['webchecks']['checks']['ssl']['vars'], 'http' => $services['webchecks']['checks']['http_regexp']['vars'] } $apps_by_zone.each | String $zone, Hash $app_list | { profiles::services::monitoring::docker_apps{$zone: app_list => $app_list, apps_accessible_from => $app_access_by_zone[$zone], apps_access_list => $apps_access_list, webhost_defaults => $webhost_defaults, webcheck_defaults => $webcheck_defaults, service_overrides => $service_overrides, targets => $targets, app_checks => $app_checks, } } #### HOSTS #### # Profiles::Services::Monitoring::Host <<| |>> # This is for spaceship invasion when it's ready. $hosts_has_large_disks = query_nodes('mountpoints.*.size_bytes >= 1099511627776') $hosts.each | String $hostgroup, Hash $list_of_hosts_with_settings | { # Splitting site lists by hostgroups - docker_host/gluster_host/etc $list_of_hosts_in_group = $list_of_hosts_with_settings['hosts'] $hostgroup_settings = $list_of_hosts_with_settings['settings'] $merged_hostgroup_settings = deep_merge($host_defaults, $list_of_hosts_with_settings['settings']) $list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{ # Splitting grouplists by hosts # Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) { $vars_has_large_disks = { 'has_large_disks' => true } } else { $vars_has_large_disks = {} } $host_data = deep_merge($merged_hostgroup_settings, $host_settings) $hostgroup_settings_vars = pick($hostgroup_settings['vars'], {}) $host_settings_vars = pick($host_settings['vars'], {}) $host_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group']) $host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_notify_group}, $vars_has_large_disks)) # Merging vars separately $hostgroups = delete_undef_values([$hostgroup] + $host_data['groups']) profiles::services::monitoring::host{$host_name: ensure => $host_data['ensure'], display_name => $host_data['display_name'], address => $host_data['address'], groups => $hostgroups, target => $host_data['target'], check_command => $host_data['check_command'], check_interval => $host_data['check_interval'], max_check_attempts => $host_data['max_check_attempts'], vars => $host_data_vars, template => $host_data['template'], } } } if !empty($hosts_api){ # All hosts managed by API $hosts_api.each | String $zone, Hash $hosts_api_zone | { # Split api hosts by zones $hosts_api_zone.each | String $hostgroup, Hash $list_of_hosts_with_settings | { # Splitting site lists by hostgroups - docker_host/gluster_host/etc $list_of_hosts_in_group = $list_of_hosts_with_settings['hosts'] $hostgroup_settings = $list_of_hosts_with_settings['settings'] $merged_hostgroup_settings = deep_merge($host_api_defaults, $list_of_hosts_with_settings['settings']) $list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{ # Splitting grouplists by hosts # Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) { $vars_has_large_disks = { 'has_large_disks' => true } } else { $vars_has_large_disks = {} } $host_data = deep_merge($merged_hostgroup_settings, $host_settings) $hostgroup_settings_vars = pick($hostgroup_settings['vars'], {}) $host_settings_vars = pick($host_settings['vars'], {}) $host_api_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group']) $host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_api_notify_group}, $vars_has_large_disks)) $hostgroups = delete_undef_values([$hostgroup] + $host_data['groups']) if defined(Profiles::Services::Monitoring::Host[$host_name]){ $hostname = "${host_name}_from_${zone}" } else { $hostname = $host_name } profiles::services::monitoring::host{$hostname: ensure => $host_data['ensure'], display_name => $host_data['display_name'], address => $host_data['address'], groups => $hostgroups, target => "${host_data['target_base']}/${zone}/hosts.conf", check_command => $host_data['check_command'], check_interval => $host_data['check_interval'], max_check_attempts => $host_data['max_check_attempts'], vars => $host_data_vars, template => $host_data['template'], } } } } } #### END OF HOSTS #### #### SERVICES #### $services.each | String $service_group, Hash $s_list |{ # Service_group and list of services in that group $service_list = $s_list['checks'] # List of actual checks, separately from SG settings $service_list.each | String $service_name, Hash $data |{ $merged_defaults = merge($service_defaults, $s_list['settings']) # global service defaults + service group defaults $merged_data = merge($merged_defaults, $data) $settings_vars = pick($s_list['settings']['vars'], {}) $this_service_vars = pick($data['vars'], {}) $all_service_vars = delete_undef_values($service_defaults['vars'] + $settings_vars + $this_service_vars) # If we override default check_timeout, but not nrpe_timeout, make nrpe_timeout the same as check_timeout if ( $merged_data['check_timeout'] and ! $this_service_vars['nrpe_timeout'] ) { # NB: Icinga will convert 1m to 60 automatically! $nrpe = { 'nrpe_timeout' => $merged_data['check_timeout'] } } else { $nrpe = {} } # By default we use nrpe and all commands are run via nrpe. So vars.nrpe_command = $service_name is a default value # If it's server-side Icinga command - we don't need 'nrpe_command' # but there is no harm to have that var and the code is shorter if $merged_data['check_command'] == 'nrpe'{ $check_command = $merged_data['vars']['nrpe_command'] ? { undef => { 'nrpe_command' => $service_name }, default => { 'nrpe_command' => $merged_data['vars']['nrpe_command'] } } }else{ $check_command = {} } # Assembling $vars from Global Default service settings, servicegroup settings, this particular check settings and let's not forget nrpe settings. if $all_service_vars['graphite_template'] { $graphite_template = {'check_command' => $all_service_vars['graphite_template']} }else{ $graphite_template = {'check_command' => $service_name} } $service_notify = [] + pick($settings_vars['notify_group'], []) + pick($this_service_vars['notify_group'], []) # pick is required everywhere, otherwise becomes "The value '' cannot be converted to Numeric" $service_notify_group = $service_notify ? { [] => $service_defaults['vars']['notify_group'], default => $service_notify } # Assing default group (systems) if no other groups are defined $vars = $all_service_vars + $nrpe + $check_command + $graphite_template + {'notify_group' => $service_notify_group} # This needs to be merged separately, because merging it as part of MERGED_DATA overwrites arrays instead of merging them, so we lose some "assign" and "ignore" values $assign = delete_undef_values($service_defaults['assign'] + $s_list['settings']['assign'] + $data['assign']) $ignore = delete_undef_values($service_defaults['ignore'] + $s_list['settings']['ignore'] + $data['ignore']) icinga2::object::service {$service_name: ensure => $merged_data['ensure'], apply => $merged_data['apply'], enable_flapping => $merged_data['enable_flapping'], assign => $assign, ignore => $ignore, groups => [$service_group], check_command => $merged_data['check_command'], check_interval => $merged_data['check_interval'], check_timeout => $merged_data['check_timeout'], check_period => $merged_data['check_period'], display_name => $merged_data['display_name'], event_command => $merged_data['event_command'], retry_interval => $merged_data['retry_interval'], max_check_attempts => $merged_data['max_check_attempts'], target => $merged_data['target'], vars => $vars, template => $merged_data['template'], } } } #### END OF SERVICES #### #### OTHER BORING STUFF #### $servicegroups.each | $servicegroup, $description |{ icinga2::object::servicegroup{ $servicegroup: target => $servicegroup_target, display_name => $description } } $hostgroups.each| String $hostgroup |{ profiles::services::monitoring::hostgroup { $hostgroup:} } $notifications.each | String $name, Hash $settings |{ $assign = pick($notification_defaults['assign'], []) + $settings['assign'] $ignore = pick($notification_defaults['ignore'], []) + $settings['ignore'] $merged_settings = $settings + $notification_defaults icinga2::object::notification{$name: target => $merged_settings['target'], apply => $merged_settings['apply'], apply_target => $merged_settings['apply_target'], command => $merged_settings['command'], interval => $merged_settings['interval'], states => $merged_settings['states'], types => $merged_settings['types'], assign => delete_undef_values($assign), ignore => delete_undef_values($ignore), user_groups => $merged_settings['user_groups'], period => $merged_settings['period'], vars => $merged_settings['vars'], } } # Merging notification settings for users with other settings $users_oncall = deep_merge($users, $oncall) # Magic. Do not touch. create_resources('icinga2::object::user', $users_oncall, $user_defaults) create_resources('icinga2::object::usergroup', $usergroups, $usergroup_defaults) create_resources('icinga2::object::timeperiod',$timeperiods) create_resources('icinga2::object::checkcommand', $check_commands) create_resources('icinga2::object::notificationcommand', $notification_commands) profiles::services::sudoers { 'icinga_runs_ping_l2': ensure => present, sudoersd_template => 'profiles/os/redhat/centos7/sudoers/icinga.erb', } } 

我仍在研究这种面条,并尽可能进行改进。 但是,正是此代码使在Hiera中使用简单明了的语法成为可能:


资料
 profiles::services::monitoring::config::services: perf_checks: settings: check_interval: '2m' assign: - 'host.vars.type == linux' checks: procs: {} load: {} memory: {} disk: check_interval: '5m' vars: notification_period: '24x7' disk_iops: vars: notifications: - 'silent' cpu: vars: notifications: - 'silent' dns_fqdn: check_interval: '15m' ignore: - 'xenserver in host.groups' vars: notifications: - 'silent' iftraffic_nrpe: vars: notifications: - 'silent' logging: settings: assign: - 'logserver in host.groups' checks: rsyslog: {} nginx_limit_req_other: {} nginx_limit_req_s2s: {} nginx_limit_req_s2x: {} nginx_limit_req_srs: {} logstash: {} logstash_api: vars: notifications: - 'silent' 

所有检查均分为几组,每组都有默认设置,例如运行这些检查的位置和频率,发送给谁的通知。


在每个检查中,您都可以覆盖任何选项,最终所有这些都加起来成为所有检查整体的默认设置。 因此,这种面条是用config.pp编写的-所有默认设置都与组的设置合并,然后与每个单独的检查合并。


另外,一项非常重要的更改是可以使用设置中的功能,例如,更改端口,地址和url以检查http_regex的功能。


 http_regexp: assign: - 'host.vars.http_regex' - 'static_sites in host.groups' check_command: 'http' check_interval: '1m' retry_interval: '20s' max_check_attempts: 6 http_port: '{{ if(host.vars.http_port) { return host.vars.http_port } else { return 443 } }}' vars: notification_period: 'host.vars.notification_period' http_vhost: '{{ if(host.vars.http_vhost) { return host.vars.http_vhost } else { return host.name } }}' http_ssl: '{{ if(host.vars.http_ssl) { return false } else { return true } }}' http_expect_body_regex: 'host.vars.http_regex' http_uri: '{{ if(host.vars.http_uri) { return host.vars.http_uri } else { return "/" } }}' http_onredirect: 'follow' http_warn_time: 8 http_critical_time: 15 http_timeout: 30 http_sni: true 

这意味着-如果主机定义中存在http_port变量-则使用它,否则使用443。例如,jabber Web界面挂在9090,Unifi挂在7443。
http_vhost表示忽略DNS并使用此地址。
如果在主机中指定了uri,请继续执行,否则使用“ /”。


http_ssl传出一个有趣的故事-这种感染不想按需断开连接。 我愚蠢地在这行上绊了很长时间,直到我发现主机定义中的变量是:


 http_ssl: false 

替代表达


 if(host.vars.http_ssl) { return false } else { return true } 

作为错误 ,最后结果


 if(false) { return false } else { return true } 

也就是说,ssl检查始终处于活动状态。 通过替换语法来决定:


 http_ssl: no 

结论


优点:


  • 现在,我们拥有一个监控系统,而没有像过去7-8个月那样的两个监控系统,或者只有一个过时且脆弱的监控系统。
  • 主机/服务(检查)的数据结构现在(在我看来)更具可读性和可理解性。 对于其他人来说,这并不是很明显,所以我不得不在本地Wiki上剪几页来解释它的工作原理和编辑位置。
  • 可以使用变量和函数灵活配置检查,例如检查http_regexp,可以在主机设置中设置所需的模式,返回代码,URL和端口。
  • 有几个仪表板,您可以为每个仪表板定义自己的显示警报列表,并通过Puppet和合并请求进行管理。

缺点:


  • 团队成员的惯性-Nagios一直在工作,而且一直在工作,这使您的Isinga不断出错并放慢速度。 我怎么看这个故事? 而且,该死,它不会更新...(真正的问题是警报历史记录不会自动更新,只能通过F5进行更新)
  • 系统的惰性-当我在Web界面中单击“立即检查”时-执行的结果取决于火星的天气,尤其是需要数十秒才能完成的复杂服务。 类似的结果是正常现象。
  • 总的来说,根据两个系统并行工作的半年度统计,Nagios的工作速度总是比Icinga快,这让我很烦。 在我看来,有一些被计时器迷住的东西,每隔5:30就会进行一次5分钟的检查,或者类似的事情。
  • 如果您随时重新启动服务(systemctl重新启动icinga2)-当时正在进行的所有检查都会在屏幕上显示严重的<信号终止状态>警报,从侧面看,好像一切都掉了( 已确认错误)

但总的来说-它有效。

Source: https://habr.com/ru/post/zh-CN444060/


All Articles