组件版本端口号链接
Zabbix Web8080https://cdn.zabbix.com/zabbix/sources/stable/6.0/
Zabbix Serverv6.0.3210051https://cdn.zabbix.com/zabbix/sources/stable/6.0/
Zabbix Porxyv6.0.410051https://www.zabbix.com/download?zabbix=6.0&os_distribution=centos&os_version=7&components=proxy&db=mysql&ws=
Zabbix Agentv6.0.410050agent:https://www.zabbix.com/download?zabbix=6.0&os_distribution=centos&os_version=7&components=agent&db=&ws=
agent2:https://www.zabbix.com/download?zabbix=6.0&os_distribution=centos&os_version=7&components=agent_2&db=&ws=
haproxyv2.8.10https://www.haproxy.org/
keepalivedv1.3.5https://keepalived.org/
nginxv1.20.1https://mirrors.aliyun.com/repo/epel-7.repo

​ 目前 Zabbix 最新的稳定版本是 7.0,想要在 Centos7 上安装 Zabbix 6.0 版本上只能通过源码编译的方式安装。本文将会介绍在 Centos7 上通过源码编译安装的方式部署一套 Zabbix 高可用集群。

架构图:

img

组件作用:

组件说明
Zabbix Web通过 Apache HTTP 运行,提供前端的访问页面。
Zabbix ServerZabbix 软件的核心组件,Zabbix Agent 向其报告可用性、系统完整性信息和统计信息。
Zabbix PorxyZabbix Proxy 可以代替 Zabbix Server 收集客户端的数据,然后把数据汇报给 Zabbix Server,以减轻 Zabbix Server 的负担,本文中没有安装 Zabbix Proxy。
Zabbix Agent部署在需要监控的服务器上,主动监控本地资源和应用程序,并将收集到的数据上报给 Zabbix Server(或 Zabbix Proxy)。

主机节点规划:

image-20240723114218009

环境搭建

部署MySQL

注意:Zabbix 要求数据库版本在 5.7.35 以上,并且 database 字符集要求是 utf8,校验集为 utf8_bin。

修改主机名

declare -A hostnames=(
    [192.168.126.71]=db1
    [192.168.126.72]=db2
)

for ip in "${!hostnames[@]}"
do
    ssh $ip "hostnamectl set-hostname ${hostnames[$ip]}"
done

添加hosts

declare -A hostnames=(
    [192.168.126.71]=lb1
    [192.168.126.72]=lb2
)
FILENAME=/etc/hosts

for ip in "${!hostnames[@]}"
do
	echo "Attempting to connect to $ip..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $ip "cat > $FILENAME << EOF
127.0.0.1 localhost
192.168.126.71 db1 db1.lab.example.com
192.168.126.72 db2 db2.lab.example.com
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $ip"
    else
        echo "Failed to update on $ip"
    fi
done

卸载相关程序

for x in db1 db2
do
    ssh $x yum remove `rpm -qa|grep mariadb` -y
done

关闭防火墙

for x in db1 db2
do
    ssh $x "systemctl disable --now firewalld && systemctl status firewalld"
done

禁用selinux

for x in db1 db2
do
    ssh $x "
	    sed -ri 's#(SELINUX=)enforcing#\1disabled#' /etc/selinux/config
	    grep ^SELINUX= /etc/selinux/config
	    setenforce 0
	    getenforce
	"
done

时间同步

for x in db1 db2
do
    ssh $x "
	    yum install -y ntpdate
	    echo '* * * * * /usr/sbin/ntpdate -u ntp.aliyun.com && /sbin/hwclock -w' | crontab -
	"
done

安装常用工具

for x in db1 db2
do
    ssh $x "
	    yum install -y vim bash-completion wget
	    echo "source /usr/share/bash-completion/bash_completion" >>~/.bashrc
	    source ~/.bashrc
	"
done

安装MySQL

for x in db1 db2
do
    ssh $x "
