GDC 에어갭의 MySQL 데이터베이스 참조 구현

이 가이드에서는 Google Distributed Cloud(GDC) 에어 갭 환경의 3개 가용성 영역에 고가용성 MySQL 8.4 InnoDB 클러스터를 배포하는 방법을 단계별로 종합적으로 설명합니다. 이 아키텍처는 Paxos 기반 합의를 위해 그룹 복제를, 지능형 연결 라우팅을 위해 MySQL 라우터를, 클러스터 조정을 위해 MySQL 셸을 활용합니다.

가상 머신(VM)을 엄격하게 활용하는 이 구현은 교차 영역 Kubernetes 확장 클러스터와 관련된 GDC 에어 갭 제한을 우회하여 데이터 손실 위험 없이 완전한 멀티 영역 복원력을 보장합니다.

아키텍처 다이어그램은 다음과 같습니다.

공동 배치된 서비스 스택을 실행하는 3개의 VM 아키텍처

시작하기 전에

VM 배포

VM 인스턴스 만들기 및 시작에 따라 사용 가능한 3개 영역에 VM 3개를 만듭니다.

키 쌍을 사용하여 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')
"

전송 및 설치

.deb 파일을 세 VM 모두의 /tmp/packages/에 업로드하고 설치합니다.

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

dpkg에서 오류가 반환되지 않는지 확인합니다. 그렇다면 로그를 확인하여 누락된 deb 패키지를 확인하고 다운로드에 포함합니다.

루트 비밀번호를 설정하라는 메시지가 표시되면 비워 둡니다. 비밀번호는 나중에 설정하겠습니다.

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

루트 비밀번호를 설정합니다.

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 라우터 부트스트랩

세 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 (기존 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을 부하 분산기 대상으로 설정

자동 장애 조치 확인

이 테스트는 클러스터가 새 리더를 선택하고 라우터가 수동 개입 없이 트래픽을 리디렉션하는지 확인합니다.

기본 장애 시뮬레이션

현재 기본 노드 (예: 노드 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()"

세 노드 모두 ONLINE 상태를 반환하는지 확인합니다.