GKE에 스테이트풀(Stateful) MySQL 클러스터 배포


이 문서는 Google Kubernetes Engine에서 고가용성 MySQL 토폴로지 배포에 관심이 있는 데이터베이스 관리자, 클라우드 설계자, 운영 전문가를 대상으로 합니다.

이 튜토리얼의 안내에 따라 MySQL 라우터 미들웨어 외에도 MySQL InnoDB 클러스터MySQL InnoDB ClusterSet를 GKE 클러스터에 배포하고 업그레이드를 수행하는 방법을 알아볼 수 있습니다.

목표

이 튜토리얼에서는 다음과 같은 방법을 알아봅니다.

  • 스테이트풀(Stateful) Kubernetes 서비스를 만들고 배포합니다.
  • 고가용성을 위해 MySQL InnoDB 클러스터를 배포합니다.
  • 데이터베이스 작업 라우팅을 위해 라우터 미들웨어를 배포합니다.
  • 재해 내결함성을 위해 MySQL InnoDB ClusterSet를 배포합니다.
  • MySQL 클러스터 장애 조치를 시뮬레이션합니다.
  • MySQL 버전 업그레이드를 수행합니다.

다음 섹션에서는 이 튜토리얼에서 빌드할 솔루션의 아키텍처를 설명합니다.

MySQL InnoDB 클러스터

리전별 GKE 클러스터에서 StatefulSet를 사용하여 MySQL InnoDB 클러스터를 만드는 데 필요한 이름 지정 및 구성이 있는 MySQL 데이터베이스 인스턴스를 배포합니다. 장애 내결함성 및 고가용성을 제공하려면 3개의 데이터베이스 인스턴스 포드를 배포합니다. 이렇게 하면 합의 프로토콜을 사용하여 기본 선택이 성공하도록 지정된 모든 시간에 서로 다른 영역에 있는 대부분의 포드를 사용할 수 있으며, MySQL InnoDB 클러스터가 단일 영역 장애를 견딜 수 있습니다.

애플리케이션, MySQL 라우터 및 MySQL 클러스터 사이의 관계를 보여주는 아키텍처 다이어그램
그림 1: 단일 MySQL InnoDB 클러스터의 아키텍처 예시

배포되면 하나의 포드를 읽기 및 쓰기 작업을 모두 제공하기 위한 기본 인스턴스로 지정할 수 있습니다. 다른 두 포드는 보조 읽기 전용 복제본입니다. 기본 인스턴스에 인프라 오류가 발생하면 이러한 두 복제본 포드 중 하나를 기본 포드로 승격할 수 있습니다.

개별 인스턴스에서 3개의 MySQL 라우터 포드를 배포하여 복원력 향상을 위한 연결 라우팅을 제공합니다. 데이터베이스 서비스에 직접 연결하는 대신 애플리케이션이 MySQL 라우터 포드에 연결됩니다. 각 라우터 포드는 각 MySQL InnoDB 클러스터 포드의 상태 및 목적을 인식하고 애플리케이션 연결을 각 정상 포드로 라우팅합니다. 라우팅 상태는 라우터 포드에 캐시되고 MySQL InnoDB 클러스터의 각 노드에 저장된 클러스터 메타데이터에서 업데이트됩니다. 인스턴스 장애가 발생하면 라우터가 라이브 인스턴스로 연결 라우팅을 조정합니다.

MySQL InnoDB ClusterSet

초기 MySQL InnoDB 클러스터로부터 MySQL InnoDB ClusterSet를 만들 수 있습니다. 이렇게 하면 기본 클러스터를 더 이상 사용할 수 없을 때 재해 내결함성을 늘릴 수 있습니다.

기본 및 복제본 MySQL InnoDB 클러스터가 비동기 복제를 통해 동기화되는 방식을 보여주는 다이어그램입니다.
그림 2: 하나의 기본 클러스터와 하나의 복제본 클러스터가 포함된 멀티 리전 ClusterSet 아키텍처 예시

MySQL InnoDB 클러스터 기본 인스턴스를 더 이상 사용할 수 없으면 ClusterSet의 복제본 클러스터를 기본 클러스터로 승격할 수 있습니다. MySQL 라우터 미들웨어를 사용할 때는 애플리케이션이 기본 데이터베이스 인스턴스의 상태를 추적할 필요가 없습니다. 선택이 수행된 후 새 기본 인스턴스로 연결을 전송하도록 라우팅이 조정됩니다. 그러나 클러스터 장애 조치 중 오류가 발생할 경우 연결이 재시도되도록 MySQL 라우터 미들웨어에 연결하는 애플리케이션이 복원력 권장사항을 따르는지 확인해야 합니다.

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

프로젝트 설정

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Enable the GKE API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  7. Enable the GKE API.

    Enable the API

역할 설정

  1. Google 계정에 역할을 부여합니다. 다음 각 IAM 역할에 대해 다음 명령어를 한 번씩 실행합니다. role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

    $ gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • PROJECT_ID를 프로젝트 ID로 바꿉니다.
    • EMAIL_ADDRESS를 이메일 주소로 바꿉니다.
    • ROLE을 각 개별 역할로 바꿉니다.

환경 설정하기

이 튜토리얼에서는 Cloud Shell을 사용하여 Google Cloud에서 호스팅되는 리소스를 관리합니다. Cloud Shell은 Docker 및 kubectl과 gcloud CLI가 사전 설치된 상태로 제공됩니다.

