Zabbix in een Docker container draaien op je VPS

Ingediend door Dirk Hornstra op 09-jul-2021 23:02

Twee projecten waar ik wat mee wil en moet doen: Zabbix en Docker. Dus maar combineren, niet Zabbix installeren als een website en met installatie-zaken zitten, maar netjes in een Docker container. Ik heb bij TransIP een VPS, waar ik in de Plesk-omgeving een menu-item Docker heb. En daar kun je jouw Docker-containers toevoegen en beheren.

Dat instellen en installeren verloopt niet zo soepel. Daarom heb ik eerst de installatie op een eigen MacBook gedaan zoals je in dit blog-bericht terug kunt lezen: link. Daarna wilde ik die stappen ook op mijn VPS uitvoeren want "hoe moeilijk kan het zijn"? Nou, daar kom je toch wel wat hindernissen tegen. 

Ik heb een zondagavond eraan verpatst en na die uren en geen werkende installatie had ik het wel even gehad. Maar goed, op mijn Linked-In profiel staat "Zabbix 4.0 certified specialist". En wat is een specialist als hij de software zelf niet ergens heeft draaien of überhaupt kan installeren? Dus deze week opnieuw de handen uit de mouwen gestoken en via een stappenplan de acties uitgevoerd. En dat geeft wél een goed resultaat.

Waarom zou je Zabbix gebruiken? Zabbix is gratis te gebruiken. Je kunt heel veel zaken monitoren. Als je een eigen website hebt of voor andere mensen een website of websites gebouwd hebt of je hebt een bedrijf en websites maken is je "business", dan is het niet meer dan logisch dat je de websites van je klanten (of gewoon je eigen, persoonlijke website) in de gaten houdt. Want er kunnen (veel) zaken fout gaan. Een foutieve redirect. Problemen op de server. Maar controleer jij elke dag jouw eigen site of sites van anderen? Nee dus. Een jaar geleden had een 301-redirect-plugin van Wordpress een foutje, waardoor iedereen die naar een website ging automatisch werd doorgestuurd naar een malafide website. Met Zabbix had je dat kunnen constateren.

Je kunt er zelf mee aan de slag. Maar mocht je er niet uitkomen of het gaat je wel goed af, maar je wilt echt "alles" weten wat er mogelijk is, dan kun je er cursussen voor volgen. Mijn collega Dirk Jan en ik hebben dat in 2019 gedaan (vandaar ook die titel 'certified specialist'). Brian van Baekel van Opensource ICT Solutions (link) is toen een aantal dagen bij ons op het werk geweest om uitleg te geven. Helemaal top!

En het nut van containers, dat heeft dit project me laten zien. Want het is nu heel simpel om even een container met zabbix-server of de zabbix-agent weg te gooien. Staat het allemaal als bestanden in een map in de www-root van je VPS, dan moet je dat allemaal los gaan weggooien. Dat scheelt veel, heel veel tijd!

Hierbij de rechtuit-rechtaan stappen die ik gedaan heb, daarna de uitleg. De titel van deze post is "Zabbix in een Docker container", maar eigenlijk zijn het 4 Docker containers:

  • een container met mySQL
  • een container met Zabbix Server
  • een container met de Zabbix front-end
  • een container met Zabbix Agent (nadat de vorige 3 containers goed werken)


De randvoorwaarden hierbij zijn (fictieve waarden, maar door die straks met jouw eigen waardes te vervangen heb je een werkend script):

  • het IP-adres van mijn server is 123.456.78.9
  • de mysql root-user geef ik het wachtwoord supergeheim123
  • de mysql user met inlog zabbix geef ik het wachtwoord hiha789
  • mySQL draait standaard op poort 3306 (in de Docker container), naar buiten zet ik dit op poort 13306
  • de web-interface draait standaard op poort 8080 (in de Docker container), omdat we ook anders sites op de VPS draaien zet ik deze naar buiten op poort 13307

 

Ik ben via SSH ingelogd op mijn development VPS. Eerst alle oude troep verwijderen:


docker ps
-- ik zie hier niets, dus geen draaiende containers
-- als je die wel hebt, je hebt een kolom NAMES, als daar staat zabbix-server-mysql staat, dan kun je:
-- docker rm -f zabbix-server-mysql
-- met -f forceer je het verwijderen, ook als deze in gebruik is.
docker images
-- ik zie hier:
-- zabbix/zabbix-web-nginx-mysql latest
-- zabbix/zabbix-server-mysql latest
docker rmi -f zabbix/zabbix-web-nginx-mysql:latest
docker rmi -f zabbix/zabbix-server-mysql:latest
-- ook hier geldt dat je met die -f je delete-actie forceert

