スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL InnoDB Cluster 管理者ユーザーアカウントを作成・管理する方法(8.0.20以降)

はじめに

InnoDB Cluster では、インストールおよびクラスター管理者ユーザーとして特別なユーザーを準備する必要があります。
その管理者ユーザーアカウントの作成や管理の方法について、最新のリファレンスマニュアルを参照すると、MySQL 8.0.20 より前と後のバージョンで区別して記載されていました。

MySQL :: MySQL Shell 8.0 :: 6.1 MySQL AdminAPI | Creating User Accounts for Administration

該当部分の説明を抜粋・引用してみると、

In versions prior to 8.0.20, the preferred method to create users for administration is using the clusterAdmin option with the dba.configureInstance() operation.

MySQL 8.0.20 より前のバージョンでは、従来通り dba.configureInstance (以下、configureInstanceと表記) の clusterAdmin オプションでクラスター管理者ユーザーを作成することが推奨、

In version 8.0.20 and later, use the setupAdminAccount(user) operation to create or upgrade a MySQL user account with the necessary privileges to administer an InnoDB Cluster or InnoDB ReplicaSet.

そして 8.0.20 以降では、MySQL Shell に新たに追加された API cluster.setupAdminAccount() (以下、setupAdminAccountと表記) を用いること、
(InnoDB Cluster だけでなく、InnoDB ReplicaSet でも)

と明記されています。

これまでの作成と管理方法にどのような変更が生じているか、新しい機能 setupAdminAccount API の使用方法を主眼に置いて調べてみました。

管理者ユーザーアカウントの要件(おさらい)

まず、InnoDB Cluster 管理者ユーザーアカウントにおける、基本的な要件を再確認しておきます。

先ほど引用したリファレンスマニュアルのページに記載されている要件を整理してみると、以下の通りでした。

ユーザー名とパスワード

  • ユーザー名は、標準のMySQLで命名可能な形式であれば任意の名前で問題ありません。
  • パスワードは、MySQLインスタンスのパスワードポリシーに適合させる必要があります。
  • ユーザー名とパスワードは全クラスターメンバーで同一である必要があります。

接続許可ホスト

  • 全てのクラスターメンバーで接続可能となるホスト名を設定したユーザーである必要があります。
  • そのため、以下のような設定をすることになります。
    • クラスターメンバー分のホストを指定した同名ユーザーを作成する。
    • ワイルドカード % やサブネットマスク形式を用いて設定する。
      • IPアドレスのネットワークセグメントやホスト名の連番サフィックスなど、特定の範囲のみ許可
      • 全ホストから許可 など

システムのセキュリティ要件などによって許容できる設定は異なりますが、本番環境では接続許可ホストを必要最低限に絞ることが必須だったりすることも多いかと思います。

検証環境などで手軽に root ユーザーでインストールしてしまいたい、ということもあるかと思いますが、MySQLインストール後にデフォルトで存在する root@localhost をそのまま使用して作成することはできません。(周知の事実ではありますが)

権限

InnoDB Cluster の管理者ユーザーは、MySQL Shellの管理APIを介してクラスターの構成や操作を行いますが、結構強力な権限が必要だということをご存じの方も多いかと思います。

前述のリファレンスマニュアルにて、Creating User Accounts for Administration の冒頭説明でも述べられています。

The user account used to administer an instance does not have to be the root account, however the user needs to be assigned full read and write privileges on the metadata tables in addition to full MySQL administrator privileges (SUPER, GRANT OPTION, CREATE, DROP and so on).

具体的に必要な権限のリストが、リファレンスマニュアルの以下のページに記載されています。