# 下载对应二进制软件包
curl -Lo /usr/local/mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
# 解压并配置环境变量
cd /usr/local/ && tar xf mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
ln -s mysql-8.0.37-linux-glibc2.17-x86_64 mysql
echo 'export PATH="/usr/local/mysql/bin:$PATH"' >> /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
mysql -V
"
done

初始化数据库

for x in db1 db2
do
    ssh $x "
useradd mysql
install -o mysql -g mysql -d /data/mysql
cd /usr/local/mysql/bin && ./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
"
done

启动数据库

FILENAME=/data/mysql/my.cnf

for x in db1 db2
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
[client]
socket=/data/mysql/mysql.sock

[mysql]
prompt = \\\\u@\\\\h \\\\d \\\\R:\\\\m:\\\\s> 

[mysqld]
bind-address = 0.0.0.0
log-error = /data/mysql/mysql.err
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /data/mysql
socket = /data/mysql/mysql.sock
log_timestamps = SYSTEM
EOF
chown -R mysql. /data/mysql/
ln -sv /data/mysql/my.cnf ~/.my.cnf
"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done
FILENAME=/usr/lib/systemd/system/mysql.service

for x in db1 db2
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/my.cnf
LimitNOFILE=5000
EOF
systemctl daemon-reload
systemctl enable mysql --now
systemctl status mysql && sleep 5 && ss -tunlp
"
done

创建

for x in db1 db2; do 
    ssh $x <<'EOF'
	mysql -e "
	    UPDATE mysql.user SET host = '%' WHERE user = 'root'; 
	    FLUSH PRIVILEGES;
	"
	EOF
done

数据组复制-MGR

declare -A local_addresses=(
    ["db1"]="192.168.126.71:33061"
    ["db2"]="192.168.126.72:33062"
)

group_seeds="${local_addresses[db01]},${local_addresses[db02]},${local_addresses[db03]}"

for x in "db1" "db2" "db3"; do
    echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > /data/mysql/my.cnf << EOF
[mysql]
socket = /tmp/mysql.sock

[mysqld]
server_id = \$(ping -c 1 \$HOSTNAME | awk -F '[().]' '/PING/ {print \$5}')
log_bin = /data/mysql/binlog/mysql-bin
log-error = /data/mysql/mysql.err
port = 3306
basedir = /usr/local/mysql
datadir = /data/mysql
socket = /tmp/mysql.sock
log_timestamps = SYSTEM
binlog_format = row
gtid-mode = on
enforce-gtid-consistency = true
log-slave-updates = 1
skip_name_resolve
master_info_repository = TABLE
relay_log_info_repository = TABLE
report_host = \$(ping -c 1 \$HOSTNAME | awk -F '[()]' '/PING/ {print \$2}')
report_port = 3306
default_authentication_plugin = mysql_native_password
binlog_checksum = NONE
mysqlx = off
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction = XXHASH64
loose-group_replication_group_name = c0c6ac27-6c30-491b-8c9e-67497719f7cc
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = \"${local_addresses[$x]}\"
loose-group_replication_group_seeds = \"$group_seeds\"
loose-group_replication_bootstrap_group = OFF

[mysql]
prompt=\\u@\\h \\d \\R:\\m:\\s>
EOF
ln -s /data/mysql/my.cnf ~/.my.cnf
systemctl restart mysql --now && systemctl status mysql
"
    if [ $? -eq 0 ]; then
        echo "Successfully updated my.cnf on $x"
    else
        echo "Failed to update my.cnf on $x"
    fi
done

安装MGR组复制功能插件(所有节点)

for x in db1 db2; do 
    ssh $x <<'EOF'
	mysql -p123456 -e "
    	install plugin group_replication SONAME 'group_replication.so';
	"
	EOF
done

部署负载均衡

修改主机名

declare -A hostnames=(
    [192.168.126.91]=lb1
    [192.168.126.92]=lb2
)

for ip in "${!hostnames[@]}"
do
    ssh $ip "hostnamectl set-hostname ${hostnames[$ip]}"
done

添加hosts

declare -A hostnames=(
    [192.168.126.91]=lb1
    [192.168.126.92]=lb2
)
FILENAME=/etc/hosts

