マルチマスタ構成のOpenstackの構築 pt.2

Pocket

概要

 皆さん、クラウド使ってますか?

 「クラウド」コンピューティングと聞いて多くの人はAWSやGCP、Azureといった大手ITサービスベンダーの製品を思い浮かべるかもしれません。これらのパブリッククラウドは数多くのOSS製品を組み合わせて構成されており、我々一般人でも既存の製品を組み合わせたり手を加えたりすることで再現することができます。

 実際に既製品を用いながら格安に、そしてサービスに使える程度の冗長性を持ったプライベートクラウドを構築していきたいと思います。part2ではOpenstackの各サービスを稼働させるのに必要な、バックエンドアプリケーションであるデータベース、AMQPなどについて実装していきます。

前提

 今回はOpenstackを「マルチマスタ構成」として、片系のマスタ(コントローラ)が停止したとしてもサービスが継続できるような構成を目指して組んでいきます。Openstackの企業向けの一般的な構成としては、3ノードからなるマスタノードを用意してMySQLサーバ含む各サービスにアクセスを分散するActive-Activeで構成しているパターンが多いと思います。しかしながら、今回はホームラボなどの家庭環境に設置できるより小規模な構成を目指してActive-Backupを採用していきます。

なぜActive-Activeだと3ノードになるのか

 一般的なマルチマスタ環境が3ノード構成以上となる由縁についてちょっと解説します。

 Openstackの各サービスの情報を保持するMySQLサーバをActive-Active構成で展開する場合には、Galera Cluster for MySQLVitessなどの製品を利用して展開するのが一般的になっています。しかしながら、Galeraを含むMySQLサーバをクラスタリングさせる製品は、InnoDB Clusterringの仕様上データの冪等性を保つ最小構成のクラスターに最低3ノードが必要となっています。

 またマスタノードを1ユニットとして同じ構成物を複数個展開する場合、Openstackの各種サービスとAMQP、RDBMSを同一ノード上に展開することが最小構成となります。エンタープライズで用いられるより大規模なOpenstackではRDBMSやAMQPを別ノードとして展開するのが一般的ですが、今回はより小規模な環境でマルチマスタ構成を実現するため、1ノードにマスタノードの機能を集約する形で設計します。

 このような技術的、規模的な制約から最小構成のマルチマスタを実現する為、Active-BackupのMySQLレプリケーションを採用しました。

システム構成図

 Active-Backupのシステムを簡単に実現する方法としては、keepalivedpacemaker, corosyncを利用してVirtual IPを2台のノード間で共有する方法が取られます。今回はpacemakerを利用してVIPを設定して、障害時にVIPを委譲することにより正副の切り替えを行います。

 今回のパートで導入するバックエンドアプリケーションのうちRabbitMQおよびMemcachedについては2ノードからのクラスタリングに対応しているアプリケーションです。しかしMySQL Server(MariaDB server)については2ノードでのクラスタリングは非推奨となるため、レプリケーション構成を組んで高可用性な構成を組んでいきましょう。

環境情報

今回のセットアップにはUbuntu 20.04 LTSを使用しています。

# cat /etc/os-release
N# cat /etc/os-release | grep VERSION
VERSION="20.04.4 LTS (Focal Fossa)"
VERSION_ID="20.04"
VERSION_CODENAME=focal

またmariadb-server, rabbbitmqおよびmemcachedについては下記のバージョンを導入しています。いずれも2022年1月時点での最新のパッケージです。

# apt list --installed | grep -e mariadb-server -e rabbitmq -e memcached

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

mariadb-server-10.3/focal-updates,focal-security,now 1:10.3.34-0ubuntu0.20.04.1 amd64 [installed,automatic]
mariadb-server-core-10.3/focal-updates,focal-security,now 1:10.3.34-0ubuntu0.20.04.1 amd64 [installed,automatic]
mariadb-server/focal-updates,focal-security,now 1:10.3.34-0ubuntu0.20.04.1 all [installed]
memcached/now 1.5.22-2ubuntu0.1 amd64 [installed,upgradable to: 1.5.22-2ubuntu0.2]
rabbitmq-server/focal-updates,focal-security,now 3.8.2-0ubuntu1.3 all [installed]