MySQL :: MySQL Shell 8.0 :: 7.3 User Accounts for InnoDB Cluster | Configuring InnoDB Cluster Administrator Accounts Manually

  • Global privileges on . for RELOAD, SHUTDOWN, PROCESS, FILE, SELECT, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION_APPLIER, CREATE USER, SYSTEM_VARIABLES_ADMIN, PERSIST_RO_VARIABLES_ADMIN, BACKUP_ADMIN, CLONE_ADMIN, and EXECUTE.
  • Schema specific privileges for mysql_innodb_cluster_metadata.*, mysql_innodb_cluster_metadata_bkp.*, and mysql_innodb_cluster_metadata_previous.* are ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE; and for mysql.* are INSERT, UPDATE, DELETE.

Note
This list of privileges is based on the current version of MySQL Shell. The privileges are subject to change between releases. Therefore the recommended way to administer accounts is using the operations described at Creating User Accounts for Administration

権限に関して留意しておく点は以下となります。

  • 上記すべてに WITH GRANT OPTION が必要である
  • マニュアルに記載している内容は、その時点のMySQL Shell の最新バージョンで必要な権限であり、バージョンアップによって変更される可能性がある

従来のユーザー作成方法

手動で作成する場合

クラスター構成前に、MySQL 従来の方法で CREATE USER + GRANT を実行します。
ユーザーを作成する分には問題はないので、InnoDB Cluster の構築においても、意外とよく行われている方法かもしれません。

例として、前述の権限を元に、icadmin@% というユーザーを手動で作成するとしたら、以下のような DDL となります。
※これらは記事執筆時点のバージョン 8.0.22 で必要な権限となります

ただし、この方法では、何を設定すべきかは、都度マニュアルを確認しないと分からないということと、マニュアルに記載されている内容がインストール対象のバージョンと必ずしも合致するとは限らない、という懸念は生じます。

dba.configureInstance API で作成する場合

MySQL Shell の API で、InnoDB Cluster のインストール事前検証と自動構成チェックを行うための機能としてよく知られています。
オプションでユーザー名(と接続許可ホスト)とパスワードを指定すれば、あとは MySQL Shell の API 側で必要最小限の権限を付与してユーザーを作成することが可能です。

  • 第一引数で指定したインスタンスに対して実行されます。
    • 下記のように root@localhost の場合は、全クラスターメンバーのローカルで実行します。
    • 予め クラスターメンバーのみ接続可能、ユーザー作成可能なユーザーを作成しておき、いずれかのノード上からリモートで他のメンバーに対して configureInstance を実行することも可能です。
  • clusterAdmin に @ 以降を含めないで設定した場合は、デフォルトで%が付与されます。
  • clusterAdminPassword を省略した場合は対話形式でパスワードの入力が必要です。
  • clusterAdmin オプションを指定せず、かつ第一引数で指定したユーザーが以下の条件を満たさない場合、ユーザー作成を促す選択肢がプロンプト表示されます。(対話形式モードで実行時のみ)
    • ワイルドカードやネットマスクがホストに設定されている
    • 実在するユーザーである
    • クラスター管理のための権限が満たされている(WITH GRANT OPTION 含む)

    下記の場合、localhost が条件を満たしていません。

    • 1 を選択した場合は、記載通り リモート接続可能な root ユーザーが作成されます。
    • 2 を選択した場合は、clusterAdmin オプションと同等の動作を手動で行うことになります。
    • 3 を選択した場合は、今のところはユーザーの接続要件はスルーして、インスタンスの構成チェックを行いたい場合です。
      実際にクラスターを作成・構成する前に、適切な設定に変更しておく必要があります。

setupAdminAccount API が実装された背景

MySQL Server Team ブログの以下の記事にて、setupAdminAccount が導入された経緯と機能が紹介されています。
MySQL Shell AdminAPI – What’s new in 8.0.20? | MySQL Server Blog

従来の方法でユーザー作成して InnoDB Cluster をインストールし、そのまま使用するということでも、一見なんの問題もなさそうではありますが…
思い付く範囲では、

  • MySQLのバージョンアップに伴ってユーザーに付与している権限の修正が必要となる場合、都度必要な権限を確認して、手動で GRANT, REVOKE を実行する必要があったり
  • インストール時に作成するユーザーを root@'%' + GRANT ALL ON *.* ... WITH GRANT OPTION などで作成してしまい、そのまま運用で使い続けている
    • 本来ならば、セキュリティの観点から、必要最低限の接続許可と権限付与に留めておきたい(のだが、どのように設定すればよいか分からない)