for ip in "${!hostnames[@]}"
do
	echo "Attempting to connect to $ip..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $ip "cat > $FILENAME << EOF
127.0.0.1 localhost
192.168.126.91 lb1 lb1.lab.example.com
192.168.126.92 lb2 lb2.lab.example.com
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $ip"
    else
        echo "Failed to update on $ip"
    fi
done

安装haproxy

for x in lb1 lb2
do
	ssh $x "
wget -c https://www.haproxy.org/download/2.8/src/haproxy-2.8.10.tar.gz 
yum install -y gcc gcc-c++ make openssl-devel pcre-devel systemd-devel
curl -L -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz
tar xf lua-5.4.4.tar.gz -C /usr/local/src/
cd /usr/local/src/lua-5.4.4
make linux test
tar xf ~/haproxy-2.8.10.tar.gz -C /usr/local/src/ 
cd /usr/local/src/haproxy-2.8.10
make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.4/src/ LUA_LIB=/usr/local/src/lua-5.4.4/src/
make install PREFIX=/usr/local/haproxy
tree /usr/local/haproxy/
ln -sv /usr/local/haproxy/sbin/haproxy /usr/sbin/haproxy
useradd -r -s /sbin/nologin -d /usr/local/haproxy/ haproxy
mkdir /etc/haproxy
haproxy -v
"
done
FILENAME=/etc/haproxy/haproxy.cfg

for x in lb1 lb2
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
global
    log 		    /dev/log local0
    log 		    /dev/log local1 notice
    chroot 		    /usr/local/haproxy
    stats socket    /var/run/haproxy.stat mode 600 level admin expose-fd listeners
    stats 			timeout 30s
    user 			haproxy
    group 			haproxy
    daemon
    
defaults
    log global
    mode tcp
    option tcplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000

frontend web_front     # zabbix web
    bind *:8080
    default_backend web_back

backend web_back
    balance roundrobin
    server web01 192.168.126.51:8080 check
    server web02 192.168.126.52:8080 check

frontend db_rw_front   # db读写
    bind *:3306
    default_backend db_rw_back

backend db_rw_back
    balance roundrobin
    server router01 192.168.126.71:3306 check
    server router02 192.168.126.72:3306 check

frontend db_ro_front   # db只读
    bind *:3307
    default_backend db_ro_back

backend db_ro_back
    balance roundrobin
    server router01 192.168.126.71:3307 check
    server router02 192.168.126.72:3307 check
   
listen stats        # 配置监听页面
    mode http
    bind :9999  # 使用9999端口
    stats enable
    log global
    stats uri /haproxy-status
    stats auth haadmin:123456  # 指定登录监听页面的用户是haadmin,密码是123456
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $x"
    else
        echo "Failed to update on $x"
    fi
done

编写haproxy启动脚本

FILENAME=/usr/lib/systemd/system/haproxy.service

for x in lb1 lb2
do
	echo "Attempting to connect to $ip..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
 
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /usr/local/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
 
[Install]
WantedBy=multi-user.target
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $x"
    else
        echo "Failed to update on $x"
    fi
done

启动haproxy

for x in lb1 lb2
do
	ssh $x "
	systemctl restart haproxy
	systemctl enable haproxy
	systemctl status haproxy
	"
done

安装keepalived

for x in lb1 lb2
do
	ssh $x yum install -y  keepalived
done

创建keepalived配置文件,两个节点配置相同

FILENAME=/etc/keepalived/keepalived.conf

declare -A local_addresses=(
    ["lb1"]="MASTER"
    ["lb2"]="BACKUP"
)

for x in lb1 lb2
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
global_defs {
    router_id 51       # 虚拟路由器 ID,两个实例应相同。
    script_user root
    enable_script_security
}

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 2
    fall 2       # require 2 failures for KO
    rise 2       # require 2 successes for OK
}

vrrp_instance web_vip {
    state \"${local_addresses[$x]}\"
    interface ens33
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret123    # VRRP 的认证类型和密码,两个实例应相同。
    }
    virtual_ipaddress {
        192.168.126.100
    }
    track_script {
        check_haproxy
    }
}