In de web-interface van Plesk zag ik nog een aantal containers (die gestopt waren), die heb ik daar verwijderd. Goed, we hebben een "clean start".


-- eerst de mysql container installeren:
docker run --name mysql-server-zabbix -t -p 13306:3306 -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="hiha789" -e MYSQL_ROOT_PASSWORD="supergeheim123" -d mysql:8 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password

-- hierna zabbix server installeren:
docker run --name zabbix-server -t -e DB_SERVER_HOST="123.456.78.9" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="hiha789" -e MYSQL_ROOT_PASSWORD="supergeheim123" -e DB_SERVER_PORT="13306" -p 10051:10051 --restart unless-stopped -d zabbix/zabbix-server-mysql:alpine-5.4-latest

-- hierna de front-end installeren:
docker run --name web-nginx-mysql-zabbix -t -e ZBX_SERVER_HOST="123.456.78.9" -e DB_SERVER_HOST="123.456.78.9" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="hiha789" -e MYSQL_ROOT_PASSWORD="supergeheim123"  -e DB_SERVER_PORT="13306" -p 13307:8080 --restart unless-stopped -d zabbix/zabbix-web-nginx-mysql:alpine-5.4-latest

Hiermee kun je in Plesk zien dat je 3 draaiende containers hebt.
Zet bij de mysql-zabbix container nog wel even een vinkje bij "Automatic start after system reboot ". En dan krijg je ook nog poort 33060, die zetten we extern ook op 33060.
Maar goed, ze hebben waarschijnlijk nog geen contact met elkaar (firewalls e.d.). Dus we controleren de status:


docker logs mysql-server-zabbix
-- die lijkt OK, laatste melding "Starting temporary server" en "mysql will log errors to..."
-- melding niet ok? doe dan even een: docker restart mysql-server-zabbix

docker logs zabbix-server
-- melding dat SQL server niet bereikt kan worden. kwestie van firewall open zetten.
-- ik voeg poort 13306 toe aan zowel TCP als UDP, maar bij IP adres stel ik alleen 123.456.78.9 in, zodat je er alleen intern bij kunt.
-- voeg ook je eigen IP van thuis toe, zodat je met een eigen programma met de mySQL database kunt connecten.
-- via www.whatismyip.com kun je zien wat jouw IP is.
docker exec -it zabbix-server bash
ifconfig
-- dit geeft dat de zabbix server intern IP-adres 172.17.0.3 heeft, heeft submask 255.255.0.0
exit
-- dit ip-adres ook toegevoegd aan de allowed-list (CIDR notatie: 172.17.0.0/16)

docker restart zabbix-server
docker logs zabbix-server
-- zou nu goed moeten gaan. dan gaan we de server eerst stoppen:
docker stop zabbix-server

-- de connectie kan gemaakt worden, maar de tabel "users"  is leeg. zal een halve import/aanmaak-actie geweest zijn.
-- ik gebruik op mijn eigen PC MYSQL WorkBench:
-- https://www.mysql.com/products/workbench/
-- maak verbinding met de database (ik gebruik user root en wachtwoord supergeheim123) en voer dan dit uit:
drop database zabbix

-- vervolgens in je SSH sessie:
docker restart zabbix-server
docker logs zabbix-server
-- het uitvoeren van het script duurt lang, dus even geduld hebben.
-- in je MYSQL WorkBench kun je met use zabbix | select * from users in de gaten houden of de records aangemaakt worden

docker logs web-nginx-mysql-zabbix
-- ziet er goed uit.

http://123.456.78.9:13307
-- ik zie het zabbix scherm. mocht je het niet zien, dan waarschijnlijk je firewall-rules aanpassen.
 

Log in met Admin / zabbix
Ga dan naar Administration - Users en geef je account een andere username + wachtwoord.
Ga dan naar Configuration - Hosts, klik op de link Zabbix Servers.
Deze heeft standaard de naam "Zabbix server". Je kunt deze veranderen als je wilt.
Maar schrijf de naam dan wel op, want die hebben we nodig voor de Agent.
En vul bij het ip-adres van de agent het ip-adres van de server in (in mijn voorbeeld 123.456.78.9). Standaard poort is 10050, die kun je zo laten staan.