というような懸念点が考えられます。

初期構築時からでも、運用途中でも、ユーザー管理の対応が容易であることに越したことは無いです。

MySQL Shell 8.0.19 のメタデータスキーマのバージョンアップを経て

導入の大きなトリガーとなったのは、MySQL Shell 8.0.19 でメタデータスキーマがバージョンアップした変更に対する管理ユーザーアカウントへの手当てだと思われます。

メタデータスキーマのバージョンアップに関しては、過去に、弊社技術ブログ記事にて詳しい内容を取り上げていますので是非ご一読ください。
MySQL Shell 8.0.19 の新機能について | スマートスタイル TECH BLOG

以下は、MySQL 8.0.17 から 8.0.22 にマイナーバージョンアップした後、dba.upgradeMetadata を実行しようとしたときに発生するエラーです。
必要な権限追加を行うよう案内されています。

マイナーバージョンアップ後、クラスター管理者ユーザーアカウントの権限は自動で更新されませんので、事前に対処しておく必要があるのです。

※上記は、直近の 8.0.19 の変更を境に発生した権限の変更差分ですが、今後のバージョンアップではまた別の権限追加が必要となるかもしれません。

そこで、MySQL バージョンアップを行った後に、既存のクラスター管理者ユーザーに対して setupAdminAccountupdate オプションを有効にして実行しておくことで、そのバージョンに適合した、不足している権限を自動で更新する、というアプローチが採用されたということのようです。

setupRouterAccount

そして、もう一つ、重要なポイントがあります。
MySQL Router の管理アカウントに対する手当ても同様に導入され、setupRouterAccount API として追加されています。

MySQL Router の bootstrap 時などに、--acountでカスタム管理者アカウントを指定しない場合、mysql_router*_**** という内部ユーザーが自動で生成されます。
プロキシソフトウェアの性質上、APサーバーやWebサーバーと同居構成をとることが殆どであると思いますが、複数の MySQL Router が InnoDB Cluster への接続構成を行う場合、そのように自動生成されるユーザーが増加していきます。

ただし、前述の弊社ブログ記事でも懸念点として挙げておりましたが、メタデータ情報のアップグレード時など MySQL Router 管理ユーザーのメタデータは削除されても、実際のユーザーは削除されないで残存してしまいます。

そこで、クラスター構成後 ~ MySQL Routerの bootstrap前に setupRouterAccount API でルーター管理者アカウントを作成しておくことで、自動生成されるユーザーの管理に悩まされることはなくなりますし、setupAdminAccount と同様に update オプションを実行することで、バージョンアップ時の権限更新対応も容易になります。

setupAdminAccount, setupRouterAccount API の使い方

前置きがだいぶ長くなってしまいましたが、実際の使用方法を見ていきたいと思います。

従来の推奨方法である、configureInstance が Dba クラスであるのに対し、
setupAdminAccount, setupRouterAccount は Cluster クラスの API であることに注意が必要です。

つまり、configureInstance はクラスター作成前に実行することができたのですが、
setupAdminAccount, setupRouterAccount はクラスター作成後でないと実行できません。

このことから、単純なコマンドの置換えは不可能ですので、setupAdminAccount, setupRouterAccount の実行タイミングを踏まえた手順を検討する必要があります。

なお、第一引数で指定するユーザー名には、configureInstanceclusterAdmin と同じ仕様となっており、@接続許可ホスト を指定することができ、何も指定しない場合のデフォルトは %となります。

初期構築の場合(案)

