---
categories: databases
title: Howto Orchestrator : Haute disponibilité et outil de gestion de la réplication.
---

* Github Orchestrator : <https://github.com/openark/orchestrator>
* Documentation Orchestrator : <https://github.com/openark/orchestrator/tree/master/docs>
* Dépot packet Debian : <https://packagecloud.io/github/orchestrator>

Orchestrator est un outil de gestion de la haute disponibilité et de la réplication MySQL / MariaDB.
Il s'exécute en tant que service et fourni un accès en ligne de commande, une API HTTP, et un interface web.

## Installation

Sur Debian on préconise l'installation du paquet .deb via le dépot officiel d'Orchestrator :

~~~
# apt install debian-archive-keyring curl gnupg apt-transport-https
# curl -L https://packagecloud.io/github/orchestrator/gpgkey > /etc/apt/trusted.gpg.d/orchestrator.asc
~~~

En Debian 11 on utlise le dépôt buster, car le dépôt bullseye n'existe pas encore, mais le paquets est compatible.
A adapter en fontion de la version de Debian, on utilise ce dépôt le fichier `/etc/apt/sources.list.d/github_orchestrator.list`

~~~
deb https://packagecloud.io/github/orchestrator/debian/ buster main
deb-src https://packagecloud.io/github/orchestrator/debian/ buster main
~~~

Puis on recharge la liste des dépots et on installe les paquets :

~~~
# apt update
# apt install orchestrator orchestrator-cli
~~~

## Configuration

### Configurer le serveur MariaDB Backend

Orchestrator a besoin d'une base de données de Backend pour stocker l'état du cluster, on préconise de créer la base de donnée orchestrator sur une instance MariaDB en dehors du cluster de réplication, sur une machine qui sert de proxy par exemple :

~~~sql
CREATE DATABASE IF NOT EXISTS orchestrator;
CREATE USER 'orchestrator'@'127.0.0.1' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON `orchestrator`.* TO 'orchestrator'@'127.0.0.1';
~~~

Le fichier de configuration d'Orchestrator se trouve dans `/etc/orchestrator.conf.json`, le packet inclu un fichier nommée `orchestrator.conf.json.sample` avecune configuration de base, on peux se servir de ce fichier pour créer le fichier de configuration de base :

~~~
cp /usr/local/orchestrator/orchestrator-sample.conf.json /etc/orchestrator.conf.json
~~~

Editer les variables suivante dans le fichier `/etc/orchestrator.conf.json`, pour configurer le backend d'Orchestrator vers l'instance MariaDB :

~~~json
{
"MySQLOrchestratorHost": "127.0.0.1",
"MySQLOrchestratorPort": 3306,
"MySQLOrchestratorDatabase": "orchestrator",
"MySQLOrchestratorUser": "orchestrator",
"MySQLOrchestratorPassword": "password",
}
~~~

### Configuration d'Ochestrator vers vos serveurs MariaDB

Pour que Ochestrator detecte votre topologie de réplication de votre cluster MariaDB, il doit avoir un compte sur chaque serveur du cluster,il doit s'agir du même compte pour tout les serveurs du cluster.
Sur le serveur primaire, on créer l'utilisateur comme ceci :

~~~sql
CREATE USER 'orchestrator_client'@'orchestrator_host' IDENTIFIED BY 'password';
GRANT SUPER, PROCESS, REPLICATION SLAVE, RELOAD ON *.* TO 'orchestrator_client'@'orchestrator_host';
GRANT SELECT ON mysql.slave_master_info TO 'orchestrator_client'@'orchestrator_host';
GRANT SELECT ON ndbinfo.processes TO 'orchestrator_client'@'orchestrator_host'; -- seulement pour un cluster NDB
GRANT SELECT ON performance_schema.replication_group_members TO 'orchestrator_client'@'orchestrator_host'; -- Only for Group Replication / InnoDB cluster
~~~

> `REPLICATION SLAVE` est requis pour `SHOW SLAVE HOSTS`, and pour scanner les binlogs si on utilise les `Pseudo GTID`. `RELOAD` est requis pour pourvoir faire un `RESET SLAVE`. `PROCESS` est requis pour surveiller les process des réplicas avec `SHOW PROCESSLIST`.

