Deze blogpost is een vervolg op MariaDB MaxScale Load Balancing op Docker:Deployment - Part1. In dit deel gaan we ons meer richten op beheeractiviteiten met geavanceerde gebruiksscenario's zoals servicecontrole, configuratiebeheer, queryverwerking, beveiliging en clusterafstemming. De voorbeeldstappen en instructies in dit bericht zijn gebaseerd op de hardloopomgevingen die we in het eerste deel van deze blogserie hebben opgezet.
Servicecontrole
Voor MaxScale is het starten en stoppen van de container de enige manier om de service te controleren. Op voorwaarde dat de container is gemaakt, kunnen we de volgende opdracht gebruiken om de service te beheren:
$ docker start maxscale
$ docker stop maxscale
$ docker restart maxscale
Werken zonder rootrechten
De Docker-containers worden standaard uitgevoerd met het root-privilege en dat geldt ook voor de toepassing die in de container wordt uitgevoerd. Dit is een ander belangrijk punt van zorg vanuit het oogpunt van beveiliging, omdat hackers root-toegang tot de Docker-host kunnen krijgen door de applicatie die in de container wordt uitgevoerd te hacken.
Om Docker uit te voeren als een niet-rootgebruiker, moet u uw gebruiker toevoegen aan de dockergroep. Maak eerst een docker-groep als er geen is:
$ sudo groupadd docker
Voeg vervolgens uw gebruiker toe aan de docker-groep. In dit voorbeeld is onze gebruiker "zwerver":
$ sudo usermod -aG docker vagrant
Log uit en weer in, zodat je groepslidmaatschap opnieuw wordt geëvalueerd (of start opnieuw op als het niet werkt). Op dit punt kunt u de MaxScale-container uitvoeren met de standaard opdracht run (geen sudo vereist) als gebruiker "zwerver":
$ docker run -d \
--name maxscale-unprivileged \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
MaxScale-proces wordt uitgevoerd door gebruiker "maxscale" en vereist geen speciale privileges tot op het rootniveau. Daarom is het altijd de beste manier om de container in niet-geprivilegieerde modus te laten draaien als u zich zorgen maakt over de beveiliging.
Configuratiebeheer
Voor een zelfstandige MaxScale-container vereist configuratiebeheer wijziging van het toegewezen configuratiebestand, gevolgd door het opnieuw starten van de MaxScale-container. Als u echter werkt als een Docker Swarm-service, moet de nieuwe configuratie als een nieuwe versie in de Swarm Configs worden geladen, bijvoorbeeld:
$ cat maxscale.cnf | docker config create maxscale_config_v2 -
Werk vervolgens de service bij door de oude configuraties (maxscale_config) te verwijderen en de nieuwe (maxscale_config_v2) toe te voegen aan hetzelfde doel:
$ docker service update \
--config-rm maxscale_config \
--config-add source=maxscale_config_v2,target=/etc/maxscale.cnf \
maxscale-cluster
Docker Swarm zal dan de containerverwijdering plannen en de procedures één container tegelijk vervangen totdat aan de replica's-vereiste is voldaan.
Upgraden en downgraden
Een van de voordelen van het uitvoeren van uw applicaties in Docker is de triviale upgrade- en downgradeprocedure. Elke actieve container is gebaseerd op een afbeelding en deze afbeelding kan eenvoudig worden gewisseld met de afbeeldingstag. Bekijk de sectie Tags in de Docker Hub om de lijst met beschikbare afbeeldingen voor MaxScale te bekijken. De volgende voorbeelden tonen het proces om een MaxScale 2.3 te downgraden naar een lagere versie 2.2:
$ docker run -d \
--name maxscale \
-p 4006:4006 \
-p 4008:4008 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale:2.3
$ docker rm -f maxscale
$ docker run -d \
--name maxscale \
-p 4006:4006 \
-p 4008:4008 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale:2.2
Zorg ervoor dat de configuratie-opties compatibel zijn met de versie die u wilt uitvoeren. De bovenstaande downgrade zou bijvoorbeeld bij de eerste uitvoering mislukken vanwege de volgende fouten:
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'master_reconnection' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'master_reconnection'.
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'delayed_retry' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'delayed_retry'.
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'transaction_replay_max_size' for object 'rw-service' of type 'service', or '1Mi' is an invalid value for parameter 'transaction_replay_max_size'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'transaction_replay' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'transaction_replay'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'causal_reads_timeout' for object 'rw-service' of type 'service', or '10' is an invalid value for parameter 'causal_reads_timeout'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'causal_reads' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'causal_reads'.
Wat we moeten doen, is de niet-ondersteunde configuratie-opties verwijderen, zoals hierboven weergegeven in het configuratiebestand, voordat we de container-image downgraden:
- master_reconnection
- delayed_retry
- transaction_replay
- causal_reads_timeout
- causal_reads
Start ten slotte de container opnieuw en je zou goed moeten zijn. Versie-upgrade voor MaxScale werkt op dezelfde manier. Verander gewoon de tag die je wilt gebruiken en je bent klaar.
MaxScale-filters
MaxScale gebruikt een component genaamd filter om de verzoeken te manipuleren of te verwerken terwijl ze er doorheen gaan. Er zijn een aantal filters die u kunt gebruiken, zoals vermeld op deze pagina, MaxScale 2.3-filters. Een specifieke zoekopdracht kan bijvoorbeeld worden aangemeld bij een bestand als deze overeenkomt met een criterium of u kunt de binnenkomende zoekopdracht herschrijven voordat deze de backend-servers bereikt.
Om een filter te activeren, moet u een sectie definiëren en de naam van de definitie opnemen in de bijbehorende servicedefinitie, zoals weergegeven in de voorbeelden verderop.
Query Logging All (QLA)
Zoals de naam al aangeeft, registreert het QLA-filter alle query's die overeenkomen met de set regels per clientsessie. Alle zoekopdrachten worden gelogd volgens het bestandsbasisformaat.
Definieer eerst de component met type=filter en module=qlafilter:
## Query Log All (QLA) filter
## Filter module for MaxScale to log all query content on a per client session basis
[qla-sbtest-no-pk]
type = filter
module = qlafilter
filebase = /tmp/sbtest
match = select.*from.*
exclude = where.*id.*
user = sbtest
Voeg dan de filtercomponent toe aan onze diensten:
[rw-service]
...
filters = qla-sbtest-no-pk
[rr-service]
...
filters = qla-sbtest-no-pk
Het is ook een goed idee om /tmp van de container toe te wijzen aan de daadwerkelijke map op de Docker-host, zodat we de container niet hoeven te openen om de gegenereerde logbestanden op te halen. Maak eerst een map aan en geef globale schrijfrechten:
$ mkdir qla
$ chmod 777 qla
Aangezien we de bovenstaande map in de container moeten binden, moeten we de actieve container stoppen en verwijderen en opnieuw uitvoeren met de volgende opdracht:
$ docker stop maxscale
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
-v $PWD/qla:/tmp \
mariadb/maxscale
U kunt dan de inhoud van de gelogde zoekopdrachten in de qla-directory ophalen:
$ cat qla/*
Date,[email protected],Query
2019-06-18 08:25:13,[email protected]::ffff:192.168.0.19,select * from sbtest.sbtest1
Query herschrijven
Het herschrijven van query's is een functie waarmee, afhankelijk van de query's die tegen de databaseserver worden uitgevoerd, snel problematische query's kunnen worden geïsoleerd en gecorrigeerd en de prestaties worden verbeterd.
Het herschrijven van query's kan via regexfilter. Dit filter kan inkomende instructies matchen of uitsluiten met behulp van reguliere expressies en deze vervangen door een andere instructie. Elke regel wordt gedefinieerd in zijn eigen sectie en neemt de sectienaam op in de bijbehorende service om deze te activeren.
Het volgende filter komt overeen met een aantal SHOW-commando's die we niet willen tonen aan de alleen-lezen clients:
## Rewrite query based on regex match and replace
[block-show-commands]
type = filter
module = regexfilter
options = ignorecase
match = ^show (variables|global variables|global status|status|processlist|full processlist).*
replace = SELECT 'Not allowed'
Vervolgens kunnen we het filter toevoegen aan de service die we willen toepassen. Alle alleen-lezen verbindingen moeten bijvoorbeeld worden gefilterd voor het bovenstaande:
[rr-service]
...
filters = qla-sbtest-no-pk | block-show-commands
Houd er rekening mee dat meerdere filters kunnen worden gedefinieerd met behulp van een syntaxis die lijkt op de Linux-shellpipe "|" syntaxis. Start de container opnieuw om de configuratiewijzigingen toe te passen:
$ docker restart maxscale
We kunnen dan verifiëren met de volgende vraag:
$ mysql -usbtest -p -h192.168.0.200 -P4006 -e 'SHOW VARIABLES LIKE "max_connections"'
+-------------+
| Not allowed |
+-------------+
| Not allowed |
+-------------+
U krijgt het resultaat zoals verwacht.
Clusterherstel
MaxScale 2.2.2 en hoger ondersteunt automatische of handmatige MariaDB-replicatie of clusterherstel voor de volgende gebeurtenissen:
- failover
- omschakeling
- weer meedoen
- reset-replicatie
Failover voor het master-slave-cluster kan en moet vaak zo worden ingesteld dat het automatisch wordt geactiveerd. De omschakeling moet handmatig worden geactiveerd via MaxAdmin, MaxCtrl of de REST-interface. Opnieuw deelnemen kan worden ingesteld op automatisch of handmatig worden geactiveerd. Deze functies zijn geïmplementeerd in de module "mariadbmon".
De volgende automatische failover-gebeurtenissen vonden plaats als we de actieve master opzettelijk afsluiten, 192.168.0.91:
$ docker logs -f maxscale
...
2019-06-19 03:53:02.348 error : (mon_log_connect_error): Monitor was unable to connect to server mariadb1[192.168.0.91:3306] : 'Can't connect to MySQL server on '192.168.0.91' (115)'
2019-06-19 03:53:02.351 notice : (mon_log_state_change): Server changed state: mariadb1[192.168.0.91:3306]: master_down. [Master, Running] -> [Down]
2019-06-19 03:53:02.351 warning: (handle_auto_failover): Master has failed. If master status does not change in 4 monitor passes, failover begins.
2019-06-19 03:53:16.710 notice : (select_promotion_target): Selecting a server to promote and replace 'mariadb1'. Candidates are: 'mariadb2', 'mariadb3'.
2019-06-19 03:53:16.710 warning: (warn_replication_settings): Slave 'mariadb2' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-06-19 03:53:16.711 warning: (warn_replication_settings): Slave 'mariadb3' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-06-19 03:53:16.711 notice : (select_promotion_target): Selected 'mariadb2'.
2019-06-19 03:53:16.711 notice : (handle_auto_failover): Performing automatic failover to replace failed master 'mariadb1'.
2019-06-19 03:53:16.723 notice : (redirect_slaves_ex): Redirecting 'mariadb3' to replicate from 'mariadb2' instead of 'mariadb1'.
2019-06-19 03:53:16.742 notice : (redirect_slaves_ex): All redirects successful.
2019-06-19 03:53:17.249 notice : (wait_cluster_stabilization): All redirected slaves successfully started replication from 'mariadb2'.
2019-06-19 03:53:17.249 notice : (handle_auto_failover): Failover 'mariadb1' -> 'mariadb2' performed.
2019-06-19 03:53:20.363 notice : (mon_log_state_change): Server changed state: mariadb2[192.168.0.92:3306]: new_master. [Slave, Running] -> [Master, Running]
Nadat de failover is voltooid, ziet onze topologie er nu als volgt uit:
Voor omschakeling is menselijke tussenkomst vereist en een manier om dit te doen via de MaxCtrl-console. Laten we zeggen dat de oude master weer operationeel is en klaar is om als master te worden gepromoveerd, we kunnen de omschakeling uitvoeren door het volgende commando te sturen:
$ docker exec -it maxscale maxctrl
maxctrl: call command mariadbmon switchover monitor mariadb1 mariadb2
OK
Waar, de opmaak is:
$ call command <monitoring module> <operation> <monitoring section name> <new master> <current master>
Verifieer vervolgens de nieuwe topologie door de servers op te sommen:
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬──────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-12144 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-12144 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-12144 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴──────────────┘
We hebben net onze oude meester terug naar zijn oorspronkelijke plek gepromoot. Leuk weetje, de automatische herstelfunctie van ClusterControl doet precies hetzelfde als deze is ingeschakeld.
Laatste gedachten
Het uitvoeren van MariaDB MaxScale op Docker biedt extra voordelen, zoals MaxScale-clustering, eenvoudig te upgraden en te downgraden, en ook geavanceerde proxyfunctionaliteiten voor MySQL- en MariaDB-clusters.