必要最低限の接続許可・権限付与となるクラスター管理者アカウントを作成したい場合の例として手順を検討してみます。

  1. クラスター初期構成用のrootユーザーを、クラスター全メンバー上で作成します。
    (rootである必要はありませんが、分かり易くするため)

  2. いずれかの1ノード上(例:プライマリーノード、以降同様)で、configureInstanceを実行します。
  3. クラスター初期構成用のrootユーザーでログインし、クラスターを作成、クラスターメンバーの追加を行います。
  4. setupAdminAccount を実行し、本来の運用で使用するクラスター管理アカウントを作成します。
  5. 4.で作成したクラスター管理アカウントでログインします。
  6. setupRouterAccount を実行し、MySQL Router 管理アカウントを作成します。
  7. MySQL Router ノード上で、6.で作成したアカウントを指定し bootstrap を実行します。

ちなみに、1.で作成したクラスター初期構成用のrootユーザー(root@gr-mysql-%)は、この手順により初期構築後は不要になる、ということで削除してみます。
ところが、削除はできますが、以下の warning が表示されます。

それもそのはず、でした。クラスター初期作成時のユーザーなので、メタデータスキーマ VIEW の DEFINER に設定されています。
ただ、SECURITY_TYPE=INVOKERなので、VIEWの参照に支障はないものと思いますが…

この状態のままにして問題が出ないと言い切れないので、以下のような対処を取ることが考えられます。

  • ユーザーを削除してしまうのであれば、一度 cluster.dissolve() でクラスター解除したあと、再構成しなおす
    • メタデータスキーマが再作成され、DEFINERは dba.createCluster() を実行したユーザーが設定されます。
  • ユーザーをそのままにしておくなら、そのアカウントが使用できないようにする
    • ACCOUNT LOCK
    • PASSWORD EXPIRE など

…と挙げてみましたが、ここまでするのも無駄で手間取るだけなので、あまり積極的に実施する必要もないでしょう。

従来の configureInstance との折衷案

上記の手順を見返すと、

  • 1 の際に全メンバーのローカル上で configureInstanceclusterAdmin オプションを使ってクラスターメンバー内でのみ接続可能なユーザーを事前に作成しておけば、以降はそのユーザーを指定して手順が進められる
  • よって 4 で setupAdminAccount の実行は不要となるのでは?

ということに気付きました。(つまり、従来の方法に立ち戻るということになります)

  1. [クラスター全メンバーで実施] クラスター管理者ユーザーを作成し、インスタンスの構成チェックを行います。
  2. [いずれかの1ノード上(例:プライマリーノード、以降同様)で実施] クラスター管理者ユーザーでログインし、クラスターを作成、クラスターメンバーの追加を行います。
  3. setupRouterAccountを実行し、MySQL Router 管理アカウントを作成します。
    (…)
    (以降、同手順)

この場合、前述のものと比べて、手順がだいぶシンプルになりました。

このことから、初期構築時は、無理に setupAdminAccount を使う必要は無いのではと考えます。

運用中に何らかのトラブルでクラスター管理ユーザーを再作成しなければならない場合などでは、setupAdminAccount が役立つのではないでしょうか。

MySQL バージョンアップ時の実行タスク

前述のとおり、MySQLをバージョンアップした後は、以下のコマンドを実行して、既存の管理者アカウントを更新します。

まとめ

MySQL Shell 8.0.20 から新たに追加された setupAdminAccount について、今回調べてみて以下のことが分かりました。

  • クラスター管理者アカウントを作成する機能です。必要な権限は透過的に設定されます。
  • 既存の管理者アカウントの権限を更新することも可能です。
    • MySQL のバージョンアップ時に併せて実施しておくことで、権限追加漏れを防ぐことができます。
  • APIの性質上、実行できるタイミングがクラスター作成後である点は注意が必要です。
    • 現時点では初期構築時に使う必要はなく、従来の configureInstance をそのまま継続利用しても問題ありませんでした。

また、MySQL Router の管理者アカウントも setupRouterAccount を使うことで同じ管理方式に統一することができます。

MySQL 8.0.20 以降をご利用、またはこれからバージョンアップを予定されている場合は、是非ご利用してみてはいかがでしょうか。


MySQL

 

Return Top