MariaDB
 sql >> Base de données >  >> RDS >> MariaDB

Exécution d'un cluster MariaDB Galera sans outils d'orchestration de conteneur :première partie

Les outils d'orchestration de conteneurs simplifient l'exécution d'un système distribué, en déployant et en redéployant des conteneurs et en gérant les pannes qui se produisent. Il peut être nécessaire de déplacer des applications, par exemple pour gérer les mises à jour, la mise à l'échelle ou les pannes d'hôte sous-jacentes. Bien que cela sonne bien, cela ne fonctionne pas toujours bien avec un cluster de bases de données fortement cohérent comme Galera. Vous ne pouvez pas simplement déplacer les nœuds de la base de données, ce ne sont pas des applications sans état. De plus, l'ordre dans lequel vous effectuez les opérations sur un cluster a une grande importance. Par exemple, le redémarrage d'un cluster Galera doit commencer à partir du nœud le plus avancé, sinon vous perdrez des données. Par conséquent, nous allons vous montrer comment exécuter Galera Cluster sur Docker sans outil d'orchestration de conteneurs, afin que vous ayez un contrôle total.

Dans cet article de blog, nous allons examiner comment exécuter un cluster MariaDB Galera sur des conteneurs Docker à l'aide de l'image Docker standard sur plusieurs hôtes Docker, sans l'aide d'outils d'orchestration comme Swarm ou Kubernetes. Cette approche est similaire à l'exécution d'un cluster Galera sur des hôtes standard, mais la gestion des processus est configurée via Docker.

Avant d'aller plus loin dans les détails, nous supposons que vous avez installé Docker, désactivé SElinux/AppArmor et effacé les règles dans iptables, firewalld ou ufw (selon ce que vous utilisez). Voici trois hôtes Docker dédiés pour notre cluster de bases de données :

  • hôte1.local - 192.168.55.161
  • hôte2.local - 192.168.55.162
  • hôte3.local - 192.168.55.163

Mise en réseau multi-hôtes

Tout d'abord, la mise en réseau Docker par défaut est liée à l'hôte local. Docker Swarm introduit une autre couche réseau appelée réseau superposé, qui étend l'interconnexion de conteneurs à plusieurs hôtes Docker dans un cluster appelé Swarm. Bien avant que cette intégration ne soit mise en place, de nombreux plugins réseau ont été développés pour prendre en charge cela - Flannel, Calico, Weave en font partie.

Ici, nous allons utiliser Weave comme plugin réseau Docker pour la mise en réseau multi-hôte. Cela est principalement dû à sa simplicité d'installation et de fonctionnement, et à la prise en charge du résolveur DNS (les conteneurs fonctionnant sous ce réseau peuvent résoudre le nom d'hôte de l'autre). Il existe deux façons de faire fonctionner Weave - systemd ou via Docker. Nous allons l'installer en tant qu'unité systemd, il est donc indépendant du démon Docker (sinon, nous devrions d'abord démarrer Docker avant que Weave ne soit activé).

  1. Téléchargez et installez Weave :

    $ curl -L git.io/weave -o /usr/local/bin/weave
    $ chmod a+x /usr/local/bin/weave
  2. Créez un fichier d'unité systemd pour 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. Définissez les adresses IP ou le nom d'hôte des pairs dans /etc/sysconfig/weave :

    $ echo 'PEERS="192.168.55.161 192.168.55.162 192.168.55.163"' > /etc/sysconfig/weave
  4. Démarrez et activez Weave au démarrage :

    $ systemctl start weave
    $ systemctl enable weave

Répétez les 4 étapes ci-dessus sur tous les hôtes Docker. Vérifiez avec la commande suivante une fois terminé :

$ weave status

Le nombre de pairs est ce que nous recherchons. Il devrait être 3 :

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

Exécuter un cluster Galera

Maintenant que le réseau est prêt, il est temps de lancer nos conteneurs de base de données et de former un cluster. Les règles de base sont :

  • Le conteneur doit être créé sous --net=weave pour avoir une connectivité multi-hôte.
  • Les ports de conteneur qui doivent être publiés sont 3306, 4444, 4567, 4568.
  • L'image Docker doit prendre en charge Galera. Si vous souhaitez utiliser Oracle MySQL, procurez-vous la version Codership. Si vous aimez Percona, utilisez cette image à la place. Dans cet article de blog, nous utilisons MariaDB.

Les raisons pour lesquelles nous avons choisi MariaDB comme fournisseur de cluster Galera sont :

  • Galera est intégré à MariaDB, à partir de MariaDB 10.1.
  • L'image MariaDB est gérée par les équipes Docker et MariaDB.
  • L'une des images Docker les plus populaires.

