MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

Uruchamianie klastra MariaDB Galera bez narzędzi do orkiestracji kontenerów:część pierwsza

Narzędzia do aranżacji kontenerów upraszczają działanie systemu rozproszonego, wdrażając i ponownie wdrażając kontenery oraz obsługując wszelkie występujące awarie. Może zaistnieć potrzeba przeniesienia aplikacji, np. do obsługi aktualizacji, skalowania lub podstawowych awarii hosta. Chociaż brzmi to świetnie, nie zawsze działa dobrze z silnie spójnym klastrem baz danych, takim jak Galera. Nie można po prostu przenosić węzłów baz danych, nie są to aplikacje bezstanowe. Duże znaczenie ma również kolejność wykonywania operacji na klastrze. Na przykład ponowne uruchomienie klastra Galera musi rozpocząć się od najbardziej zaawansowanego węzła, w przeciwnym razie utracisz dane. Dlatego pokażemy Ci, jak uruchomić Galera Cluster w Dockerze bez narzędzia do aranżacji kontenerów, dzięki czemu masz pełną kontrolę.

W tym poście na blogu przyjrzymy się, jak uruchomić klaster MariaDB Galera w kontenerach platformy Docker przy użyciu standardowego obrazu platformy Docker na wielu hostach platformy Docker, bez pomocy narzędzi do orkiestracji, takich jak Swarm lub Kubernetes. To podejście jest podobne do uruchamiania Galera Cluster na standardowych hostach, ale zarządzanie procesami jest konfigurowane za pomocą Dockera.

Zanim przejdziemy dalej do szczegółów, zakładamy, że zainstalowałeś Docker, wyłączyłeś SElinux/AppArmor i wyczyściłeś reguły wewnątrz iptables, firewalld lub ufw (w zależności od tego, którego używasz). Poniżej znajdują się trzy dedykowane hosty platformy Docker dla naszego klastra baz danych:

  • host1.lokalny - 192.168.55.161
  • host2.local - 192.168.55.162
  • host3.local - 192.168.55.163

Sieć wielohostowa

Przede wszystkim domyślna sieć Docker jest powiązana z hostem lokalnym. Docker Swarm wprowadza kolejną warstwę sieciową zwaną siecią nakładkową, która rozszerza intersieć kontenera na wiele hostów Dockera w klastrze zwanym Swarm. Na długo przed wprowadzeniem tej integracji powstało wiele wtyczek sieciowych, które to obsługują — flanelowe, perkalowe, splotowe to tylko niektóre z nich.

Tutaj użyjemy Weave jako wtyczki sieciowej platformy Docker do sieci z wieloma hostami. Wynika to głównie z prostoty instalacji i działania oraz obsługi mechanizmu rozpoznawania nazw DNS (kontenery działające w tej sieci mogą nawzajem rozwiązywać nazwy hostów). Istnieją dwa sposoby na uruchomienie Weave - systemd lub przez Docker. Zamierzamy zainstalować go jako jednostkę systemd, więc jest niezależny od demona Docker (w przeciwnym razie musielibyśmy najpierw uruchomić Dockera przed aktywacją Weave).

  1. Pobierz i zainstaluj Weave:

    $ curl -L git.io/weave -o /usr/local/bin/weave
    $ chmod a+x /usr/local/bin/weave
  2. Utwórz plik jednostki systemd dla Weave:

    $ cat > /etc/systemd/system/weave.service << EOF
    [Unit]
    Description=Weave Network
    Documentation=http://docs.weave.works/weave/latest_release/
    Requires=docker.service
    After=docker.service
    [Service]
    EnvironmentFile=-/etc/sysconfig/weave
    ExecStartPre=/usr/local/bin/weave launch --no-restart $PEERS
    ExecStart=/usr/bin/docker attach weave
    ExecStop=/usr/local/bin/weave stop
    [Install]
    WantedBy=multi-user.target
    EOF
  3. Zdefiniuj adresy IP lub nazwę hosta peerów w /etc/sysconfig/weave:

    $ echo 'PEERS="192.168.55.161 192.168.55.162 192.168.55.163"' > /etc/sysconfig/weave
  4. Uruchom i włącz Weave przy starcie:

    $ systemctl start weave
    $ systemctl enable weave

Powtórz powyższe 4 kroki na wszystkich hostach platformy Docker. Zweryfikuj za pomocą następującego polecenia po wykonaniu:

$ weave status

Dbamy o liczbę rówieśników. Powinno być 3:

          ...
          Peers: 3 (with 6 established connections)
          ...

Prowadzenie klastra Galera

Teraz sieć jest gotowa, czas uruchomić nasze kontenery bazy danych i utworzyć klaster. Podstawowe zasady to:

  • Kontener musi być utworzony pod opcją --net=weave, aby mieć połączenie z wieloma hostami.
  • Porty kontenerów, które należy opublikować, to 3306, 4444, 4567, 4568.
  • Obraz platformy Docker musi obsługiwać Galerę. Jeśli chcesz używać Oracle MySQL, pobierz wersję Codership. Jeśli chcesz Percony, użyj zamiast tego tego obrazu. W tym poście na blogu używamy MariaDB.

Wybraliśmy MariaDB jako dostawcę klastra Galera:

  • Galera jest osadzona w MariaDB, począwszy od MariaDB 10.1.
  • Obraz MariaDB jest obsługiwany przez zespoły Docker i MariaDB.
  • Jeden z najpopularniejszych obrazów Dockera.

Bootstrapowanie klastra Galera musi być wykonywane po kolei. Po pierwsze, najbardziej aktualny węzeł musi być uruchomiony z „wsrep_cluster_address=gcomm://”. Następnie uruchom pozostałe węzły z pełnym adresem składającym się ze wszystkich węzłów w klastrze, np. „wsrep_cluster_address=gcomm://węzeł1,węzeł2,węzeł3”. Aby wykonać te czynności przy użyciu kontenera, musimy wykonać kilka dodatkowych czynności, aby upewnić się, że wszystkie kontenery działają jednorodnie. Plan jest więc następujący:

  1. Musielibyśmy zacząć od 4 kontenerów w tej kolejności - mariadb0 (bootstrap), mariadb2, mariadb3, mariadb1.
  2. Kontener mariadb0 będzie używał tego samego datadir i configdir co mariadb1.
  3. Użyj mariadb0 na hoście1 do pierwszego ładowania początkowego, a następnie uruchom mariadb2 na hoście2, mariadb3 na hoście3.
  4. Usuń mariadb0 z hosta1, aby ustąpić miejsca mariadb1.
  5. Na koniec uruchom mariadb1 na hoście1.

Pod koniec dnia miałbyś trzywęzłowy klaster Galera (mariadb1, mariadb2, mariadb3). Pierwszy kontener (mariadb0) jest kontenerem przejściowym wyłącznie do celów ładowania początkowego przy użyciu adresu klastra „gcomm://”. Współdzieli ten sam katalog danych i katalog konfiguracyjny z mariadb1 i zostanie usunięty po utworzeniu klastra (mariadb2 i mariadb3 działają) i zsynchronizowaniu węzłów.

Domyślnie Galera jest wyłączona w MariaDB i musi być włączona z flagą o nazwie wsrep_on (ustawiony na ON) i wsrep_provider (ustawiony na ścieżkę biblioteki Galera) oraz szereg parametrów związanych z Galera. Dlatego musimy zdefiniować niestandardowy plik konfiguracyjny dla kontenera, aby poprawnie skonfigurować Galerę.

Zacznijmy od pierwszego kontenera mariadb0. Utwórz plik w /containers/mariadb1/conf.d/my.cnf i dodaj następujące linie:

$ mkdir -p /containers/mariadb1/conf.d
$ cat /containers/mariadb1/conf.d/my.cnf
[mysqld]

default_storage_engine          = InnoDB
binlog_format                   = ROW

innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_file_per_table           = 1
innodb_autoinc_lock_mode        = 2
innodb_lock_schedule_algorithm  = FCFS # MariaDB >10.1.19 and >10.2.3 only

wsrep_on                        = ON
wsrep_provider                  = /usr/lib/galera/libgalera_smm.so
wsrep_sst_method                = xtrabackup-v2

Ponieważ obraz nie jest dostarczany z MariaDB Backup (która jest preferowaną metodą SST dla MariaDB 10.1 i MariaDB 10.2), na razie pozostaniemy przy xtrabackup-v2.

Aby wykonać pierwszy ładowanie początkowe dla klastra, uruchom kontener ładowania początkowego (mariadb0) na hoście1 z "datadir" i "conf.d" mariadb1:

$ docker run -d \
        --name mariadb0 \
        --hostname mariadb0.weave.local \
        --net weave \
        --publish "3306" \
        --publish "4444" \
        --publish "4567" \
        --publish "4568" \
        $(weave dns-args) \
        --env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
        --env MYSQL_USER=proxysql \
        --env MYSQL_PASSWORD=proxysqlpassword \
        --volume /containers/mariadb1/datadir:/var/lib/mysql \
        --volume /containers/mariadb1/conf.d:/etc/mysql/mariadb.conf.d \
        mariadb:10.2.15 \
        --wsrep_cluster_address=gcomm:// \
        --wsrep_sst_auth="root:PM7%[email protected]^1" \
        --wsrep_node_address=mariadb0.weave.local

Parametry użyte w powyższym poleceniu to:

  • --nazwa , tworzy kontener o nazwie „mariadb0”,
  • --nazwa hosta , przypisuje kontenerowi nazwę hosta „mariadb0.weave.local”,
  • --net , umieszcza kontener w sieci weave w celu obsługi sieci z wieloma hostami,
  • --opublikuj , udostępnia hostowi porty 3306, 4444, 4567, 4568 w kontenerze,
  • $(weave dns-args) , konfiguruje program rozpoznawania nazw DNS dla tego kontenera. To polecenie można przetłumaczyć na Docker run jako "--dns=172.17.0.1 --dns-search=weave.local.",
  • --env MYSQL_ROOT_PASSWORD , hasło roota MySQL,
  • --env MYSQL_USER , tworzy użytkownika "proxysql", który będzie później używany z ProxySQL do routingu bazy danych,
  • --env MYSQL_PASSWORD , hasło użytkownika "proxysql",
  • --volume /containers/mariadb1/datadir:/var/lib/mysql , tworzy /containers/mariadb1/datadir, jeśli nie istnieje i mapuje go z /var/lib/mysql (katalog danych MySQL) kontenera (dla węzła ładowania początkowego można to pominąć),
  • --volume /containers/mariadb1/conf.d:/etc/mysql/mariadb.conf.d , montuje pliki z katalogu /containers/mariadb1/conf.d hosta platformy Docker, do kontenera w /etc/mysql/mariadb.conf.d.
  • mariadb:10.2.15 , używa obrazu MariaDB 10.2.15 stąd,
  • --wsrep_cluster_address , parametry połączenia Galera dla klastra. „gcomm://” oznacza bootstrap. W przypadku pozostałych kontenerów zamiast tego użyjemy pełnego adresu.
  • --wsrep_sst_auth , ciąg uwierzytelniający dla użytkownika SST. Użyj tego samego użytkownika co root,
  • --wsrep_node_address , nazwa hosta węzła, w tym przypadku użyjemy FQDN dostarczonej przez Weave.

Kontener ładowania początkowego zawiera kilka kluczowych rzeczy:

  • Nazwa, nazwa hosta i adres_węzła_wsrep to mariadb0, ale używa woluminów mariadb1.
  • Adres klastra to „gcomm://”
  • Istnieją dwa dodatkowe parametry --env — MYSQL_USER i MYSQL_PASSWORD. Te parametry utworzą dodatkowego użytkownika dla naszego celu monitorowania proxysql.

Zweryfikuj za pomocą następującego polecenia:

$ docker ps
$ docker logs -f mariadb0

Gdy zobaczysz następujący wiersz, oznacza to, że proces ładowania początkowego został zakończony, a Galera jest aktywna:

2018-05-30 23:19:30 139816524539648 [Note] WSREP: Synchronized with group, ready for connections

Utwórz katalog, aby załadować nasz niestandardowy plik konfiguracyjny na pozostałych hostach:

$ mkdir -p /containers/mariadb2/conf.d # on host2
$ mkdir -p /containers/mariadb3/conf.d # on host3

Następnie skopiuj plik my.cnf, który utworzyliśmy dla mariadb0 i mariadb1 odpowiednio do mariadb2 i mariadb3:

