使用 docker 安装部署 Zabbix5.0 并进行优化

架构概览

zabbix_deploy

网络环境不宜说太多:四朵独立的云,中间通过防火墙隔离,需要搭建一套监控系统对全网的网络设备进行监控,通过 Zabbix Server + Proxy 分布式部署方式来实现。

版本选择

截止目前,Zabbix 已经发布了 6.0 pre-release,稳定版也已经来到了 5.4。

在生产环境部署时,为稳定起见,建议使用 Long-term support (LTS) 版本。

本次部署选用的是 Zabbix 5.0 LTS 版本。

版本及软件依赖

存储空间要求:

  • 历史数据:(监控项/刷新周期) * days * 24 * 3600 * 单条数据大小(约为50B)
  • 趋势数据:(监控项/3600) * days * 24 * 3600 * 单条大小(约128B)
  • 事件数据:每秒事件数 * days * 24 * 3600 * 单条大小(约130B)

硬件性能

Name Platform CPU/Memory Database Monitored hosts
Small CentOS Virtual Appliance MySQL InnoDB 100
Medium CentOS 2 CPU cores/2GB MySQL InnoDB 500
Large RedHat Enterprise Linux 4 CPU cores/8GB RAID10 MySQL InnoDB or PostgreSQL >1000
Very large RedHat Enterprise Linux 8 CPU cores/16GB Fast RAID10 MySQL InnoDB or PostgreSQL >10000

Zabbix 硬件性能取决于监控项(主动)的数量和更新间隔,数量越多需要的性能就越高。

前置条件

  1. 安装 Docker,可参考阿里云镜像站:https://developer.aliyun.com/mirror/docker-ce

  2. Docker 镜像加速(拉取镜像时默认从 Docker hub 进行拉取,国内网络速度较慢,可更换为国内源提高访问速度):

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

使用 docker info 命令查看国内镜像配置是否生效:

image-20211228232224039

本文使用的 Docker 版本:

1
2
docker --version
Docker version 20.10.12, build e91ed57

镜像准备

根据 Zabbix 架构图,需要拉取如下几个镜像:

1
2
3
4
5
6
docker pull zabbix/zabbix-web-nginx-mysql:5.0-centos-latest
docker pull zabbix/zabbix-server-mysql:5.0-centos-latest
docker pull zabbix/zabbix-proxy-mysql:5.0-centos-latest
docker pull zabbix/zabbix-snmptraps:5.0-centos-latest
docker pull zabbix/zabbix-agent:5.0-centos-latest
docker pull mysql:5.7

镜像拉取完成后,可以通过 docker images 查看镜像列表。

image-20211228232758646

运行 Demo

通过 Docker 搭建一个最小化版本的 Zabbix,如果想体验基本功能,安装 MySQL、Server、Web、Agent 即可,本例中也添加了 Proxy,运行如下命令,即可快速搭建完成一个 Zabbix 监控平台。

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
# 运行本地数据库
docker run --name zbx5-mysql -d \
--network=host \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--restart unless-stopped mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin \
--default-authentication-plugin=mysql_native_password

# 启动 server 后端
docker run --name zbx5-server-mysql -d \
-e DB_SERVER_HOST="127.0.0.1" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--network=host \
--restart unless-stopped \
zabbix/zabbix-server-mysql:5.0-centos-latest

# 启动 proxy,由于默认 Server 和 Proxy 端口都为 10051,避免冲突,这里使用 11111
docker run --name zbx5-proxy-mysql -d \
-e DB_SERVER_HOST="127.0.0.1" \
-e ZBX_LISTENPORT=11111 \
-e ZBX_HOSTNAME="zabbix-proxy-test1" \
-e ZBX_SERVER_HOST="127.0.0.1" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--network=host \
--restart unless-stopped \
zabbix/zabbix-proxy-mysql:5.0-centos-latest

