Ten wpis na blogu jest kontynuacją MariaDB MaxScale Load Balancing w Docker:Deployment - Part1. W tej części skupimy się bardziej na operacjach zarządzania z zaawansowanymi przypadkami użycia, takimi jak kontrola usług, zarządzanie konfiguracją, przetwarzanie zapytań, zabezpieczenia i uzgadnianie klastrów. Przykładowe kroki i instrukcje przedstawione w tym poście są oparte na środowiskach biegowych, które skonfigurowaliśmy w pierwszej części tej serii blogów.
Kontrola usług
W przypadku MaxScale uruchamianie i zatrzymywanie kontenera jest jedynym sposobem kontrolowania usługi. Jeśli kontener został utworzony, do zarządzania usługą możemy użyć następującego polecenia:
$ docker start maxscale
$ docker stop maxscale
$ docker restart maxscale
Bieganie bez uprawnień roota
Kontenery platformy Docker domyślnie działają z uprawnieniami administratora, podobnie jak aplikacja działająca w kontenerze. Jest to kolejny poważny problem z punktu widzenia bezpieczeństwa, ponieważ hakerzy mogą uzyskać dostęp na poziomie administratora do hosta platformy Docker poprzez zhakowanie aplikacji działającej w kontenerze.
Aby uruchomić Docker jako użytkownik inny niż root, musisz dodać swojego użytkownika do grupy Docker. Po pierwsze, utwórz grupę doków, jeśli jej nie ma:
$ sudo groupadd docker
Następnie dodaj użytkownika do grupy Docker. W tym przykładzie nasz użytkownik to „włóczęga”:
$ sudo usermod -aG docker vagrant
Wyloguj się i zaloguj ponownie, aby ponownie ocenić członkostwo w grupie (lub uruchom ponownie, jeśli to nie działa). W tym momencie możesz uruchomić kontener MaxScale za pomocą standardowego polecenia uruchamiania (nie wymaga sudo) jako użytkownik "vagrant":
$ docker run -d \
--name maxscale-unprivileged \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
Proces MaxScale jest uruchamiany przez użytkownika „maxscale” i nie wymaga żadnych specjalnych uprawnień aż do poziomu root. Dlatego uruchomienie kontenera w trybie nieuprzywilejowanym jest zawsze najlepszym sposobem, jeśli martwisz się o bezpieczeństwo.
Zarządzanie konfiguracją
W przypadku autonomicznego kontenera MaxScale zarządzanie konfiguracją wymaga modyfikacji zmapowanego pliku konfiguracyjnego, a następnie ponownego uruchomienia kontenera MaxScale. Jeśli jednak działasz jako usługa Docker Swarm, nowa konfiguracja musi zostać załadowana do konfiguracji Swarm jako nowa wersja, na przykład:
$ cat maxscale.cnf | docker config create maxscale_config_v2 -
Następnie zaktualizuj usługę, usuwając stare konfiguracje (maxscale_config) i dodaj nową (maxscale_config_v2) do tego samego celu:
$ docker service update \
--config-rm maxscale_config \
--config-add source=maxscale_config_v2,target=/etc/maxscale.cnf \
maxscale-cluster
Docker Swarm zaplanuje następnie usunięcie kontenera i zamieni procedury po jednym kontenerze na raz, aż do spełnienia wymagań dotyczących replik.
Aktualizacja i degradacja
Jedną z zalet uruchamiania aplikacji w Dockerze jest prosta procedura uaktualniania i obniżania wersji. Każdy uruchomiony kontener jest oparty na obrazie, który można łatwo przełączyć za pomocą tagu obrazu. Aby uzyskać listę dostępnych obrazów dla MaxScale, sprawdź sekcję Tagi w Docker Hub. Poniższe przykłady pokazują proces zmiany wersji MaxScale 2.3 do wcześniejszej wersji 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
Upewnij się, że opcje konfiguracji są zgodne z wersją, którą chcesz uruchomić. Na przykład powyższa zmiana na starszą wersję nie powiedzie się przy pierwszym uruchomieniu z powodu następujących błędów:
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'.
To, co musimy zrobić, to usunąć nieobsługiwane opcje konfiguracji, jak pokazano powyżej w pliku konfiguracyjnym, przed obniżeniem obrazu kontenera:
- master_reconnection
- delayed_retry
- transaction_replay
- causal_reads_timeout
- causal_reads
Na koniec ponownie uruchom pojemnik i powinieneś być dobry. Aktualizacja wersji dla MaxScale działa podobnie. Po prostu zmień tag, którego chcesz użyć i gotowe.
Filtry MaxScale
MaxScale używa komponentu zwanego filtrem do manipulowania lub przetwarzania żądań podczas ich przechodzenia. Istnieje wiele filtrów, których możesz użyć, wymienionych na tej stronie, Filtry MaxScale 2.3. Na przykład określone zapytanie może zostać zarejestrowane w pliku, jeśli spełnia kryteria, lub możesz przepisać przychodzące zapytanie, zanim dotrze ono do serwerów zaplecza.
Aby aktywować filtr, musisz zdefiniować sekcję i dołączyć nazwę definicji do odpowiedniej definicji usługi, jak pokazano w poniższych przykładach.
Zapytania o rejestrowanie wszystkiego (QLA)
Jak sama nazwa wskazuje, filtr QLA rejestruje wszystkie zapytania zgodne z zestawem reguł na sesję klienta. Wszystkie zapytania będą rejestrowane zgodnie z formatem bazy plików.
Najpierw zdefiniuj komponent z type=filter i 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
Następnie dodaj komponent filtra do naszych usług:
[rw-service]
...
filters = qla-sbtest-no-pk
[rr-service]
...
filters = qla-sbtest-no-pk
Dobrym pomysłem jest również zmapowanie /tmp kontenera z rzeczywistym katalogiem na hoście Docker, dzięki czemu nie musimy uzyskiwać dostępu do kontenera, aby pobrać wygenerowane pliki dziennika. Najpierw utwórz katalog i nadaj globalne uprawnienia do zapisu:
$ mkdir qla
$ chmod 777 qla
Ponieważ musimy powiązać powyższy katalog z kontenerem, musimy zatrzymać i usunąć działający kontener i uruchomić go ponownie za pomocą następującego polecenia:
$ 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
Następnie możesz pobrać zawartość zarejestrowanych zapytań w katalogu qla:
$ cat qla/*
Date,[email protected],Query
2019-06-18 08:25:13,[email protected]::ffff:192.168.0.19,select * from sbtest.sbtest1
Przepisywanie zapytań
Przepisywanie zapytań to funkcja, która w zależności od zapytań działających na serwerze bazy danych, pozwala szybko wyizolować i poprawić problematyczne zapytania oraz poprawić wydajność.
Przepisywanie zapytań można wykonać za pomocą regexfilter. Ten filtr może dopasować lub wykluczyć przychodzące instrukcje przy użyciu wyrażeń regularnych i zastąpić je inną instrukcją. Każda reguła jest zdefiniowana we własnej sekcji i zawiera nazwę sekcji w odpowiedniej usłudze, aby ją aktywować.
Poniższy filtr będzie pasował do wielu poleceń SHOW, których nie chcemy udostępniać klientom tylko do odczytu:
## 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'
Następnie możemy dołączyć filtr do usługi, którą chcemy zastosować. Na przykład wszystkie połączenia tylko do odczytu muszą być filtrowane pod kątem powyższego:
[rr-service]
...
filters = qla-sbtest-no-pk | block-show-commands
Należy pamiętać, że wiele filtrów można zdefiniować za pomocą składni podobnej do potoku powłoki systemu Linux „|” składnia. Uruchom ponownie kontener, aby zastosować zmiany w konfiguracji:
$ docker restart maxscale
Następnie możemy zweryfikować za pomocą następującego zapytania:
$ mysql -usbtest -p -h192.168.0.200 -P4006 -e 'SHOW VARIABLES LIKE "max_connections"'
+-------------+
| Not allowed |
+-------------+
| Not allowed |
+-------------+
Otrzymasz wynik zgodnie z oczekiwaniami.
Odzyskiwanie klastra
MaxScale 2.2.2 i nowsze obsługują automatyczną lub ręczną replikację MariaDB lub odzyskiwanie klastra w przypadku następujących zdarzeń:
- przełączenie awaryjne
- przełączenie
- dołącz ponownie
- resetuj-replikację
Przełączanie awaryjne klastra master-slave może i często powinno być ustawione na automatyczne aktywowanie. Przełączanie należy aktywować ręcznie za pomocą interfejsu MaxAdmin, MaxCtrl lub REST. Ponowne dołączanie można ustawić na automatyczne lub aktywować ręcznie. Te funkcje są zaimplementowane w module „mariadbmon”.
Następujące zdarzenia automatycznego przełączania awaryjnego miały miejsce, jeśli celowo wyłączyliśmy aktywny master, 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]
Po zakończeniu przełączania awaryjnego nasza topologia wygląda teraz tak:
Do operacji przełączania wymaga interwencji człowieka i jednego sposobu na zrobienie tego za pomocą konsoli MaxCtrl. Załóżmy, że stary master znów działa i jest gotowy do awansu na mastera, możemy wykonać operację przełączania, wysyłając następujące polecenie:
$ docker exec -it maxscale maxctrl
maxctrl: call command mariadbmon switchover monitor mariadb1 mariadb2
OK
Gdzie formatowanie to:
$ call command <monitoring module> <operation> <monitoring section name> <new master> <current master>
Następnie zweryfikuj nową topologię, wymieniając serwery:
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 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴──────────────┘
Właśnie przenieśliśmy naszego starego mistrza z powrotem na jego pierwotne miejsce. Ciekawostka, funkcja automatycznego odzyskiwania ClusterControl robi dokładnie to samo, jeśli jest włączona.
Ostateczne myśli
Uruchamianie MariaDB MaxScale na platformie Docker zapewnia dodatkowe korzyści, takie jak klastrowanie MaxScale, łatwość uaktualniania i obniżania wersji, a także zaawansowane funkcje proxy dla klastrów MySQL i MariaDB.