Memigrasikan data MySQL dari Persistent Disk ke Hyperdisk di GKE


Tutorial ini menunjukkan cara memigrasikan data MySQL yang ada dari Persistent Disk (PD) ke Hyperdisk di Google Kubernetes Engine untuk mengupgrade performa penyimpanan Anda. Hyperdisk menawarkan IOPS dan throughput yang lebih tinggi daripada Persistent Disk, yang dapat meningkatkan performa MySQL dengan mengurangi latensi untuk kueri dan transaksi database. Anda dapat menggunakan snapshot disk untuk memigrasikan data ke jenis disk yang berbeda, bergantung pada kompatibilitas jenis mesin. Misalnya, volume Hyperdisk hanya kompatibel dengan beberapa jenis mesin generasi ketiga, keempat, dan yang lebih baru seperti N4, yang tidak mendukung Persistent Disk. Untuk mengetahui informasi selengkapnya, lihat seri mesin yang tersedia.

Untuk mendemonstrasikan migrasi dari Persistent Disk ke Hyperdisk, tutorial ini menggunakan database Sakila untuk menyediakan set data sampel. Sakila adalah database contoh yang disediakan oleh MySQL yang dapat Anda gunakan sebagai skema untuk tutorial dan contoh. Database ini merepresentasikan toko penyewaan DVD fiktif dan mencakup tabel untuk film, aktor, pelanggan, dan penyewaan.

Panduan ini ditujukan bagi spesialis Penyimpanan dan administrator Penyimpanan yang membuat dan mengalokasikan penyimpanan, serta mengelola keamanan data dan akses data. Untuk mempelajari lebih lanjut peran umum dan contoh tugas yang kami referensikan dalam Google Cloud konten, lihat Peran dan tugas pengguna umum GKE Enterprise.

Arsitektur deployment

Diagram berikut mengilustrasikan proses migrasi dari Persistent Disk ke Hyperdisk.

  • Aplikasi MySQL berjalan di node pool GKE dengan jenis mesin N2, yang menyimpan datanya di SSD Persistent Disk.
  • Untuk memastikan konsistensi data, aplikasi di-scale down untuk mencegah penulisan baru.
  • Snapshot Persistent Disk dibuat, yang berfungsi sebagai cadangan data point-in-time yang lengkap.
  • Hyperdisk baru disediakan dari snapshot, dan instance MySQL baru di-deploy di kumpulan node N4 yang kompatibel dengan Hyperdisk secara terpisah. Instance baru ini terpasang ke Hyperdisk yang baru dibuat, sehingga menyelesaikan migrasi ke penyimpanan berperforma lebih tinggi.
Diagram arsitektur yang menunjukkan migrasi data MySQL dari Persistent Disk ke Hyperdisk menggunakan snapshot.
Gambar 1: Migrasi data MySQL dari Persistent Disk ke Hyperdisk menggunakan snapshot.

Tujuan

Dalam tutorial ini, Anda akan mempelajari cara melakukan hal-hal berikut:

  • Deploy cluster MySQL.
  • Upload set data pengujian.
  • Buat snapshot data Anda.
  • Buat Hyperdisk dari snapshot.
  • Mulai cluster MySQL baru di kumpulan node jenis mesin N4 yang kompatibel dengan Hyperdisk.
  • Verifikasi integritas data untuk mengonfirmasi keberhasilan migrasi.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponen Google Cloudyang dapat ditagih berikut:

  • GKE
  • Compute Engine, which includes:
    • Storage capacity provisioned for both Persistent Disk and Hyperdisk.
    • Storage costs for the snapshots.

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga.