Cloud Shell을 사용해 다음과 같이 환경을 설정합니다.

  1. 환경 변수를 설정합니다.

    export PROJECT_ID=PROJECT_ID
    export CLUSTER_NAME=gkemulti-west
    export REGION=COMPUTE_REGION
    

    다음 값을 바꿉니다.

    • PROJECT_ID: Google Cloud 프로젝트 ID입니다.
    • COMPUTE_REGION: Compute Engine 리전. 이 튜토리얼에서 리전은 us-west1입니다. 일반적으로 자신에게 가까운 리전이 필요합니다.
  2. 기본 환경 변수를 설정합니다.

     gcloud config set project PROJECT_ID
     gcloud config set compute/region COMPUTE_REGION
    
  3. 코드 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. 작업 디렉터리로 변경합니다.

    cd kubernetes-engine-samples/databases/gke-stateful-mysql/kubernetes
    

GKE 클러스터 만들기

이 섹션에서는 리전별 GKE 클러스터를 만듭니다. 영역별 클러스터와 달리 리전별 클러스터의 제어 영역은 여러 영역에 복제되므로, 단일 영역에서 중단이 발생해도 제어 영역이 사용 불가능해지지 않습니다.

GKE 클러스터를 만들려면 다음 단계를 따르세요.

Autopilot

  1. Cloud Shell에서 us-west1 리전에 GKE Autopilot 클러스터를 만듭니다.

    gcloud container clusters create-auto $CLUSTER_NAME \
        --region=$REGION
    
  2. GKE 클러스터 사용자 인증 정보를 가져옵니다.

    gcloud container clusters get-credentials $CLUSTER_NAME \
      --region=$REGION
    
  3. 3개 영역에 서비스를 배포합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prepare-three-zone-ha
      labels:
        app: prepare-three-zone-ha
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: prepare-three-zone-ha
      template:
        metadata:
          labels:
            app: prepare-three-zone-ha
        spec:
          affinity:
            # Tell Kubernetes to avoid scheduling a replica in a zone where there
            # is already a replica with the label "app: prepare-three-zone-ha"
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - prepare-three-zone-ha
                topologyKey: "topology.kubernetes.io/zone"
          containers:
          - name: prepare-three-zone-ha
            image: busybox:latest
            command:
                - "/bin/sh"
                - "-c"
                - "while true; do sleep 3600; done"
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
    kubectl apply -f prepare-for-ha.yaml
    

    기본적으로 Autopilot은 2개 영역에 리소스를 프로비저닝합니다. prepare-for-ha.yaml에 배포가 정의되었으면 replicas:3, requiredDuringSchedulingIgnoredDuringExecution을 사용하는 podAntiAffinity, topologyKey: "topology.kubernetes.io/zone"을 설정하여 Autopilot이 클러스터의 세 영역에 걸쳐 노드를 프로비저닝합니다.

  4. 배포 상태를 확인합니다.

    kubectl get deployment prepare-three-zone-ha --watch
    

    세 포드가 준비 상태로 표시되면 CTRL+C를 사용하여 이 명령어를 취소합니다. 출력은 다음과 비슷합니다.

    NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    prepare-three-zone-ha   0/3     3            0           9s
    prepare-three-zone-ha   1/3     3            1           116s
    prepare-three-zone-ha   2/3     3            2           119s
    prepare-three-zone-ha   3/3     3            3           2m16s
    
  5. 이 스크립트를 실행하여 포드가 세 영역에 배포되었는지 검증합니다.

    bash ../scripts/inspect_pod_node.sh default
    

    출력의 각 줄은 포드에 해당하며 두 번째 열은 클라우드 영역을 나타냅니다. 출력은 다음과 비슷합니다.

    gk3-gkemulti-west1-default-pool-eb354e2d-z6mv us-west1-b prepare-three-zone-ha-7885d77d9c-8f7qb
    gk3-gkemulti-west1-nap-25b73chq-739a9d40-4csr us-west1-c prepare-three-zone-ha-7885d77d9c-98fpn
    gk3-gkemulti-west1-default-pool-160c3578-bmm2 us-west1-a prepare-three-zone-ha-7885d77d9c-phmhj
    

표준

  1. Cloud Shell에서 us-west1 리전에 GKE Standard 클러스터를 만듭니다.

    gcloud container clusters create $CLUSTER_NAME \
      --region=$REGION \
      --machine-type="e2-standard-2" \
      --disk-type="pd-standard" \
      --num-nodes="5"
    
  2. GKE 클러스터 사용자 인증 정보를 가져옵니다.

    gcloud container clusters get-credentials $CLUSTER_NAME \
      --region=$REGION
    

MySQL StatefulSet 배포

이 섹션에서는 하나의 MySQL StatefulSet를 배포합니다. 각 StatefulSet는 3개의 MySQL 복제본으로 구성됩니다.

