Depois do lab de EC2 com CloudWatch, a instância ficou no ar. Pareceu uma boa oportunidade de aproveitar o ambiente e montar algo diferente: um servidor de monitoramento centralizado que visse as duas clouds que uso, AWS e OCI.

A ideia era subir um Zabbix Server na AWS e conectar agentes rodando em lugares diferentes - uma EC2 e a minha instância da OCI. Multicloud de verdade, não só no nome.

Para não fazer o básico, decidi separar a aplicação do banco desde o início: Zabbix Server em container Docker, banco de dados no RDS. É como se faz em produção e queria ver esse fluxo na prática.

Arquitetura do lab: EC2 com Zabbix Server, RDS MySQL, agente na EC2 e agente na OCI
Arquitetura do lab: EC2 com Zabbix Server, RDS MySQL, agente na EC2 e agente na OCI

A arquitetura ficou assim:

  • Zabbix Server: EC2 t3.small, Ubuntu 24.04, Docker
  • Banco de dados: RDS MySQL 8.4
  • Agente 1: EC2 t2.micro (a instância do lab de CloudWatch)
  • Agente 2: OCI Ubuntu 22.04 (meu homelab)

Subindo o servidor Zabbix

Instância t3.small, Ubuntu 24.04, 20 GB de armazenamento, mesma chave SSH dos outros labs. Depois de subir, o processo padrão:

sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker ubuntu

No Security Group abri a porta 10051 para anywhere - é a porta que os agentes usam para falar com o servidor.

Docker Compose inicial (com MySQL em container)

Comecei com o MySQL em container para validar que tudo funcionava antes de migrar para o RDS:

services:
  zabbix-db:
    image: mysql:8.0
    container_name: zabbix-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: zabbix_pass
      MYSQL_ROOT_PASSWORD: root_pass
    volumes:
      - zabbix-db-data:/var/lib/mysql
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_bin

  zabbix-server:
    image: zabbix/zabbix-server-mysql:ubuntu-7.0-latest
    container_name: zabbix-server
    restart: unless-stopped
    ports:
      - "10051:10051"
    environment:
      DB_SERVER_HOST: zabbix-db
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: zabbix_pass
      MYSQL_ROOT_PASSWORD: root_pass
    depends_on:
      - zabbix-db

  zabbix-frontend:
    image: zabbix/zabbix-web-nginx-mysql:ubuntu-7.0-latest
    container_name: zabbix-frontend
    restart: unless-stopped
    ports:
      - "80:8080"
    environment:
      DB_SERVER_HOST: zabbix-db
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: zabbix_pass
      PHP_TZ: America/Sao_Paulo
      ZBX_SERVER_HOST: zabbix-server
    depends_on:
      - zabbix-db
      - zabbix-server

volumes:
  zabbix-db-data:

Zabbix subiu, frontend acessível em http://IP-DA-EC2. Login padrão: Admin / zabbix.

Zabbix ainda sem hosts cadastrados.
Zabbix funcionando com MySQL em container, ainda sem hosts cadastrados


Configurando os agentes

Agente na EC2 de lab

Instalei o zabbix-agent2 direto no sistema - mais simples que Docker para uma instância que já existe:

wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-2+ubuntu24.04_all.deb
sudo dpkg -i zabbix-release_7.0-2+ubuntu24.04_all.deb
sudo apt update
sudo apt install zabbix-agent2 -y

Editei o arquivo de configuração:

sudo nano /etc/zabbix/zabbix_agent2.conf
Server=IP-DO-ZABBIX-SERVER
ServerActive=IP-DO-ZABBIX-SERVER
Hostname=ec2-lab-nginx
sudo systemctl enable zabbix-agent2
sudo systemctl start zabbix-agent2

Abri a porta 10050 no Security Group dessa instância, com source restrito ao IP do Zabbix Server.

Agente na OCI

Na OCI usei Docker para facilitar a remoção depois - a instância já tem outros serviços rodando no docker-compose. Adicionei o agente no compose existente, sem criar arquivo separado:

  zabbix-agent:
    image: zabbix/zabbix-agent2:ubuntu-7.0-latest
    container_name: zabbix-agent
    restart: unless-stopped
    ports:
      - "10050:10050"
    environment:
      ZBX_SERVER_HOST: IP-PUBLICO-DO-ZABBIX-SERVER
      ZBX_HOSTNAME: oci-homelab
    privileged: true
    volumes:
      - /proc:/proc
      - /sys:/sys
      - /dev:/dev

O privileged: true e os volumes são necessários para o agente acessar as métricas reais do host. Sem isso ele monitora só o container, o que não serve pra nada aqui.

Para liberar a porta na OCI tive que usar iptables direto, além das regras de ingress no painel:

sudo iptables -I INPUT -p tcp -s IP-DO-ZABBIX-SERVER --dport 10050 -j ACCEPT
sudo netfilter-persistent save

Adicionando os hosts no Zabbix

