Compare commits

..

17 Commits

Author SHA1 Message Date
Eli Winderickx
679bc6992c Zabbix upgrade 2025-12-23 20:12:09 +01:00
Eli Winderickx
00a9c1e1e3 Git info refresh 2025-12-18 11:20:56 +01:00
Eli Winderickx
19ea93c8bd Package update 2025-12-13 07:23:50 +01:00
Eli Winderickx
9db388dcc1 The Blog rebuild 2025-12-13 07:12:14 +01:00
Eli Winderickx
b9babf8cf0 Meta data aangepast 2025-01-31 21:44:57 +01:00
Eli Winderickx
7bde247875 lsyncd 2025-01-31 21:32:43 +01:00
Eli Winderickx
216cb3a81f MySQL Extra stappen in Podman 2025-01-23 14:18:44 +01:00
Eli Winderickx
ad5a651290 Update file 24-10-05-Zabbix_Utils_in_Python.md 2024-10-13 08:36:43 +00:00
Eli Winderickx
01a64bf9c2 Replace ZabbixUtils_Cover.png 2024-10-13 08:35:18 +00:00
Eli Winderickx
d20687ffdc Merge branch 'Proxy-Utils' into 'main'
Proxy utils

See merge request eliwinderickx/blog2024!2
2024-10-13 08:32:13 +00:00
Eli Winderickx
b82f1f0cf3 Update file 24-10-05-Zabbix_Utils_in_Python.md 2024-10-13 08:29:53 +00:00
Eli Winderickx
519ae7f77c Upload New File 2024-10-13 08:29:31 +00:00
Eli Winderickx
91f3ae8242 Python Zabbix_utils 2024-10-06 08:44:38 +03:00
Eli Winderickx
4ba6c308e7 Merge branch 'Zabbix-in-Docker' into 'main'
Zabbix in Docker:

See merge request eliwinderickx/blog2024!1
2024-07-08 18:15:10 +00:00
Eli Winderickx
96056db072 Zabbix in Docker:
- Cover
- Proxy + Agent aangevuld
2024-07-08 20:09:35 +02:00
Eli Winderickx
c12d8689ec CoverZabbixInDocker 2024-07-08 18:54:50 +02:00
Eli Winderickx
ef9763f6bb First draft 2024-07-08 08:49:47 +02:00
33 changed files with 579 additions and 18 deletions

30
Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
# Use a lightweight Node.js image
FROM node:22-alpine AS builder
# Set the working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the rest of the application code
COPY . .
# Build the Next.js application
RUN npm run build
# Use a new image for the production environment
FROM node:22-alpine AS runner
# Set the working directory
WORKDIR /app
# Copy built files from the builder stage
COPY --from=builder /app ./
# Expose the application port
EXPOSE 3000
# Command to run the application
CMD ["npm", "start"]

View File

@@ -1,5 +1,5 @@
{
"title": "Blog Winderickx.me",
"title": "Blog Tuxonauts.be",
"description": "Technologie blog vol informatie",
"repositoryUrl": "https://gitlab.com/eliwinderickx/blog2024"
"repositoryUrl": "https://git.tuxonauts.be/ewinderickx/Blog"
}

View File