MySQL StatefulSet를 배포하려면 다음 단계를 수행합니다.

  1. StatefulSet의 네임스페이스를 만듭니다.

    kubectl create namespace mysql1
    
  2. MySQL 보안 비밀을 만듭니다.

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-secret
    type: Opaque
    data:
      password: UGFzc3dvcmQkMTIzNDU2 # Password$123456
      admin-password: UGFzc3dvcmQkMTIzNDU2 # Password$123456
    kubectl apply -n mysql1 -f secret.yaml
    

    비밀번호는 각 포드에 배포되고 이 튜토리얼에서 MySQL InnoDB 클러스터 및 ClusterSet 배포에 대한 관리 스크립트 및 명령어에 사용됩니다.

  3. StorageClass를 만듭니다.

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast-storageclass
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: WaitForFirstConsumer
    reclaimPolicy: Retain
    allowVolumeExpansion: true
    parameters:
      type: pd-balanced
    kubectl apply -n mysql1 -f storageclass.yaml
    

    이 스토리지 클래스에는 성능과 비용을 균형적으로 조정하는 pd-balanced Persistent Disk 유형이 사용됩니다. volumeBindingMode 필드는 WaitForFirstConsumer로 설정되어 포드가 생성될 때까지 GKE에서 PersistentVolume 프로비저닝이 지연됩니다. 이 설정은 포드가 예약된 동일한 영역에 디스크가 프로비저닝되도록 합니다.

  4. MySQL 인스턴스 포드의 StatefulSet를 배포합니다.

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: dbc1
      labels:
        app: mysql
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: mysql
      serviceName: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          topologySpreadConstraints:
          - maxSkew: 1
            topologyKey: "topology.kubernetes.io/zone"
            whenUnsatisfiable: DoNotSchedule
            labelSelector:
              matchLabels:
                app: mysql
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - mysql
                topologyKey: "kubernetes.io/hostname"
          containers:
          - name: mysql
            image: mysql/mysql-server:8.0.28
            command:
            - /bin/bash
            args:
            - -c
            - >-
              /entrypoint.sh
              --server-id=$((20 +  $(echo $HOSTNAME | grep -o '[^-]*$') + 1))
              --report-host=${HOSTNAME}.mysql.mysql1.svc.cluster.local
              --binlog-checksum=NONE
              --enforce-gtid-consistency=ON
              --gtid-mode=ON
              --default-authentication-plugin=mysql_native_password
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            - name: MYSQL_ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: admin-password
            - name: MYSQL_ROOT_HOST
              value: '%'
            ports:
            - name: mysql
              containerPort: 3306
            - name: mysqlx
              containerPort: 33060
            - name: xcom
              containerPort: 33061
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "1Gi"
                memory: "1Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "1Gi"
                memory: "1Gi"
            volumeMounts:
            - name: mysql
              mountPath: /var/lib/mysql
              subPath: mysql
            readinessProbe:
              exec:
                command:
                - bash
                - "-c"
                - |
                  mysql -h127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e'SELECT 1'
              initialDelaySeconds: 30
              periodSeconds: 2
              timeoutSeconds: 1
            livenessProbe:
              exec:
                command:
                - bash
                - "-c"
                - |
                  mysqladmin -uroot -p$MYSQL_ROOT_PASSWORD ping
              initialDelaySeconds: 30
              periodSeconds: 10
              timeoutSeconds: 5
      updateStrategy:
        rollingUpdate:
          partition: 0
        type: RollingUpdate
      volumeClaimTemplates:
      - metadata:
          name: mysql
          labels:
            app: mysql
        spec:
          storageClassName: fast-storageclass
          volumeMode: Filesystem
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi
    kubectl apply -n mysql1 -f c1-mysql.yaml
    

    이 명령어는 3개의 복제본으로 구성된 StatefulSet를 배포합니다. 이 튜토리얼에서는 기본 MySQL 클러스터가 us-west1의 3개 영역에 걸쳐 배포됩니다. 출력은 다음과 비슷합니다.

    service/mysql created
    statefulset.apps/dbc1 created
    

    이 튜토리얼에서 리소스 한도 및 요청은 비용 절약을 위해 최솟값으로 설정됩니다. 프로덕션 워크로드를 계획할 때는 조직 니즈에 맞게 값을 적절하게 설정해야 합니다.

  5. StatefulSet가 성공적으로 생성되었는지 확인합니다.

    kubectl get statefulset -n mysql1 --watch
    

    StatefulSet가 준비되려면 약 10분 정도 걸릴 수 있습니다.

  6. 포드 3개가 모두 준비된 상태이면 Ctrl+C를 사용하여 명령어를 종료합니다. CPU 또는 메모리 부족으로 인해 PodUnscheduleable 오류가 발생하면 큰 워크로드를 수용할 수 있게 제어 영역 크기가 조정될 때까지 몇 분 정도 기다립니다.

    출력은 다음과 비슷합니다.

    NAME   READY   AGE
    dbc1   1/3     39s
    dbc1   2/3     50s
    dbc1   3/3     73s
    
  7. GKE 클러스터 노드에서 포드 배치를 조사하려면 다음 스크립트를 실행합니다.

    bash ../scripts/inspect_pod_node.sh mysql1 mysql
    

    포드 이름, GKE 노드 이름, 노드가 프로비저닝된 영역과 함께 다음과 비슷하게 출력이 표시됩니다.

    gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0
    gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1
    gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2
    

    출력의 열은 각각 호스트 이름, 클라우드 영역, 포드 이름을 나타냅니다.

    StatefulSet 사양(c1-mysql.yaml)의 topologySpreadConstraints 정책에 따라 스케줄러가 장애 도메인(topology.kubernetes.io/zone)에 균등하게 포드를 배치합니다.

    podAntiAffinity 정책은 동일한 GKE 클러스터 노드(kubernetes.io/hostname)에 포드를 배치할 필요가 없는 제약조건을 적용합니다. MySQL 인스턴스 포드의 경우 이 정책을 사용하면 Google Cloud 리전의 세 영역에 포드가 균등하게 배포됩니다. 이러한 배치는 각 데이터베이스 인스턴스를 개별 장애 도메인에 배치하여 MySQL InnoDB 클러스터의 고가용성을 지원합니다.

기본 MySQL InnoDB 클러스터 준비