# 启动前端页面,默认端口是 8080
docker run --name zbx5-web-nginx-mysql -d \
-e ZBX_SERVER_HOST="127.0.0.1" \
-e DB_SERVER_HOST="127.0.0.1" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--network=host \
--restart unless-stopped \
zabbix/zabbix-web-nginx-mysql:5.0-centos-latest

# 启动 Agent
docker run --name zbx5-agent -d \
-e ZBX_HOSTNAME="local-agent" \
-e ZBX_SERVER_HOST="127.0.0.1" \
--network=host \
--restart unless-stopped \
zabbix/zabbix-agent:5.0-centos-latest

启动完成后,通过 docker ps 查看所有容器已经正在运行,之后通过访问 http://ip:8080 即可访问!

默认用户名/密码是:Admin/zabbix

image-20211229203922391

生产环境部署

网络模式

默认情况下,容器的网卡都是经过 NAT 的,为了保证相关服务可以正常被外部访问,容器都使用主机模式的网络(--network=host),即端口连接、端口监听都使用物理机的地址。

数据库

如果已经有现成的数据库,则不用使用本地数据库,直接配置指定远程数据库即可。

Zabbix 支持 MySQL、PostgreSQL 等,使用不同后端数据库,需要选择对应的 Zabbix 容器镜像。

以下为本地使用容器搭建 MySQL 示例(==对上文 Demo 的解释==):

1
2
3
4
5
6
7
8
9
docker run --name zbx5-mysql -td \
--network=host \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--restart unless-stopped mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin \
--default-authentication-plugin=mysql_native_password

运行之后,一个本地数据库就搭建完成了,之后可以在 Linux 中使用 docker exec -it zbx5-mysql mysql -proot 来连接到本地数据库,其中 MYSQL_DATABASE 为新建的数据库,MYSQL_ROOT_PASSWORD 为数据库超级管理员 root 的密码(生产环境中请使用符合密码策略的强密码)

image-20211229002522793

目录梳理

由于 Docker 不能完成数据持久化(删除容器后即丢失),并且多个容器之间存在共享目录或者文件的情况(例如:snmptraps 写 log,Server 读 log),所以需要把配置文件、数据文件等放在本地,并使用 volume 映射到 Docker 中读取。

Docker 挂载本地目录时,使用 -v $hostDir:$containerDir 参数。

每个容器镜像都给出了允许挂载的目录卷,可查阅 Docker Hub 上对应的镜像主页说明。Zabbix docker 镜像主页MySQL docker 镜像主页

本次部署选择将所有组件需要的目录统一放到 /opt/zabbix-volumes/ 下,分为:

  • snmp:存放 snmp 相关的配置文件(snmptraps 需要)
  • zabbix-data:Zabbix Server/Proxy 数据文件,如自定义脚本、模块、mib文件等
  • zabbix_proxy.conf.d:自定义 proxy 配置文件
  • zabbix_server.conf.d:自定义 server 配置文件

以上目录可以直接从已有的 demo 环境中获取到:

1
2
3
4
5
6
7
8
9
mkdir -p /opt/zabbix-volumes/ && cd /opt/zabbix-volumes/
# server 和 proxy 目录基本一致
docker cp zbx5-server-mysql:/var/lib/zabbix/ ./zabbix-data/
docker cp zbx5-snmptraps:/etc/snmp .
# snmptrap 处理脚本(默认)
docker cp zbx5-snmptraps:/usr/sbin/zabbix_trap_handler.sh ./snmp
mkdir -p zabbix-data/alertscripts
mkdir -p zabbix-data/externalscripts
mkdir -p zabbix-data/export

最后目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 # tree
.
├── snmp
│   ├── snmpd.conf
│   ├── snmptrapd.conf
│   └── zabbix_trap_handler.sh
├── zabbix-data
│   ├── alertscripts
│   ├── enc
│   ├── export
│   ├── externalscripts
│   ├── mibs
│   ├── modules
│   ├── snmptraps
│   ├── ssh_keys
│   └── ssl
│   ├── certs
│   ├── keys
│   └── ssl_ca
├── zabbix_proxy.conf.d
└── zabbix_server.conf.d