docker exec -it zabbix-server bash
ifconfig
-- dit geeft dat de zabbix server intern IP-adres 172.17.0.3 heeft
exit

docker run --name zabbix-agent -t -p 10050:10050 -e ZBX_HOSTNAME="Zabbix server" -e ZBX_SERVER_HOST=172.17.0.3 --restart unless-stopped -d zabbix/zabbix-agent:alpine-5.4-latest

docker logs zabbix-agent

Vervolgens moet je (waarschijnlijk) in de firewall nog een paar poorten open zetten. Zabbix server draait op poort 10051, de agent op poot 10050. Deze zet ik in de firewall open voor het interne IP (123.456.78.9) en de 172.17.0.0/16 range.

Nadat ik dat gedaan heb kreeg ik in het dashboard te zien dat Zabbix Server online was. De agent werkte nog niet. Met docker logs zabbix-agent zag ik de foutmelding dat een request van 172.17.0.1 niet toegestaan was. Ik heb dus een docker stop zabbix-agent | docker rm zabbix-agent en toen onderstaande uitgevoerd:


docker run --name zabbix-agent -t -p 10050:10050 -e ZBX_HOSTNAME="Zabbix server" -e ZBX_SERVER_HOST=172.17.0.1 --restart unless-stopped -d zabbix/zabbix-agent:alpine-5.4-latest

docker logs zabbix-agent

En daarmee heb ik een werkende Docker - Zabbix installatie!

Je site draait nu op HTTP. Dat moet eigenlijk nog HTTPS worden. Ik heb daar instructies voor gevonden, maar dat plaats ik wel even in een volgende post.

Wat is hier nu anders gegaan dan wat ik de vorige keer gedaan heb? In de voorbeelden wordt gebruik gemaakt van een intern netwerk en namen, maar op 1 of andere manier kon ik vervolgens niets in de browser zien. Op basis van mijn voorgaande acties heb ik bovenstaande uiteindelijk uit kunnen werken. Dus ik laat dit nog staan, mocht jij (of ik) op een later tijdstip nog wat problemen tegenkomen en wat willen proberen, dan kun je dat hieronder alsnog vinden!

------------------

Mijn eerdere (mislukte) pogingen:

Kijken of ik hier wel het netwerk aan kan maken:

docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 zabbix-net

Net als op mijn eigen computer krijg ik een output van cijfers en letters. Dat ziet er goed uit. Vervolgens mySQL installeren:


docker run --name mysql-server -t -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="wachtwoordvoorzabbixuser" -e MYSQL_ROOT_PASSWORD="wachtwoordvoorrootgebruiker" --network=zabbix-net -d mysql:8.0 --restart unless-stopped --character-set-server=utf8 --collation-server=utf8_bin --default-authentication-plugin=mysql_native_password

De image bestaat niet meer, wordt automatisch gedownload en aan het einde zie ik weer een output van cijfers en letters. Ook dit lijkt hier goed te gaan. Het lijkt erop dat ik vorige keer een stap gemist heb, ik moet de Zabbix Java gateway starten:


docker run --name zabbix-java-gateway -t --network=zabbix-net --restart unless-stopped -d zabbix/zabbix-java-gateway:alpine-5.4-latest

Dat gaat goed. Nu Zabbix Server installeren:


docker run --name zabbix-server-mysql -t -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="wachtwoordvoorzabbixuser" -e MYSQL_ROOT_PASSWORD="wachtwoordvoorrootgebruiker" -e ZBX_JAVAGATEWAY="zabbix-java-gateway" --network=zabbix-net      -p 10051:10051 --restart unless-stopped -d zabbix/zabbix-server-mysql:alpine-5.2-latest

Dat gaat goed. Nu de front-end nog installeren:


docker run --name zabbix-web-nginx-mysql -t -e ZBX_SERVER_HOST="zabbix-server-mysql" -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="wachtwoordvoorzabbixuser" -e MYSQL_ROOT_PASSWORD="wachtwoordvoorrootgebruiker" --network=zabbix-net -p 1337:8080 --restart unless-stopped -d zabbix/zabbix-web-nginx-mysql:alpine-5.2-latest

Let op dat je niet -p 80:8080 gebruikt, want op een VPS wordt poort 80 al door je andere website(s) gebruikt en krijg je een foutmelding als onderstaande.