MySQL InnoDB 클러스터를 구성하려면 다음 단계를 수행합니다.

  1. Cloud Shell 터미널에서 클러스터에 추가할 MySQL 인스턴스에 대해 그룹 복제 구성을 설정합니다.

    bash ../scripts/c1-clustersetup.sh
    
    POD_ORDINAL_START=${1:-0}
    POD_ORDINAL_END=${2:-2}
    for i in $(seq ${POD_ORDINAL_START} ${POD_ORDINAL_END}); do
      echo "Configuring pod mysql1/dbc1-${i}"
      cat <<'  EOF' | kubectl -n mysql1 exec -i dbc1-${i} -- bash -c 'mysql -uroot -proot --password=${MYSQL_ROOT_PASSWORD}'
    INSTALL PLUGIN group_replication SONAME 'group_replication.so';
    RESET PERSIST IF EXISTS group_replication_ip_allowlist;
    RESET PERSIST IF EXISTS binlog_transaction_dependency_tracking;
    SET @@PERSIST.group_replication_ip_allowlist = 'mysql.mysql1.svc.cluster.local';
    SET @@PERSIST.binlog_transaction_dependency_tracking = 'WRITESET';
      EOF
    done

    이 스크립트는 세 개의 각 MySQL 인스턴스에 원격으로 연결하여 다음 환경 변수를 설정하고 유지합니다.

    • group_replication_ip_allowlist: 클러스터 내 인스턴스가 그룹에 있는 모든 인스턴스에 연결하도록 허용합니다.
    • binlog_transaction_dependency_tracking='WRITESET': 충돌하지 않고 동시에 로드되는 트랜잭션을 허용합니다.

    8.0.22 이전의 MySQL 버전에서는 group_replication_ip_allowlist 대신 group_replication_ip_whitelist를 사용합니다.

  2. 각 포드에 대해 셸을 만들 필요가 없도록 보조 터미널을 엽니다.

  3. dbc1-0 포드의 MySQL 셸에 연결합니다.

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash \
        -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'
    
  4. 다른 인스턴스에 연결하기 위해 MySQL 그룹 복제 허용 목록을 확인합니다.

    \sql SELECT @@group_replication_ip_allowlist;
    

    출력은 다음과 비슷합니다.

    +----------------------------------+
    | @@group_replication_ip_allowlist |
    +----------------------------------+
    | mysql.mysql1.svc.cluster.local   |
    +----------------------------------+
    
  5. server-id가 각 인스턴스에서 고유한지 확인합니다.

    \sql SELECT @@server_id;
    

    출력은 다음과 비슷합니다.

    +-------------+
    | @@server_id |
    +-------------+
    |          21 |
    +-------------+
    
  6. MySQL InnoDB 클러스터 사용을 위해 각 인스턴스를 구성하고 각 인스턴스에 관리자 계정을 만듭니다.

    \js
    dba.configureInstance('root@dbc1-0.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root@dbc1-1.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root@dbc1-2.mysql.mysql1.svc.cluster.local', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    

    MySQL InnoDB 클러스터가 제대로 작동하기 위해서는 모든 인스턴스의 사용자 이름 및 비밀번호가 동일해야 합니다. 각 명령어는 다음과 비슷한 출력을 생성합니다.

    ...
    
    The instance 'dbc1-2.mysql:3306' is valid to be used in an InnoDB cluster.
    
    Cluster admin user 'icadmin'@'%' created.
    The instance 'dbc1-2.mysql.mysql1.svc.cluster.local:3306' is already
    ready to be used in an InnoDB cluster.
    
    Successfully enabled parallel appliers.
    
  7. MySQL InnoDB 클러스터에서 인스턴스를 사용하도록 준비되었는지 확인합니다.

    dba.checkInstanceConfiguration()
    

    출력은 다음과 비슷합니다.

    ...
    
    The instance 'dbc1-0.mysql.mysql1.svc.cluster.local:3306' is valid to be used in an InnoDB cluster.
    
    {
        "status": "ok"
    }
    

    선택적으로 각 MySQL 인스턴스에 연결하고 이 명령어를 반복할 수 있습니다. 예를 들어 이 명령어를 실행하여 dbc1-1 인스턴스에서 상태를 확인합니다.

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash \
        -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \
        --js --execute "dba.checkInstanceConfiguration()"'
    

기본 MySQL InnoDB 클러스터 만들기

다음으로, MySQL 관리자 createCluster 명령어를 사용하여 MySQL InnoDB 클러스터를 만듭니다. 클러스터의 기본 인스턴스가 되는 dbc1-0 인스턴스로 시작한 후 클러스터에 2개의 복제본을 더 추가합니다.

MySQL InnoDB 클러스터를 초기화하기 위해 다음 단계를 수행합니다.

  1. MySQL InnoDB 클러스터를 만듭니다.

    var cluster=dba.createCluster('mycluster');
    

    createCluster 명령어를 실행하면 다음 작업이 트리거됩니다.

    • 메타데이터 스키마를 배포합니다.
    • 그룹 복제에 대한 구성이 올바른지 확인합니다.
    • 새 클러스터의 시드 인스턴스로 등록합니다.
    • 복제 사용자 계정과 같은 필요한 내부 계정을 만듭니다.
    • 그룹 복제를 시작합니다.

    이 명령어는 dbc1-0 호스트를 기본으로 하는 MySQL InnoDB 클러스터를 초기화합니다. 클러스터 참조는 클러스터 변수에 저장됩니다.

    결과는 다음과 유사합니다.

    A new InnoDB cluster will be created on instance 'dbc1-0.mysql:3306'.
    
    Validating instance configuration at dbc1-0.mysql:3306...
    
    This instance reports its own address as dbc1-0.mysql.mysql1.svc.cluster.local:3306
    
    Instance configuration is suitable.
    NOTE: Group Replication will communicate with other instances using
    'dbc1-0.mysql:33061'. Use the localAddress
    option to override.
    
    Creating InnoDB cluster 'mycluster' on
    'dbc1-0.mysql.mysql1.svc.cluster.local:3306'...
    
    Adding Seed Instance...
    Cluster successfully created. Use Cluster.addInstance() to add MySQL
    instances.
    At least 3 instances are needed for the cluster to be able to withstand
    up to one server failure.
    
  2. 클러스터에 두 번째 인스턴스를 추가합니다.

    cluster.addInstance('icadmin@dbc1-1.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  3. 남은 인스턴스를 클러스터에 추가합니다.

    cluster.addInstance('icadmin@dbc1-2.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    

    출력은 다음과 비슷합니다.

    ...
    The instance 'dbc1-2.mysql:3306' was successfully added to the cluster.
    
  4. 클러스터 상태를 확인합니다.

    cluster.status()
    

    이 명령어는 클러스터 상태를 표시합니다. 토폴로지는 기본 인스턴스 하나와 보조 인스턴스 2개가 포함된 3개의 호스트로 구성됩니다. 선택적으로 cluster.status({extended:1})을 호출할 수 있습니다.

    출력은 다음과 비슷합니다.

    {
        "clusterName": "mysql1",
        "defaultReplicaSet": {
            "name": "default",
            "primary": "dbc1-0.mysql:3306",
            "ssl": "REQUIRED",
            "status": "OK",
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
            "topology": {
                "dbc1-0.mysql:3306": {
                    "address": "dbc1-0.mysql:3306",
                    "memberRole": "PRIMARY",
                    "mode": "R/W",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                },
                "dbc1-1.mysql:3306": {
                    "address": "dbc1-1.mysql:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                },
                "dbc1-2.mysql:3306": {
                    "address": "dbc1-2.mysql:3306",
                    "memberRole": "SECONDARY",
                    "mode": "R/O",
                    "readReplicas": {},
                    "replicationLag": null,
                    "role": "HA",
                    "status": "ONLINE",
                    "version": "8.0.28"
                }
            },
            "topologyMode": "Single-Primary"
        },
        "groupInformationSourceMember": "dbc1-0.mysql:3306"
    }
    

    선택적으로 cluster.status({extended:1})를 호출하여 추가 상태 세부정보를 가져올 수 있습니다.

샘플 데이터베이스 만들기

샘플 데이터베이스를 만들려면 다음 단계를 수행합니다.

  1. 데이터베이스를 만들고 데이터베이스에 데이터를 로드합니다.

    \sql
    create database loanapplication;
    use loanapplication
    CREATE TABLE loan (loan_id INT unsigned AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL , status VARCHAR(30) );
    
  2. 데이터베이스에 샘플 데이터를 삽입합니다. 데이터를 삽입하려면 클러스터의 기본 인스턴스에 연결되어 있어야 합니다.

    INSERT INTO loan (firstname, lastname, status) VALUES ( 'Fred','Flintstone','pending');
    INSERT INTO loan (firstname, lastname, status) VALUES ( 'Betty','Rubble','approved');
    
  3. 이전 단계에서 삽입한 3개의 행이 테이블에 포함되어 있는지 확인합니다.

    SELECT * FROM loan;
    

    출력은 다음과 비슷합니다.

    +---------+-----------+------------+----------+
    | loan_id | firstname | lastname   | status   |
    +---------+-----------+------------+----------+
    |       1 | Fred      | Flintstone | pending  |
    |       2 | Betty     | Rubble     | approved |
    +---------+-----------+------------+----------+
    2 rows in set (0.0010 sec)
    

MySQL InnoDB ClusterSet 만들기

전용 ClusterSet 복제 채널을 사용하여 기본 클러스터에서 복제본 클러스터로 복제를 관리하기 위해 MySQL InnoDB ClusterSet를 만들 수 있습니다.

MySQL InnoDB ClusterSet는 기본 MySQL InnoDB 클러스터를 멀티 영역 또는 멀티 리전과 같은 대체 위치에 있는 하나 이상의 자체 복제본과 연결하여 MySQL InnoDB 클러스터 배포에 재해 내결함성을 제공합니다.

MySQL 셸을 닫은 경우 새 Cloud Shell 터미널에서 다음 명령어를 실행하여 새 셸을 만듭니다.

  kubectl -n mysql1 exec -it dbc1-0 -- \
      /bin/bash -c 'mysqlsh \
      --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql.mysql1.svc.cluster.local"'

MySQL InnoDB ClusterSet,를 만들려면 다음 단계를 수행합니다.

  1. MySQL 셸 터미널에서 클러스터 객체를 가져옵니다.

    \js
    cluster=dba.getCluster()
    

    출력은 다음과 비슷합니다.

    <Cluster:mycluster>
    
  2. 클러스터 객체에 저장된 MySQL InnoDB 클러스터를 기본 클러스터로 사용하여 MySQL InnoDB ClusterSet를 초기화합니다.

    clusterset=cluster.createClusterSet('clusterset')
    

    출력은 다음과 비슷합니다.

    A new ClusterSet will be created based on the Cluster 'mycluster'.
    
    * Validating Cluster 'mycluster' for ClusterSet compliance.
    
    * Creating InnoDB ClusterSet 'clusterset' on 'mycluster'...
    
    * Updating metadata...
    
    ClusterSet successfully created. Use ClusterSet.createReplicaCluster() to add Replica Clusters to it.
    
    <ClusterSet:clusterset>
    
  3. MySQL InnoDB ClusterSet 상태를 확인합니다.

    clusterset.status()
    

    출력은 다음과 비슷합니다.

    {
        "clusters": {
            "mycluster": {
                "clusterRole": "PRIMARY",
                "globalStatus": "OK",
                "primary": "dbc1-0.mysql:3306"
            }
        },
        "domainName": "clusterset",
        "globalPrimaryInstance": "dbc1-0.mysql:3306",
        "primaryCluster": "mycluster",
        "status": "HEALTHY",
        "statusText": "All Clusters available."
    }
    

    선택적으로 clusterset.status({extended:1})을 호출하여 클러스터 정보를 포함한 추가 상태 세부정보를 가져올 수 있습니다.

  4. MySQL 셸을 종료합니다.

    \q
    

MySQL 라우터 배포

MySQL 라우터를 배포하여 클라이언트 애플리케이션 트래픽을 적절한 클러스터로 보낼 수 있습니다. 라우팅은 데이터베이스 작업을 실행하는 애플리케이션의 연결 포트를 기반으로 합니다.

  • 쓰기는 기본 ClusterSet의 기본 클러스터 인스턴스로 라우팅됩니다.
  • 읽기는 기본 클러스터의 모든 인스턴스로 라우팅될 수 있습니다.

MySQL 라우터를 시작하면 MySQL InnoDB ClusterSet 배포에 부트스트래핑됩니다. MySQL InnoDB ClusterSet에 연결된 MySQL 라우터 인스턴스는 제어되는 전환 또는 긴급 장애 조치를 인식하고 트래픽을 새 기본 클러스터로 보냅니다.

MySQL 라우터를 배포하려면 다음 단계를 수행합니다.

  1. Cloud Shell 터미널에서 MySQL 라우터를 배포합니다.

    kubectl apply -n mysql1 -f c1-router.yaml
    

    출력은 다음과 비슷합니다.

    configmap/mysql-router-config created
    service/mysql-router created
    deployment.apps/mysql-router created
    
  2. MySQL 라우터 배포의 준비 상태를 확인합니다.

    kubectl -n mysql1 get deployment mysql-router --watch
    

    3개의 포드가 모두 준비되면 출력이 다음과 비슷하게 표시됩니다.

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    mysql-router   3/3     3            0           3m36s
    

    콘솔에 PodUnschedulable 오류가 표시되면 GKE가 노드를 더 프로비저닝하는 동안 1~2분 정도 기다립니다. 새로고침하면 3/3 OK가 표시됩니다.

  3. 기존 클러스터 멤버에서 MySQL 셸을 시작합니다.

    kubectl -n mysql1 exec -it dbc1-0 -- \
        /bin/bash -c 'mysqlsh --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
    

    이 명령어는 dbc1-0 포드에 연결한 후 dbc1-0 MySQL 인스턴스에 연결된 셸을 시작합니다.

  4. 라우터 구성을 확인합니다.

    clusterset=dba.getClusterSet()
    clusterset.listRouters()
    

    출력은 다음과 비슷합니다.

    {
      "domainName": "clusterset",
      "routers": {
        "mysql-router-7cd8585fbc-74pkm::": {
            "hostname": "mysql-router-7cd8585fbc-74pkm",
            "lastCheckIn": "2022-09-22 23:26:26",
            "roPort": 6447,
            "roXPort": 6449,
            "rwPort": 6446,
            "rwXPort": 6448,
            "targetCluster": null,
            "version": "8.0.27"
        },
        "mysql-router-7cd8585fbc-824d4::": {
          ...
        },
        "mysql-router-7cd8585fbc-v2qxz::": {
          ...
        }
      }
    }
    
  5. MySQL 셸을 종료합니다.

    \q
    
  6. 이 스크립트를 실행하여 MySQL 라우터 포드 배치를 검사합니다.

    bash ../scripts/inspect_pod_node.sh mysql1 | sort
    

    이 스크립트는 mysql1 네임스페이스의 모든 포드에 대한 노드 및 클라우드 영역 배치를 보여줍니다. 출력은 다음과 비슷합니다.

    gke-gkemulti-west-5-default-pool-1ac6e8b5-0h9v us-west1-c mysql-router-6654f985f5-df97q
    gke-gkemulti-west-5-default-pool-1ac6e8b5-ddjx us-west1-c dbc1-1
    gke-gkemulti-west-5-default-pool-1f5baa66-bf8t us-west1-a dbc1-2
    gke-gkemulti-west-5-default-pool-1f5baa66-kt03 us-west1-a mysql-router-6654f985f5-qlfj9
    gke-gkemulti-west-5-default-pool-4bcaca65-2l6s us-west1-b mysql-router-6654f985f5-5967d
    gke-gkemulti-west-5-default-pool-4bcaca65-jch0 us-west1-b dbc1-0
    

    MySQL 라우터 포드가 영역에 균등하게 분배된 것을 확인할 수 있습니다. 즉, MySQL 포드와 동일한 노드 또는 다른 MySQL 라우터 포드와 동일한 노드에 배치되지 않습니다.

GKE 및 MySQL InnoDB 클러스터 업그레이드 관리

MySQL 및 Kubernetes 업데이트는 모두 정기적으로 출시됩니다. 작업 권장사항에 따라 소프트웨어 환경을 정기적으로 업데이트하세요. 기본적으로 GKE는 클러스터 및 노드 풀 업그레이드를 자동으로 관리합니다. Kubernetes 및 GKE는 또한 MySQL 소프트웨어 업그레이드를 쉽게 수행할 수 있도록 추가 기능을 제공합니다.

GKE 업그레이드 계획

다음을 포함하여 스테이트풀(Stateful) 서비스를 실행할 때 위험을 줄이고 클러스터를 매끄럽게 업그레이드할 수 있도록 사전적인 단계를 수행하고 구성을 설정할 수 있습니다.

  • 표준 클러스터: 클러스터 업그레이드를 위한 GKE 권장사항을 참조하세요. 유지보수 기간 중 업그레이드가 수행되도록 적절한 업그레이드 전략을 선택합니다.

    • 비용 최적화가 중요하고 워크로드가 60분 이내의 단계적 종료를 허용할 수 있는 경우 일시 급증 업그레이드를 선택합니다.
    • 워크로드가 중단에 대한 내결함성이 낮고 리소스 사용량이 더 많아서 일시적으로 비용이 증가하는 경우 블루-그린 업그레이드를 선택합니다.

    자세한 내용은 스테이트풀(Stateful) 워크로드를 실행하는 클러스터 업그레이드를 참조하세요. Autopilot 클러스터는 선택한 출시 채널에 따라 자동으로 업그레이드됩니다.

  • 의도한 시간에 업그레이드가 수행되도록 유지보수 기간을 사용합니다. 유지보수 기간 이전에 데이터베이스 백업이 성공적인지 확인합니다.

  • 업그레이드한 MySQL 노드로 트래픽을 허용하기 전 준비 프로브 및 활성 프로브를 사용하여 트래픽에 사용할 준비가 되었는지 확인합니다.

  • 트래픽을 수락하기 전 복제가 동기화되었는지 여부를 평가하는 프로브를 만듭니다. 이 작업은 데이터베이스의 복잡성 및 스케일에 따라 커스텀 스크립트를 통해 수행할 수 있습니다.

포드 중단 예산(PDB) 정책 설정

MySQL InnoDB 클러스터가 GKE에서 실행될 때는 쿼럼 요구사항을 충족하기 위해 언제든지 실행 중인 인스턴스 수가 충분해야 합니다.

이 튜토리얼에서는 MySQL 클러스터가 3개의 인스턴스로 구성되므로, 쿼럼 형성을 위해 2개의 인스턴스를 사용할 수 있어야 합니다. PodDisruptionBudget 정책을 사용하면 언제든지 종료할 수 있는 포드 수를 제한할 수 있습니다. 이것은 스테이트풀(Stateful) 서비스의 안정 상태 운영 및 클러스터 업그레이드 모두에 유용합니다.

제한된 개수의 포드가 동시에 중단되도록 보장하기 위해 워크로드의 PDB를 maxUnavailable: 1로 설정합니다. 이렇게 하면 서비스 작업의 어느 시점에서든 실행 중인 포드 수가 1개를 초과하지 않습니다.

다음 PodDisruptionBudget 정책 매니페스트는 MySQL 애플리케이션에 대해 사용 불가능한 최대 포드 수를 1로 설정합니다.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mysql-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: mysql

PDB 정책을 클러스터에 적용하려면 다음 단계를 수행합니다.

  1. kubectl을 사용하여 PDB 정책을 적용합니다.

    kubectl apply -n mysql1 -f mysql-pdb-maxunavailable.yaml
    
  2. PDB 상태를 확인합니다.

    kubectl get poddisruptionbudgets -n mysql1 mysql-pdb -o yaml
    

    출력의 status 섹션에서 currentHealthydesiredHealthy 포드 수를 확인합니다. 출력은 다음과 비슷합니다.

    status:
    ...
      currentHealthy: 3
      desiredHealthy: 2
      disruptionsAllowed: 1
      expectedPods: 3
    ...
    

MySQL 바이너리 업그레이드 계획

Kubernetes 및 GKE는 MySQL 바이너리를 쉽게 업그레이드할 수 있는 기능을 제공합니다. 그러나 업그레이드 준비를 위해 일부 작업을 수행해야 합니다.

업그레이드 프로세스를 시작하기 전 다음 고려사항에 유의하세요.

  • 먼저 테스트 환경에서 업그레이드를 수행해야 합니다. 프로덕션 시스템의 경우 사전 프로덕션 환경에서 추가 테스트를 수행해야 합니다.
  • 일부 바이너리 출시의 경우 업그레이드를 수행한 후 버전을 다운그레이드할 수 없습니다. 시간을 내어 업그레이드로 인한 영향을 파악하세요.
  • 복제 소스는 새 버전으로 복제될 수 있습니다. 그러나 새 버전에서 이전 버전으로의 복사는 일반적으로 지원되지 않습니다.
  • 업그레이드된 버전을 배포하기 전 데이터베이스 백업이 완료되었는지 확인합니다.
  • Kubernetes 포드의 임시적 특성에 주의하세요. 영구 볼륨에 있지 않은 포드로 저장된 구성 상태는 포드를 재배치할 때 손실됩니다.
  • MySQL 바이너리 업그레이드의 경우 앞에서 설명한 대로 동일한 PDB, 노드 풀 업데이트 전략, 프로브를 사용합니다.

프로덕션 환경에서는 다음과 같은 권장사항을 따라야 합니다.

  • 새 버전의 MySQL로 컨테이너 이미지를 만듭니다.
  • 소스 제어 저장소에 이미지 빌드 안내를 저장합니다.
  • Cloud Build와 같이 자동화된 이미지 빌드 및 테스트 파이프라인을 사용하고 Artifact Registry와 같은 이미지 레지스트리에 이미지 바이너리를 저장합니다.

이 튜토리얼을 단순하게 만들기 위해 여기에서는 컨테이너 이미지를 빌드 및 저장하지 않고 대신 공개 MySQL 이미지를 사용합니다.

업그레이드된 MySQL 바이너리 배포

MySQL 바이너리 업그레이드를 수행하려면 StatefulSet 리소스의 이미지 버전을 수정하는 선언적 명령어를 실행합니다. GKE는 현재 포드를 중지하고, 업그레이드된 바이너리로 새 포드를 배포하고, 새 포드에 영구 디스크를 연결하기 위해 필요한 단계를 수행합니다.

  1. PDB가 생성되었는지 확인합니다.

    kubectl get poddisruptionbudgets -n mysql1
    
  2. 스테이트풀(Stateful) 세트 목록을 가져옵니다.

    kubectl get statefulsets -n mysql1
    
  3. app 라벨을 사용하여 실행 중인 포드 목록을 가져옵니다.

    kubectl get pods --selector=app=mysql -n mysql1
    
  4. 스테이트풀(Stateful) 세트에서 MySQL 이미지를 업데이트합니다.

    kubectl  -n mysql1 \
        set image statefulset/dbc1 \
        mysql=mysql/mysql-server:8.0.30
    

    출력은 다음과 비슷합니다.

    statefulset.apps/mysql image updated
    
  5. 종료 중인 포드 및 새 포드의 상태를 확인합니다.

    kubectl get pods --selector=app=mysql -n mysql1
    

MySQL 바이너리 업그레이드 검증

업그레이드 동안 출시, 새 포드, 기존 서비스의 상태를 확인할 수 있습니다.

  1. rollout status 명령어를 실행하여 업그레이드를 확인합니다.

    kubectl rollout status statefulset/dbc1 -n mysql1
    

    출력은 다음과 비슷합니다.

    partitioned roll out complete: 3 new pods have been updated...
    
  2. 스테이트풀(Stateful) 세트를 검사하여 이미지 버전을 확인합니다.

    kubectl get statefulsets -o wide -n mysql1
    

    출력은 다음과 비슷합니다.

    NAME   READY   AGE   CONTAINERS   IMAGES
    dbc1   3/3     37m   mysql        mysql/mysql-server:8.0.30
    
  3. 클러스터의 상태를 확인합니다.

    kubectl -n mysql1 \
         exec -it dbc1-0 -- \
           /bin/bash \
             -c 'mysqlsh \
             --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-1.mysql.mysql1.svc.cluster.local" \
             --js \
             --execute "print(dba.getClusterSet().status({extended:1})); print(\"\\n\")"'
    

    각 클러스터 인스턴스에 대해 출력에서 상태 및 버전 값을 확인합니다. 출력은 다음과 비슷합니다.

    ...
      "status": "ONLINE",
      "version": "8.0.30"
    ...
    

마지막 앱 배포 출시 롤백

업그레이드된 바이너리 버전의 배포를 되돌리면 출시 프로세스가 취소되고 이전 이미지 버전을 사용하여 포드 세트가 새로 배포됩니다.

이전 작동 버전으로 배포를 되돌리려면 rollout undo 명령어를 사용합니다.

kubectl rollout undo statefulset/dbc1 -n mysql1

출력은 다음과 비슷합니다.

statefulset.apps/dbc1 rolled back

데이터베이스 클러스터 수평 확장

MySQL InnoDB 클러스터를 수평 확장하려면 GKE 클러스터 노드 풀에 노드를 더 추가하고(표준 사용 시에만 필요), 추가 MySQL 인스턴스를 배포한 후 기존 MySQL InnoDB 클러스터에 각 인스턴스를 추가합니다.

표준 클러스터에 노드 추가

Autopilot 클러스터를 사용할 때는 이 작업이 필요하지 않습니다.

표준 클러스터에 노드를 추가하려면 Cloud Shell 또는 Google Cloud 콘솔에 대해 아래 안내를 따릅니다. 자세한 단계는 노드 풀 크기 조정을 참조하세요

gcloud

Cloud Shell에서 각 관리형 인스턴스 그룹의 8개 인스턴스로 기존 노드 풀 크기를 조정합니다.

gcloud container clusters resize ${CLUSTER_NAME} \
     --node-pool default-pool \
     --num-nodes=8

콘솔

표준 클러스터에 노드를 추가하려면 다음 안내를 따르세요.

  1. Google Cloud 콘솔에서 gkemulti-west1 클러스터 페이지를 엽니다.
  2. 노드를 선택하고 기본 풀을 클릭합니다.
  3. 인스턴스 그룹으로 스크롤합니다.
  4. 각 인스턴스 그룹에 대해 Number of nodes 값 크기를 5개 노드에서 8개 노드로 조정합니다.

기본 클러스터에 MySQL 포드 추가

클러스터 수평 확장을 위해 추가 MySQL 포드를 배포하려면 다음 단계를 수행합니다.

  1. Cloud Shell에서 MySQL 배포의 복제본 수를 3개에서 5개로 업데이트합니다.

    kubectl scale  -n mysql1 --replicas=5 -f c1-mysql.yaml
    
  2. 배포 진행 상태를 확인합니다.

    kubectl -n mysql1 get pods --selector=app=mysql -o wide
    

    포드가 준비되었는지 확인하려면 --watch 플래그를 사용하여 배포를 확인합니다. Autopilot 클러스터 사용 중 Pod Unschedulable 오류가 표시되면 GKE가 추가 포드를 수용하기 위해 노드를 프로비저닝하고 있음을 나타낼 수 있습니다.

  3. 클러스터에 추가할 새 MySQL 인스턴스에 대해 그룹 복제 설정을 구성합니다.

    bash ../scripts/c1-clustersetup.sh 3 4
    

    이 스크립트는 서수 3~4로 포드에서 실행되는 인스턴스에 명령어를 제출합니다.

  4. MySQL 셸을 엽니다.

    kubectl -n mysql1 \
      exec -it dbc1-0 -- \
          /bin/bash \
            -c 'mysqlsh \
            --uri="root:$MYSQL_ROOT_PASSWORD@dbc1-0.mysql"'
    
  5. 2개의 새 MySQL 인스턴스를 구성합니다.

    dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    dba.configureInstance('root:$MYSQL_ROOT_PASSWORD@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"),clusterAdmin: 'icadmin', clusterAdminPassword: os.getenv("MYSQL_ADMIN_PASSWORD")});
    

    이 명령어는 MySQL InnoDB 클러스터 사용을 위해 인스턴스가 올바르게 구성되었는지 확인하고 필요한 구성 변경사항을 수행합니다.

  6. 새 인스턴스 중 하나를 기본 클러스터에 추가합니다.

    cluster = dba.getCluster()
    cluster.addInstance('icadmin@dbc1-3.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  7. 새로운 보조 인스턴스를 기본 클러스터에 추가합니다.

    cluster.addInstance('icadmin@dbc1-4.mysql', {password: os.getenv("MYSQL_ROOT_PASSWORD"), recoveryMethod: 'clone'});
    
  8. 클러스터 상태도 포함된 ClusterSet 상태를 확인합니다.

    clusterset = dba.getClusterSet()
    clusterset.status({extended: 1})
    

    출력은 다음과 비슷합니다.

    "domainName": "clusterset",
    "globalPrimaryInstance": "dbc1-0.mysql:3306",
    "metadataServer": "dbc1-0.mysql:3306",
    "primaryCluster": "mycluster",
    "status": "HEALTHY",
    "statusText": "All Clusters available."
    
  9. MySQL 셸을 종료합니다.

    \q
    

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

프로젝트 삭제

청구되지 않도록 하는 가장 쉬운 방법은 튜토리얼에서 만든 프로젝트를 삭제하는 것입니다.

Delete a Google Cloud project:

gcloud projects delete PROJECT_ID

다음 단계