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.
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.
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.
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.