使用 Amazon EKS 的 Amazon EBS CSI 驱动程序动态预配数据库存储
使用 Amazon EKS 的 Amazon EBS CSI 驱动程序动态预配数据库存储
在当今的云计算环境中,企业和 SaaS 平台在管理复杂的数据库和实时数据处理方面都面临着诸多挑战。这些场景需要既稳定又可扩展的存储解决方案。亚马逊云科技为包括 Amazon Elastic Block Store (EBS) 在内的各种存储服务提供了容器存储接口 (CSI) 驱动程序。通过这些驱动程序,您可以根据特定的工作负载需求选择适当的存储类型。尤其是 EBS CSI 驱动程序,它提供了一种 Kubernetes 原生方式,可在亚马逊云科技服务上预配和管理块存储。这样,您便能够动态预配存储、从故障中快速恢复、确保数据一致性,而且所有这些都可以在 Amazon EKS 的上下文中实现。无论您要处理的是 PostgreSQL、MySQL 还是 MongoDB 等自建数据库,EBS CSI 驱动程序都会简化这些存储解决方案的部署和扩展。
本教程以这一系列第 1 部分中建立的 Amazon EKS 集群为基础,将深入探讨如何设置 EBS CSI 驱动程序附加组件。在上一篇教程的集群配置中,我们安装并关联了 EBS CSI 驱动程序附加组件和 OpenID Connect (OIDC) 端点。有关如何创建集群,请参阅构建预配置运行高流量微服务的 Amazon EKS 集群。或者,若要使用本教程所需的组件设置现有集群,请按照 EKS 官方文档中的创建 IAM OpenID Connect (OIDC) 端点和创建服务账户的 IAM 角色 (IRSA) 中的说明进行操作。
在本教程中,您将使用安装在 Amazon EKS 集群上的 EBS CSI 驱动程序附加组件,以便为数据库存储动态预配 EBS 卷,还将部署 MySQL 数据库的示例工作负载。
前提条件
开始本教程学习之前,您需要:
概述
本教程是使用 Amazon EKS 管理高流量微服务平台系列的第二部分,专门介绍使用 EBS CSI 驱动程序实现动态预配和存储解决方案。本教程不仅会展示如何在集群内预配存储,还将介绍动态预配的概念。本教程包括以下部分:
- 身份验证:利用专为 EBS CSI 驱动程序设计且预配置的服务账户的 IAM 角色 (IRSA)。该角色在指定的亚马逊云科技可用区中使用,与 OpenID Connect (OIDC) 端点一起确保 Kubernetes Pod 和亚马逊云科技服务之间安全通信。
- EBS CSI 驱动程序附加组件设置:Amazon EKS 附加组件(如 EBS CSI 驱动程序附加组件)是精选的软件附加组件,包括最新的安全补丁和错误修复。亚马逊云科技管理控制台会通知您 Amazon EKS 附加组件的新版本。如果您选择手动安装 EBS CSI 驱动程序,则您有责任确保其为最新版本。请注意,EBS 卷绑定到特定的亚马逊云科技可用区,并且只能通过同一可用区内的节点访问,因此适用于在同一可用区内运行节点的工作负载。
- 示例应用程序部署:使用示例 MySQL 数据库为自建数据库构建和预配存储。利用 EBS CSI 驱动程序的自定义注解和参数,特别是“ReadWriteOnce”访问模式,指示 EBS CSI 驱动程序处理数据库的存储预配操作。如需了解更多示例,请参阅 EBS CSI 驱动程序 GitHub 存储库中的示例。
请注意,如果您仍处于刚开始的为期 12 个月的亚马逊云科技免费套餐期限内,务必要关注,若 EBS 卷的使用量超出免费套餐限额,将会产生额外的亚马逊云科技费用。
步骤 1:配置集群环境变量
在使用 Helm 或其他命令行工具与您的 Amazon EKS 集群进行交互之前,定义封装集群详细信息的特定环境变量是必不可少的。这些变量将在后续命令中使用,以确保命令运行在正确的集群和资源上。
1. 首先,确认您在正确的集群上下文中操作。这样可以确保任何后续命令都能发送到预期的 Kubernetes 集群。您可以通过执行以下命令来验证当前上下文:
kubectl config current-context
2. 为您的 EKS 集群定义 CLUSTER_NAME 环境变量。请将 region 的示例值替换为实际值。
export CLUSTER_NAME=$(aws eks describe-cluster --region us-east-2 --name managednodes-quickstart --query "cluster.name" --output text)
3. 为您的 EKS 集群定义 CLUSTER_REGION 环境变量。请将 region 的示例值替换为实际值。
export CLUSTER_REGION=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.arn" --output text | cut -d: -f4)
4. 为您的 EKS 集群定义 CLUSTER_VPC 环境变量。
export CLUSTER_VPC=$(aws eks describe-cluster --name ${CLUSTER_NAME} --region ${CLUSTER_REGION} --query "cluster.resourcesVpcConfig.vpcId" --output text)
5. 为与您的 EKS 集群关联的账户定义 ACCOUNT_ID 环境变量。
export ACCOUNT_ID=$(aws eks describe-cluster --name ${CLUSTER_NAME} --region ${CLUSTER_REGION} --query "cluster.arn" --output text | cut -d':' -f5)
步骤 2:验证或创建 IAM 角色和服务账户
ebs-csi-controller-sa 服务账户对于在 Kubernetes 中管理 EBS 卷至关重要。请确保在集群上 kube-system 命名空间的设置正确无误。
kubectl get sa ebs-csi-controller-sa -n kube-system -o yaml
输出结果应如下所示:
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::111111111111:role/AmazonEKS_EBS_CSI_DriverRole
creationTimestamp: "2023-08-17T00:20:02Z"
labels:
app.kubernetes.io/component: csi-driver
app.kubernetes.io/managed-by: EKS
app.kubernetes.io/name: aws-ebs-csi-driver
app.kubernetes.io/version: 1.21.0
name: ebs-csi-controller-sa
namespace: kube-system
resourceVersion: "14579"
uid: faab5e29-76bc-4a04-8f73-7906a5621050
如果您还没有为 EBS CSI 驱动程序设置服务账户的 IAM 角色 (IRSA),或者执行上述命令后收到错误提示,可以使用以下命令创建服务账户的 IAM 角色 (IRSA) 以及服务账户名称 ebs-csi-controller-sa。请注意,在运行此命令之前,确认您的集群已经关联了一个 OpenID Connect (OIDC) 端点。
eksctl create iamserviceaccount \
--name ebs-csi-controller-sa \
--namespace kube-system \
--region ${CLUSTER_REGION} \
--cluster ${CLUSTER_NAME} \
--role-name `AmazonEKS_EBS_CSI_DriverRole` \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--approve
步骤 3:验证或安装 EBS CSI 驱动程序附加组件
使用以下命令验证是否已安装 Amazon EBS CSI 驱动程序附加组件:
kubectl get deployment ebs-csi-controller -n kube-system
输出结果应如下所示:
NAME READY UP-TO-DATE AVAILABLE AGE
ebs-csi-controller 2/2 2 2 101m
(可选)如果您还没有安装 EBS CSI 驱动程序附加组件,或者收到错误提示,可以运行以下命令安装该附加组件。
eksctl create addon \
--name aws-ebs-csi-driver \
--cluster ${CLUSTER_NAME} \
--region ${CLUSTER_REGION} \
--service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole \
--force
输出结果应该如下所示:
2023-08-19 10:13:14 [ℹ] creating addon
步骤 4:创建 Kubernetes 密钥
这一步将创建 Kubernetes 密钥,以安全存储 MySQL 凭证。通过使用密钥,可以在应用程序代码和配置文件之外保存密码和用户名等敏感信息。这样,可以将对这些信息的访问权限与应用程序的其余部分分开管理,从而增强了应用程序的安全性。密钥将在 StatefulSet 中引用,为 MySQL 容器提供必要的环境变量。
1. 创建 .env 文件,并粘贴以下内容。
MYSQL_ROOT_PASSWORD=my-secret-pw
MYSQL_USER=test-user
MYSQL_PASSWORD=my-secret-user-pw
MYSQL_DATABASE=sample
2. 在刚刚创建的 .env 文件所在的目录中,运行以下命令,创建包含敏感凭证的 Kubernetes 密钥。
kubectl create secret generic mysql-secrets --from-env-file=.env
步骤 5:部署 MySQL 数据库
以下文件包含在 Amazon EKS 集群上设置 Amazon EBS CSI 驱动程序所需的 Kubernetes 清单。它定义了一个名为 ebs-sc 的 StorageClass,用于在 Amazon EBS 上设置存储预配,并具有等待第一个消费者的绑定模式;还定义了一个名为 mysql-ebs 的 Pod,该 Pod 运行 Linux 操作系统容器。另外,还将 EBS CSI 驱动程序指定为预配程序(即 ebs.csi.aws.com)。这些组成部分一起提供了在 Kubernetes 集群中定义、声明和使用持久存储的完整示例。
1. 创建一个名为 mysql-ebs.yaml 的 Kubernetes 清单,并粘贴以下内容。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-ebs
namespace: default
labels:
app.kubernetes.io/team: database
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: mysql-ebs
serviceName: mysql
template:
metadata:
labels:
app.kubernetes.io/component: mysql-ebs
app.kubernetes.io/team: database
spec:
containers:
- name: mysql
image: "public.ecr.aws/docker/library/mysql:5.7"
args:
- "--ignore-db-dir=lost+found"
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: mysql-secrets
ports:
- name: mysql
containerPort: 3306
protocol: TCP
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: gp2
resources:
requests:
storage: 30Gi
2. 部署 mysql-ebs.yaml 中的 Kubernetes 资源:
kubectl apply -f mysql-ebs.yaml
部署工作负载时,EBS CSI 驱动程序使用 StorageClass 根据指定的配置预配 EBS 卷。StatefulSet 中的 volumeClaimTemplates 定义卷所需的属性,例如 accessModes、storageClassName 和资源请求。然后,EBS CSI 驱动程序将卷绑定到 StatefulSet 的 Pod,从而允许 MySQL 容器使用持久存储。
步骤 6:验证卷是否挂载到 Pod
这一步将使用以下命令,验证卷是否已动态预配并挂载:
kubectl exec --stdin mysql-ebs-0 -- bash -c "df -h"
可以看到 Linux 操作系统上最近附加的 EBS 卷。如果一切正常运行,您应当会在 /var/lib/mysql 路径下看到 30 GB 的卷。这就证实了 Pod 已成功创建卷并将其附加到 Linux 操作系统。输出结果应如下所示:
Filesystem Size Used Avail Use% Mounted on
overlay 80G 2.8G 78G 4% /
tmpfs 64M 0 64M 0% /dev
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/nvme0n1p1 80G 2.8G 78G 4% /etc/hosts
/dev/nvme1n1 30G 211M 30G 1% /var/lib/mysql
tmpfs 6.9G 12K 6.9G 1% /run/secrets/[kubernetes.io/serviceaccount](http://kubernetes.io/serviceaccount)
tmpfs 3.8G 0 3.8G 0% /proc/acpi
tmpfs 3.8G 0 3.8G 0% /sys/firmware
清理资源
# Delete the MySQL deployment (Pod)
kubectl delete pods mysql-ebs-0
# Delete the PersistentVolumeClaim (PVC)
kubectl delete pvc data-mysql-ebs-0
# Delete the StorageClass
kubectl delete sc ebs-sc
# Delete the EBS CSI Driver Add-On
eksctl delete addon --name aws-ebs-csi-driver --cluster ${CLUSTER_NAME}
总结
完成本教程后,您便学习了在 Amazon EKS 集群上使用 EBS CSI 驱动程序为有状态工作负载设置数据存储的复杂过程。此学习之旅内容全面,包括部署示例应用程序和配置对确保系统安全稳定至关重要的基本组件。完成本教程后,您不仅设置了用于动态预配 Amazon EBS 卷的 EBS CSI 驱动程序,而且还为实现可扩展的弹性存储解决方案奠定了基础。要进一步增强您的新设置,可探索实现其他功能,例如调度卷、生成卷快照和调整卷大小的功能。如需了解更多信息,请参阅 GitHub 上的 EBS CSI 驱动程序文档。