VagrantでCentOS7にMySQL8最新バージョンをプロヴィジョニングする
前提条件と目標
MySQL8のプロヴィジョニングの問題点
MySQL8ではセキュリティの強化が行われ、デフォルト設定が大幅に変更されました。
設定の変更についてはmy.cnfで書き換えが可能ですのでさほど大きな問題ではありません*1が、rootのパスワード変更を対話型のmysql_secure_installationを通じて行う必要があることが問題です。
mysql_secure_installationを通じて手動で変更する手順は他のサイトさんにお任せするとして、Vagrantの仮想環境でこの問題を解消する方法を探ります。
実際には何度もvagrant upとvagrant destroyを繰り返してようやく実現できました。
プロジェクトの作成
ここではmysql8-testというプロジェクト名で進めていきます。
任意の場所にmysql8-testを作成して、Vagrantfileを作成します。
前回までの理解を活かして、直接テキストエディタで編集していきます。
プラグインとVMの設定
VirtualBoxを使用するときにはvagrant-vbguestプラグインを迷わず使用していきます。
VMの名前も指定して、仮想マシンの管理をしやすくしておきます。
この時点でのVagrantfileはこのようになります。
#設定ブロックの宣言 Vagrant.configure("2") do |config| #プラグインの指定 config.vagrant.plugins = ["vagrant-vbguest"] #VMの設定 config.vm.define "mysql8-test" do |mysql8| mysql8.vm.box = "centos/7" mysql8.vm.synced_folder ".", "/vagrant", disabled: true mysql8.vm.synced_folder "./vsync","/vsync", create: true #VirtualBoxへの設定 mysql8.vm.provider "virtualbox" do |vb| vb.name = "mysql8-test" end end end
まずはMySQL8をインストールするときの手順をの公式ドキュメントで確認
MySQLのリポジトリを追加する
公式の手順によると、CentOS7でシェルから実行するなら以下のコマンドになります。
最後の”1”がバージョン番号とあるため、新規バージョンが出た時にはリポジトリを変更する必要がないか確認した方がいいかもしれません。*2
yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
ここまでをVagrantfileに記述する
この手順をVagrantfileに追加しますが、私はこの時点では追加の手順がどの程度になるかわからなかったため、スクリプトとして切り出しました。
ここではスクリプトファイルをmysql8-provision.shとして、Vagrantfileと同じ階層に設置しています。
Vagrantfile
#設定ブロックの宣言 Vagrant.configure("2") do |config| #プラグインの指定 config.vagrant.plugins = ["vagrant-vbguest"] #VMの設定 config.vm.define "mysql8-test" do |mysql8| mysql8.vm.box = "centos/7" mysql8.vm.synced_folder ".", "/vagrant", disabled: true mysql8.vm.synced_folder "./vsync","/vsync", create: true #VirtualBoxへの設定 mysql8.vm.provider "virtualbox" do |vb| vb.name = "mysql8-test" end #プロヴィジョン mysql8.vm.provision "shell", path: "./mysql8-provision.sh" end end
mysql8-provision.sh
#!/bin/bash #OSアップデート yum update -y #MySQL8インストール yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm yum install -y mysql-community-server #yumキャッシュの削除 yum clean all rm -rf /var/cache/yum
自動プロヴィジョニングのためのMySQL8の初期設定
公式のインストール手順としては、この後インストールの確認のためにサービスを起動して初期パスワードを変更しています。
最初はこれをそのまま自動化しようとしていましたが、それでは不都合な点が多く、ここからは独自の手順となります。
公式の手順の問題点
まず最初の問題点が、この状態でサービスを起動させてしまうと、すべてデフォルトの設定でMySQLサーバーの初期化が行われてしまうことでした。
SSHログインでシェルから操作する前提ならこの状態からも変更できますが、Vagrantを通じてプロヴィジョニングするとなると、課題が多すぎます。
ただ、これはあくまでも「デフォルトでサービスを起動してしまった」ときの制限であって、以下のような手順であれば問題なく自動化できます。
mysqldでサーバーを初期化する
公式のドキュメントをよく読むと、mysqldに引数を渡すことで、条件を指定して初期化を実行できることがわかります。
これを利用して、少ない手順で初期化を行えるようにします。
rootパスワード無しでサーバーを初期化する
公式ドキュメントに、rootパスワード無しでサーバーを初期化する方法がありました。
CentOS7へのyumでのインストールだと、下記がそれにあたります。
/usr/sbin/mysqld --initialize-insecure --user=mysql
当然この状態で使い続けるのは危険ですので、rootのパスワードを変更する手順を確認します。
パスワード無しのrootにログインして、パスワードを変更する
対話型でのパスワードの使用が強制となっているため、通常の手順ではログインができません。オプションを指定して、パスワード無しのログインであることを明示します。
mysql -u root --skip-password
続けて、mysqlクライアントからSQLでパスワードの変更を行います。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password’;
上記のSQLは、mysqlコマンドへの引数として渡すことで、シェルから実行可能です。統合すると、下記のようなコマンドになります。
mysql -u root --skip-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';"
new_passwordの部分は当然ながら、書き換えの必要があります。
スクリプトに記述する
この手順を、先ほど作成したmysql8-provision.shに追加します。
先ほどはMySQL8を初期化することを念頭に置いていたため飛ばしていましたが、MySQL8をサービスに登録して起動させる手順も追加しておきます。
#!/bin/bash #OSアップデート yum update -y #MySQL8インストール yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm yum install -y mysql-community-server #キャッシュの削除 yum clean all rm -rf /var/cache/yum #サーバー初期化 /usr/sbin/mysqld --initialize-insecure --user=mysql systemctl enable mysqld systemctl start mysqld #パスワード変更 mysql -u root --skip-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';"
動作確認
プロジェクトフォルダにVagrantfileとmysql8-provision.shがあることを確認して、vagrant upを実行します。
VMが起動したらSSH接続を行い、mysqlへrootでログインできるか確認します。
mysql -u root -p Enter password:(new_passwordを入力) Welcome to the MySQL monitor. Commands end with ; or \g.
これでVagrantでCentOS7にMySQL8最新バージョンをプロヴィジョニングすることに成功しました!
お疲れ様でした。
補足事項
MySQLサーバーの設定の変更
上記の手順ではMySQLサーバーの設定には一切変更を加えていません。
MySQL8の変更点の代表としてログイン時の認証形式の変更があり、デフォルト設定のままだと対応していない様々なクライアントが接続できない可能性があります。
必要に応じてmy.cnfに認証形式を従来のものに戻す設定をしておく方が良いかもしれません。従来の認証形式に戻す設定は下記になります。
default_authentication_plugin=mysql_native_password
また、MySQL8では、ユーザーアカウントごとに認証に使用するプラグインを指定できるようになっているようです。
mysql_secure_installationの処理
ネットで検索できるMySQLのインストール手順では、mysql_secure_installationを利用して不要なサンプルデータベースやデフォルト設定を削除する手順が含まれているものが多くなっています。
この記事の環境ではこれらのサンプルやデフォルトの設定がそもそも行われないため、必要がありませんでした。
他の環境ではmysql_secure_installationが行っている処理をプロヴィジョニングに含める必要があるかもしれません。
こちらの記事qiita.com
が参考になるかと思います。
Vagrantfileやスクリプトにパスワードを記述することについて
ローカル環境での一時的なテストであれば、さして問題ではありませんが、共同作業のためにこれらのファイルを共有する場合、セキュリティ的な問題になります。
Vagrantではファイルからの定数の追い出しには、環境変数を使う方法やRubyの変数を利用する方法があります。
環境変数はローカル環境全体に影響を持ちますので、Rubyの変数を利用するのがおすすめです。また、この場合でもプロジェクトのVagrantfileに記述してしまうと意味がありませんので、ローカル環境の.vagrant.dフォルダ内にVagrantfileを設置して、そこに変数を宣言するのが良いかと思います。
その場合、今回のプロジェクトのファイルには下記のような変更が加わります。
.vagrant.d/Vagrantfile
MYSQL8_PASS="new_password"
プロジェクトのVagrantfile(変更箇所のみ)
mysql8.vm.provision "shell", path: "./mysql8-provishion.sh" , args: MYSQL8_PASS
シェルを利用する場合、arg:に引数を指定することで、シェル側から$を使ってアクセスすることが出来ます。
mysql8-provision.sh(変更箇所のみ)
mysql -u root --skip-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$1';"
シェル側では$を使って引数をコマンドに埋め込むことが出来ます。
この方法でも、多数のプロジェクトをVagrantで管理していると名前の衝突の可能性があるため、その点には注意が必要です。