博文|Zabbix从单点到无宕机集群,质的改变!

2021-06-22 19:39:16 浏览数 (1)

王会新 | 宏时数据技术工程师

  • Zabbix5.0 认证工程师,精通Zabbix开源监控系统架构,参与过国内多家银行、保险、证券、制造业客户的Zabbix监控实施。
  • Zabbix5.0中文手册官方译者。

Zabbix proxy允许跨区域跨网段监控,DMZ (隔离区),甚至用以下示例也是常见的解决方法。例如,使用proxy代理将被动检查“转变”为主动检查,或从Zabbix server向proxy代理移动部分负载。

通常情况下如图所示:

多个区域Zabbix Proxy代理负责各自区域的主机,而Zabbix Server直接监控proxy代理组合的主机。在此设置下,完全没有冗余。可以使用专门为Zabbix server开发的Linux实用程序来构建HA集群。

一、代理集群

如果用Linux作为proxy代理,那么可以采用与Zabbix server相同的实用程序实现HA,并为proxy代理构建集群。虽然有可能实现,但这令配置更为复杂,需要静态IP,动态IP,额外的安装包更多防火墙规则与SELinux策略等等。

这样,由于proxy代理使用虚拟IP地址通信, proxy代理对于agents而言是“透明的”。在Zabbix server中来自proxy代理通信将通过VIP完成。

但是该配置不是最简单的,我们无法知道如果出现问题,不是正在使用的Zabbix Proxy是否会启动。当故障转移发生时,集群配置将启动Zabbix Proxy守护进程。

二、无集群配置代理

如果不想配置使用proxie代理集群时,那么需要找到另外一种解决方案,以便在需要时进行故障切换。

请看下图:

这种方式下,我们就有了两个proxy代理,他们完全是彼此独立运行,而且两个proxy代理的守护进程都在运行并向Zabbix Server报告,因此我们知道它们在按照预期运行。

如果Zabbix Proxy 1-a停止运行,无论出现任何原因,我们都需要切换到Zabbix Proxy 1-b。此proxy代理的添加在Zabbix Agent的配置文件中的“Server=”和“ServerActive=”参数,因此没有问题, Zabbix Agent将继续运行:

然而,你可能已经注意到,proxy代理在默认情况下每秒都会向Zabbix server发送检索到的值(在Proxy配置中,DataSenderFrequency=1),但它们仅每小时向Zabbix server请求一次Configdata(在Proxy配置中,ConfigFrequency=3600)。当然,可以将此值调整为每秒一次,那么从proxy 1-a到1-b的故障平滑切换。但论及性能,这是非常不合需要的,所以必须为其找到解决方法。

另一个问题是在Zabbix server前端的一个主机可以连接到一个Proxy而不是多个。这意味着,即使设法在一秒内更新Proxy配置,仍然必须以某种方式将每个主机从Proxy 1-a移动到Proxy 1-b,以便进行监控。

三、工作流和配置

如果创建一种不同的方式将主机从Proxy 1-a切换到Proxy 1-b,那么必须使用针对Zabbix server的API来调用完成。通常会使用某种脚本语言(Python, Bash, Perl等)进行调用。为了获得正确的流程,需要定义以下几个步骤:

  • 登录Zabbix server来执行API调用
  • 获得Proxy 1-a的主机ID
  • 获得Proxy 1-b的主机ID
  • 将所有主机从Proxy 1-a切换至Proxy 1-b
  • 确保Zabbix Server配置已更新
  • 确保Zabbix Proxy配置已更新

当然,获取Proxy 1-a和1-b(步骤2和3)的主机ID可以在完全静态地情况下完成,即在脚本中提供名称。这种方式仅适用于两个proxy,如果有更多proxy代理,必须创建更多名称不同的脚本,而这不是你想要的。为了让此过程更加灵活,必须在Zabbix配置上进行优化。

四、Zabbix配置

1. 设想

假设Zabbix内有代表Proxy代理主机,它们通过Proxy代理本身进行监控。

2. Proxy何时会“死亡”?

首先,必须找出proxy代理何时不再响应。根据Proxy的默认配置,它将在与Zabbix server通信时遵循以下的规则:

  • 如果有数据需要发送,每秒执行一次。
  • 如果没有数据需要发送,每分钟发送一次心跳信号,让Zabbix server知道一切正常。

利用这些对我们有利的规则,可以创建监控项来监控Proxy报告的最后时刻:

使用内部监控项让我们能监控proxy何时进行最后一次报告。

为了保证灵活性,建议在模版上创建这些监控项和触发器,而不是直接在主机上创建。

使用Fuzzytime触发器功能对时间差异发出警报是可行的:

在这样的设置下,如果Proxy 1-a出现故障(在此范例中)将会产生问题。为后续的使用,需要以proxy名称启动触发器名称,一定必须是相同的匹配。同时,必须明确哪个proxy(名称)与Proxy 1-a相对应:

当然,我们可以使用动作发送消息以引起对此问题的关注,但是我们已经决定让脚本执行自动切换转移。

3. 动作配置

在动作部分,将创建一个新的动作:

这种情况下,仅指向来自特定模板的触发器上发生的所有事情,这就不需要考虑匹配特定的触发器或名称。在操作中调用脚本并将proxy代理名称传递给脚本,这样就知道是哪个proxy代理出现了故障。

同时,必须将对应proxy代理的名称推送给脚本:

注:这是个单行代码,命令中没有回车符。

此时,已经将所有必要信息传递给脚本以便进行故障切换。我们将在Zabbix前端中创建一个额外的配置用于后续使用。

五、前端脚本

该前端脚本将强制Zabbix proxy在执行时重新加载其配置缓存。在Proxy默认配置中保持、甚至减慢上述“ConfigFrequency=3600” 参数的方法之一。要使其命令正常调用,必须在proxy代理上启动RemoteCommands (EnableRemoteCommands=1)。

脚本逻辑

步骤一:登录Zabbix server以执行API调用

使用user.login的方法将获得一个SessionID用于后续步骤。请确保用于登录的用户有足够的权限(超级管理员),否则将遇到一些限制。

步骤二:获取故障proxy的主机ID

使用{EVENT.NAME}通过解析,可以从问题名称中得到proxy代理名称。使用该名称和方法proxy.get可以检索Proxy ID。

步骤三:获取对应proxy的主机ID

使用{EVENT.TAGS}通过解析,可以从作为第二个参数发送至脚本的标签中获得counter proxy代理名称。使用该名称和方法proxy.get可以检索与故障proxy对应的Proxy ID。

步骤四:将所有主机从故障proxy移动到对应切换到对应的proxy

一旦从步骤二中得知ProxyID,应在步骤四内进行以下步骤:

  • 获取proxy本代理本身的HostID 使用函数host.get并过滤proxy名称,将获得proxy的HostID
  • 获取数组中故障proxy监控的所有主机 使用函数host.get并过滤在步骤二检索到的proxyID,将获得该proxy监控的所有主机的列表,包括proxy主机本身。
  • 从数组中移除HostID 从步骤4.2构建的数组中移除步骤4.1的宿主机以获得干净的列表。

完成所有步骤后,将得到一个由所有主机所组成的数组。使用函数host.update,可以在每个主机上仅更新一个字段:proxy_hostid。如果从步骤4.3开始循环该数组,结果将是所有主机从故障proxy切换到运行的proxy。

步骤五:确保Zabbix Server配置已更新

在步骤四中,所有主机已经从一个proxy移动到了另一个,但现在必须等待一分钟(Zabbix Server配置的默认参数:CacheUpdateFrequency=60),Zabbix Server才会注意到配置的变化。在Zabbix server上,该操作可以用以下命令强制执行“/usr/sbin/zabbix_server -Rconfig_cache_reload”,这样配置将立即同步。

步骤六:确保Zabbix Proxy配置已更新

现在,由于Proxy配置中的默认设置(ConfigFrequency=3600),新的proxy代理需要一小时才能意识到应该监控主机。当然,这会破坏了故障切换的宗旨,导致了一小时的停机时间。

在脚本中,调用另一个API动作:script.get来查找名为“update proxy cache(更新proxy缓存)”的脚本。一旦找到,提取该脚本的ID。使用该脚本ID,可以执行脚本(API调用script.execute)并提供执行脚本的主机ID。当然,提供的是步骤三中检索的counterproxy的主机ID。结果是当Server意识到其新配置后(步骤六),强制Proxy进行相同操作,并向server查询其最新配置。几秒钟内,监控将从正在运行的代理中开始运作,故障代理已被停用。

六、有什么缺点?

当然每个解决方案,在构建解决方案或介绍新的限制时都有事项要牢记。如果使用“Active agent auto-registration(主动注册)”发现主机,并且两个Proxy IP都在Zabbix Agent配置“ServerActive”参数中列出时,那么Zabbix Agent极有可能被不同的proxy代理所发现,因此在前端不断跳转,这是非常不可取的。为了解决这个问题,有以下两种解决方案:

  • 不要使用自动注册
  • 使用“action.update” API调用增强步骤四,自动注册和条件“Proxy等于<PROXYNAME>”也随之被更新,反映了新的主动proxy。

七、总结

尽管不支持开箱即用,但通过使用自定义脚本、Zabbix内置功能和一点创造性,在没有复杂集群配置的情况下为proxy代理创建冗余和HA设置是完全可行的。该博文源于一个真实用例:客户(Opensource ICT Solutions, 比荷卢经济联盟第一个Zabbix 高级合作伙伴和培训合作伙伴,美国第一个官方培训机构)要求我们创建一个冗余环境,且每个proxy都没有复杂配置。

当然,我们也可以帮助您设置您的Zabbix环境,或实施这篇博文中描述的解决方案,请联系我们来探索更多可能性!

0 人点赞