3 Minuten Lesezeit (665 Worte)

Ein Geheimnis behalten: MySQL Router „Bootstrapping“ ohne „root“-Account

Über viele Dinge macht man sich auch als erfahrender Berater erst Gedanken, wenn man vor Ihnen steht. Ich habe in den vergangenen Jahren einige InnoDB-Cluster inkl. MySQL-Router in Betrieb genommen. Bisher war dies immer ein interaktiver Prozess, bei dem es kein Problem war, auch Passwörter von privilegierten Usern einfach (an der Konsole) einzugeben. Dass dies auch anders gehen muss, war zumindest theoretisch klar, da ja z. B. der MySQL-Operator für Kubernetes auch in der Lage ist, Router zu „deployen“. Zeit für einen Blick in die Dokumentation. 

Ein paar Grundlagen 

Über den MySQL-InnoDB-Cluster und den MySQL-Router haben wir schon häufiger berichtet. Der Router hat die Aufgabe, den Zustand des Clusters und die Rollen der Knoten im System zu kennen und dies den Clients transparent zu machen. In der Praxis bedeutet dies vereinfacht, dass der Client und/oder der Applikationsserver seine Verbindung gegen den Router starten möchte, von diesem aber dann an ein System im Cluster weitergeleitet wird. So muss der Client eben nicht wissen, welcher Knoten im Cluster aktuell die primäre Rolle (und damit z. B. auch schreibende Zugriffe verarbeiten) einnimmt. 

(Quelle: https://dev.mysql.com/doc/refman/8.0/en/images/innodb_cluster_overview.png)

Die Stiefel schnüren!

Um einen Router in Betrieb zu nehmen, wird ein sogenannter Bootstrapping-Prozess gestartet. Dabei verbindet sich der Router mit einem Knoten im entsprechenden InnoDB Cluster und legt sich einen speziellen User-Account auf allen Knoten an, mit dem der Cluster-Status geprüft werden kann. Dieser User benötigt eigentlich keine überbordenden Rechte: 

GRANT USAGE ON *.* TO `router`@`%` 
GRANT SELECT, EXECUTE ON `mysql_innodb_cluster_metadata`.* TO `router`@`%` 
GRANT INSERT, UPDATE, DELETE ON `mysql_innodb_cluster_metadata`.`routers` TO `router`@`%` 
GRANT INSERT, UPDATE, DELETE ON `mysql_innodb_cluster_metadata`.`v2_routers` TO `router`@`%` 
GRANT SELECT ON `performance_schema`.`global_variables` TO `router`@`%` 
GRANT SELECT ON `performance_schema`.`replication_group_member_stats` TO `router`@`%` 
GRANT SELECT ON `performance_schema`.`replication_group_members` TO `router`@`%` 

Laut dem Beispiel in der Dokumentation soll hierfür der „root“-User beim Bootstrapping genutzt werden, da dieser ja über das Recht verfügt, neue User auf den beteiligten Knoten anzulegen.

$> mysqlrouter --bootstrap root@localhost:3310 --directory /tmp/myrouter --conf-use-sockets --account routerfriend --account-create always

Quelle: https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-deploying-bootstrapping.html

Sofern kein Benutzername (—account) definiert wird, „denkt“ sich MySQL hier einen eigenen Namen (hier „mysql_router12_u36vawan0901“) aus:

bash> root@2210103d6224:/# mysqlrouter --bootstrap=root:root@node1 -d my_router --user=mysql 
# Bootstrapping MySQL Router instance at '/my_router'... 
… 
bash  cat my_router/mysqlrouter.conf | grep user | grep router 
user=mysql_router12_u36vawan0901 

Den Stiefel enger schnüren! 

Nun möchte man in bestimmten Szenarien (Container, Automatisierungslösungen, Skripting) aber nicht den DBA-Account „root“ inkl. Passwort preisgeben. Kann man den Bootstrap-Prozess also anders gestalten? Ja, man kann. Anstatt beim Bootstrapping den User anlegen zu lassen, bereiten wir den Account vor. Dazu könnten wir natürlich mit simplen SQL (siehe oben) den User einfach von Hand erzeugen. Einfacher geht es aber mit der Shell. Dazu unternehmen wir die folgenden Schritte: 

# Verbindung zum Cluster aufnehmen 
MySQL  JS >\c root:root@node1 
 
# Cluster Objekt instanzieren 
MySQL  node1:33060+ ssl  JS > var clu = dba.getCluster('ordix'); 
 
# Router Account anlegen 
MySQL  node1:33060+ ssl  JS > clu.setupRouterAccount('my_router') 
 
Missing the password for new account my_router@%. Please provide one. 
Password for new account: ****** 
Confirm password: ****** 
 
Creating user my_router@%. 
Account my_router@% was successfully created.  

Im letzten Schritt verwenden wir nun den neuen, nicht sonderlich hoch privilegierten User-Account zum Initialisieren (bootstrappen) des Routers: 

bash> mysqlrouter --bootstrap=my_router:geheim@node1 --account=my_router --directory=safe_router --user=mysql --account-create=never --force 
# Bootstrapping MySQL Router instance at '/safe_router'... 
…
root@2210103d6224:/# cat safe_router/mysqlrouter.conf | grep user 
user=my_router  

Fazit 

Wie zu erkennen ist, lässt sich die „sichere“ automatisierte Installation von Routern recht einfach bewerkstelligen. Dies ist natürlich kein Geheimwissen und lässt sich (mit einer gewissen Ausdauer) auch über die Dokumentation nachvollziehen. Vielleicht ist dieser Beitrag aber trotzdem ein kleiner „Shortcut“.

Sie haben Fragen rund um den hochverfügbaren Betrieb von MySQL und Co.? Dann sprechen Sie uns an. Wir helfen gerne. 

Seminarempfehlung

 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Gäste
Mittwoch, 08. Februar 2023

Sicherheitscode (Captcha)

×
Informiert bleiben!

Bei Updates im Blog, informieren wir per E-Mail.

Weitere Artikel in der Kategorie