L'amorçage d'un cluster Galera doit être effectué dans l'ordre. Tout d'abord, le nœud le plus à jour doit être démarré avec "wsrep_cluster_address=gcomm://". Ensuite, démarrez les nœuds restants avec une adresse complète composée de tous les nœuds du cluster, par exemple, "wsrep_cluster_address=gcomm://node1,node2,node3". Pour accomplir ces étapes à l'aide d'un conteneur, nous devons effectuer quelques étapes supplémentaires pour nous assurer que tous les conteneurs fonctionnent de manière homogène. Donc le plan est :

  1. Nous aurions besoin de commencer avec 4 conteneurs dans cet ordre :mariadb0 (bootstrap), mariadb2, mariadb3, mariadb1.
  2. Le conteneur mariadb0 utilisera les mêmes datadir et configdir avec mariadb1.
  3. Utilisez mariadb0 sur host1 pour le premier bootstrap, puis démarrez mariadb2 sur host2, mariadb3 sur host3.
  4. Supprimez mariadb0 sur host1 pour céder la place à mariadb1.
  5. Enfin, démarrez mariadb1 sur host1.

À la fin de la journée, vous auriez un cluster Galera à trois nœuds (mariadb1, mariadb2, mariadb3). Le premier conteneur (mariadb0) est un conteneur transitoire à des fins d'amorçage uniquement, utilisant l'adresse de cluster "gcomm://". Il partage les mêmes datadir et configdir avec mariadb1 et sera supprimé une fois le cluster formé (mariadb2 et mariadb3 sont en place) et les nœuds synchronisés.

Par défaut, Galera est désactivé dans MariaDB et doit être activé avec un indicateur appelé wsrep_on (réglé sur ON) et wsrep_provider (défini sur le chemin de la bibliothèque Galera) plus un certain nombre de paramètres liés à Galera. Ainsi, nous devons définir un fichier de configuration personnalisé pour le conteneur afin de configurer Galera correctement.

Commençons par le premier conteneur, mariadb0. Créez un fichier sous /containers/mariadb1/conf.d/my.cnf et ajoutez les lignes suivantes :

$ 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

Étant donné que l'image n'est pas fournie avec MariaDB Backup (qui est la méthode SST préférée pour MariaDB 10.1 et MariaDB 10.2), nous allons nous en tenir à xtrabackup-v2 pour le moment.

Pour effectuer le premier démarrage du cluster, exécutez le conteneur de démarrage (mariadb0) sur host1 avec le "datadir" et "conf.d" de 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

Les paramètres utilisés dans la commande ci-dessus sont :

  • --nom , crée le conteneur nommé "mariadb0",
  • --nom d'hôte , attribue au conteneur un nom d'hôte "mariadb0.weave.local",
  • --net , place le conteneur dans le réseau tissé pour la prise en charge de la mise en réseau multi-hôte,
  • --publier , expose les ports 3306, 4444, 4567, 4568 du conteneur à l'hôte,
  • $(tisser dns-args) , configure le résolveur DNS pour ce conteneur. Cette commande peut être traduite en Docker run comme "--dns=172.17.0.1 --dns-search=weave.local.",
  • --env MYSQL_ROOT_PASSWORD , le mot de passe root MySQL,
  • --env MYSQL_USER , crée un utilisateur "proxysql" à utiliser ultérieurement avec ProxySQL pour le routage de la base de données,
  • --env MYSQL_PASSWORD , le mot de passe de l'utilisateur "proxysql",
  • --volume /containers/mariadb1/datadir:/var/lib/mysql , crée /containers/mariadb1/datadir s'il n'existe pas et le mappe avec /var/lib/mysql (MySQL datadir) du conteneur (pour le nœud bootstrap, cela peut être ignoré),
  • --volume /containers/mariadb1/conf.d:/etc/mysql/mariadb.conf.d , monte les fichiers sous le répertoire /containers/mariadb1/conf.d de l'hôte Docker, dans le conteneur à /etc/mysql/mariadb.conf.d.
  • mariadb:10.2.15 , utilise l'image MariaDB 10.2.15 d'ici,
  • --wsrep_cluster_address , Chaîne de connexion Galera pour le cluster. "gcomm://" signifie bootstrap. Pour le reste des conteneurs, nous allons utiliser une adresse complète à la place.
  • --wsrep_sst_auth , chaîne d'authentification pour l'utilisateur SST. Utilisez le même utilisateur que root,
  • --wsrep_node_address , le nom d'hôte du nœud, dans ce cas nous allons utiliser le FQDN fourni par Weave.