16 directories, 3 files

参数/环境变量

在容器内服务运行的时候如果需要传递参数,可以使用 -e 选项来指定。如指定数据库的用户名:docker run ... -e MYSQL_USER="zabbix" ...

看容器支持的每个参数及其含义,可查阅 Docker Hub 上对应的镜像主页说明。Zabbix docker 镜像主页MySQL docker 镜像主页

每个 Docker 镜像都支持若干自定义参数,如果不传参的话,使用的就是是默认参数,官方镜像支持配置文件中的全部参数。

使用 -e 传参后, docker 启动时会逐个进行写入,见下文图中 ** Updating '/etc/zabbix/zabbix_server.conf' parameter....,最终会生成一份完整的配置文件。

这样的话会有一个问题:官方的镜像支持了上百个参数,如果要对运行中的 Zabbix 容器进行参数调整,使用 -e 指定参数启动容器后,要想调整只能把容器删除后再重新启动新的容器,可维护性不高(个人理解,如有更好的思路进行交流~)。

通过查看配置文件,可以使用 Include 参数将其他文件或目录包含在 Server/Proxy/Agent 的配置中,实现自定义加载配置文件;这样只需要以最小化配置启动容器,自定义配置通过单独的文件加载,之后热加载或者重启容器即可使新的配置文件生效,也便于维护。

官方镜像中并未提供 Include 参数的配置及更新,所以需要在官方镜像基础上重新打包,使其支持 Include 参数。

自定义 Zabbix Server 镜像

最小化运行 Zabbix Server 端,运行时需要指定数据库的地址(必选参数),以保证数据可以正常存取。

1
2
3
4
5
6
7
8
9
10
docker run --name zbx5-server-mysql -t \
-e DB_SERVER_HOST="127.0.0.1" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
-e ZBX_ENABLE_SNMP_TRAPS=true \
--network=host \
--restart unless-stopped \
-d zabbix/zabbix-server-mysql:5.0-centos-latest

运行完成之后,通过 docker logs ${docker_id} 可以看到运行日志,首先进行了数据库的初始化,之后写入配置文件,最后启动 Server 端。

如果是已有数据库已有数据表,则不会再次进行初始化。

image-20211229015713693

运行成功后,将原始容器的启动脚本拷贝出来进行修改。

1
2
3
4
cd ~
mkdir docker-build/zbx_server -p
docker cp zbx5-server-mysql:/usr/bin/docker-entrypoint.sh ./docker-build/zbx_server
cd docker-build/zbx_server

编辑原始启动文件:

1
2
3
4
5
# vim docker-entrypoint.sh
# 移动到 440 行左右,这里的配置就是调用函数更新配置,在这里添加需要的 `Include` 参数
...
update_config_var $ZBX_CONFIG "Include" "${ZBX_INCLUDE}"
...

image-20211229112406476

编辑 Dockerfile,制作新的镜像:

1
2
3
# cat Dockerfile
FROM zabbix/zabbix-server-mysql:5.0-centos-latest
COPY ./docker-entrypoint.sh /usr/bin/docker-entrypoint.sh

image-20211229112709803

重新打包镜像:

1
2
# 使用当前目录的 Dockerfile 创建镜像,新镜像标签为 xdai/zabbix-server-mysql:v1
docker build -t xdai/zabbix-server-mysql:v1 .

image-20211229113707531

之后使用 v1 这个版本的镜像启动时,就可以支持 Include 参数了。

自定义 Zabbix Proxy 镜像

原理同上。

1
2
3
4
5
6
7
8
9
10
11
12
# 启动 Proxy 容器,因为测试环境 Proxy 和 Server 在同一台机器上启动,端口无法重用,所以指定监听端口为 11111
docker run --name zbx5-proxy-mysql -t \
-e DB_SERVER_HOST="127.0.0.1" \
-e ZBX_LISTENPORT=11111 \
-e ZBX_HOSTNAME="zabbix-proxy-test1" \
-e ZBX_SERVER_HOST="127.0.0.1" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root" \
--network=host \
--restart unless-stopped \
-d zabbix/zabbix-proxy-mysql:5.0-centos-latest