On configure le fichier `/etc/orchestrator.conf.json` avec les variables suivantes pour indiquer l'utilisateur `orchestrator_client` :

~~~json
{
"MySQLTopologyUser": "orchestrator_client",
"MySQLTopologyPassword": "password",
}
~~~

Ensuite on peux démarrer Orchestrator comme ceci :

~~~
# systemctl start orchestrator.service 
~~~

### Configuration : Découverte des serveurs SQL par résolution de nom

Si on veux que orchestrator fasse la découverte des serveurs SQL avec la résolution de nom on peut mettre cette configuration dans `/etc/orchestrator.conf.json` :

~~~json
{
 "HostnameResolveMethod": "default",
  "MySQLHostnameResolveMethod": "@@hostname",
}
~~~

### Configuration : Classement des serveurs

Orchestrator peut classer les serveurs en fontion du nom du cluster, du datacenter, etc...

Voici la configuration qu'on mets par défaut :

~~~json
{
  "ReplicationLagQuery": "",
  "DetectClusterAliasQuery": "select ifnull(max(cluster_name), '') as cluster_alias from meta.cluster where anchor=1",
  "DetectClusterDomainQuery": "select ifnull(max(cluster_domain), '') as cluster_domain from meta.cluster where anchor=1",
  "DetectInstanceAliasQuery": "",
  "DetectPromotionRuleQuery": "",
  "DataCenterPattern": "[.]([^.]+)[.][^.]+[.]mydomain[.]com",
  "PhysicalEnvironmentPattern": "[.]([^.]+[.][^.]+)[.]mydomain[.]com",
}
~~~

#### Replication lag

Par défaut Orchestrator utlise `SHOW SLAVE STATUS` et à une tolérrance de 1 seconde de lag.
Il ne tient pas en compte de décalages en cascade en cas de réplication chaînéé.
Si on veux modifié ce comportement, on peut utilisé des outils personalisés tel que `pt-heartbeat`, ça fourni une décalage "absolu" par rapport au primaire, ainsi qu'un lag inférieur à la seconde.

#### Cluster alias

Dans votre topologie vos instances portent différents nom tel que "main", "inst01" etc... Cependant les cluster MySQL eux-même ne connaissent pas ces noms.

`DetectClusterAliasQuery` est une requpête par laquelle vous permettrez a Orchestrator de connaître le nom de votre cluster.

Le nom est important, on l'utilise pour indiquer à Orchestrator des éléments tels que "veuillez récupérer automatiquement ce cluster" ou "quelles sont toutes les instances participantes dans ce cluster".

Pour rendre ces données accessibles par une requête, on créer une table dans un méta schéma, comme ceci, sur les serveurs SQL :