@@ -8,8 +8,9 @@ Hier probeer ik interessante weetjes te verzamelen over de producten waarmee ik
Aarzel dus niet en neem gerust contact op!
- [Gitlab](https://gitlab.com/eliwinderickx)
- [Github](https://github.com/winderickxeli)
- [Git](https://git.tuxonauts.be)
- [Matrix](https://matrix.to/#/@ewinderickx:chat.tuxonauts.be)
- [Tuxonauts](https://tuxonauts.be)
- [LinkedIn](https://www.linkedin.com/in/eli-winderickx-507944223)
![](/eli.jpg)

4
package-lock.json generated
View File

@@ -6,7 +6,7 @@
"": {
"name": "brevifolia-next",
"dependencies": {
"@next/font": "13.0.4",
"@next/font": "^13.0.4",
"glob": "^8.0.3",
"gray-matter": "^4.0.3",
"next": "13.0.4",
@@ -190,6 +190,8 @@
},
"node_modules/@next/font": {
"version": "13.0.4",
"resolved": "https://registry.npmjs.org/@next/font/-/font-13.0.4.tgz",
"integrity": "sha512-csZhVqe870p7XE03WfbDLzjVwdBAWxe6/lWGQosfqY/XN5tsmfDLpj442veicfCiiuF7/ydSnAAJxH8PQVBVWQ==",
"license": "MIT"
},
"node_modules/@next/swc-android-arm-eabi": {

View File

@@ -2,16 +2,16 @@
"name": "brevifolia-next",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"dev": "next dev -p 5000",
"start": "next start -p 5000"
},
"dependencies": {
"@next/font": "13.0.4",
"@next/font": "^13.0.4",
"glob": "^8.0.3",
"gray-matter": "^4.0.3",
"next": "13.0.4",
"glob": "^8.0.3",
"raw-loader": "^4.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -21,4 +21,5 @@
"eslint": "8.27.0",
"eslint-config-next": "13.0.4"
}
}

View File

@@ -1,13 +1,13 @@
import "../styles/globals.css"
import { Work_Sans } from "@next/font/google"
import localFont from "@next/font/local"
// importing the Work Sans font with
// the Next.js 13 Font Optimization Feature
const workSans = Work_Sans({
weight: ["400", "700"],
style: ["normal", "italic"],
subsets: ["latin"],
})
const workSans = localFont({ src: '../public/fonts/WorkSans.ttf' })
// const workSans = Work_Sans({
// weight: ["400", "700"],
// style: ["normal", "italic"],
// subsets: ["latin"],
// })
function MyApp({ Component, pageProps }) {
return <main className={workSans.className}>

View File

@@ -0,0 +1,141 @@
---
title: "Zabbix in Docker"
excerpt: "De beste monitoring software op ieder platform"
date: "2024-07-08T21:00:00.000Z"
author: Eli Winderickx
hero_image: /cover_ZabbixInDocker.png
category: Zabbix,Docker,Intro,Installatie
---
## Waarom doen we dit?
Zabbix is een ontzettend goede monitoring software en echt een aanrader voor iedere IT'er om op z'n minst eens te proberen. Er zijn echter bepaalde platformen zoals Microsoft Windows Server waar Zabbix niet op werkt.
Niet getreurd! Ook hier is een alternatief beschikbaar. Je kan namelijk in container variant Zabbix draaien. Deze methode zorgt ervoor dat je niet alleen snel en eenvoudig Zabbix kan starten, je kan ook nog eens het doen op een nieuwe waaier van platformen.
Nu alles uitgeklaard is, kunnen we erin vliegen. we gaan een netwerk in Docker opzetten, alle relevante componenten opspinnen met de juiste configuratie en daarnaast gaan we een apart netwerk aanmaken voor een Zabbix Proxy op te zetten. Dat gaat dan kunnen simuleren hoe proxies in het echte leven ook gebruikt kunnen worden: off-site.
> De poorten die op het host toestel gekozen zijn, zitten in een range die zullen werken voor zowel Docker en Podman. Specifiek voor die container opstellingen die rootless zouden gaan.
## De uitvoering
We maken eerst een netwerk aan waarin we onze core componenten gaan laten verbinden.
```bash
docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 zabbix-net
```
Een volgende belangrijke stap is een database aanmaken. Hier kiezen we voor de laatste versie van MySQL. In principe kan je hier ook PostgreSQL kiezen. We moeten hier vooral de nodige variabelen meegeven zodat MySQL blijft werken. Vooral `MYSQL_DATABASE`, `MYSQL_USER` en `MYSQL_PASSWORD` zijn heel relevant. We geven met `-v` ook een map mee die gebruikt zal worden in de container voor de database zelf op te slaan. Specifiek voor Zabbix moeten we ook nog de character set en collation meegeven.
> Voor podman moet je eerst `podman unshare chown 27:27 /pad/naar/db` uitvoeren. Anders heb je niet de nodige rechten.
```bash
docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" \
-v /var/lib/mysql:/var/lib/mysql:Z \
--network=zabbix-net --restart unless-stopped -d mysql \
--character-set-server=utf8 --collation-server=utf8_bin
```
Een volgende component is de Zabbix Java Gateway. Die is optioneel en enkel relevant als je Java applicaties plant te monitoren. Deze heeft niet veel nodig en moet vooral in het juiste netwerk bestaan.
```bash
docker run --name zabbix-java-gateway -t \
--network=zabbix-net \
--restart unless-stopped \
-d zabbix/zabbix-java-gateway:alpine-7.0-latest
```
Ook het volgende component is enkel relevant als je SNMP traps plant te ontvangen. Hier gaan we ook een paar mappen meegeven waarin één van de mappen gebruikt wordt om de ontvangen traps op te slaan en de andere om eventuele MIBs te voorzien.
```bash
docker run --name zabbix-snmptraps -t \
-v /var/lib/zbx_instance/snmptraps:/var/lib/zabbix/snmptraps:rw \
-v /var/lib/zbx_instance/mibs:/usr/share/snmp/mibs:ro \
--network=zabbix-net \
-p 1162:1162/udp \
--restart unless-stopped \
-d zabbix/zabbix-snmptraps:alpine-7.0-latest
```
Nu zijn we eindelijk gekomen aan de Zabbix server. Hier geven we heel wat opties mee. We lopen er even door:
- `DB_SERVER_HOST`: Dit is een verwijzing naar onze MySQL container. geef hier de naam in die we eerder gebruikt hadden.
- `MYSQL_DATABASE`, `MYSQL_USER` en `MYSQL_PASSWORD` moeten ook overeenkomen met de settings die we eerder al hadden geconfigureerd.
- `ZBX_ALLOWUNSUPPORTEDDBVERSIONS`: Dit is een configuratie om ondersteuning met MySQL 9 toe te staan. Officieel is deze nog niet ondersteund en dus zou dit best niet in productie gebruik worden. Voor onze test omgeving is dit geen probleem.
- `ZBX_JAVAGATEWAY`: Hiermee kunnen deze container linken aan onze Zabbix server.
- `ZBX_ENABLE_SNMP_TRAPS` en `--volumes-from`: Anders dan bij de Zabbix Java Gateway, heeft Zabbix server enkel toegang nodig naar de fysieke volumes van de Zabbix SNMP trapper.
- `-p`: Hier hebben we 11051 gekozen als poort voor Zabbix trapper process. Vooral om aan te tonen dat Zabbix ook met andere poorten werkt.
```bash
docker run --name zabbix-server-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
-e ZBX_ENABLE_SNMP_TRAPS="true" \
-e ZBX_ALLOWUNSUPPORTEDDBVERSIONS=1 \
--network=zabbix-net \
-p 11051:10051 \
--volumes-from zabbix-snmptraps \
--restart unless-stopped \
-d zabbix/zabbix-server-mysql:alpine-7.0-latest
```
Nu de Zabbix server draait, moeten we de ook nog een manier hebben om de configuratie aan te passen en de data te weergeven. Hier komt de Zabbix web container naar boven. Deze moet uiteraard verbinden met hetzelfde netwerk en ook dezelfde database als de Zabbix Server. Hier kiezen we om poort `8080`, opnieuw voor compabiliteit voor rootless containers.
```bash
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="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--network=zabbix-net \
-p 8080:8080 \
--restart unless-stopped \
-d zabbix/zabbix-web-nginx-mysql:alpine-7.0-latest
```
### De proxy in een apart netwerk
Omdat we het graag een beetje uitdagender maken en real-life situaties simuleren, heb ik hier gekozen om de proxy in een apart netwerk te steken. Deze stap is uiteraard optioneel maar wel relevant als je proxy op andere fysieke locaties wilt testen.
De proxy moet hier uiteraard naar de Zabbix Server kunnen verbinden. Omdat we de modus van de Zabbix proxy niet meegeven, gaat die standaard in Active mode starten en wilt die dus zelf verbinding maken met de Zabbix server. We kunnen dat configureren door `ZBX_SERVER_HOST` in te stellen.
Met containers is dat niet altijd duidelijk naar welk IP-adres we willen verbinden maar we kunnen wel iets anders gebruiker om de verbinding mogelijk te maken. Voor Docker kunnen we `host.docker.internal` gebruiken als een soort localhost adres. Bij Podman is dat `host.containers.internal`.
> Hier gebruik ik een Zabbix Proxy met SQLite3. Dat is in de meeste gevallen de meest interessante optie om als database backend te gebruiken.
```bash
docker network create --subnet 172.19.0.0/16 --ip-range 172.19.240.0/20 zabbix-proxy
docker run --name some-zabbix-proxy-sqlite3 --init -d \
-e -e ZBX_HOSTNAME=remote-proxy
-e ZBX_SERVER_HOST=host.containers.internal:11051 \
--network=zabbix-proxy \
-p 11055:10051 \
zabbix/zabbix-proxy-sqlite3:latest
```
### De agent
Om ons verhaal goed af te maken, gaan we natuurlijk ook een agent installeren in het netwerk van de proxy. Daar horen nog een paar opties bij. Op moment van schrijven is 6.4 nog de laatste versie van de Zabbix Agent beschikbaar.
```bash
docker run --name some-zabbix-agent -e ZBX_HOSTNAME="my-agent" \
-e ZBX_SERVER_HOST=host.containers.internal -e ZBX_SERVER_PORT=11055 \
--network=zabbix-proxy \
--init -d zabbix/zabbix-agent2:latest
```
## Nu naar de webinterface
Als je goed gevolgd hebt, zijn alle containers actief. Dat betekent ook dat de Zabbix web interface beschikbaar moet zijn op [localhost](http://localhost:8080). Je kan daar nu aanmelden met de standaard logingegevens: Admin / zabbix
Onder Administration -> Proxies kan je nu een nieuwe Proxy aanmaken. Het belangrijkste is hier is de juiste naam (`ZBX_HOSTNAME`) in te geven en ook de mode op `active` laten staan. Als je de proxy goed toegevoegd hebt, staat de status op Online, version op 7.0.0.
![](./AddZabbixProxy.png)
Nu de Proxy in orde is, kunnen we de agent ook toevoegen. Dit doen we onder `Data collection` -> `Hosts`. Hier moeten we een paar gegevens ingeven om dit werkende te krijgen:
- Host name (`ZBX_HOSTNAME`)
- Host groups (`Linux servers`)
- Proxy (`remote-proxy`)
- Templates (`Linux by Zabbix agent active`)
## Proficiat!
Je hebt nu een werkende Zabbix installatie! Nu kan je beginnen met alles te monitoren. Dus voeg nieuwe hosts toe, link templates en exploreer. Dit is een uitstekend moment om eens na te gaan welke de nieuwe features zijn in Zabbix 7.0. Weet je hier niet goed? Dan is hier een [cheat sheet](https://www.zabbix.com/whats_new_7_0).

View File

@@ -0,0 +1,104 @@
---
title: "zabbix_utils met Python3"
excerpt: "Eenvoudig gebruik maken van de Zabbix API"
date: "2024-10-05T21:00:00.000Z"
author: Eli Winderickx
hero_image: /ZabbixUtils_Cover.png
category: Zabbix,Python,Scripting
---
# De zabbix_utils library
In sommige gevallen hebben we niet meteen de mogelijkheid om data of configuratie door te sturen naar Zabbix of willen we iets geautomatiseerder gebruiken. Zabbix heeft hiervoor een heel goed gedocumenteerde API maar dat is niet altijd even gebruiksvriendelijk.
Gelukkig heeft Zabbix hiervoor de perfecte oplossing; Een Python library. Python is een eenvoudig te leren scripttaal die wereldwijd breed gebruikt wordt door tal van gebruikers. Als jij er nog geen gebruik van maakt, zal je dat na deze post zeker wel doen!
Wat je verder moet weten over de zabbix_utils is dat deze library gebruikt maakt van alles wat Zabbix te bieden heeft. Iedere beschikbare API call kan met deze tools gemaakt worden. Dat varieert dus van configuratie wijzigingen doorvoeren, tot wijzigingen aan jouw Zabbix installatie zelf tot zelfs verzamelde gegevens uitlezen. Van zodra je een beetje vertrouwd bent met deze library, kan je er van zelf mee aan de slag. Voor die verdere stappen verwijs ik je graag door naar de [documentatie](https://www.zabbix.com/documentation/current/en/manual/api). Voor nu zullen we al even naar een eenvoudig voorbeeld kijken.
## Eerst een paar zaken op orde stellen
Je moet natuurlijk een paar dingen eerst installeren. Ik ga er opnieuw van uit dat je een RHEL gebasseerd OS gebruikt. Anders gaat iedere zoekmachine je wel kunnen helpen. Hier lopen we er even door:
- Python3: `dnf install python3`
- Pip: `dnf install python3-pip`
- zabbix_utils: `pip3 install zabbix_utils`
- Wonderwords: (optioneel voor de Utils maar nodig voor het script hieronder): pip3 install wonderwords
> Python is een heel populaire programmeer / scripttaal. Het is ook heel eenvoudig te lezen en snel te leren. Hierbij moet je vooral rekening houden dat je voldoende spaties of tabs gebruikt om aan te geven dat je nog in een functie of loop aan het werken bent.
## Een simpel script
Nu we alles hebben, kunnen we ermee aan de slag. We beginnen met de basis van een script. Maak dus een leeg document aan en volg gerust mee.
```python
#!/usr/bin/python3
# Importeer utils en wonderwords
from zabbix_utils import ZabbixAPI
from wonderwords import RandomWord
# Variabelen
zabbix_url="https://link.to.zabbix/api_jsonrpc.php"
api_token="<token>"
rw = RandomWord()
# Login
api = ZabbixAPI(url=api_token)
api.login(token=api_token)
```
We starten hier dus met een Python script. Vervolgens importeren we de nodige bibliotheken. Onder variabelen hebben we daar dan met `zabbix_url` een pad naar onze Zabbix instantie met daarachter `api_jsonrpc.php` wat de endpoint voor de API is.
De Token kan aangemaakt worden in Zabbix onder `User settings` door links onderaan de pagina vervolgens op `API tokens` te klikken. In het nieuwe venster kan je nu een token aanmaken. Zorg voor een duidelijke omschrijving en eventueel een vervaldatum. Zorg dat je daarna de token goed kopieert en opslaat. Je kan wel een nieuwe token genereren maar dezelfde string ga je niet meer te zien krijgen.
> Op gebied van rechten zorgt de token voor dezelfde rechten als de user voor wie de token is aangemaakt. Als die user iets niet kan, kan de API daar geen verandering brengen.
Voor het laatste stukje van het eerste deel gaan we de effectieve login doen. We zetten een verbinding op naar `zabbix_url` en melden dan aan met de token.
```python
# Maak een host aan
def create_host(host_name):
result = api.host.create({
"host": host_name,
"interfaces": [{
"type": 1,
"main": 1,
"useip": 0,
"ip": "",
"dns": f"<DNS NAAM>",
"port": "10050"
}],
"tags": [{
"tag": "purpose",
"value": "dummy"
}],
"tls_accept": 2,
"tls_connect": 2,
"tls_psk": "<PSK>",
"tls_psk_identity": "PSKIdentity",
"monitored_by": 2,
"proxy_groupid": "1",
"groups": [{
"groupid": "26"
}],
"templates": [{
"templateid": "10561"
}]
})
return result
```
In dit script maken we een host aan met naam `host_name`. We definieëren een Zabbix interface aan die op DNS zal verbinden op poort 10050. We kunnen daaronder tags terugvinden. Hier is er slechts eentje maar dat kunnen er veel meer zijn. Daarna stellen we ook een preshared key in. Dit zorgt ervoor dat we meteen kunnen genieten van een beveiligde verbinding.
Het volgende stuk geven we aan dat de host door een Proxy group wordt beheerd en we geven ook mee welke group dat is. Tot slot geven we ook aan tot welke groep het toestel behoort en welke templates dat gelinkt mogen worden. Hier gebruik ik een zelf aangemaakte group maar de `templateid` kan je gerust gebruiken.
> Als je wilt weten welke `groupid` of `templateid` je moet gebruiken, kan je naar die entiteit gaan en kan je in de URL meestal die code terugvinden.
```python
# Genereer 20 nieuwe hosts met een unieke naam
for _ in range(20):
word1=rw.word()
word2=rw.word()
host_name = f"{word1.capitalize()} {word2.capitalize()}"
result = create_host(host_name)
print(f"Created host: {host_name} - Result: {result}")
```
Om het script nu bruikbaar te maken, gaan we hier een kleine loop maken die 20 keer twee willekeurige woorden gaat genereren om daar dan een host van te maken. Het resultaat krijgen we daarna ook gewoon terug.
Dat was het al! Nu hebben we een volledig werkend script. Dit kan je uitvoeren met `python3 <naam van je script>` en verder is het nu gewoon doen! Veel succes en happy monitoring!

62
posts/25-01-31-lsync.md Normal file
View File

@@ -0,0 +1,62 @@
---
title: "Syschroniseer mappen met lsync"
excerpt: "Het kan handig zijn om bestanden over servers gesynchroniseerd te houden. Dat is niet moeilijk en hier zie je hoe."
date: "2025-01-27T12:00:00.000Z"
author: Eli Winderickx
hero_image: /cover_lsyncd.png
category: synchronisatie,lsync,Linux
---
# Synchroniseer mappen met lsync
Het is handig dat we op vershillende manieren bestanden kunnen overzetten naar andere servers. Er werd al heel hard gebruik gemaakt van `SCP`. Tegenwoordig is dat niet meer veilig en gebruik je best `rsync`. Een heel handig programma'tje. Deze kan je nu ook gebruiken in combinatie met andere software zoals `lsync` (L, niet I) om mappen gesynchroniseerd te houden. Deze tool werkt namelijk als een service.
## Installatie
Zoals je kan verwachten kan je je packagemanager gebruiken om de tool terug te vinden en te installeren. Deze zou in de standaard repos moeten zitten.
```bash
sudo dnf install lsyncd
sudo apt install lsyncd
```
## Configuratie
`lsync` werkt met lua als configuratie taal. Daarnaast wordt je verwacht om zelf heel wat zaken klaar te zetten of in te stellen. Dat begint met het aanmaken van de nodige mappen en aanmaken van de vereiste bestanden die je gaat gebruiken.
```bash
sudo mkdir -p /data/{bron,bestemming}
sudo mkdir /var/log/lsyncd
sudo mkdir /etc/lsyncd
sudo touch /var/log/lsyncd/lsyncd.{log,status}
```
Nu kunnen we de algemene configuratie aanmaken in `/etc/lsyncd/lsyncd.conf.lua`.
```lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status"
}
```
Hierop aanvullend gaan we ook de synchronisatie instellen in datzelfde bestand. Van zo sync blokken kunenn er meerdere bestaan. Elke blok gaat dan een unieke synchronisatie vertegenwoordigen.
```lua
sync {
default.rsync,
source = "/data/source",
target = "/data/dest"
}
```
Zoals je je kan inbeelden is dit niet geheel relevant. Dit synchroniseert twee mappen op dezelfde server. We kunnen dit nu aan passen om de bestanden naar een andere server te verplaatsen. Een paar aandachtspunten is dat dit programma stanaard als `root` gebruiker wordt uitgevoerd. Zo gaan verbindingen opgestart worden. Het is dus interessant om de verbinding op voorhand al eens te testen met de root gebruiker. Best practices zijn dan ook om een andere externe gebruiker in te stellen zodat er niet wordt aangemeld met de `root` user.
```lua
sync {
default.rsync,
source = "/pad/naar/lokale/map",
target = "externegebruiker@server:/pad/naar/te/delen/map",
rsync = {
rsh = "/usr/bin/ssh -i /pad/naar/.ssh/identityfile"
}
}
```
Als dan eenmaal alles goed staat, kan je de service starten met: `sudo systemctl enable --now lsync.service`. Problemen met de configuratie kan je terugvinden met `sudo systemctl status lsync.service`. Daarnaast problemen met de verbinding zelf worden opgeslagen in het logbestand dat we in de configuratie hebben opgegeven. (`/var/log/lsyncd/lsyncd.log`)

View File

@@ -0,0 +1,220 @@
---
title: "Zabbix upgraden in moeilijke omstandigheden"
excerpt: "Een Zabbix upgrade is simpel, tot er vanalles extra bij komt kijken"
date: "2025-02-18T12:00:00.000Z"
author: Eli Winderickx
hero_image: /ZabbixRebranding_cover.png
category: Zabbix,upgrades,Linux
---
# Situering
We beginnen bij het begin. Een Zabbix 6.4 server op een Rocky Linux 8 server met een PostgreSQL 13 en een bijhorende oude TimeScaleDB versie. Dat is een hele boterham om aan te pakken. Daarnaast was de server ook stilaan End-of-life waardoor er een ander fysiek toestel werd voorzien. Niet alleen zijn er veel bewegende componenten die elk met hun complexiteit komen, er is ook nog een downtime waarmee rekening te houden. Door het geautomatiseerde proces binnen de omgeving, was Zabbix een centraal component. Nieuwe releases kunen niet plaatsvinden als Zabbix niet beschikbaar is. Gelukkig kon ik goed oefenen zodat we op D-day de hinder beperkt konden houden. Hieronder ben ik stap per stap aan de slag gegaan.
# Backup maken
## De database op de oude server voorbereiden
Op de oude server was een oudere PostgreSQL versie voorzien en een TimeScaleDB die gelijktijdig voorzien werd. Specifiek aan TimeScaleDB is dat die heel kieskeurig is naar de versie van PostgreSQL en ook TimeScaleDB. Helaas kan ik met de oude versie niet meteen een migratie doen naar een moderner OS. Eerst moet er dus een upgrade gebeuren. De eenvoudigste oplossing was TimeScaleDB te upgraden. We kunnen deze software upgraden naar versie 2.15. Deze versie van TimeScaleDB is zowel op de oude server met PG 13 ondersteund maar ook PG16. Dit komt met een kleine downtime maar dat was in te plannen.
```bash
sudo systemctl stop zabbix-server
sudo dnf install timescaledb-2-loader-postgresql-13-2.15.2-0.el8.x86_64 timescaledb-2-postgresql-13-2.15.2-0.el8.x86_64
sudo systemctl restart postgresql-13.service
sudo -u postgres psql -d zabbix -X
ALTER EXTENSION timescaledb UPDATE;
```
## Database backup
Nu kunnen we de database overnemen. In de eerste plaats om de upgrade te testen maar uiteindelijk ook om de upgrade te doen.
```bash
time pg_dump -j 16 -Fd -Z 0 -d zabbix -f /backup/zabbix/
rsync -avP /backup/zabbix/ <nieuwe server>:/var/lib/postgresql/migratie
```
## Configuratie bestanden
We moeten uiteraard naast de databank ook de configuratie bestanden meenemen. Dat is zo voor Zabbix, NGINX, PostgreSQL en ook alternatieve scripts. Hier kan je die terugvinden:
Zabbix:
- /etc/zabbix/
- zabbix_server.conf.d/zabbix-server.conf
- zabbix_java_gateway.conf
- web/zabbix.conf.php
Nginx:
- /etc/nginx/conf.d/
- zabbix-nossl.conf
- zabbix-ssl.conf
- zabbix.conf
- /etc/ssl/
- certs
Postgres:
- /var/lib/pgsql/13/data
- postgresql.conf
- pg_hba.conf
- special.conf
- certs
Alertscripts:
- /usr/lib/zabbix/alertscripts
- smssender.php
# Nieuwe server
## Databank
Op de nieuwe server kunnen we nu ook de database installeren. Hiervoor kiezen we PostgreSQL 16. Dat is niet de laatste versie maar wel de versie die courant is in de organisatie.
```bash
# Aparte datadisk voor databank
sudo lvcreate -L 1TiB --name pg_data vg_data
sudo mkfs.xfs /dev/mapper/vg_data-pg_data
sudo mkdir /var/lib/postgresql
sudo echo "UUID=$(lsblk -lf | grep "pg_data" | awk '{print $3}') /var/lib/postgresql xfs defaults 0 0" | sudo tee -a /etc/fstab
sudo systemctl daemon-reload
sudo mount -a
# Installeer PostgreSQL 16
sudo apt install apt install postgresql-16
# Configuratie aanpassen en tunen naar de Monitor server
sudo vim /etc/postgresql/16/main/conf.d/special.conf
sudo chown postgres:postgres /etc/postgresql/16/main/conf.d/special.conf
```
Nu PostgreSQL beschikbaar is, kunnen we ook TimeScaleDB installeren. Hiervoor kiezen we dezelfde versie als op de oude server, weliswaar voor PostgreSQL 16.
```bash
## TimeScaleDB installeren als pakket
sudo apt install timescaledb-2-postgresql-16='2.15.2*' timescaledb-2-loader-postgresql-16='2.15.2*'
# De configuratie moet nog een beetje verder getuned worden
sudo timescaledb-tune -conf-path /etc/postgresql/16/main
# Service herstarten en database aanmaken met extentie
sudo systemctl restart postgresql.service
sudo -u postgres createuser --pwprompt zabbix
sudo -u postgres psql -c "DROP DATABASE IF EXISTS zabbix;"
sudo -u postgres createdb -O zabbix zabbix
sudo -u postgres psql -d zabbix -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"
```
## Database herstel
Nu de software klaarstaat, kunnen we de database importeren. Voor TimeScaleDB, moeten we daar ook iets speciaals doen.
```bash
tmux
sudo -u postgres psql -d zabbix -c "SELECT timescaledb_pre_restore();"
sudo -u postgres time pg_restore -d zabbix /var/lib/postgresql/migratie
sudo -u postgres psql -d zabbix -c "SELECT timescaledb_post_restore();"
sudo -u postgres psql
\c zabbix
GRANT ALL privileges on all tables in schema public to zabbix;
GRANT ALL ON SCHEMA public TO zabbix;
```
Dat duurde even maar nu hebben we de database klaarstaan. In principe zouden we nu Zabbix 6.4 installeren en zou alles moeten werken. Uiteraard willen we verder landen dus doen we verder. De volgende stap is een database patch uitvoeren. Helaas is het niet eenvoudig met TimeScaleDB. Oudere data wordt gecomprimeerd. Dat moeten we eerst te niet doen voordat we de patch kunnen uitvoeren.
```SQL
\c zabbix
-- Schakel de policies uit
SELECT remove_compression_policy('trends');
SELECT remove_compression_policy('trends_uint');
SELECT remove_compression_policy('history');
SELECT remove_compression_policy('history_uint');
SELECT remove_compression_policy('history_log');
SELECT remove_compression_policy('history_str');
SELECT remove_compression_policy('history_text');
-- Alle gecomprimeerde chunks uitpakken
DO $$
DECLARE
r RECORD;
hypertable TEXT;
start_time TIMESTAMP;
end_time TIMESTAMP;
BEGIN
start_time := clock_timestamp();
FOR hypertable IN
SELECT unnest(ARRAY[
'trends',
'trends_uint',
'history',
'history_uint',
'history_log',
'history_str',
'history_text'
])
LOOP
FOR r IN
SELECT format('%I.%I', chunk_schema, chunk_name) AS full_chunk_name
FROM timescaledb_information.chunks
WHERE is_compressed = true AND hypertable_name = hypertable
LOOP
RAISE NOTICE 'Decompressing chunk from %: %', hypertable, r.full_chunk_name;
EXECUTE format('SELECT decompress_chunk(''%s'');', r.full_chunk_name);
END LOOP;
END LOOP;
end_time := clock_timestamp();
RAISE NOTICE 'Total execution time: % seconds', EXTRACT(EPOCH FROM end_time - start_time);
END
$$;
-- Compressie uitzetten
ALTER TABLE trends SET (timescaledb.compress=false);
ALTER TABLE trends_uint SET (timescaledb.compress=false);
ALTER TABLE history SET (timescaledb.compress=false);
ALTER TABLE history_uint SET (timescaledb.compress=false);
ALTER TABLE history_log SET (timescaledb.compress=false);
ALTER TABLE history_str SET (timescaledb.compress=false);
ALTER TABLE history_text SET (timescaledb.compress=false);
-- Vereiste Datapatch uitvoeren
BEGIN;
ALTER TABLE trends
ALTER COLUMN value_min TYPE DOUBLE PRECISION,
ALTER COLUMN value_min SET DEFAULT '0.0000',
ALTER COLUMN value_avg TYPE DOUBLE PRECISION,
ALTER COLUMN value_avg SET DEFAULT '0.0000',
ALTER COLUMN value_max TYPE DOUBLE PRECISION,
ALTER COLUMN value_max SET DEFAULT '0.0000';
ALTER TABLE history
ALTER COLUMN value TYPE DOUBLE PRECISION,
ALTER COLUMN value SET DEFAULT '0.0000';
COMMIT;
```
## Zabbix installeren
Als je de juiste repo geactiveerd hebben, kan je Zabbix eenvoudig installeren. Als we Zabbix starten, zal eerst de database upgrade starten. Volg dit in het log bestand om zeker te zijn dat alles goed gegaan is.
```bash
apt install zabbix-server-pgsql zabbix-frontend-php php8.3-pgsql zabbix-nginx-conf zabbix-sql-scripts zabbix-agent2 zabbix-java-gateway zabbix-agent2-plugin-postgresql
systemctl enable zabbix-server zabbix-agent2 nginx php8.3-fpm
sudo tail -f /var/log/zabbix/zabbix_server.log
```
Zabbix 7.0 is nu actief en zou goed moeten werken. Let wel dat we nu niet gedaan hebben. We zitten nog steeds met een oude versie van TimeScaleDB. Hiervoor stoppen we best opnieuw Zabbix voordat we de upgrade doen. We gaan naar de laatst ondersteunde versie op moment van researchen.
```bash
sudo systemctl stop zabbix-server
sudo apt install timescaledb-2-postgresql-16='2.18.2*' timescaledb-2-loader-postgresql-16='2.18.2*'
sudo apt install timescaledb-2-postgresql-16='2.21.3*' timescaledb-2-loader-postgresql-16='2.21.3*'
sudo systemctl start zabbix-server && sudo tail -f /var/log/zabbix/zabbix_server.log
```
Als je nu geen fouten ziet in het server log, ben je klaar. Voor mij waren er nog firewall problemen, ik moest de Zabbix proxies ook upgraden en dan werkt alles opnieuw. De Proxies moest ik upgraden omdat ik naar een nieuwe fysieke server verbind. Als ik een lokale upgrade deed, was dat niet nodig.
## Whats next
- Zabbix agent: Deze zijn niet dringend want Zabbix 7.0 workt ook met de 6.4 agents
- SNMP: Een van de grote veranderingen is asynchroon data collection. Hiervoor moet in Zabbix frontend nog wijzigingen gebeuren om dit in orde te krijgen.
# Test
Als deel van mijn testen, moest ik mijn nieuwe server ook klaarzetten voor een nieuwe test of voor D-day. Dat was eenvoudig genoeg.
```bash
sudo systemctl stop zabbix-server.service
sudo -u postgres psql -c "drop database zabbix;"
sudo apt purge timescaledb-2-postgresql-16 timescaledb-2-loader-postgresql-16
```

BIN
public/AddZabbixProxy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
public/cover_lsyncd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/fonts/WorkSans.ttf Normal file

Binary file not shown.