运行成功后,将原始容器的启动脚本拷贝出来进行修改。

1
2
3
4
cd ~
mkdir docker-build/zbx_proxy -p
docker cp zbx5-proxy-mysql:/usr/bin/docker-entrypoint.sh ./docker-build/zbx_proxy
cd docker-build/zbx_proxy

编辑原始启动文件:

1
2
3
4
5
# vim docker-entrypoint.sh
# 移动到 440 行左右,这里的配置就是调用函数更新配置,在这里添加需要的 `Include` 参数
...
update_config_var $ZBX_CONFIG "Include" "${ZBX_INCLUDE}"
...

编辑 Dockerfile,制作新的镜像:

1
2
3
# cat Dockerfile
FROM zabbix/zabbix-proxy-mysql:5.0-centos-latest
COPY ./docker-entrypoint.sh /usr/bin/docker-entrypoint.sh

重新打包镜像:

1
2
# 使用当前目录的 Dockerfile 创建镜像,新镜像标签为 xdai/zabbix-proxy-mysql:v1
docker build -t xdai/zabbix-proxy-mysql:v1 .

自定义 Agent 镜像

同上,略略略~

开始部署

!!! 如果在同一台设备上,部署前需要删除之前的 demo 环境,以免冲突。

以下内容均已在生产环境验证稳定运行,目前通过 Zabbix SNMP 监控网络设备(总计 400+ 带内网络设备,总计监控项 25w+)及 Agent 监控少量 Linux 服务器。

自定义配置均为实践踩坑所得优化参数。

后端数据库

同上文数据库一节,Server 采用 RDS 的方式远程连接,本例中使用本地数据库;Proxy 由于是临时数据存储,故使用本地数据库。

如果在 Server/Proxy 的自定义配置文件中调整了参数,更多的进程意味着需要更多的数据库连接,所以默认的连接数不够多,可能会造成容器异常退出,所以需要调整本地数据库的默认连接数。

连接数异常报错信息(通过 docker logs zbx-server-mysql查看):

1
2
3
4
 ...
385:20211229:152438.049 [Z3001] connection to database 'zabbix' failed: [1040] Too many connections
385:20211229:152438.049 Cannot connect to the database. Exiting...
...

修改连接数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 登录数据库
docker exec -it zbx5-mysql mysql -uroot -proot
# 查看最大连接数
mysql> show variables like "%max_connections%";
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
# 查看服务器响应的最大连接数
mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 152 |
+----------------------+-------+
# 修改最大连接数(重启容器后会失效!)
mysql> set global max_connections = 1000;
Query OK, 0 rows affected (0.01 sec)

如果想要数据库的配置持久化,需要修改 MySQL 配置文件信息,自行百度~

Server 后端

Server 端的自定义配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# vim zabbix_server.conf.d/custom.conf
StartPollers=200
StartPreprocessors=50
StartPollersUnreachable=30
StartTrappers=50
StartPingers=30
StartLLDProcessors=30
StartDiscoverers=10
StartAlerters=5
CacheSize=1024M
HistoryCacheSize=512M
HistoryIndexCacheSize=512M
TrendCacheSize=512M
ValueCacheSize=512M
StartProxyPollers=5
Timeout=30
ProxyConfigFrequency=60

将配置文件放在自定义配置目录下,挂载对应的数据卷,启动容器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker run --name zabbix-server -d \
-e DB_SERVER_HOST="127.0.0.1" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e ZBX_ENABLE_SNMP_TRAPS=true \
-e ZBX_INCLUDE="/etc/zabbix/zabbix_server.conf.d/*.conf" \
--network=host \
-v /opt/zabbix-volumes/zabbix_server.conf.d:/etc/zabbix/zabbix_server.conf.d \
-v /opt/zabbix-volumes/zabbix-data:/var/lib/zabbix \
-v /opt/zabbix-volumes/zabbix-data:/usr/lib/zabbix \
-v /opt/zabbix-volumes/zabbix-data/export:/var/lib/zabbix/export \
-v /opt/zabbix-volumes/zabbix-data/snmptraps:/var/lib/zabbix/snmptraps \
-v /etc/localtime:/etc/localtime \
--restart unless-stopped \
xdai/zabbix-server-mysql:v1

