本教程演示了如何将现有 MySQL 数据从 Persistent Disk (PD) 迁移到 Google Kubernetes Engine 上的 Hyperdisk,以提升存储性能。Hyperdisk 的 IOPS 和吞吐量高于 Persistent Disk,因此可以缩短数据库查询和事务的延迟时间,从而提升 MySQL 性能。您可以使用 磁盘快照 将数据迁移到不同的磁盘类型,具体取决于机器类型兼容性。例如,Hyperdisk 卷仅与某些第三代、第四代及更高版本的机器类型(例如不支持 Persistent Disk 的 N4)兼容。如需了解详情,请参阅可用的机器系列。
为了演示从 Persistent Disk 到 Hyperdisk 的迁移,本教程使用 Sakila 数据库 提供示例数据集。Sakila 是 MySQL 提供的示例数据库,您可以将其用作教程和示例的架构。它代表一家虚构的 DVD 租赁商店,包含影片、演员、客户和租赁的表。
本指南适用于负责创建和分配存储空间以及管理数据安全和数据访问权限的存储专家和存储管理员。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
部署架构
下图展示了从 Persistent Disk 到 Hyperdisk 的迁移过程。
- MySQL 应用在具有 N2 机器类型的 GKE 节点池池上运行,并将其数据存储在 Persistent Disk SSD 上。
- 为了确保数据一致性,应用会纵向缩容,以防止写入新数据。
- 系统会创建 Persistent Disk 的快照,作为数据的完整时间点备份。
- 系统会根据快照预配新的 Hyperdisk,并在单独的 Hyperdisk 兼容型 N4 节点池部署新的 MySQL 实例。此新实例会挂接到新创建的 Hyperdisk,从而完成向高性能存储空间的迁移。
目标
在本教程中,您将学习如何执行以下操作:
- 部署 MySQL 集群。
- 上传测试数据集。
- 创建数据的快照。
- 根据快照创建 Hyperdisk。
- 在启用 Hyperdisk 的 N4 机器类型节点池中启动新的 MySQL 集群。
- 验证数据完整性以确认迁移成功。
费用
在本文档中,您将使用的以下收费组件: Google Cloud
- GKE
- Compute Engine, which includes:
- Storage capacity provisioned for both Persistent Disk and Hyperdisk.
- Storage costs for the snapshots.
您可使用 价格计算器 根据您的预计使用情况来估算费用。
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud新手, 请创建一个账号来评估我们的产品在 实际场景中的表现。新客户还可获享 $300 赠金,用于 运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, GKE, Identity and Access Management Service Account Credentials APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, GKE, Identity and Access Management Service Account Credentials APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
确保您在项目中拥有以下一个或多个角色: roles/container.admin、roles/iam.serviceAccountAdmin、roles/compute.admin
检查角色
-
在 Google Cloud 控制台中,前往 IAM 页面。
转到 IAM - 选择项目。
-
在主账号 列中,找到标识您或您所属群组的所有行。如需了解您属于哪些群组,请与您的 管理员联系。
- 对于指定或包含您的所有行,请检查角色 列以查看 角色列表是否包含所需的角色。
授予角色
-
在 Google Cloud 控制台中,前往 IAM 页面。
转到 IAM - 选择项目。
- 点击 授予访问权限。
-
在新的主账号 字段中,输入您的用户标识符。 这通常是 Google 账号的电子邮件地址。
- 点击选择角色,然后搜索相应角色。
- 如需授予其他角色,请点击 添加其他角色 ,然后添加其他各个角色。
- 点击 Save (保存)。
-
设置 Cloud Shell
-
在 Google Cloud 控制台中,激活 Cloud Shell。
Cloud Shell 会话随即会在控制台的底部启动,并显示命令行提示符。 Google Cloud Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟来完成初始化。
- 设置默认项目:
gcloud config set project PROJECT_ID将
PROJECT_ID替换为您的项目 ID。
Cloud Shell 会话随即会启动并显示命令行提示符。该会话可能需要几秒钟来完成初始化。
准备环境
在 Cloud Shell 中,为您的项目、位置和集群前缀设置环境变量。
export PROJECT_ID=PROJECT_ID export EMAIL_ADDRESS=EMAIL_ADDRESS export KUBERNETES_CLUSTER_PREFIX=offline-hyperdisk-migration export LOCATION=us-central1-a替换以下内容:
PROJECT_ID:您的 Google Cloud 项目 ID。EMAIL_ADDRESS:您的电子邮件地址。LOCATION:您要在其中创建部署资源的可用区。在本教程中,请使用us-central1-a可用区。
从 GitHub 克隆示例代码库:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples转到
offline-hyperdisk-migration目录以开始创建部署资源:cd kubernetes-engine-samples/databases/offline-hyperdisk-migration
创建 GKE 集群和节点池
为简单起见,本教程使用可用区级集群,因为 Hyperdisk 卷是可用区级资源,只能在单个可用区内访问。
创建可用区级 GKE 集群:
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"添加具有 N2 机器类型的节点池,用于初始 MySQL 部署:
gcloud container node-pools create regular-pool \ --cluster ${KUBERNETES_CLUSTER_PREFIX}-cluster \ --machine-type n2-standard-4 \ --location ${LOCATION} \ --num-nodes 1添加具有 N4 机器类型的 Hyperdisk 节点池,MySQL 部署将迁移到该节点池并在此运行:
gcloud container node-pools create hyperdisk-pool \ --cluster ${KUBERNETES_CLUSTER_PREFIX}-cluster \ --machine-type n4-standard-4 \ --location ${LOCATION} \ --num-nodes 1连接到该集群:
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${LOCATION}
在 Persistent Disk 上部署 MySQL
在本部分中,您将部署使用 Persistent Disk 进行存储的 MySQL 实例,并向其加载示例数据。
为 Hyperdisk 创建并应用
StorageClass。本教程稍后将使用此StorageClass。kubectl apply -f manifests/01-storage-class/storage-class-hdb.yaml创建并部署 MySQL 实例,该实例包含节点亲和性,以确保 Pod 安排在
regular-pool节点上,并预配 Persistent Disk SSD 卷。kubectl apply -f manifests/02-mysql/mysql-deployment.yaml此清单会创建 MySQL 部署和服务,并动态预配 Persistent Disk 以进行数据存储。
root用户的密码为migration。部署 MySQL 客户端 Pod 以加载数据,并验证数据迁移:
kubectl apply -f manifests/02-mysql/mysql-client.yaml kubectl wait pods mysql-client --for condition=Ready --timeout=300s连接到客户端 Pod:
kubectl exec -it mysql-client -- bash从客户端 Pod shell 中,下载并导入 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 / # 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;验证数据是否已导入:
USE sakila; SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'sakila';输出会显示包含行数的表列表。
| 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)退出
mysql会话:exit;退出客户端 Pod shell:
exit获取为 MySQL 创建的 PersistentVolume (PV) 的名称,并将其存储在环境变量中:
export PV_NAME=$(kubectl get pvc mysql-pv-claim -o jsonpath='{.spec.volumeName}')
将数据迁移到 Hyperdisk 卷
现在,您有一个 MySQL 工作负载,其数据存储在 Persistent Disk SSD 卷上。本部分介绍如何使用快照将此数据迁移到 Hyperdisk 卷。此迁移方法还会保留原始 Persistent Disk 卷,以便您在必要时回滚到使用原始 MySQL 实例。
虽然您可以从磁盘创建快照,而无需将其与工作负载分离,但为了确保 MySQL 的数据完整性,您必须在创建快照期间阻止向磁盘写入任何新数据。将 MySQL 部署纵向缩容到
0个副本以停止写入:kubectl scale deployment existing-mysql --replicas=0从现有 Persistent Disk 创建快照:
gcloud compute disks snapshot ${PV_NAME} --zone=${LOCATION} --snapshot-names=original-snapshot --description="snapshot taken from pd-ssd"根据快照创建名为
mysql-recovery的新 Hyperdisk 卷:gcloud compute disks create mysql-recovery --project=${PROJECT_ID} \ --type=hyperdisk-balanced \ --size=150GB --zone=${LOCATION} \ --source-snapshot=projects/${PROJECT_ID}/global/snapshots/original-snapshot使用您的项目 ID 更新已恢复 PV 的清单文件:
sed -i "s/PRJCTID/$PROJECT_ID/g" manifests/02-mysql/restore_pv.yaml根据新的 Hyperdisk 创建 PersistentVolume (PVC) 和 PersistentVolumeClaim:
kubectl apply -f manifests/02-mysql/restore_pv.yaml
验证数据迁移
部署使用新创建的 Hyperdisk 卷的新 MySQL 实例。此 Pod 将安排在由 N4 节点组成的 hyperdisk-pool
节点池池上。
部署新的 MySQL 实例:
kubectl apply -f manifests/02-mysql/recovery_mysql_deployment.yaml如需验证数据完整性,请再次连接到 MySQL 客户端 Pod:
kubectl exec -it mysql-client -- bash在客户端 Pod 中,连接到新的 MySQL 数据库 (
recovered-mysql.default) 并验证数据。密码为migration。mysql -u root -h recovered-mysql.default -p USE sakila; SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'sakila';数据应与 Persistent Disk 卷上的原始 MySQL 实例中的数据 相同。
退出
mysql会话:exit;退出客户端 Pod shell:
exit
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
删除项目: Google Cloud
gcloud projects delete PROJECT_ID
删除各个资源
如果您使用的是现有项目,并且不想将其删除,请逐个删除资源:
设置清理环境变量,并检索由
mysql-pv-claimPersistentVolumeClaim 创建的 Persistent Disk 卷的名称: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}')将
PROJECT_ID替换为您的项目 ID。删除该快照:
gcloud compute snapshots delete original-snapshot --quiet删除 GKE 集群:
gcloud container clusters delete ${KUBERNETES_CLUSTER_PREFIX}-cluster --location=${LOCATION} --quiet删除 Persistent Disk 卷和 Hyperdisk 卷:
gcloud compute disks delete ${PV_NAME} --zone=${LOCATION} --quiet gcloud compute disks delete mysql-recovery --zone=${LOCATION} --quiet
后续步骤
- 查看 GKE 示例 GitHub 代码库中的更多代码示例。
- 了解如何使用 Hyperdisk 卷扩缩存储性能。
- 了解如何使用 Compute Engine Persistent Disk CSI 驱动程序管理 Persistent Disk 卷和 Hyperdisk 卷。
- 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud 架构中心。