Com os agentes rodando nos dois lados, fui ao frontend cadastrar os hosts. Em Configuration → Hosts → Create host:

Para a EC2:

  • Host name: ec2-lab-nginx
  • Groups: Linux servers
  • Interfaces → Agent: IP da EC2, porta 10050

Para a OCI:

  • Host name: oci-homelab
  • IP público da OCI, porta 10050

Em ambos adicionei o template Linux by Zabbix agent na aba Templates. Depois de salvar, aguardei uns dois minutos e os dois apareceram verdes em Monitoring → Hosts.


Migrando o banco para o RDS

Com tudo funcionando, parti para a migração do MySQL em container para o RDS.

Criando o RDS

No console AWS criei um RDS MySQL 8.4 pelo modo de criação fácil. Durante a criação vinculei à instância EC2 do Zabbix - a AWS automaticamente coloca o RDS na mesma VPC, configura o Security Group e a subnet. Nenhuma configuração manual de rede necessária.

Exportando o banco atual

docker exec zabbix-db mysqldump --no-tablespaces -u zabbix -pzabbix_pass zabbix > zabbix_backup.sql

A flag --no-tablespaces foi necessária porque o usuário zabbix não tem o privilégio PROCESS. Sem ela o mysqldump retorna erro de permissão.

Criando o banco no RDS

mysql -h SEU-ENDPOINT-RDS -u admin -p
CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'zabbix'@'%' IDENTIFIED BY 'zabbix_pass';
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'%';
FLUSH PRIVILEGES;
EXIT;

Erros no import

Erro 1: log_bin_trust_function_creators

ERROR 1419 (HY000): You do not have the SUPER privilege and binary logging is enabled

O RDS ativa binary logging por padrão e bloqueia criação de functions sem privilégio SUPER. Como o RDS não dá SUPER para ninguém, a solução é habilitar o parâmetro log_bin_trust_function_creators.

O parâmetro fica no parameter group, mas o grupo padrão não é editável. Tive que criar um grupo customizado:

RDS → Parameter groups → Create parameter group → mysql8.4 → nome zabbix-params → editar → log_bin_trust_function_creators = 1

Depois associei ao banco em Modify DB instance e reiniciei a instância para aplicar.

Erro 2: ALLOW_NONEXISTENT_DEFINER

ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or ALLOW_NONEXISTENT_DEFINER privilege(s)

O dump tinha definers do usuário zabbix que o RDS não aceita importar. Resolvi limpando os definers do arquivo:

sed 's/DEFINER=[^*]*\*/\*/g' zabbix_backup.sql > zabbix_backup_clean.sql
mysql -h SEU-ENDPOINT-RDS -u admin -p zabbix < zabbix_backup_clean.sql

Atualizando o Docker Compose

Removi o serviço zabbix-db e o volume, e atualizei as variáveis de ambiente para apontar para o RDS:

services:
  zabbix-server:
    image: zabbix/zabbix-server-mysql:ubuntu-7.0-latest
    container_name: zabbix-server
    restart: unless-stopped
    ports:
      - "10051:10051"
    environment:
      DB_SERVER_HOST: SEU-ENDPOINT-RDS
      DB_SERVER_PORT: 3306
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: zabbix_pass
      MYSQL_ROOT_USER: admin
      MYSQL_ROOT_PASSWORD: SUA-SENHA-ADMIN-RDS

  zabbix-frontend:
    image: zabbix/zabbix-web-nginx-mysql:ubuntu-7.0-latest
    container_name: zabbix-frontend
    restart: unless-stopped
    ports:
      - "80:8080"
    environment:
      DB_SERVER_HOST: SEU-ENDPOINT-RDS
      DB_SERVER_PORT: 3306
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: zabbix_pass
      MYSQL_ROOT_USER: admin
      MYSQL_ROOT_PASSWORD: SUA-SENHA-ADMIN-RDS
      PHP_TZ: America/Sao_Paulo
      ZBX_SERVER_HOST: zabbix-server

Um detalhe que travou o container: a imagem do Zabbix tenta se conectar ao banco com usuário root por padrão. No RDS não existe usuário root - o superusuário se chama admin. Sem as variáveis MYSQL_ROOT_USER e MYSQL_ROOT_PASSWORD apontando para o admin do RDS, o container não subia. Foi o último erro antes de tudo funcionar.

docker compose down
docker compose up -d

Tudo certo, banco subiu no RDS.

Console AWS mostrando o RDS MySQL ativo e conectado ao Zabbix Server
RDS MySQL ativo no console AWS, com a instância EC2 do Zabbix associada

Dashboard do Zabbix com os dois hosts monitorados em status verde
Dashboard do Zabbix com os dois hosts - EC2 e OCI - ativos e monitorados

Dashboard da instância OCI no Zabbix
Dashboard da instância OCI no Zabbix


O que ficou desse lab foi menos sobre o Zabbix em si e mais sobre o RDS. Nunca tinha usado de verdade, e os três erros do import me ensinaram mais sobre como o serviço funciona.