Le conteneur d'amorçage contient plusieurs éléments clés :

  • Le nom, le nom d'hôte et l'adresse wsrep_node_address sont mariadb0, mais il utilise les volumes de mariadb1.
  • L'adresse du cluster est "gcomm://"
  • Il existe deux paramètres --env supplémentaires :MYSQL_USER et MYSQL_PASSWORD. Ces paramètres créeront un utilisateur supplémentaire pour notre objectif de surveillance proxysql.

Vérifiez avec la commande suivante :

$ docker ps
$ docker logs -f mariadb0

Une fois que vous voyez la ligne suivante, cela indique que le processus d'amorçage est terminé et que Galera est actif :

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

Créez le répertoire pour charger notre fichier de configuration personnalisé dans les hôtes restants :

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

Ensuite, copiez le my.cnf que nous avons créé pour mariadb0 et mariadb1 vers mariadb2 et mariadb3 respectivement :

$ 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

Ensuite, créez 2 autres conteneurs de base de données (mariadb2 et mariadb3) respectivement sur host2 et host3 :

$ 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

** Remplacez ${NAME} par mariadb2 ou mariadb3 respectivement.

Cependant, il y a un hic. Le script de point d'entrée vérifie le service mysqld en arrière-plan après l'initialisation de la base de données en utilisant l'utilisateur root MySQL sans mot de passe. Étant donné que Galera effectue automatiquement la synchronisation via SST ou IST lors du démarrage, le mot de passe de l'utilisateur racine MySQL changera, reflétant le nœud amorcé. Ainsi, vous verriez l'erreur suivante lors du premier démarrage :

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.

L'astuce consiste à redémarrer une fois de plus les conteneurs en échec, car cette fois, le répertoire de données MySQL aurait été créé (lors de la première tentative d'exécution) et il ignorerait la partie d'initialisation de la base de données :

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

Une fois démarré, vérifiez en regardant la ligne suivante :

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

À ce stade, 3 conteneurs sont en cours d'exécution, mariadb0, mariadb2 et mariadb3. Notez que mariadb0 est démarré à l'aide de la commande bootstrap (gcomm://), ce qui signifie que si le conteneur est automatiquement redémarré par Docker à l'avenir, il pourrait potentiellement devenir disjoint du composant principal. Ainsi, nous devons supprimer ce conteneur et le remplacer par mariadb1, en utilisant la même chaîne de connexion Galera avec le reste et utiliser les mêmes datadir et configdir avec mariadb0.

Tout d'abord, arrêtez mariadb0 en envoyant SIGTERM (pour vous assurer que le nœud va être arrêté correctement) :

$ docker kill -s 15 mariadb0

Ensuite, démarrez mariadb1 sur host1 en utilisant une commande similaire à mariadb2 ou 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

Cette fois, vous n'avez pas besoin de faire l'astuce de redémarrage car MySQL datadir existe déjà (créé par mariadb0). Une fois le conteneur démarré, vérifiez que la taille du cluster est de 3, que l'état doit être Primaire et que l'état local est synchronisé :

$ 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                                                                        |
+---------------------------+-------------------------------------------------------------------------------+

À ce stade, notre architecture ressemble à ceci :

Bien que la commande run soit assez longue, elle décrit bien les caractéristiques du conteneur. C'est probablement une bonne idée d'envelopper la commande dans un script pour simplifier les étapes d'exécution, ou d'utiliser un fichier de composition à la place.

Routage de base de données avec ProxySQL

Nous avons maintenant trois conteneurs de base de données en cours d'exécution. La seule façon d'accéder au cluster est maintenant d'accéder au port publié de MySQL de l'hôte Docker individuel, qui est 3306 (mapper à 3306 vers le conteneur). Que se passe-t-il si l'un des conteneurs de la base de données tombe en panne ? Vous devez basculer manuellement la connexion du client vers le prochain nœud disponible. Selon le connecteur d'application, vous pouvez également spécifier une liste de nœuds et laisser le connecteur effectuer le basculement et le routage des requêtes pour vous (Connector/J, PHP mysqlnd). Sinon, ce serait une bonne idée d'unifier les ressources de la base de données en une seule ressource, que l'on peut appeler un service.

C'est là que ProxySQL entre en scène. ProxySQL peut agir en tant que routeur de requête, équilibrant la charge des connexions à la base de données de la même manière que "Service" dans le monde Swarm ou Kubernetes. Nous avons construit une image ProxySQL Docker à cet effet et maintiendrons l'image pour chaque nouvelle version avec notre meilleur effort.

Avant d'exécuter le conteneur ProxySQL, nous devons préparer le fichier de configuration. Voici ce que nous avons configuré pour proxysql1. Nous créons un fichier de configuration personnalisé sous /containers/proxysql1/proxysql.cnf sur host1 :

$ 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"
        }
)

La configuration ci-dessus :

  • configurer deux groupes d'hôtes, le groupe à écrivain unique et le groupe à plusieurs écrivains, comme défini dans la section "mysql_servers",
  • envoyer des lectures à tous les nœuds Galera (groupe d'hôtes 20) tandis que les opérations d'écriture iront à un seul serveur Galera (groupe d'hôtes 10),
  • planifier le proxysql_galera_checker.sh,
  • utilisez monitor_username et monitor_password comme informations d'identification de surveillance créées lors du premier démarrage du cluster (mariadb0).

Copiez le fichier de configuration sur host2, pour la redondance ProxySQL :

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

Ensuite, exécutez les conteneurs ProxySQL sur host1 et host2 respectivement :

$ 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

** Remplacez ${NAME} par proxysql1 ou proxysql2 respectivement.

Nous avons spécifié --restart=always pour le rendre toujours disponible quel que soit l'état de sortie, ainsi que le démarrage automatique au démarrage du démon Docker. Cela garantira que les conteneurs ProxySQL agissent comme un démon.

Vérifiez l'état des serveurs MySQL surveillés par les deux instances ProxySQL (OFFLINE_SOFT est attendu pour le groupe d'hôtes à écrivain unique) :

$ 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       |
+--------------+----------------------+--------------+

À ce stade, notre architecture ressemble à ceci :

Toutes les connexions provenant de 6033 (soit du réseau host1, host2 ou du conteneur) seront équilibrées en charge vers les conteneurs de base de données backend à l'aide de ProxySQL. Si vous souhaitez accéder à un serveur de base de données individuel, utilisez plutôt le port 3306 de l'hôte physique. Il n'y a pas d'adresse IP virtuelle en tant que point de terminaison unique configuré pour le service ProxySQL, mais nous pourrions l'avoir en utilisant Keepalived, qui est expliqué dans la section suivante.

Adresse IP virtuelle avec Keepalived

Puisque nous avons configuré les conteneurs ProxySQL pour qu'ils s'exécutent sur host1 et host2, nous allons utiliser des conteneurs Keepalived pour lier ces hôtes ensemble et fournir une adresse IP virtuelle via le réseau hôte. Cela permet à un point de terminaison unique pour les applications ou les clients de se connecter à la couche d'équilibrage de charge soutenue par ProxySQL.

Comme d'habitude, créez un fichier de configuration personnalisé pour notre service Keepalived. Voici le contenu de /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
}

Copiez le fichier de configuration sur host2 pour la seconde instance :

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

Modifiez la priorité de 101 à 100 dans le fichier de configuration copié sur host2 :

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

** L'instance de priorité la plus élevée conservera l'adresse IP virtuelle (dans ce cas, host1), jusqu'à ce que la communication VRRP soit interrompue (au cas où host1 tombe en panne).

Ensuite, exécutez la commande suivante sur host1 et host2 respectivement :

$ 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

** Remplacez ${NAME} par keepalived1 et keepalived2.

La commande run indique à Docker :

  • --nom , créez un conteneur avec
  • --cap-add=NET_ADMIN , ajouter des fonctionnalités Linux pour l'étendue de l'administration réseau
  • --net=hôte , connectez le conteneur au réseau hôte. Cela fournira une adresse IP virtuelle sur l'interface hôte, ens33
  • --restart=always , laissez toujours le conteneur en cours d'exécution,
  • --volume=/containers/${NAME}/keepalived.conf:/usr/local/etc/keepalived/keepalived.conf , mappez le fichier de configuration personnalisé pour l'utilisation du conteneur.

Une fois les deux conteneurs démarrés, vérifiez l'existence de l'adresse IP virtuelle en examinant l'interface réseau physique du nœud 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

Les clients et les applications peuvent désormais utiliser l'adresse IP virtuelle 192.168.55.160 pour accéder au service de base de données. Cette adresse IP virtuelle existe actuellement sur host1. Si host1 tombe en panne, keepalived2 reprendra l'adresse IP et l'affichera sur host2. Notez que la configuration de ce keepalived ne surveille pas les conteneurs ProxySQL. Il surveille uniquement la publicité VRRP des pairs Keepalived.

À ce stade, notre architecture ressemble à ceci :

Résumé

Nous avons donc maintenant un cluster MariaDB Galera dirigé par un service ProxySQL hautement disponible, tous exécutés sur des conteneurs Docker.

Dans la deuxième partie, nous allons voir comment gérer cette configuration. Nous verrons comment effectuer des opérations telles que l'arrêt progressif, le démarrage, la détection du nœud le plus avancé, le basculement, la récupération, la mise à l'échelle, les mises à niveau, la sauvegarde, etc. Nous discuterons également des avantages et des inconvénients d'avoir cette configuration pour notre service de base de données en cluster.

Bonne conteneurisation !