$ scp /containers/mariadb1/conf.d/my.cnf /containers/mariadb2/conf.d/ # on host1
$ scp /containers/mariadb1/conf.d/my.cnf /containers/mariadb3/conf.d/ # on host1

Następnie utwórz kolejne 2 kontenery bazy danych (mariadb2 i mariadb3) odpowiednio na hoście2 i hoście3:

$ docker run -d \
        --name ${NAME} \
        --hostname ${NAME}.weave.local \
        --net weave \
        --publish "3306:3306" \
        --publish "4444" \
        --publish "4567" \
        --publish "4568" \
        $(weave dns-args) \
        --env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
        --volume /containers/${NAME}/datadir:/var/lib/mysql \
        --volume /containers/${NAME}/conf.d:/etc/mysql/mariadb.conf.d \
        mariadb:10.2.15 \
        --wsrep_cluster_address=gcomm://mariadb0.weave.local,mariadb1.weave.local,mariadb2.weave.local,mariadb3.weave.local \
        --wsrep_sst_auth="root:PM7%[email protected]^1" \
        --wsrep_node_address=${NAME}.weave.local

** Zastąp ${NAME} odpowiednio mariadb2 lub mariadb3.

Jest jednak pewien haczyk. Skrypt punktu wejścia sprawdza usługę mysqld w tle po zainicjowaniu bazy danych przy użyciu użytkownika root MySQL bez hasła. Ponieważ Galera automatycznie wykonuje synchronizację przez SST lub IST podczas uruchamiania, hasło użytkownika root MySQL zostanie zmienione, odzwierciedlając węzeł ładowania początkowego. W związku z tym podczas pierwszego uruchomienia zobaczysz następujący błąd:

018-05-30 23:27:13 140003794790144 [Warning] Access denied for user 'root'@'localhost' (using password: NO)
MySQL init process in progress…
MySQL init process failed.

Sztuczka polega na tym, aby ponownie zrestartować uszkodzone kontenery, ponieważ tym razem katalog danych MySQL zostałby utworzony (przy pierwszej próbie uruchomienia) i pominąłby część inicjalizacji bazy danych:

$ docker start mariadb2 # on host2
$ docker start mariadb3 # on host3

Po uruchomieniu zweryfikuj, patrząc na następujący wiersz:

$ docker logs -f mariadb2
…
2018-05-30 23:28:39 139808069601024 [Note] WSREP: Synchronized with group, ready for connections