参数解释:

  • --restart unless-stopped:除非手动 stop 容器,否则容器退出后会不断尝试拉起
  • -v /etc/localtime:/etc/localtime:保持和本机时区同步
  • -e ZBX_ENABLE_SNMP_TRAPS=true:开启后,从 snmptraps.log 读取 trap 信息

Web 前端

Zabbix 前端通过 PHP 来实现,默认只提供了通过参数的方式修改配置,如果需要自定义配置文件,可以参考上文重新制作镜像。

启动前端容器,如果数据库和 Server 端不在同一台服务器上,注意修改对应参数:

1
2
3
4
5
6
7
8
9
10
11
docker run --name zabbix-web -d \
-e ZBX_SERVER_HOST="127.0.0.1" \
-e DB_SERVER_HOST="127.0.0.1" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e PHP_TZ="Asia/Shanghai" \
--network=host \
-v /etc/localtime:/etc/localtime \
--restart unless-stopped \
zabbix/zabbix-web-nginx-mysql:5.0-centos-latest

参数解释:

  • -e PHP_TZ="Asia/Shanghai:设置时区为上海。

默认端口为 8080,前端容器正常启动后,即可进行访问。

内存占用过高的问题

运行一段时间之后,发现服务器内存被占满,通过查看进程,发现是 php-fpm 相关进程有多个,平均每个占用了 1G,在容器内修改配置文件控制一下进程数量:

1
2
3
4
5
6
# php 内存占用过高
# /etc/php-fpm.d/zabbix.conf
pm = dynamic
pm. start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 8

参数解释:

1
2
3
4
5
6
pm = dynamic 如何控制子进程,选项有static和dynamic    
pm.max_children:静态方式下开启的php-fpm进程数量
pm.max_requests:php-fpm子进程能处理的最大请求数
pm.start_servers:动态方式下的起始php-fpm进程数量
pm.min_spare_servers:动态方式下的最小php-fpm进程数
pm.max_spare_servers:动态方式下的最大php-fpm进程数量
切换中文后,图形上面显示乱码的问题

默认的字体没有汉语字符集,直接替换字体即可(也可以直接自定义镜像)。

首先下载一个字体,这里使用的是文泉驿微米黑字体,下载之后覆盖容器内的字体即可。

1
docker cp /tmp/wqy-microhei.tto zabbix-web:/usr/share/zabbix/assets/fonts/DejaVuSans.ttf

小米新发布的字体也不错,支持十种字重,下载地址:MiSans

Proxy

关于 Proxy 的信息可直接查看官网,有非常详尽的说明:Proxy 概述,以下为摘抄:

  • 主动模式:主动模式下的 Zabbix proxy 会主动连接到 Zabbix server 并请求配置数据。前端添加时不需要指定端口,只需要 Proxy 配置的名字和 Server 端添加的名字一致即可(用于判断哪个 Proxy 连上来了)。

  • 被动模式:需要 Server 端主动连到 Proxy 上,所以添加时需要提供端口信息,配置文件从本地读取。

  • Zabbix proxy 到 Zabbix server 只需要一条 tcp 连接,仅在防火墙上配置一条规则即可。

  • Proxy 收集的所有数据在传输到服务器之前都存储在本地。这样就不会因与服务器的任何临时通信问题而丢失任何数据。当它把对应的数据发送给 Zabbix server 以后,本地临时存储的数据就会清除

  • 代理配置文件中的 ProxyLocalBuffer 和 ProxyOfflineBuffer 参数控制数据在本地保留的时间。

  • 基于上述,Proxy 的数据库和 Server 的数据库一定要分开,否则会造成数据错乱或丢失。

由于我们生产环境中网络因素(不可抗力),仅能使用 proxy 被动模式来部署。

Proxy 端的自定义配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
# vim zabbix_proxy.conf.d/custom.conf
EnableRemoteCommands=1
ProxyOfflineBuffer=240
StartPollers=50
StartDiscoverers=10
StartPreprocessors=20
StartPollersUnreachable=10
StartPingers=10
CacheSize=1024M
HistoryCacheSize=512M
HistoryIndexCacheSize=512M
Timeout=30

将配置文件放在自定义配置目录下,挂载对应的数据卷,启动容器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker run --name zabbix-proxy -d \
-e DB_SERVER_HOST="127.0.0.1" \
-e ZBX_LISTENPORT=11111 \
-e ZBX_PROXYMODE=1 \
-e ZBX_HOSTNAME="zabbix-proxy-test" \
-e ZBX_SERVER_HOST="127.0.0.1" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e ZBX_ENABLE_SNMP_TRAPS=true \
-e ZBX_INCLUDE="/etc/zabbix/zabbix_proxy.conf.d/*.conf" \
--network=host \
-v /opt/zabbix-volumes/zabbix_proxy.conf.d:/etc/zabbix/zabbix_proxy.conf.d \
-v /opt/zabbix-volumes/zabbix-data:/var/lib/zabbix \
-v /opt/zabbix-volumes/zabbix-data/snmptraps:/var/lib/zabbix/snmptraps \
-v /etc/localtime:/etc/localtime \
--restart unless-stopped \
xdai/zabbix-proxy-mysql:v1

Proxy 启动后,可以在前端 Web 上进行添加测试一下。

被动模式,端口 11111。

image-20211230005830309

添加成功后,上次在线时间(Last seen)会一直重置为 0,表示 Proxy 可被正常检测到。

image-20211230010013164

Agent

Zabbix Server 端启动后,会默认监控本机的 10050 端口(zabbix_agent 端口)来对本机进行监控,如果没有运行 agent,系统会提示该主机离线。

image-20211230010402200

启动 Agent 容器,本机监控一般不需要额外的参数:

1
2
3
4
5
6
7
docker run --name zabbix-agent -d \
-e ZBX_HOSTNAME="local-agent" \
-e ZBX_SERVER_HOST="127.0.0.1" \
--network=host \
-v /etc/localtime:/etc/localtime \
--restart unless-stopped \
zabbix/zabbix-agent:5.0-centos-latest

Agent 端启动后,Web 上可以看到本机状态恢复正常。

image-20211230010908510

SNMPTraps

如果使用的 SNMPv3 版本,需要把每台网络设备的信息都录入进去,主要是 engine-id 不同;SNMPv2版本只需要写上只读只写的团体字即可。

SNMPTrap 的配置文件如下,配置文件的编写参考 net-snmp

1
2
3
4
5
6
7
snmpTrapdAddr udp:1162
# Start
# createUser -e ENGINEID myuser SHA "my authentication pass" AES "my encryption pass"
createUser -e 800063A2805E9B20F2010000000001 snmpv3user MD5 snmpv3pw
# End
authUser log,execute snmpv3user
disableAuthorization no

获取 snmp engine-id 的两种方法:

  • 登录交换机查看配置
  • 使用 snmpwalk 命令查询 OID:snmpwalk -v 3 -u snmpv3user -a md5 -A snmpv3pw -l authNoPriv ${网络设备地址} 1.3.6.1.6.3.10.2.1.1.0

如果设备较多,可以使用 for 循环批量获取,以下脚本供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python2
import commands

