MariaDB・MySQL用のProxyであるMaxScaleを使う際にConfigに環境変数からパラメータを渡す方法を調査し、まとめました。

MaxScaleとは?

MariaDB・MySQL用のSQL Proxyで、例えばDBのmax_connectionsが飽和してしまうようなアーキテクチャの場合などに、DBとの間に挟む事でconnectionをまとめてくれたり、自動フェイルオーバのサポート、SQLに対して任意の値をマスクした結果を返す事ができるような機能を提供しているようです。
今回はマスクの機能が使いたいために調査をしていた所、環境変数からDBのパスワードを渡す方法がわからなかったため調べました。

Configに環境変数を渡す方法

公式ドキュメントを読んだら書いてました。

デフォルトではfalseになっているsubstitute_valiablesという設定値を設定ファイルのmaxscaleセクションでtrueにすれば機能するようになるみたいです。

Enable or disable the substitution of environment variables in the MaxScale configuration file. If the substitution of variables is enabled and a configuration line like

some_parameter=$SOME_VALUE

is encountered, then $SOME_VALUE will be replaced with the actual value of the environment variable SOME_VALUE. Note: Variable substitution will be made only if ‘$’ is the first character of the value. Everything following ‘$’ is interpreted as the name of the environment variable. * Referring to a non-existing environment variable is a fatal error.

By default, the value of substitute_variables is false.

substitute_variables=true

The setting of substitute_variables will have an effect on all parameters in the all other sections, irrespective of where the [maxscale] section is placed in the configuration file. However, in the [maxscale] section, to ensure that substitution will take place, place the substitute_variables=true line first.

試してみた

実際にMaxScaleをDockerで立ち上げてきちんと動くのか試してみました。
今回はSQLの実行結果をマスクしてみたかったのでマスクするサンプルを使い動作確認を行いました。 試してみたい方はリポジトリをcloneしてもらえればdockerとdocker-composeさえあれば簡単に試せると思います。

簡単に設定を確認する。

# パラメータの確認
$ cat maxscale/maxscale.cnf | grep substitute
substitute_variables=true

# DBの接続情報を環境変数から渡す
$ cat maxscale/maxscale.cnf.d/example.cnf | grep -B5 PASS
[Masking-Service]
type=service
router=readconnroute
servers=db-server
user=$DB_USER
password=$DB_PASS

# dockerの環境変数から認証情報を渡す
$ cat docker-compose.yml
version: '3.7'
services:
    mysql:
        image: mysql:5.6
        volumes:
            - ./initdb:/docker-entrypoint-initdb.d
        environment:
            MYSQL_ALLOW_EMPTY_PASSWORD: 'Y'

    maxscale:
      build:
        context: .
        dockerfile: Dockerfile.maxscale
      environment:
        DB_USER: 'maxuser'
        DB_PASS: 'maxpwd'
      ports:
        - "3306:3306"  # proxy port
        - "8989:8989"  # REST API port

こんな感じで準備ができたところで実際に動作確認をしてみる。

# コンテナ起動
$ docker-compose up -d --build
Building maxscale
...
Successfully tagged mysql-maxscale-masking-example_maxscale:latest
mysql-maxscale-masking-example_mysql_1 is up-to-date
mysql-maxscale-masking-example_maxscale_1 is up-to-date

$ docker-compose ps
                  Name                                Command             State                       Ports
--------------------------------------------------------------------------------------------------------------------------------
mysql-maxscale-masking-example_maxscale_1   /bin/sh -c ./entrypoint.sh    Up      0.0.0.0:3306->3306/tcp, 0.0.0.0:8989->8989/tcp
mysql-maxscale-masking-example_mysql_1      docker-entrypoint.sh mysqld   Up      3306/tcp

# MySQLに直接クエリを投げる
$ docker-compose exec mysql mysql -umaxuser -pmaxpwd -h localhost test -e "select * from masking1;"
Warning: Using a password on the command line interface can be insecure.
+---------------------+
| card_number1        |
+---------------------+
| 1234-5678-9012-3456 |
| 1234-5678-9013-3456 |
| 1234-5678-9014-3456 |
+---------------------+

# MaxScaleを通してクエリを投げる
$ mysql -umaxuser -pmaxpwd -h 127.0.0.1 test -e "select * from masking1;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------+
| card_number1        |
+---------------------+
| ******************* |
| ******************* |
| ******************* |
+---------------------+

環境変数から差し込んだ認証情報で、MaxScaleがきちんと動作していることを確認できました。

まとめ

substitute_variablesを有効化する事で、MaxScaleのConfigに環境変数からパラメータを渡す事ができました。
SQL Proxyに関してはクエリの結果をマスクするなど高度な機能がある事を知らなかったため、初めて知れて良かったです。 SQL Proxyは用途によってはかなり重宝しそうですね。