~~~sql
CREATE TABLE IF NOT EXISTS cluster (
  anchor TINYINT NOT NULL,
  cluster_name VARCHAR(128) CHARSET ascii NOT NULL DEFAULT '',
  cluster_domain VARCHAR(128) CHARSET ascii NOT NULL DEFAULT '',
  PRIMARY KEY (anchor)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
~~~

et on peuple la table comme ceci (on peux le faire également par Ansible ou un cron) :

~~~
# mysql meta -e "INSERT INTO cluster (anchor, cluster_name, cluster_domain) VALUES (1, 'TestEvoCluster', 'EvoCluster') ON DUPLICATE KEY UPDATE cluster_name=VALUES(cluster_name), cluster_domain=VALUES(cluster_domain)";
~~~

#### Data center

Orchestrator classe les topologies de cluster SQL dans des `Data Center`, cela les colorera joliment dans l'interface web, mais il prendra en compte la variable `Data Center` lors de l'exécution des basculements.

On configure la reconnaissance du `Data Center` selon l'une des deux méthodes :

* `DataCenterPattern` : Une expression régilière à utliser sur le FQDN : `"[.]([^.]+)[.][^.]+[.]mydomain[.]com"`
* `DetectDataCenterQuery` : une requête qui renvoie le nom du `Data Center`

### MySQL / MariaDB Configuration

Vos topologies MySQL doivent remplir certaines conditions pour prendre en charge les bascules.
Ces exigences dépendent en grande partie des types de topologies / configuration que vous utilisez.

* Oracle/Percona avec GTID : les serveurs pouvant être promus doivent avoir `log_bin` et `log_slave_updates` activés. Les secondaires doivent utliser `AUTO_POSITION=1` (via CHANGE MASTER TO MASTER_AUTO_POSITION=1)
* MariaDB GTID : les serveurs pouvant être promus doivent avoir `log_bin` et `log_slave_updates` activés.

### Configuration : Détection de panne

Orchestrator détectera toujours les pannes de votre topologie. Dans la configuration on peut définir la fréquence d'interrogation et des moyens spécifiques pour que Orchestrator vous avertisse d'une telle détection.

Considérez également que vos topologies MySQL elles-mêmes doivent suivre certaines règles, voir `MySQL / MariaDB Configuration`

Voici la configuration de base pour la détection de panne :

~~~json
{
"RecoveryPeriodBlockSeconds": 3600,
  "RecoveryIgnoreHostnameFilters": [],
  "RecoverMasterClusterFilters": [
    "*"
  ],
  "RecoverIntermediateMasterClusterFilters": [
    "_intermediate_master_pattern_"
  ],
}
~~~

* Orchestrator récupérera automatiquement les pannes principales intermédiaire pour tous les clusters.
* Orchestrator récupérera automatiquement les défaillances  pour tous les clusters, les primaire des autres cluster ne récupéreront pas automatiquement. Un humain pourra initier des récupérations.
* Une fois qu'un cluster a connu une récupération, Orchestrator bloque les récupérations automatiques pendant 3 600 secondes (1 heure). C'est un mécanisme anti-flap.

### Promotion de primaire

A des fins de maintenance ou autre, on peux remplacer un primaire existant par un autre, il s'agit d'une promotion en douceur , cela fait une rotation des rôles, un secondaire existant devient un primaire, l'ancien primaire devient un secondaire.

Voici en détail comment la bascule se passe :

* L'utilisateur ou Orchestrator choisit un réplica existant comme nouveau primaire désigné. 
* Orchestrator s'assure que le réplica désigné prend le relais avec les autres réplica.
* Orchestrator transforme le primaire en `read-only`
* Orchestrator s'assure que votre serveur désigné est rattrapé par la réplication.
* Orchestrator promeut votre serveur désigné en tant que nouveau primaire.
* Orchestrator rend le serveur promu accessible en écriture.
* Orchestrator rétrograde l'ancien primaire et le place comme réplique directe du nouveau primaire.
    * si possible, Orchestrator définit l'utilisateur/le mot de passe de réplication pour le primaire rétrogradé.

L'opération peut prendre quelques secondes, pendant lesquelles votre application est censée retournée des erreurs, car le primaire est en lecture seule.

On peux faire une bascule soit :

* En ligne de commande :

~~~
# orchestrator-client -c graceful-master-takeover -alias mycluster -d primaire.à.promouvoir:3306
~~~

Passe le réplica indiqué a promouvoir en primaire, ne démarre pas la réplication sur le primaire rétrogradé en réplica.

~~~
# orchestrator-client -c graceful-master-takeover-auto -alias mycluster -d primaire.à.promouvoir:3306
~~~

Passe le réplica indiqué a promouvoir en primaire, démarre la réplication automatiquement sur le primaire rétrogradé en réplica.

* Via l'API Web :
   * `/api/graceful-master-takeover/:clusterHint/:designatedHost/:designatedPort` : Passe le réplica indiqué a promouvoir en primaire, ne démarre pas la réplication sur le primaire rétrogradé en réplica.
   * `/api/graceful-master-takeover/:clusterHint` : Passe le réplica indiqué a promouvoir en primaire, démarre la réplication automatiquement sur le primaire rétrogradé en réplica.

* On peux faire les bascules également depuis l'interface web.