CONF_TMPL = "createUser -e %s snmpv3user MD5 snmpv3pw\n"
OID = "1.3.6.1.6.3.10.2.1.1.0"
# 读取设备 IP 列表文件,获取 IP 列表信息
with open ("ip_list", "r") as f:
ip_list = f.readlines()
# 打开配置文件句柄
snmptrap_conf_file = open("snmptraped.conf", "w+")
# 循环获取 engine_id 并写入配置文件
for ip in ip_list:
cmd = "snmpwalk -v 3 -u snmpv3user -a md5 -A snmpv3pw -l authNoPriv %s %s" %(ip.strip(), OID)
engine_id = commands.getoutput(cmd).split("=")[1].split(":")[1].replace(" ","")
snmptrap_conf_file.write(CONF_TMPL % (engine_id))
# 关闭配置文件句柄
snmptrap_conf_file.close()

启动 SNMPTraps 容器,这里需要注意:snmptraps 容器需要和 server/proxy 容器共享同一个 snmptraps 目录,并且需要使用 root 用户启动(--privileged=true)。

1
2
3
4
5
6
7
8
9
docker run --name snmptraps -d \
-v /opt/zabbix-volumes/snmp:/etc/snmp \
-v /opt/zabbix-volumes/zabbix-data:/var/lib/zabbix \
-v /opt/zabbix-volumes/zabbix-data/snmptraps:/var/lib/zabbix/snmptraps \
--network=host \
--restart unless-stopped \
-v /etc/localtime:/etc/localtime \
--privileged=true \
zabbix/zabbix-snmptraps:5.0-centos-latest

网络设备配置

以 H3C 交换机配置 SNMMPv3 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
# snmp 配置
snmp-agent
snmp-agent sys-info version v3
snmp-agent group v3 snmpv3group authentication read-view iso-ivew write-view iso-view notify-view iso-view
snmp-agent mib-view included iso-view iso
snmp-agent usm-user v3 snmpv3user snmpv3group simple authentication-mode md5 snmpv3pw
# trap 配置
snmp-agent trap enable
snmp-agent trap periodical-interval 0
snmp-agent trap source LoopBack1
# x.x.x.x 为 zabbix server/proxy 地址,运行 snmptraps 容器的服务器
snmp-agent target-host trap address udp-domain x.x.x.x params securityname snmpuv3user v3 authentication
undo snmp-agent trap enable syslog

总结

到这里,Zabbbix 就平台搭建完成了。

本文是对生产环境部署 Zabbix 平台的事后记录,目前已经稳定运行约一年。由于内网环境无法联网,部署时的记录无法导出,有一些细节改动由于时间关系已经淡忘。。。

关于使用,可参考官方文档,后面有时间也会做一些使用的分享。

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
#====================================
# docker 安装
需要完善的事项:docker卷存储(配置文件、日志等的路径)

# 接收snmptrap
# 默认配置文件/etc/snmp/snmptrapd.conf
snmpTrapdAddr udp:1162
createUser -e 800063A2805E9B20F2010000000001 snmpv3user MD5 snmpv3pw
authUser log,execute snmpv3user
disableAuthorization no



docker run --name zbx5-snmptraps \
-v /home/x/zabbix-conf/snmp:/etc/snmp \
--network=host \
--restart unless-stopped \
--privileged=true \
-d zabbix/zabbix-snmptraps:5.0-centos-latest
---
/var/lib/zabbix/snmptraps
The volume contains log file snmptraps.log named with received SNMP traps.
---
/var/lib/zabbix/mibs
The volume allows to add new MIB files. It does not support subdirectories, all MIBs must be placed to /var/lib/zabbix/mibs.
---


/var/lib/zabbix/snmptraps 存放接收到的trap
/var/lib/zabbix/mibs 进行mib扩展及解析,配置文件添加 'mibs +ALL',并在mibs文件夹中放入所有mib文件
# 解析oid
snmptranslate -On HH3C-ARP-ENTRY-MIB::hh3cARPEntry

--
# 出现大量 hh3cPeriodicalTrap
undo snmp-agent trap log
--
trap 升级为告警,自定义正则表达式
#TODO: 正则匹配指定字段的值来进行出发告警
---


6.
Security name:{$SNMP_SECNAME}
Authentication passphrase:{$SNMP_AUTH}
Privacy passphrase:{$SNMP_PRIV}