Mariadbインストール

mariadb-serverパッケージのインストール

 Ubuntuの標準レポジトリからmysql-server(mariadb-server)を導入していきます。mysql-serverパッケージ自体はmariadb-serverのエイリアスなので、実際にはmariadb-serverが導入されます。以下、RHEL/CentOSユーザの方はyum, dnfに適宜置き換えて読んでください。

# apt install mysql-server
Reading package lists... Done
Building dependency tree
Reading state information... Done

Processing triggers for systemd (245.4-4ubuntu3.15) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.7) ...

mariadb-serverセットアップ

 mysql-serverには初期セットアップに有用な初期化のスクリプトが付属しています。下記からrootパスワードの初期化、リモートログインの無効化等の必要な措置を実施していきましょう。

 実行すると各設定について対話式のプロンプトが開始されます。「Set root password?」でyes/yを選択するとrootパスワードの初期化が実行されます。また「Remove anonymous users?」で確認される、初期セットアップ時に作成されている匿名ユーザについては、安全の為削除しておきましょう。「Disallow root login remotely?」ではrootユーザの遠隔ログインについて停止することができます。

# mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

mariadb-server replicationの設定

 ここからは実際にActive-Backup構成のMySQL Serverについて、レプリケーションを構成していきます。今回は192.168.60.101(controller01-dev)をマスタ側、192.168.60.102(controller02-dev)をスレーブ側として設定します。

master側 mysql-serverの設定

 mariadb-serverのserver.cnfを編集していきます。レプリケーションを設定するためには各ノードについて識別するため、server-idを一意の値に各ノードで設定してください。またレプリケーションを実行するためmysql-serverのバイナリログを有効化する必要があります。

/etc/mysql/mariadb.conf.d/50-server.cnf
bind-address            = 0.0.0.0

server-id              = 1
log_bin                = /var/log/mysql/mysql-bin.log

 設定を反映する為にsystemdからmysql-serverを再起動します。

# systemctl restart mysqld

 mysql-server上からレプリケーションに関する設定を行っていきます。データレプリケーションを行う為のユーザ replication@192.168.60.102を追加して、レプリケーションに関する権限を付与していきましょう。この操作はすべてマスタ側から実行していきます。

# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 37
Server version: 10.3.34-MariaDB-0ubuntu0.20.04.1-log Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE USER `replication`@`192.168.60.102` IDENTIFIED BY '****************';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO `replication`@`192.168.60.102`;
Query OK, 0 rows affected (0.000 sec)

 マスタ側からスレーブ側に初回同期する為に、全データベースのデータを書き出します。この時点で初回の同期としてfixするために、これ以降マスタ側のmysql-serverは触らないようにしましょう。

# mysqldump -u root -p --all-databases --flush-logs --single-transaction --master-data=2 > mast
er.sql
Enter password:

slave側 mysql-serverの設定

 スレーブ側もマスタ側と同様にserver-idの設定とバイナリログの有効化を設定します。

/etc/mysql/mariadb.conf.d/50-server.cnf
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 0.0.0.0

server-id              = 2
log_bin                = /var/log/mysql/mysql-bin.log

 マスタ側と同様に設定変更を反映する為にsystemdからmysql-serverを再起動します。

# systemctl restart mysqld

 マスタ側でdumpしたデータベースについて、scpなどの手段でスレーブ側転送します。初回同期として転送したdumpファイルをスレーブ側でインポートしましょう。

# mysql -u root -p < master.sql
Enter password:

 mysql replicationを設定する為に、現在のMASTER_LOG_POSが必要となるのでここで確認しておきましょう。転送してきたmaster.sqlの先頭20行程度の位置に、ロテートされた現在のログファイルとログファイルの位置が記録されています。