Pengguna Google Cloud baru mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Sebelum memulai

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine, GKE, Identity and Access Management Service Account Credentials APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine, GKE, Identity and Access Management Service Account Credentials APIs.

    Enable the APIs

  8. Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Buka IAM
    2. Pilih project.
    3. Klik Grant access.
    4. Di kolom New principals, masukkan ID pengguna Anda. Biasanya berupa alamat email untuk Akun Google.

    5. Di daftar Select a role, pilih peran.
    6. Untuk memberikan peran tambahan, klik Tambahkan peran lain, lalu tambahkan setiap peran tambahan.
    7. Klik Simpan.
    8. Menyiapkan Cloud Shell

      1. In the Google Cloud console, activate Cloud Shell.

        Activate Cloud Shell

        Sesi Cloud Shell akan dimulai dan menampilkan perintah command line. Diperlukan waktu beberapa detik untuk melakukan inisialisasi sesi.

      2. Setel project default Anda:

          gcloud config set project PROJECT_ID
        

        Ganti PROJECT_ID dengan project ID Anda.

      3. Menyiapkan lingkungan

        1. Di Cloud Shell, tetapkan variabel lingkungan untuk project, lokasi, dan awalan cluster Anda.

          export PROJECT_ID=PROJECT_ID
          export EMAIL_ADDRESS=EMAIL_ADDRESS
          export KUBERNETES_CLUSTER_PREFIX=offline-hyperdisk-migration
          export LOCATION=us-central1-a
          

          Ganti kode berikut:

          • PROJECT_ID: Google Cloud project ID Anda.
          • EMAIL_ADDRESS: alamat email Anda.
          • LOCATION: zona tempat Anda ingin membuat resource deployment. Untuk tujuan tutorial ini, gunakan zona us-central1-a.
        2. Clone repositori kode contoh dari GitHub:

          git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
          
        3. Buka direktori offline-hyperdisk-migration untuk mulai membuat resource deployment:

          cd kubernetes-engine-samples/databases/offline-hyperdisk-migration
          

        Buat cluster GKE dan node pool

        Tutorial ini menggunakan cluster zonal agar lebih sederhana karena volume Hyperdisk adalah resource zonal dan hanya dapat diakses dalam satu zona.

        1. Buat cluster GKE zona:

          gcloud container clusters create ${KUBERNETES_CLUSTER_PREFIX}-cluster \
              --location ${LOCATION} \
              --node-locations ${LOCATION} \
              --shielded-secure-boot \
              --shielded-integrity-monitoring \
              --machine-type "e2-micro" \
              --num-nodes "1"
          
        2. Tambahkan node pool dengan jenis mesin N2 untuk deployment MySQL awal:

          gcloud container node-pools create regular-pool \
              --cluster ${KUBERNETES_CLUSTER_PREFIX}-cluster \
              --machine-type n2-standard-4 \
              --location ${LOCATION} \
              --num-nodes 1
          
        3. Tambahkan node pool dengan jenis mesin N4 di Hyperdisk tempat deployment MySQL akan dimigrasikan dan dijalankan:

          gcloud container node-pools create hyperdisk-pool \
              --cluster ${KUBERNETES_CLUSTER_PREFIX}-cluster \
              --machine-type n4-standard-4 \
              --location ${LOCATION} \
              --num-nodes 1
          
        4. Hubungkan ke cluster:

          gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${LOCATION}
          

        Men-deploy MySQL di Persistent Disk

        Di bagian ini, Anda akan men-deploy instance MySQL yang menggunakan Persistent Disk untuk penyimpanan, dan memuatnya dengan data contoh.

        1. Buat dan terapkan StorageClass untuk Hyperdisk. StorageClass ini akan digunakan nanti dalam tutorial.

          apiVersion: storage.k8s.io/v1
          kind: StorageClass
          metadata:
            name: balanced-storage
          provisioner: pd.csi.storage.gke.io
          volumeBindingMode: WaitForFirstConsumer
          allowVolumeExpansion: true
          parameters:
            type: hyperdisk-balanced
            provisioned-throughput-on-create: "250Mi"
            provisioned-iops-on-create: "7000"
          kubectl apply -f manifests/01-storage-class/storage-class-hdb.yaml
          
        2. Buat dan deploy instance MySQL yang mencakup afinitas node untuk memastikan Pod dijadwalkan di node regular-pool, dan menyediakan volume SSD Persistent Disk.

          apiVersion: v1
          kind: Service
          metadata:
            name: regular-mysql
            labels:
              app: mysql
          spec:
            ports:
              - port: 3306
            selector:
              app: mysql
            clusterIP: None
          ---
          apiVersion: v1
          kind: PersistentVolumeClaim
          metadata:
            name: mysql-pv-claim
            labels:
              app: mysql
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 30Gi
            storageClassName: premium-rwo
          ---
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: existing-mysql
            labels:
              app: mysql
          spec:
            selector:
              matchLabels:
                app: mysql
            strategy:
              type: Recreate
            template:
              metadata:
                labels:
                  app: mysql
              spec:
                containers:
                - image: mysql:8.0
                  name: mysql
                  env:
                  - name: MYSQL_ROOT_PASSWORD
                    value: migration
                  - name: MYSQL_DATABASE
                    value: mysql
                  - name: MYSQL_USER
                    value: app
                  - name: MYSQL_PASSWORD
                    value: migration
                  ports:
                  - containerPort: 3306
                    name: mysql
                  volumeMounts:
                  - name: mysql-persistent-storage
                    mountPath: /var/lib/mysql
                affinity: 
                  nodeAffinity:
                    preferredDuringSchedulingIgnoredDuringExecution:
                    - weight: 1
                      preference:
                        matchExpressions:
                        - key: "node.kubernetes.io/instance-type"
                          operator: In
                          values:
                          - "n2-standard-4"
                volumes:
                - name: mysql-persistent-storage
                  persistentVolumeClaim:
                    claimName: mysql-pv-claim
          kubectl apply -f manifests/02-mysql/mysql-deployment.yaml
          

          Manifest ini membuat deployment dan layanan MySQL, dengan Persistent Disk yang disediakan secara dinamis untuk penyimpanan data. Sandi untuk pengguna root adalah migration.

        3. Deploy Pod klien MySQL untuk memuat data, dan verifikasi migrasi data:

          apiVersion: v1
          kind: Pod
          metadata:
            name: mysql-client
          spec:
            containers:
            - name: main
              image: mysql:8.0
              command: ["sleep", "360000"]
              resources:
                requests:
                  memory: 1Gi
                  cpu: 500m
                limits:
                  memory: 1Gi
                  cpu: "1"
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: migration
          kubectl apply -f manifests/02-mysql/mysql-client.yaml
          kubectl wait pods mysql-client --for condition=Ready --timeout=300s
          
        4. Hubungkan ke Pod klien:

          kubectl exec -it mysql-client -- bash
          
        5. Dari shell Pod klien, download dan impor set data contoh Sakila:

          # Download the dataset
          curl --output dataset.tgz "https://downloads.mysql.com/docs/sakila-db.tar.gz"
          
          # Extract the dataset
          tar -xvzf dataset.tgz -C /home/mysql
          
          # Import the dataset into MySQL (the password is "migration").
          mysql -u root -h regular-mysql.default -p
              SOURCE /sakila-db/sakila-schema.sql;
              SOURCE /sakila-db/sakila-data.sql;
          
        6. Pastikan data telah diimpor:

          USE sakila;
          SELECT      table_name,      table_rows  FROM      INFORMATION_SCHEMA.TABLES  WHERE TABLE_SCHEMA = 'sakila';
          

          Output menampilkan daftar tabel dengan jumlah baris.

          | TABLE_NAME                 | TABLE_ROWS |
          +----------------------------+------------+
          | actor                      |        200 |
          | actor_info                 |       NULL |
          | address                    |        603 |
          | category                   |         16 |
          | city                       |        600 |
          | country                    |        109 |
          | customer                   |        599 |
          | customer_list              |       NULL |
          | film                       |       1000 |
          | film_actor                 |       5462 |
          | film_category              |       1000 |
          | film_list                  |       NULL |
          | film_text                  |       1000 |
          | inventory                  |       4581 |
          | language                   |          6 |
          | nicer_but_slower_film_list |       NULL |
          | payment                    |      16086 |
          | rental                     |      16419 |
          | sales_by_film_category     |       NULL |
          | sales_by_store             |       NULL |
          | staff                      |          2 |
          | staff_list                 |       NULL |
          | store                      |          2 |
          +----------------------------+------------+
          23 rows in set (0.01 sec)
          
        7. Keluar dari sesi mysql:

          exit;
          
        8. Keluar dari shell Pod klien:

          exit
          
        9. Dapatkan nama PersistentVolume (PV) yang dibuat untuk MySQL dan simpan di variabel lingkungan:

          export PV_NAME=$(kubectl get pvc mysql-pv-claim -o jsonpath='{.spec.volumeName}')
          

        Memigrasikan data ke volume Hyperdisk

        Sekarang Anda memiliki workload MySQL dengan data yang disimpan di volume SSD Persistent Disk. Bagian ini menjelaskan cara memigrasikan data ini ke volume Hyperdisk menggunakan snapshot. Pendekatan migrasi ini juga mempertahankan volume Persistent Disk asli, yang memungkinkan Anda melakukan roll back untuk menggunakan instance MySQL asli jika diperlukan.

        1. Meskipun Anda dapat membuat snapshot dari disk tanpa melepaskannya dari beban kerja, untuk memastikan integritas data MySQL, Anda harus menghentikan penulisan baru ke disk selama pembuatan snapshot. Turunkan skala deployment MySQL menjadi 0 replika untuk menghentikan penulisan:

          kubectl scale deployment regular-mysql --replicas=0
          
        2. Buat snapshot dari Persistent Disk yang ada:

          gcloud compute disks snapshot ${PV_NAME} --location=${LOCATION} --snapshot-name=original-snapshot --description="snapshot taken from pd-ssd"
          
        3. Buat volume Hyperdisk baru bernama mysql-recovery dari snapshot:

          gcloud compute disks create mysql-recovery --project=${PROJECT_ID} \
              --type=hyperdisk-balanced \
              --size=150GB --location=${LOCATION} \
              --source-snapshot=projects/${PROJECT_ID}/global/snapshots/original-snapshot
          
        4. Perbarui file manifes untuk PV yang dipulihkan dengan project ID Anda:

          apiVersion: v1
          kind: PersistentVolume
          metadata:
            name: backup
          spec:
            storageClassName: balanced-storage
            capacity:
              storage: 150G
            accessModes:
              - ReadWriteOnce
            claimRef:
              name: hyperdisk-recovery
              namespace: default
            csi:
              driver: pd.csi.storage.gke.io
              volumeHandle: projects/PRJCTID/zones/us-central1-a/disks/mysql-recovery
              fsType: ext4
          ---
          apiVersion: v1
          kind: PersistentVolumeClaim
          metadata:
            namespace: default
            name: hyperdisk-recovery
          spec:
            storageClassName: balanced-storage
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 150G
          sed -i "s/PRJCTID/$PROJECT_ID/g" manifests/02-mysql/restore_pv.yaml
          
        5. Buat PersistentVolume (PVC) dan PersistentVolumeClaim dari Hyperdisk baru:

          kubectl apply -f manifests/02-mysql/restore_pv.yaml
          

        Memverifikasi migrasi data

        Deploy instance MySQL baru yang menggunakan volume Hyperdisk yang baru dibuat. Pod ini akan dijadwalkan di kumpulan node hyperdisk-pool yang terdiri dari node N4.

        1. Deploy instance MySQL baru:

          apiVersion: v1
          kind: Service
          metadata:
            name: recovered-mysql
            labels:
              app: new-mysql
          spec:
            ports:
              - port: 3306
            selector:
              app: new-mysql
            clusterIP: None
          ---
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: new-mysql
            labels:
              app: new-mysql
          spec:
            selector:
              matchLabels:
                app: new-mysql
            strategy:
              type: Recreate
            template:
              metadata:
                labels:
                  app: new-mysql
              spec:
                containers:
                - image: mysql:8.0
                  name: mysql
                  env:
                  - name: MYSQL_ROOT_PASSWORD
                    value: migration
                  - name: MYSQL_DATABASE
                    value: mysql
                  - name: MYSQL_USER
                    value: app
                  - name: MYSQL_PASSWORD
                    value: migration
                  ports:
                  - containerPort: 3306
                    name: mysql
                  volumeMounts:
                  - name: mysql-persistent-storage
                    mountPath: /var/lib/mysql
                affinity: 
                  nodeAffinity:
                    preferredDuringSchedulingIgnoredDuringExecution:
                    - weight: 1
                      preference:
                        matchExpressions:
                        - key: "cloud.google.com/gke-nodepool"
                          operator: In
                          values:
                          - "hyperdisk-pool"      
                volumes:
                - name: mysql-persistent-storage
                  persistentVolumeClaim:
                    claimName: hyperdisk-recovery
          kubectl apply -f manifests/02-mysql/recovery_mysql_deployment.yaml
          
        2. Untuk memverifikasi integritas data, hubungkan ke Pod klien MySQL lagi:

          kubectl exec -it mysql-client -- bash
          
        3. Di dalam Pod klien, hubungkan ke database MySQL baru (recovered-mysql.default) dan verifikasi data. Sandi default-nya adalah migration.

          mysql -u root -h recovered-mysql.default -p
          USE sakila;
          SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'sakila';
          

          Data harus sama seperti di instance MySQL asli Anda di volume Persistent Disk.

        4. Keluar dari sesi mysql:

          exit;
          
        5. Keluar dari shell Pod klien:

          exit
          

        Pembersihan

        Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

        Menghapus project

        1. In the Google Cloud console, go to the Manage resources page.

          Go to Manage resources

        2. In the project list, select the project that you want to delete, and then click Delete.
        3. In the dialog, type the project ID, and then click Shut down to delete the project.

        Menghapus resource satu per satu

        Jika Anda telah menggunakan project yang sudah ada dan tidak ingin menghapusnya, hapus resource individual tersebut:

        1. Tetapkan variabel lingkungan untuk pembersihan dan ambil nama volume Persistent Disk yang dibuat oleh PersistentVolumeClaim mysql-pv-claim:

          export PROJECT_ID=PROJECT_ID
          export KUBERNETES_CLUSTER_PREFIX=offline-hyperdisk-migration
          export location=us-central1-a
          export PV_NAME=$(kubectl get pvc mysql-pv-claim -o jsonpath='{.spec.volumeName}')
          

          Ganti PROJECT_ID dengan project ID Anda.

        2. Hapus snapshot:

          gcloud compute snapshots delete original-snapshot --quiet
          
        3. Hapus cluster GKE:

          gcloud container clusters delete ${KUBERNETES_CLUSTER_PREFIX}-cluster --location=${LOCATION} --quiet
          
        4. Hapus volume Persistent Disk dan Hyperdisk:

          gcloud compute disks delete ${PV_NAME} --location=${LOCATION} --quiet
          gcloud compute disks delete mysql-recovery --location=${LOCATION} --quiet
          

        Langkah berikutnya