docker: Error response from daemon: driver failed programming external connectivity on endpoint zabbix-web-nginx-mysql (cijfers-en-letters): Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use.

-- per ongeluk toch gedaan? dan eerst dit doen:
docker rm zabbix-web-nginx-mysql
-- en dan bovenstaande met de juiste poorten opnieuw uitvoeren.

Ik zou nu verwachten dat ik op domein-vps.nl:1337 ik mijn inlogscherm zou zien. Maar ik krijg niets. Ik voeg daarom eerst in de Firewall toe dat inkomend verkeer op poort 1337 toegestaan is.

Wat een drama, werkt dus voor geen meter. Alles weer verwijderd. Nog een keer gedaan, maar ook nu geen sjoege.

Ik was op 2 mei 2021 best ver met mijn "Zabbix in een Docker-container", maar omdat het encrypten van het wachtwoord niet goed ging, de container nog wel eens herstart werd, had ik niet een goed werkende omgeving. Maar omdat ik zelf een aantal sites heb draaien en ook voor anderen wat opgezet heb, is Zabbix een essentieel iets wat ik werkend moet hebben.

Ik ben op 4 juli 2021 opnieuw begonnen op mijn "development VPS" om te kijken of ik het nu wel werkend kon krijgen. Mijn eerdere stappen en uitleg kun  je terug lezen door verder naar beneden te scrollen, het start bij de 3 streepjes ( --- ).

---

De onderstaande tekst is van mijn blogpost die ik 2 mei 2021 uitgewerkt heb. Omdat de boel uiteindelijk niet goed genoeg draaide ben ik opnieuw begonnen, maar "ter referentie" laat ik het hier nog staan, mocht er nog iets in staan waar je wat aan hebt. Een aantal zaken heb ik ook in het voorgaande verhaal gebruikt.

Ik ben eerst begonnen om mijn "oude spul" op te ruimen op mijn VPS. Je doet dit door via SSH connectie te maken met je VPS. Dit zijn de commando's:



-- toon de actieve containers
docker ps
docker rm zabbix-mysql
docker rm zabbix-mysql-server
-- geen containers meer. dan alle geïnstalleerde images:
docker images
docker rmi mysql:latest
docker rmi zabbix/zabbix-server-mysql:latest

Het eerste statement gaat al fout, de docker network create. Foutmelding met failed to create NAT chain of iets dergelijks. Dan maar kijken of we het zonder dat netwerk kunnen doen:


 

docker run --name zabbix-mysql-server -t \
-p 31337:3306 \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD=“mijnwachtwoord” \
-e MYSQL_ROOT_PASSWORD=“heelcryptischwachtwoord” \
-d mysql:8.0 \
--character-set-server=utf8 \
--collation-server=utf8_bin \
--default-authentication-plugin=mysql_native_password

Bovenstaande is voor de mysql-server, nu de zabbix-server instantie:


 

docker run --name zabbix-server-mysql -t \
-e DB_SERVER_HOST="zabbix-mysql-server
" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="mijnwachtwoord
" \
-e MYSQL_ROOT_PASSWORD="heelcryptischwachtwoord
" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
-p 10051:10051 \
--restart unless-stopped \
-d zabbix/zabbix-server-mysql:alpine-5.2-latest

Dit gaat goed, nu nog de front-end installeren:



docker run --name zabbix-web-nginx-mysql -t \

-e ZBX_SERVER_HOST="zabbix-server-mysql" \
-e DB_SERVER_HOST="zabbix-mysql-server
" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="mijnwachtwoord
" \
-e MYSQL_ROOT_PASSWORD="heelcryptischwachtwoord
" \
-p 1337:8080 \
--restart unless-stopped \
-d zabbix/zabbix-web-nginx-mysql:alpine-5.2-latest

Hiermee werkte het nog niet. In de VPS-interface kun je variabelen toevoegen of aanpassen. Ik heb dit gedaan:


zabbix-server docker-container:

DB_SERVER_HOST    zabbix-mysql-server
die zabbix-mysql-server heb ik vervangen met het IP-adres van de VPS

veld DB_SERVER_PORT    toegevoegd
is default 3306, nu op 31337

zabbix-web-nginx-mysql-container:
ZBX_SERVER_HOST    zabbix-server-mysql
die zabbix-server-mysql vervangen met het IP-adres van de VPS