# head -25 master.sql | tail -5

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=385;

--
-- GTID to start replication from

mysql replicationの開始

 スレーブ側のmysql-serverにログインして実際にレプリケーションを開始します。作成したレプリケーション用ユーザの認証情報を使用して、バイナリログのレプリケーション開始箇所を指定したうえで、レプリケーション元となるサーバを指定しましょう。

 START SLAVEを実行するとスレーブ側のmysql-serverはread onlyとなり、レプリケーションが開始されます。

# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 38
Server version: 10.3.34-MariaDB-0ubuntu0.20.04.1-log Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.60.101', MASTER_PORT=3306, MASTER_USER='replication', MASTER_PASSWORD='****************', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=385;
Query OK, 0 rows affected (0.004 sec)

MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.001 sec)

参考

RabbitMQインストール

rabbitmq-serverパッケージのインストール

 こちらもmysql-serverと同様にUbuntuの標準レポジトリから導入していきます。controller01-devおよびcontroller02-devの両系でインストールを行ってください。

# apt install rabbitmq-server
Reading package lists... Done
Building dependency tree
Reading state information... Done
Adding group `rabbitmq' (GID 121) ...
Done.
Adding system user `rabbitmq' (UID 117) ...
Adding new user `rabbitmq' (UID 117) with group `rabbitmq' ...
Not creating home directory `/var/lib/rabbitmq'.
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service → /lib/systemd/system/rabbitmq-server.service.
Processing triggers for systemd (245.4-4ubuntu3.15) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.7) ...

rabbitmq-serverのクラスタ化

 rabbitmq-serverをクラスタ化する作業を続けていきます。.erlang.cookieファイルを正副共通のものを使用する必要があるため、正系から副系に転送しましょう。

# scp /var/lib/rabbitmq/.erlang.cookie root@192.168.60.102:/var/lib/rabbitmq/.erlang.cookie
root@192.168.60.102's password:
.erlang.cookie                                                                                    100%   20    71.2KB/s   00:00

 必要に応じて転送した.erlang.cookieファイルの所有者およびパーミッションを修正します。これまでの手順通りにベアメタルサーバのキッティング作業直後から実行している場合は、取得したuidがズレていないので恐らく必要ない(はず)です。

# chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
# chmod 400 /var/lib/rabbitmq/.erlang.cookie

 インストール直後のパッケージを展開するタイミングでsystemd経由で自動的に起動されていますが、そのままでは展開した.erlang.cookieファイルが適用されていません。転送した.erlang.cookieファイルを適用した状態で起動する為、systemdから再起動します。

# systemctl enable rabbitmq-server.service
# systemctl restart rabbitmq-server.service

 この時点でrabbitmqの cluster statusを確認したとしても、現時点ではクラスタ化設定が完了していません。正系副系の両系は個別のrabbitmq-serverとして稼働しています。

# rabbitmqctl cluster_status
Cluster status of node rabbit@controller01-dev ...
Basics

Cluster name: rabbit@controller01-dev

Disk Nodes

rabbit@controller01-dev

Running Nodes

rabbit@controller01-dev

 ここからrabbitmq-serverを実際にクラスタ化していきます。以下の作業は副系(controller02-dev)でのみ事項してください。

 stop_appで稼働しているAMQPを一旦停止して、resetでノードを一旦初期化します。その後controller01-devのホスト名とユーザ、「rabbit@controller01-dev」を指定してクラスタに参加します。 IPアドレスでは指定できない(名前解決できる必要がある)ので /etc/hostsで定義したホスト名で指定します。

 クラスタに参加した後、停止していたAMQPを再開していきます。

# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@controller02-dev ...
# rabbitmqctl reset
Resetting node rabbit@controller02-dev ...
# rabbitmqctl join_cluster --ram rabbit@controller01-dev
Clustering node rabbit@controller02-dev with rabbit@controller01-dev
# rabbitmqctl start_app
Starting node rabbit@controller02-dev ...
 completed with 0 plugins.

rabbitmq clusterの正常性の確認

 先ほどと同様にcluster_statusを確認すると、Running Nodesに正副両系が登録されたことが確認できます。Offlineとなっている場合は上記の手順の中で何らかスキップしてしまっている可能性があるため、rabbitmqctl resetを再度実行して初期化した後に手順を再実行してください。

# rabbitmqctl cluster_status
Cluster status of node rabbit@controller01-dev ...
Basics

Cluster name: rabbit@controller01-dev

Disk Nodes

rabbit@controller01-dev

RAM Nodes

rabbit@controller02-dev

Running Nodes

rabbit@controller01-dev
rabbit@controller02-dev

ha policyの適用

 rabbitmq-server clusterをha-modeで稼働させるため、ha policyを適用していきます。

# rabbitmqctl set_policy ha-all '^(?!amq\.).*' '{"ha-mode": "all"}'
Setting policy "ha-all" for pattern "^(?!amq\.).*" to "{"ha-mode": "all"}" with priority "0" for vhost "/" ...

Openstack用ユーザの作成

 また今回のパートではすぐには使用しませんが、Openstackの各サービスからrabbitmq-serverを利用するためのユーザを作成しておきましょう。

# rabbitmqctl add_user openstack ****************
Adding user "openstack" ...
# rabbitmqctl set_permissions openstack ".*" ".*" ".*"
Setting permissions for user "openstack" in vhost "/" ...

Memcachedインストール

memcachedパッケージのインストール

 こちらも同様にUbuntuの標準レポジトリから導入していきます。memcachedはクライアント側が利用する際に、両系を指定したうえでデータをハッシュ化して保存する機能を有している為、特にクラスタ化に際して追加で設定する必要はありません。

 正副の両系でパッケージをインストールしてください。

# apt install memcached
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  libanyevent-perl libcache-memcached-perl libmemcached libyaml-perl
The following NEW packages will be installed:
  memcached
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /lib/systemd/system/memcached.service.
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for systemd (245.4-4ubuntu3.15) ...

 起動時にサービスが自動的に開始されるために、systemdからサービスとして有効化しておきましょう。こちらも正副両系で実行しておきましょう。

# systemctl enable memcached
Synchronizing state of memcached.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable memcached

memcachedのfile descripterの調整

 導入時の状態のままmemcachedを利用すると、file descripter数がUbuntuデフォルトの1024で設定されています。memcachedは各Openstackサービスからのセッション情報の保持などに利用される為、file descripter数を上げないと保持するセッションがあふれる可能性があるため設定を変更しましょう。

 実際に現在の実行プロセスをpsより確認し、pidからfile descripter数を確認すると上限が1024で設定されていることが分かります。

# ps aux | grep memcached
memcache  478716  0.0  0.0 409768  3924 ?        Ssl  11:33   0:01 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -P /var/run/memcached/memcached.pid
# cat /proc/478716/limits | grep files
Max open files            1024                 1024

 まずOSで設定されているfile descripter数を変更し、各プロセスで利用可能な上限値を引き上げます。

/etc/security/limits.conf
*               soft    nofile          65535
*               hard    nofile          65535
root            soft    nofile          65535
root            hard    nofile          65535

 次にsystemd上の設定としての上限値を変更していきます。systemdを介さずに実行している場合はこの設定は必要ありません。

/usr/lib/systemd/system/memcached.service
[Service]
LimitNOFILE=65535

 最後にmemcached.conf上からincoming connectionの上限値を変更します。

/etc/memcached.conf
# Limit the number of simultaneous incoming connections. The daemon default is 1024
-c 65535

 次回は実際にOpenstackの主要サービスである、keystoneとplacementを展開していきます。またマシンイメージを保持するGlanceについても展開していきましょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください