GDC エアギャップでの MySQL データベースのリファレンス実装

このガイドでは、Google Distributed Cloud(GDC)のエアギャップ環境の 3 つのアベイラビリティ ゾーンに、高可用性の MySQL 8.4 InnoDB クラスタをデプロイするための包括的なステップバイステップ チュートリアルを提供します。このアーキテクチャでは、Paxos ベースのコンセンサスに Group Replication、インテリジェントな接続ルーティングに MySQL Router、クラスタ オーケストレーションに MySQL Shell を活用しています。

仮想マシン(VM)のみを使用することで、この実装はクロスゾーン Kubernetes ストレッチ クラスタに関する GDC エアギャップの制限を回避し、データ損失のリスクを冒すことなく、完全なマルチゾーンの復元力を確保します。

アーキテクチャ図は次のとおりです。

サービスがコロケーションされたスタックを実行する 3 台の VM アーキテクチャ。

始める前に

VM をデプロイする

VM インスタンスの作成と起動に沿って、使用可能な 3 つのゾーンに 3 つの VM を作成します。

鍵ペアを使用して VM への SSH 接続を確立するようにローカル環境を構成します。VM に接続する

これは、セキュア コピー(SCP)を使用してパッケージを転送するために必要です。ファイルを転送する

検証には、Ubuntu 22.04 OS と n3-standard-2-gdc マシンタイプを使用しました。本番環境では、リソースが多いマシンタイプを使用します。

次のコマンドを使用して VM の IP を取得します。

VM_NAME=$1

if [[ -z "$VM_NAME" ]]; then
  echo "Error: VM_NAME must be provided."
  echo "Usage: $0 <VM_NAME>"
  exit 1
fi

# 1. Get External IP from 'instances list'
EXT_IP=$(gdcloud compute instances list | awk -v vm="${VM_NAME}" '$1 == vm {print $5}')

if [[ -z "$EXT_IP" ]]; then
  echo "Error: Could not find VM '${VM_NAME}' in the instance list."
  exit 1
fi

INTERNAL_IP=$(gdcloud compute instances describe "${VM_NAME}" | awk '/^status:/ {in_status=1} in_status && /- [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' | cut -d'/' -f1)

if [[ -z "$INTERNAL_IP" ]]; then
  INTERNAL_IP="<Not assigned or not found>"
fi

echo "${VM_NAME}"
echo "External IP: ${EXT_IP}"
echo "Internal IP: ${INTERNAL_IP}"

環境変数を構成する

ローカル ワークステーションのシェル セッションで次の変数を設定します。

export PROJECT_ID="your-project-id"
export VM1_NAME="mysql-node-1"
export VM2_NAME="mysql-node-2"
export VM3_NAME="mysql-node-3"
export VM1_IP="10.0.1.245" # Zone 1
export VM2_IP="10.0.1.241" # Zone 2
export VM3_IP="10.0.1.242" # Zone 3
export CLUSTER_NAME="mysql-ha-cluster"

ネットワークの構成

プロジェクト外または組織外の DB にアクセスする必要がある場合は、それに応じて PNP(プロジェクト ネットワーク ポリシー)を設定してください。

ユースケースに応じて、PNP の概要のセクションに沿って対応します。

エアギャップのあるソフトウェアの準備

Docker を使用してパッケージをダウンロードする

接続されたワークステーションから次のコマンドを実行して、MySQL 8.4 と Shell コンポーネントを取得します。

mkdir -p ./mysql-packages
docker run --rm -v "$(pwd)/mysql-packages:/packages" ubuntu:22.04 bash -c "
  apt-get update && apt-get install -y curl gnupg apt-rdepends wget lsb-release
  curl -LsS https://dev.mysql.com/get/mysql-apt-config_0.8.39-1_all.deb -o config.deb
  # Configure for MySQL 8.4 LTS
  DEBIAN_FRONTEND=noninteractive dpkg -i config.deb 
  apt-get update
  cd /packages
  PACKAGES='mysql-server mysql-shell mysql-router'
  apt-get download \$(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \${PACKAGES} | grep '^\w')
"

転送とインストール

3 つの VM すべての /tmp/packages/.deb ファイルをアップロードしてインストールします。

# From workstation: scp ./mysql-packages/*.deb ${VM_IP}:/tmp/packages/
# On each VM:
sudo dpkg -i /tmp/packages/*.deb

dpkg がエラーを返さないことを確認します。その場合は、ログを調べて、不足している可能性のある deb パッケージを確認し、ダウンロードに含めます。

root パスワードの設定を求められたら、空白のままにします。パスワードは後で設定します。

MySQL ノードの構成

クラスタで使用するように MySQL を構成する

すべてのノードの /etc/mysql/mysql.conf.d/mysqld.cnf を編集して、GTID とバイナリ ロギングを有効にします。

[mysqld]
bind-address = 0.0.0.0
server-id = 1 # Use 2 and 3 for other VMs
gtid-mode = ON
enforce-gtid-consistency = ON
binlog-format = ROW
log-bin = mysql-bin
report_host = 10.0.1.245 # Use the VM's specific IP

サービスを再起動します。

sudo systemctl restart mysql

次に、DB に接続します。

sudo mysql

root パスワードを設定します。

CREATE USER 'root'@'%' IDENTIFIED WITH 'caching_sha2_password' BY 'your_new_secure_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

InnoDB クラスタの初期化と検証

MySQL Shell を使用してクラスタを作成する

VM 1 のみで、MySQL Shell を使用してクラスタを初期化します。

mysqlsh --uri root@localhost
# Inside MySQL Shell:
\js
dba.configureInstance('root@VM1_IP')
var cluster = dba.createCluster('mysql-ha-cluster')
cluster.addInstance('root@VM2_IP')
cluster.addInstance('root@VM3_IP')
cluster.status()

MySQL Router をブートストラップする

3 つの VM すべてで、ルーターをブートストラップして新しいクラスタを検出します。

sudo mysqlrouter --bootstrap root@VM1_IP --user=mysqlrouter
sudo systemctl restart mysqlrouter
sudo systemctl enable mysqlrouter

バランシングと接続を確認する

次のコマンドを任意のノードから実行して、ルーターがトラフィックを正しく分散していることを確認します。

  1. 書き込みルーティング(アクティブ プライマリ)を確認する: ポート 6446(クラシック RW)をクエリします。現在のプライマリのホスト名を厳密に返す必要があります。

    mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  2. 読み取りバランシング(ラウンドロビン)を確認する: ポート 6447(Classic RO)を複数回クエリします。クラスタ内の使用可能なすべてのノードのホスト名を順番に処理する必要があります。

    for i in {1..4}; do mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6447 -e "SELECT @@hostname;"; done
    
  3. 接続トポロジを確認する: MySQL Shell を使用して、すべてのメンバーが ONLINE であり、正しくバランスが取れていることを確認します。

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

グローバル ロードバランサの設定

GDC グローバル L4 ロードバランサを使用して、アプリケーションに単一の安定した仮想 IP(VIP)を提供します。内部グローバル ロードバランサを構成するに沿って、内部グローバル L4 ロードバランサを設定し、VM をそのターゲットとして設定します。VM をロードバランサのターゲットとして設定するをご覧ください。

自動フェイルオーバーの検証

このテストでは、クラスタが新しいリーダーを選出し、ルーターが手動介入なしでトラフィックをリダイレクトすることを確認します。

プライマリ障害をシミュレートする

現在のプライマリ(Node 1 など)を特定し、MySQL サービスを停止します。

sudo systemctl stop mysql

選挙とルーティングのシフトを確認する

コンセンサス プロトコルが新しいリーダーを選出するまで 10 ~ 20 秒待ちます。

  1. クラスタのステータスを確認する: VM 2 または 3 から、新しいプライマリが選択されたことを確認します。

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

    残りのノードのいずれかが PRIMARY とマークされ、失敗したノードが UNREACHABLE または MISSING とマークされていることを確認します。

  2. 書き込みルーティングを確認する: RW ポート(6446)をもう一度テストします。新しいプライマリのホスト名が返されます。

    mysql -u root -p -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  3. グローバル VIP の接続をテストする: アプリケーション サーバーから、グローバル VIP をクエリします。

    mysql -u root -p -h ${LB_IP} -P 3306 -e "SELECT @@hostname;"
    

再参加を復元して確認する

障害が発生したノードで MySQL サービスを開始し、セカンダリ レプリカとして再参加することを確認します。

sudo systemctl start mysql
mysqlsh --uri root@localhost --cluster -e "cluster.status()"

3 つのノードすべてが ONLINE ステータスを返すことを確認します。