W tym momencie działają 3 kontenery:mariadb0, mariadb2 i mariadb3. Zwróć uwagę, że mariadb0 jest uruchamiany za pomocą polecenia bootstrap (gcomm://), co oznacza, że ​​jeśli kontener zostanie automatycznie zrestartowany przez Docker w przyszłości, może potencjalnie zostać rozłączony z podstawowym komponentem. Dlatego musimy usunąć ten kontener i zastąpić go mariadb1, używając tych samych parametrów połączenia Galera z resztą i użyć tego samego datadir i configdir z mariadb0.

Najpierw zatrzymaj mariadb0, wysyłając SIGTERM (aby upewnić się, że węzeł zostanie bezpiecznie zamknięty):

$ docker kill -s 15 mariadb0

Następnie uruchom mariadb1 na hoście1 za pomocą podobnego polecenia jak mariadb2 lub mariadb3:

$ docker run -d \
        --name mariadb1 \
        --hostname mariadb1.weave.local \
        --net weave \
        --publish "3306:3306" \
        --publish "4444" \
        --publish "4567" \
        --publish "4568" \
        $(weave dns-args) \
        --env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
        --volume /containers/mariadb1/datadir:/var/lib/mysql \
        --volume /containers/mariadb1/conf.d:/etc/mysql/mariadb.conf.d \
        mariadb:10.2.15 \
        --wsrep_cluster_address=gcomm://mariadb0.weave.local,mariadb1.weave.local,mariadb2.weave.local,mariadb3.weave.local \
        --wsrep_sst_auth="root:PM7%[email protected]^1" \
        --wsrep_node_address=mariadb1.weave.local

Tym razem nie musisz wykonywać sztuczki z restartem, ponieważ katalog danych MySQL już istnieje (utworzony przez mariadb0). Po uruchomieniu kontenera sprawdź, czy rozmiar klastra wynosi 3, stan musi być Podstawowy, a stan lokalny jest zsynchronizowany:

$ docker exec -it mariadb3 mysql -uroot "-pPM7%[email protected]^1" -e 'select variable_name, variable_value from information_schema.global_status where variable_name in ("wsrep_cluster_size", "wsrep_local_state_comment", "wsrep_cluster_status", "wsrep_incoming_addresses")'
+---------------------------+-------------------------------------------------------------------------------+
| variable_name             | variable_value                                                                |
+---------------------------+-------------------------------------------------------------------------------+
| WSREP_CLUSTER_SIZE        | 3                                                                             |
| WSREP_CLUSTER_STATUS      | Primary                                                                       |
| WSREP_INCOMING_ADDRESSES  | mariadb1.weave.local:3306,mariadb3.weave.local:3306,mariadb2.weave.local:3306 |
| WSREP_LOCAL_STATE_COMMENT | Synced                                                                        |
+---------------------------+-------------------------------------------------------------------------------+

W tym momencie nasza architektura wygląda mniej więcej tak:

Chociaż polecenie run jest dość długie, dobrze opisuje charakterystykę kontenera. Prawdopodobnie dobrym pomysłem jest umieszczenie polecenia w skrypcie, aby uprościć kroki wykonywania, lub zamiast tego użyć pliku do tworzenia.

Routowanie bazy danych z ProxySQL

Teraz mamy uruchomione trzy kontenery bazy danych. Jedynym sposobem uzyskania dostępu do klastra jest teraz uzyskanie dostępu do opublikowanego portu MySQL pojedynczego hosta platformy Docker, czyli 3306 (mapowanie na 3306 do kontenera). Co się stanie, jeśli jeden z kontenerów bazy danych ulegnie awarii? Musisz ręcznie przełączyć połączenie klienta w tryb failover z następnym dostępnym węzłem. W zależności od konektora aplikacji, możesz również określić listę węzłów i pozwolić konektorowi na przełączenie awaryjne i routing zapytań za Ciebie (Connector/J, PHP mysqlnd). W przeciwnym razie dobrym pomysłem byłoby ujednolicenie zasobów bazy danych w jeden zasób, który można nazwać usługą.

W tym miejscu pojawia się ProxySQL. ProxySQL może działać jako router zapytań, równoważąc obciążenie połączeń z bazą danych, podobnie do tego, co potrafi "Service" w świecie Swarm lub Kubernetes. W tym celu zbudowaliśmy obraz Docker ProxySQL i dokładamy wszelkich starań, aby zachować obraz dla każdej nowej wersji.

Zanim uruchomimy kontener ProxySQL, musimy przygotować plik konfiguracyjny. Oto, co skonfigurowaliśmy dla proxysql1. Tworzymy niestandardowy plik konfiguracyjny w /containers/proxysql1/proxysql.cnf na hoście1:

$ cat /containers/proxysql1/proxysql.cnf
datadir="/var/lib/proxysql"
admin_variables=
{
        admin_credentials="admin:admin"
        mysql_ifaces="0.0.0.0:6032"
        refresh_interval=2000
}
mysql_variables=
{
        threads=4
        max_connections=2048
        default_query_delay=0
        default_query_timeout=36000000
        have_compress=true
        poll_timeout=2000
        interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
        default_schema="information_schema"
        stacksize=1048576
        server_version="5.1.30"
        connect_timeout_server=10000
        monitor_history=60000
        monitor_connect_interval=200000
        monitor_ping_interval=200000
        ping_interval_server=10000
        ping_timeout_server=200
        commands_stats=true
        sessions_sort=true
        monitor_username="proxysql"
        monitor_password="proxysqlpassword"
}
mysql_servers =
(
        { address="mariadb1.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
        { address="mariadb2.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
        { address="mariadb3.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
        { address="mariadb1.weave.local" , port=3306 , hostgroup=20, max_connections=100 },
        { address="mariadb2.weave.local" , port=3306 , hostgroup=20, max_connections=100 },
        { address="mariadb3.weave.local" , port=3306 , hostgroup=20, max_connections=100 }
)
mysql_users =
(
        { username = "sbtest" , password = "password" , default_hostgroup = 10 , active = 1 }
)
mysql_query_rules =
(
        {
                rule_id=100
                active=1
                match_pattern="^SELECT .* FOR UPDATE"
                destination_hostgroup=10
                apply=1
        },
        {
                rule_id=200
                active=1
                match_pattern="^SELECT .*"
                destination_hostgroup=20
                apply=1
        },
        {
                rule_id=300
                active=1
                match_pattern=".*"
                destination_hostgroup=10
                apply=1
        }
)
scheduler =
(
        {
                id = 1
                filename = "/usr/share/proxysql/tools/proxysql_galera_checker.sh"
                active = 1
                interval_ms = 2000
                arg1 = "10"
                arg2 = "20"
                arg3 = "1"
                arg4 = "1"
                arg5 = "/var/lib/proxysql/proxysql_galera_checker.log"
        }
)

Powyższa konfiguracja:

  • skonfiguruj dwie grupy hostów, grupę z jednym zapisem i grupę z wieloma zapisami, zgodnie z definicją w sekcji „mysql_servers”,
  • wysyłaj odczyty do wszystkich węzłów Galera (grupa hostów 20), podczas gdy operacje zapisu trafią do jednego serwera Galera (grupa hostów 10),
  • zaplanuj plik proxysql_galera_checker.sh,
  • użyj monitor_username i monitor_password jako poświadczeń monitorowania utworzonych podczas pierwszego ładowania klastra (mariadb0).

Skopiuj plik konfiguracyjny do hosta2, aby zapewnić redundancję ProxySQL:

$ mkdir -p /containers/proxysql2/ # on host2
$ scp /containers/proxysql1/proxysql.cnf /container/proxysql2/ # on host1

Następnie uruchom kontenery ProxySQL odpowiednio na hoście1 i hoście2:

$ docker run -d \
        --name=${NAME} \
        --publish 6033 \
        --publish 6032 \
        --restart always \
        --net=weave \
        $(weave dns-args) \
        --hostname ${NAME}.weave.local \
        -v /containers/${NAME}/proxysql.cnf:/etc/proxysql.cnf \
        -v /containers/${NAME}/data:/var/lib/proxysql \
        severalnines/proxysql

** Zastąp ${NAME} odpowiednio przez proxysql1 lub proxysql2.

Określiliśmy --restart=always aby był zawsze dostępny, niezależnie od statusu wyjścia, a także automatycznego uruchamiania podczas uruchamiania demona Docker. Dzięki temu kontenery ProxySQL będą działać jak demon.

Sprawdź stan serwerów MySQL monitorowanych przez obie instancje ProxySQL (dla grupy hostów z jednym zapisem oczekuje się OFFLINE_SOFT):

$ docker exec -it proxysql1 mysql -uadmin -padmin -h127.0.0.1 -P6032 -e 'select hostgroup_id,hostname,status from mysql_servers'
+--------------+----------------------+--------------+
| hostgroup_id | hostname             | status       |
+--------------+----------------------+--------------+
| 10           | mariadb1.weave.local | ONLINE       |
| 10           | mariadb2.weave.local | OFFLINE_SOFT |
| 10           | mariadb3.weave.local | OFFLINE_SOFT |
| 20           | mariadb1.weave.local | ONLINE       |
| 20           | mariadb2.weave.local | ONLINE       |
| 20           | mariadb3.weave.local | ONLINE       |
+--------------+----------------------+--------------+

W tym momencie nasza architektura wygląda mniej więcej tak:

Wszystkie połączenia przychodzące z 6033 (albo z sieci host1, host2 lub kontenera) będą równoważone do kontenerów bazy danych zaplecza przy użyciu ProxySQL. Jeśli chcesz uzyskać dostęp do pojedynczego serwera bazy danych, użyj zamiast tego portu 3306 hosta fizycznego. Nie ma wirtualnego adresu IP jako pojedynczego punktu końcowego skonfigurowanego dla usługi ProxySQL, ale możemy to osiągnąć za pomocą Keepalived, co wyjaśniono w następnej sekcji.

Wirtualny adres IP z podtrzymaniem

Ponieważ skonfigurowaliśmy kontenery ProxySQL tak, aby działały na hoście 1 i hoście2, zamierzamy użyć kontenerów Keepalived, aby połączyć te hosty i zapewnić wirtualny adres IP za pośrednictwem sieci hosta. Dzięki temu pojedynczy punkt końcowy dla aplikacji lub klientów może łączyć się z warstwą równoważenia obciążenia wspieraną przez ProxySQL.

Jak zwykle utwórz niestandardowy plik konfiguracyjny dla naszej usługi Keepalived. Oto zawartość /containers/keepalived1/keepalived.conf:

vrrp_instance VI_DOCKER {
   interface ens33               # interface to monitor
   state MASTER
   virtual_router_id 52          # Assign one ID for this route
   priority 101
   unicast_src_ip 192.168.55.161
   unicast_peer {
      192.168.55.162
   }
   virtual_ipaddress {
      192.168.55.160             # the virtual IP
}

Skopiuj plik konfiguracyjny do hosta2 dla drugiej instancji:

$ mkdir -p /containers/keepalived2/ # on host2
$ scp /containers/keepalived1/keepalived.conf /container/keepalived2/ # on host1

Zmień priorytet z 101 na 100 w skopiowanym pliku konfiguracyjnym na hoście2:

$ sed -i 's/101/100/g' /containers/keepalived2/keepalived.conf

**Instancja o wyższym priorytecie będzie przechowywać wirtualny adres IP (w tym przypadku jest to host1), dopóki komunikacja VRRP nie zostanie przerwana (w przypadku awarii hosta1).

Następnie uruchom następujące polecenie odpowiednio na hoście1 i hoście2:

$ docker run -d \
        --name=${NAME} \
        --cap-add=NET_ADMIN \
        --net=host \
        --restart=always \
        --volume /containers/${NAME}/keepalived.conf:/usr/local/etc/keepalived/keepalived.conf \ osixia/keepalived:1.4.4

** Zamień ${NAME} na keepalived1 i keepalived2.

Polecenie run mówi Dockerowi, aby:

  • --nazwa , utwórz kontener za pomocą
  • --cap-add=NET_ADMIN , dodaj możliwości Linuksa dla zakresu administratora sieci
  • --net=host , dołącz kontener do sieci hosta. Zapewni to wirtualny adres IP na interfejsie hosta, ens33
  • --restart=zawsze , zawsze utrzymuj kontener uruchomiony,
  • --volume=/containers/${NAME}/keepalived.conf:/usr/local/etc/keepalived/keepalived.conf , zamapuj niestandardowy plik konfiguracyjny do użycia kontenera.

Po uruchomieniu obu kontenerów zweryfikuj istnienie wirtualnego adresu IP, patrząc na fizyczny interfejs sieciowy węzła MASTER:

$ ip a | grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.55.161/24 brd 192.168.55.255 scope global ens33
    inet 192.168.55.160/32 scope global ens33

Klienci i aplikacje mogą teraz korzystać z wirtualnego adresu IP 192.168.55.160 w celu uzyskania dostępu do usługi bazy danych. Ten wirtualny adres IP istnieje w tej chwili na hoście1. Jeśli host1 ulegnie awarii, keepalived2 przejmie adres IP i uruchomi go na hoście2. Zwróć uwagę, że konfiguracja tego keepalive nie monitoruje kontenerów ProxySQL. Monitoruje tylko reklamę VRRP peerów Keepalved.

W tym momencie nasza architektura wygląda mniej więcej tak:

Podsumowanie

Tak więc teraz mamy klaster MariaDB Galera, na czele z wysoce dostępną usługą ProxySQL, działającą w kontenerach Docker.

W części drugiej przyjrzymy się, jak zarządzać tą konfiguracją. Przyjrzymy się, jak wykonywać operacje, takie jak łagodne zamykanie, ładowanie, wykrywanie najbardziej zaawansowanego węzła, przełączanie awaryjne, odzyskiwanie, skalowanie w górę/w dół, aktualizacje, tworzenie kopii zapasowych i tak dalej. Omówimy również zalety i wady tej konfiguracji dla naszej usługi klastrowanej bazy danych.

Miłego kontenerowania!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak ADDTIME() działa w MariaDB

  2. Funkcje ciągów MariaDB (pełna lista)

  3. Pełna lista zestawów znaków obsługiwanych przez MariaDB

  4. Jak wykryć, czy wartość zawiera co najmniej jedną cyfrę w MariaDB?

  5. Automatyzacja sprawdzania obiektów schematu bazy danych