DB_SERVER_HOST    zabbix-mysql-server
die zabbix-mysql-server vervangen met het IP-adres van de VPS

DB_SERVER_PORT toegevoegd
is default 3306, nu op 31337

Als ik daar de web-interface open krijg ik echter "The server requested authentication method unknown to the client".
Via deze pagina (link) lijkt het erop dat de Zabbix-user niet met de mysql_native_password optie aangemaakt is.

ALTER USER 'zabbix'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mijnwachtwoord';
FLUSH PRIVILEGES;

-- in mijn geval 'zabbix'@'%' om het werkend te krijgen.

Hierna de mysql-container opnieuw opgestart en ja: ik krijg beeld.
In de Zabbix-omgeving krijg ik te zien dat de zabbix-client niets doet.

Ik heb nu een werkende Zabbix-omgeving (eindelijk!). Deze blog-post was ik eerst gestart met onderstaand statement, maar toen kreeg ik het niet werkend. Als referentie laat ik dat verhaal hier toch nog even staan:

Ik had dit in juni 2019 al eens gestart, maar dat wilde niet echt werken. Nu kwam ik dit artikel tegen van september 2019, dat lijkt me een mooie leidraad om erbij te hebben: link.

Op mijn ene VPS omgeving had ik in het verleden al wat ingericht, ik ga even naar de andere VPS om vanaf 0 te beginnen. Ook daar is al een bepaalde Docker-service op "Localhost", maar die kan ik alleen of uit zetten. Daar kan ik dus niet zoveel mee, dacht ik. Maar toen kwam ik erachter dat linksonder mijn "view" ingesteld stond als Business View of iets dergelijks. Na deze op Power User ingesteld te hebben kon ik images uploaden. Op mijn VPS staat CentOS. Via hoofdstuk 5 van de Zabbix documentatie (link) ga ik door naar naar de pagina van Zabbix Server (link) en zou ik dit in moeten voeren:

docker pull zabbix/zabbix-server-mysql:latest

docker run --name some-zabbix-server-mysql -e DB_SERVER_HOST="some-mysql-server" 
-e MYSQL_DATABASE="mijndatabase" -e MYSQL_USER="some-user" -e MYSQL_PASSWORD="some-password" 
-d zabbix/zabbix-server-mysql:latesthttps://hub.docker.com/_/mysql

De "some-zabbix-server-mysql" is de naam waarmee je container straks zichtbaar wordt in Plesk. Die geef ik dus de gewone naam "zabbix-mysql-server". De DB_SERVER_HOST is de host van je mySQL-database. Ik heb een database aangemaakt, en omdat ik vermoed dat localhost bij een container niet gaat werken, heb ik hier eerst ip-adres:3306 van gemaakt. En bij "some-user"  en "some-password" vul je de gebruikersnaam en wachtwoord van je mysql-database in. Bij de tag vul ik 5.4 in omdat dat op dit moment de meest recente versie is. En ik heb ook nog een -e MYSQL_DATABASE="mijndatabase" toegevoegd, omdat zabbix de standaard databasenaam is, maar ik deze een eigen naam wil geven.

Ik krijg (net als de vorige keer volgens mij) de foutmelding dat er geen connectie met de mySQL-server gemaakt kan worden. Dat zie je mooi in de console-log die je in Plesk kunt bekijken. Dus eerst maar mySQL workbench gedownload om te kijken of ik vanaf thuis wel connectie kan maken/krijgen. Als dat al niet werkt, dan zal het iets met firewall-regels of iets dergelijks te maken hebben (vermoed ik). Dat is het ook niet. MariaDB luistert standaard alleen maar naar "localhost". Ik moet dus ook een mySQL-docker instantie gaan activeren.

Dus ik ben eerst gaan kijken of ik een mysql-instantie in een Docker kan laten draaien. Dat kan ook nog wel eens handig zijn op mijn ontwikkel-laptop, daar staat al Docker Desktop op en dan hoef je geen XAMPP te installeren.

Eerst naar de mysql-pagina van Docker: link.


docker pull mysql:latest

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=zabbixdb 
-e MYSQL_USER=zabbixuser -e MYSQL_PASSWORD=zabbixpassword -d mysql:latest

Bovenstaand "run" commando is uitgebreider dan het standaard commando. Ik heb dit gedaan om direct de zabbix-database aan te maken bij opnieuw opstarten. Ik moet nog even kijken hoe dat allemaal werkt.