vrrp_instance db_vip {
    state \"${local_addresses[$x]}\"
    interface ens33
    virtual_router_id 52
    priority 100
    nopreempt
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret456
    }
    virtual_ipaddress {
        192.168.126.200
    }
    track_script {
        check_haproxy
    }
}
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $x"
    else
        echo "Failed to update on $x"
    fi
done

启动keepalived

for x in lb1 lb2
do
	ssh $x "
systemctl restart keepalived.service
systemctl enable keepalived.service
systemctl status keepalived.service
	"
done

验证通过VIP连接mysql集群的读写和只读端口。

mysql -h192.168.126.200 -P 3306
mysql -h192.168.126.200 -P 3307

Zabbix Server和前端部署

以下操作在所有zabbix-server节点执行,基于外部mysql数据库进行部署。

官方文档:https://www.zabbix.com/cn/download

修改主机名

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)

for ip in "${!hostnames[@]}"
do
    ssh $ip "hostnamectl set-hostname ${hostnames[$ip]}"
done

添加hosts

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)

FILENAME=/etc/hosts

for ip in "${!hostnames[@]}"
do
	echo "Attempting to connect to $ip..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $ip "cat > $FILENAME << EOF
127.0.0.1 localhost
192.168.126.51 server1 server1.lab.example.com
192.168.126.52 server2 server2.lab.example.com
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $ip"
    else
        echo "Failed to update on $ip"
    fi
done

时间同步

for x in server1 server2
do
    ssh $x "
	    yum install -y ntpdate
	    echo '* * * * * /usr/sbin/ntpdate -u ntp.aliyun.com && /sbin/hwclock -w' | crontab -
	"
done

安装zabbix-server

CentOS 7.X 系统默认不支持Yum方式安装Zabbix 6.0 服务端(CentOS 8.X支持),所以服务端采用编译安装方式!

部署nginx

for x in server1 server2
do
    ssh $x "
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum -y install nginx
nginx -v
	"
done
declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)
FILENAME=/etc/nginx/conf.d/zabbix.conf

for x in "${!hostnames[@]}"
do
    echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << \"EOF\"
server {
  listen 8080;
  
  location / {
    root /usr/share/nginx/html/zabbix;
    index index.php index.html index.htm;
  }
  
  location ~ \.php$ {
    root /usr/share/nginx/html/zabbix;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
    include fastcgi_params;
    access_log /var/log/nginx/zabbix_access.log;
    error_log /var/log/nginx/zabbix_error.log;
  }
}
EOF
mkdir -p /usr/share/nginx/html/zabbix
"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done

for x in server1 server2
do
    ssh $x "
nginx -t
systemctl restart nginx
systemctl enable nginx
systemctl status nginx
	"
done

部署并配置PHP

for x in server1 server2
do
    ssh $x "
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum -y install php72w php72w-cli php72w-common php72w-devel php72w-embedded php72w-gd php72w-mbstring php72w-pdo php72w-xml php72w-fpm php72w-mysqlnd php72w-opcache php72w-ldap php72w-bcmath
php -v
"
done

修改PHP启动用户/组配置

for x in server1 server2
do
    ssh $x "
sed -ri 's#^(user = )apache#\1nginx#' /etc/php-fpm.d/www.conf
sed -ri 's#^(group = )apache#\1nginx#' /etc/php-fpm.d/www.conf
	"
done

修改PHP优化配置

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)
FILENAME=/etc/php.ini

for x in "${!hostnames[@]}"
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
max_execution_time = 300
max_input_time = 600
post_max_size = 80M
date.timezone = Asia/Shanghai
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done
for x in server1 server2
do
    ssh $x "
nginx -t
systemctl start php-fpm
systemctl enable php-fpm
systemctl status php-fpm
	"
done

测试Nginx+PHP环境

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)
FILENAME=/usr/share/nginx/html/zabbix/index.php

for x in "${!hostnames[@]}"
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
<?php
phpinfo();
?>
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done

浏览器访问:http://IP:9780/index.php

image-20240722015627500

安装Zabbix-Server

for x in server1 server2
do
    ssh $x "
yum install -y mysql-devel pcre-devel openssl-devel zlib-devel libxml2-devel net-snmp-devel net-snmp libssh2-devel OpenIPMI-devel libevent-devel openldap-devel libcurl-devel fping gcc gcc-c++ make
curl -LO https://cdn.zabbix.com/zabbix/sources/stable/6.0/zabbix-6.0.32.tar.gz --insecure
tar xf ~/zabbix-6.0.32.tar.gz -C /opt/
cd /opt/zabbix-6.0.32/
./configure \
--sysconfdir=/etc/zabbix/ \
--bindir=/etc/zabbix/bin/ \
--sbindir=/etc/zabbix/bin/ \
--libexecdir=/etc/zabbix/libexec \
--sharedstatedir=/etc/zabbix/sharedstatedir \
--localstatedir=/etc/zabbix/statedir \
--runstatedir=/etc/zabbix/run \
--libdir=/etc/zabbix/lib \
--includedir=/etc/zabbix/include \
--oldincludedir=/etc/zabbix/oldinclude\
--datarootdir=/etc/zabbix/share \
--datadir=/etc/zabbix/data \
--enable-server \
--with-mysql \
--with-net-snmp \
--with-libxml2 \
--with-ssh2 \
--with-openipmi \
--with-zlib \
--with-libpthread \
--with-libevent \
--with-openssl \
--with-ldap \
--with-libcurl \
--with-libpcre
make install
"
done

配置Zabbix前端UI

for x in server1 server2
do
    ssh $x "
cp -rp /opt/zabbix-6.0.32/ui/* /usr/share/nginx/html/zabbix/

"
done

创建初始化数据库

注意:在一台zabbix server上执行就行

mysql -h 192.168.126.200 -e "
	create database zabbix character set utf8mb4 collate utf8mb4_bin;
	CREATE USER 'zabbix'@'%' IDENTIFIED WITH mysql_native_password BY 'Zbx@123456';
	grant all privileges on zabbix.* to 'zabbix'@'%';
	set global log_bin_trust_function_creators = 1;
"

导入初始化数据

注意:在一台zabbix server上执行就行

for file in /opt/zabbix-6.0.32/database/mysql/*.sql; do
    mysql --default-character-set=utf8mb4 -uzabbix -p'Zbx@123456' -h192.168.126.200 -Dzabbix < "$file"
done

mysql -h 192.168.126.200 -e "
	set global log_bin_trust_function_creators = 0;
"

编写配置文件

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)
FILENAME=/etc/zabbix/zabbix_server.conf

for x in "${!hostnames[@]}"
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
DBHost=192.168.126.200
DBName=zabbix
DBUser=zabbix
DBPassword=Zbx@123456
DBPort=3306
HANodeName=\$HOSTNAME
NodeAddress=\$(ping -c 1 \$HOSTNAME | awk -F '[()]' '/PING/ {print \$2}'):10051
LogFile=/var/log/zabbix/zabbix_server.log
EOF
sudo useradd -r -s /sbin/nologin zabbix
chown -R  zabbix:zabbix /etc/zabbix/
"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done

启动server

declare -A hostnames=(
    [192.168.126.51]=server1
    [192.168.126.52]=server2
)
FILENAME=/usr/lib/systemd/system/zabbix-server.service

for x in "${!hostnames[@]}"
do
	echo "Attempting to connect to $x..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $x "cat > $FILENAME << EOF
[Unit]
Description=Zabbix Server with MySQL DB
After=syslog.target network.target mysqld.service

[Service]
Type=simple
ExecStart=/etc/zabbix/bin/zabbix_server -f
User=zabbix

Restart=on-failure
RestartSec=30s
KillMode=control-group
KillSignal=SIGTERM
TimeoutStopSec=30s

[Install]
WantedBy=multi-user.target
EOF
chown nginx:nginx  /usr/share/nginx  -R
"
    if [ $? -eq 0 ]; then
        echo "Successfully on $x"
    else
        echo "Failed on $x"
    fi
done
for x in server1 server2
do
	ssh $x "
		systemctl restart zabbix-server
		systemctl enable zabbix-server
		systemctl status zabbix-server
	"
done

WEB页面配置

访问:http://IP:8080/

image-20240722132723297

默认账号密码:Admin/zabbix

image-20240722180024886

前端乱码

#!/bin/bash

# 定义变量
FONT_SRC="/usr/share/fonts/wqy-microhei/wqy-microhei.ttc"
FONT_NAME="wqy-microhei.ttc"

# 安装 wqy-microhei-fonts
echo "Installing wqy-microhei-fonts..."
yum -y install wqy-microhei-fonts

# 查找 Zabbix 字体目录
echo "Searching for Zabbix font directories..."
FONT_DIRS=$(find / -type d -name 'fonts' -path '*assets/*' 2>/dev/null)

if [ -z "$FONT_DIRS" ]; then
    echo "No Zabbix font directories found."
    exit 1
else
    echo "Found Zabbix font directories:"
    echo "$FONT_DIRS"
fi

# 查找 Zabbix 配置文件
echo "Searching for Zabbix configuration files..."
ZABBIX_CONFS=$(find / -type f -name 'zabbix.conf.php' 2>/dev/null)

if [ -z "$ZABBIX_CONFS" ]; then
    echo "No Zabbix configuration files found."
    exit 1
else
    echo "Found Zabbix configuration files:"
    echo "$ZABBIX_CONFS"
fi

# 复制字体文件到所有字体目录
for FONT_DIR in $FONT_DIRS; do
    echo "Copying font to $FONT_DIR..."
    sudo cp $FONT_SRC $FONT_DIR
    # 设置字体文件权限
    echo "Setting font permissions in $FONT_DIR..."
    sudo chmod 644 $FONT_DIR/$FONT_NAME
done

# 修改所有找到的 Zabbix 配置文件
echo "Configuring Zabbix to use the new font..."
for ZABBIX_CONF in $ZABBIX_CONFS; do
    echo "Updating $ZABBIX_CONF"
    for FONT_DIR in $FONT_DIRS; do
        sudo sed -i "s|\(\$IMAGE_FONT_PATH\s*=\s*\).*|\1'$FONT_DIR/';|g" $ZABBIX_CONF
        sudo sed -i "s|\(\$IMAGE_FONT_NAME\s*=\s*\).*|\1'$FONT_NAME';|g" $ZABBIX_CONF
    done
done

echo "Font installation and configuration completed."

部署Zabbix proxy

修改主机名

declare -A hostnames=(
    [192.168.126.61]=proxy1
    [192.168.126.62]=proxy2
)

for ip in "${!hostnames[@]}"
do
    ssh $ip "hostnamectl set-hostname ${hostnames[$ip]}"
done

添加hosts

declare -A hostnames=(
    [192.168.126.61]=proxy1
    [192.168.126.62]=proxy2
)

FILENAME=/etc/hosts

for ip in "${!hostnames[@]}"
do
	echo "Attempting to connect to $ip..."
    ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $ip "cat > $FILENAME << EOF
127.0.0.1 localhost
192.168.126.61 proxy1 proxy1.lab.example.com
192.168.126.62 proxy2 proxy2.lab.example.com
EOF"
    if [ $? -eq 0 ]; then
        echo "Successfully updated on $ip"
    else
        echo "Failed to update on $ip"
    fi
done

时间同步

for x in proxy1 proxy2
do
    ssh $x "
	    yum install -y ntpdate
	    echo '* * * * * /usr/sbin/ntpdate -u ntp.aliyun.com && /sbin/hwclock -w' | crontab -
	"
done

安装zabbix proxy

for x in proxy1 proxy2
do
    ssh $x "
	rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/7/x86_64/zabbix-release-6.0-4.el7.noarch.rpm
	yum clean all
	yum install -y zabbix-proxy-mysql zabbix-sql-scripts zabbix-selinux-policy
	"
done

proxy1配置

创建初始化数据

mysql -h 192.168.126.200 -e "
	create database zabbix_proxy1_db character set utf8mb4 collate utf8mb4_bin;
	CREATE USER 'zabbix_proxy1'@'%' IDENTIFIED WITH mysql_native_password BY 'Zbx@123456';
	grant all privileges on zabbix_proxy1_db.* to 'zabbix_proxy1'@'%';
	set global log_bin_trust_function_creators = 1;
"

导入数据

cat /usr/share/zabbix-sql-scripts/mysql/proxy.sql | mysql --default-character-set=utf8mb4 -uzabbix_proxy1 -Dzabbix_proxy1_db -h192.168.126.200 -p'Zbx@123456'
mysql -h 192.168.126.200 -e "
	set global log_bin_trust_function_creators = 0;
"

编写配置文件

touch /var/log/zabbix-proxy.log
chown zabbix:zabbix /var/log/zabbix-proxy.log
cat > /etc/zabbix/zabbix_proxy.conf << EOF
ProxyMode=0
Server=192.168.126.51;192.168.126.52
Hostname=proxy1
DBHost=192.168.126.200
DBName=zabbix_proxy1_db
DBUser=zabbix_proxy1
DBPassword=Zbx@123456
DBPort=3306
ListenPort=10051
LogFile=/var/log/zabbix-proxy.log
PidFile=/run/zabbix/zabbix_proxy.pid
EOF
chown zabbix:zabbix /etc/zabbix/zabbix_proxy.conf

注意:Hostname要和web页面的名字相同

启动服务

systemctl restart zabbix-proxy
systemctl enable zabbix-proxy
systemctl status zabbix-proxy

web端添加proxy

image-20240722192101899

部署Zabbix Agent

修改主机名

hostnamectl set-hostname agent1

时间同步

yum install -y ntpdate
echo '* * * * * /usr/sbin/ntpdate -u ntp.aliyun.com && /sbin/hwclock -w' | crontab -

部署agent

rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/7/x86_64/zabbix-release-6.0-4.el7.noarch.rpm
yum clean all
yum install -y zabbix-agent2 zabbix-agent2-plugin-*

编写配置文件

mv /etc/zabbix/zabbix_agentd.conf /etc/zabbix/zabbix_agentd.conf.bak
cat > /etc/zabbix/zabbix_agent2.conf <<EOF
Server=192.168.126.61
ServerActive=192.168.126.61
Hostname=db1
PidFile=/run/zabbix/zabbix_agent2.pid
LogFile=/var/log/zabbix/zabbix_agent2.log
EOF

注意:Hostname要和web页面的名字相同

启动服务

systemctl restart zabbix-agent2
systemctl enable zabbix-agent2
systemctl status zabbix-agent2

web端添加agent

image-20240722200228159

监控任意主机

步骤:

  1. 安装客户端agent,修改配置文件并进行测试;
  2. web页面添加主机,关联模板;
  3. 调试

自定义监控项

步骤:

  • 客户端
  1. 通过命令、脚本取出对应的值;

  2. 根据zabbix格式要求,书写配置文件,创建键值;

  3. 重启客户端测试键值是否可用;

  • 服务端
  1. 服务端测试键值;
  2. 键值与监控项关联;
  3. web页面测试
  • web页面配置图形(可选)
  • web页面配置触发器(报警)

范例1:

通过命令、脚本取出对应的值

ss -tunlp | grep -w 80 | wc -l
1
pkill nginx
ss -tunlp | grep -w 80 | wc -l
0

在配置文件中创建键值

cat > xxxx/zabbix_agent2.d/web.conf <<EOF
#UserParameter=key,cmd
#UserParameter=check.ngx,sh /server/scripts/xxx.sh
UserParameter=check.nginx,ss -lntup|grep -w 80|wc -l
EOF

重启客户端

客户端本地测试键值

zabbix_agent2 -t  check.nginx
check.ngx                                     [s |1 ]

s:文字

1:测试结果

服务端测试

zabbix_get -s 监控的主机 -p 10050 -k system.hostname
监控的主机的主机名
zabbix_get -s 监控的主机 -p 10050 -k check.nginx
1

web页面创建监控项

把客户端创建的键值与zbx服务端监控项关联起来

image-20240723121947118

image-20240723122035246

根据监控项获取的数值(内容),决定是否要告警、是否要提示异常。

image-20240723122102446

image-20240723122114342

故障测试:systemctl stop nginx

image-20240723122138160

web页面: 添加图形

image-20240723122200320

范例2:

目标:检查指定用户是否存在异地登录。

通过命令、脚本取出对应的值

lastlog | grep root | awk '{print $3}'
192.168.126.1

在配置文件中创建键值

cat > xxxx/zabbix_agent2.d/web.conf <<EOF
#UserParameter=key,cmd
#UserParameter=check.ngx,sh /server/scripts/xxx.sh
UserParameter=user.login.check[*],lastlog |grep -w "$1" |awk '{print $$3}'
EOF

重启客户端

客户端本地测试键值

zabbix_agent2 -t user.login.check[root]
user.login.check[root]                        [s|192.168.126.1]

s:文字

1:测试结果

服务端测试

zabbix_get -s zabbix_web01 -k user.login.check[root]
192.168.126.1

web页面创建监控项

把客户端创建的键值与zbx服务端监控项关联起来

image-20240723123259765

触发器

image-20240723123554636

常见的键值和触发器函数

键值

zabbix客户端常用键值链接:https://www.zabbix.com/documentation/6.0/zh/manual/config/items/itemtypes/zabbix_agent

常用键值说明
agent.hostname主机名 获取的是客户端配置文件中指定的主机名
system.hostname主机名 系统的主机名 类似于hostname
agent.ping服务端与客户端是否通畅 通1 不通非1
net.if.in[if,]网络接口上传(进入)流量统计。返回 整数 if表示网卡名字 可以忽略。
net.if.out[if,]流出流量统计。返回整数
proc.num[,,,,]进程数。返回整数 name进程名字 user用户 state进程状态 cmdline进程对应的命令
net.tcp.port[,port]检查是否能建立 TCP 连接到指定端口。 返回 0 - 不能连接;1 - 可以连接

案例:过滤僵尸进程数量

state 写为 zomb

zabbix_get -s 172.16.1.7 -p 10050 -k proc.num[,,zomb]

zabbix_get -s 172.16.1.7 -k net.if.in[eth0,]

zabbix_get -s 172.16.1.7 -k proc.num[nginx]

zabbix_get -s 172.16.1.7 -k net.tcp.port[,80]

触发器函数

写在触发器表达式中.用于设置报警条件.触发器函数要结合键值(监控项).

功能(函数)说明
last()最近值 (最新的值),取出最近一些值
nodata()是否有数据
diff()是否发生变化 一般配合md5check()
avg()平均值
min()最小值
max()最大值

分析案例:* 目的是用来检查/etc/passwd*的变化情况,*间接检查是否有用户增加或删除.*

# 倒数第1个 /etc/passwd 的md5值

last(/Zabbix server/vfs.file.cksum[/etc/passwd,sha256],#1)

<>*

# 倒数第2个 /etc/passwd 的md5值

last(/Zabbix server/vfs.file.cksum[/etc/passwd,sha256],#2)

# 倒数第1个md5的值和倒数第2个md5的是 如果不相等了,则报警.目的是用来检查/etc/passwd的变化情况,间接检查是否有用户增加或删除.

*分析案例:* *触发器案例 swap*

条件1:swap总大小大于0

条件2:swap当前使用的大小大于0(没有直接可以使用的监控项,这里调整为当前swap空闲率小于100)发器案例 swap

# 条件swap总大小大于0

last(/web01/system.swap.size[,total])>0

# 条件swap当前使用的大小大于0(没有直接可以使用的监控项,这里调

整为当前swap空闲率小于100)

last(/web01/system.swap.size[,pfree])<100

# 表示并且

-a __> and

-o __> or

# 完整的表达式

last(/web01/system.swap.size[,total])>0 and

last(/web01/system.swap.size[,pfree])<100