1.2.3.1.1 在 AWS EKS 上部署 TiDB 集群

本节介绍如何使用个人电脑(Linux 或 macOS 系统)在 AWS EKS (Elastic Kubernetes Service) 上部署 TiDB 集群。

1. 环境配置准备

部署前,请确认已安装以下软件并完成配置:

  • awscli >= 1.16.73,控制 AWS 资源

    要与 AWS 交互,必须。最快的方式是使用 aws configure 命令:

    替换下面的 AWS Access Key ID 和 AWS Secret Access Key:

    1. AWS Access Key ID [None]: IOSFODNN7EXAMPLE
    2. AWS Secret Access Key [None]: wJaXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    3. Default region name [None]: us-west-2
    4. Default output format [None]: json
  • terraform >= 0.12

  • >= 1.11
  • helm >= 2.11.0 且 < 3.0.0
  • aws-iam-authenticator,AWS 权限鉴定工具,确保安装在 PATH 路径下。

    最简单的安装方法是下载编译好的二进制文件 aws-iam-authenticator,如下所示。

    Linux 用户下载二进制文件:

    1. curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.12.7/2019-03-27/bin/linux/amd64/aws-iam-authenticator

    macOS 用户下载二进制文件:

    1. curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.12.7/2019-03-27/bin/darwin/amd64/aws-iam-authenticator

    二进制文件下载完成后,执行以下操作:

    1. chmod +x ./aws-iam-authenticator && \
    2. sudo mv ./aws-iam-authenticator /usr/local/bin/aws-iam-authenticator

2. 部署集群

默认部署会创建一个新的 VPC、一个 t2.micro 实例作为堡垒机,并包含以下 ec2 实例作为工作节点的 EKS 集群:

  • 3 台 m5.xlarge 实例,部署 PD
  • 3 台 c5d.4xlarge 实例,部署 TiKV
  • 2 台 c5.4xlarge 实例,部署 TiDB
  • 1 台 c5.2xlarge 实例,部署监控组件

使用如下命令部署集群。

从 Github 克隆代码并进入指定路径:

  1. git clone --depth=1 https://github.com/pingcap/tidb-operator && \
  2. cd tidb-operator/deploy/aws

使用 terraform 命令初始化并部署集群:

  1. terraform init
  1. terraform apply

注意:

terraform apply 过程中必须输入 “yes” 才能继续。

整个过程可能至少需要 10 分钟。terraform apply 执行成功后,控制台会输出类似如下的信息:

可以通过 terraform output 命令再次获取上面的输出信息。

注意:

3. 访问数据库

terraform apply 完成后,可先通过 ssh 远程连接到堡垒机,再通过 MySQL client 来访问 TiDB 集群。

所需命令如下(用上面的输出信息替换 <> 部分内容):

  1. ssh -i credentials/<eks_name>.pem centos@<bastion_ip>
  1. mysql -h <default-cluster_tidb-dns> -P 4000 -u root

eks_name 默认为 my-cluster。如果 DNS 名字无法解析,请耐心等待几分钟。

还可以通过 kubectlhelm 命令使用 kubeconfig 文件 credentials/kubeconfig_<eks_name> 和 EKS 集群交互,主要有两种方式,如下所示。

  • 指定 —kubeconfig 参数:

    1. kubectl --kubeconfig credentials/kubeconfig_<eks_name> get po -n <default_cluster_name>
    1. helm --kubeconfig credentials/kubeconfig_<eks_name> ls
  • 或者,设置 KUBECONFIG 环境变量:

    1. export KUBECONFIG=$PWD/credentials/kubeconfig_<eks_name>
    1. kubectl get po -n <default_cluster_name>
    1. helm ls

可以通过浏览器访问 <monitor-dns>:3000 地址查看 Grafana 监控指标。

Grafana 默认登录信息:

  • 用户名:admin
  • 密码:admin

5. 升级 TiDB 集群

要升级 TiDB 集群,可在 terraform.tfvars 文件中设置 default_cluster_version 变量到更高版本,然后运行 terraform apply

例如,要升级 TiDB 集群到 4.0.1,则修改 default_cluster_versionv4.0.1

6. 扩容 TiDB 集群

若要扩容 TiDB 集群,可在 terraform.tfvars 文件中设置 default_cluster_tikv_count 或者 default_cluster_tidb_count 变量,然后运行 terraform apply

例如,可以将 default_cluster_tidb_count 从 2 改为 4 以扩容 TiDB:

  1. default_cluster_tidb_count = 4

注意:

  • 由于缩容过程中无法确定会缩掉哪个节点,目前还不支持 TiDB 集群的缩容。
  • 扩容过程会持续几分钟,可以通过 kubectl --kubeconfig credentials/kubeconfig_<eks_name> get po -n <default_cluster_name> --watch 命令持续观察进度。

7. 自定义

可以按需在 terraform.tfvars 文件中设置各个变量,例如集群名称和镜像版本等。

由于 TiDB 服务通过 暴露,默认情况下,会创建一个 Amazon EC2 实例作为堡垒机,访问创建的 TiDB 集群。堡垒机上预装了 MySQL 和 Sysbench,所以可以通过 SSH 方式登陆到堡垒机后通过 ELB 访问 TiDB。如果的 VPC 中已经有了类似的 EC2 实例,可以通过设置 create_bastionfalse 禁掉堡垒机的创建。

TiDB 版本和组件数量也可以在 terraform.tfvars 中修改,可以按照自己的需求配置。

Terraform 脚本中为运行在 EKS 上的 TiDB 集群提供了合理的默认配置。有自定义需求时,可以在 clusters.tf 中通过 override_values 参数为每个 TiDB 集群指定一个 values.yaml 文件来自定义集群参数配置。

作为例子,默认集群使用了 ./default-cluster.yaml 作为 values.yaml 配置文件,并在配置中打开了”配置文件滚动更新”特性。

值得注意的是,在 EKS 上部分配置项无法在 values.yaml 中进行修改,包括集群版本、副本数、NodeSelector 以及 TolerationsNodeSelectorTolerations 由 Terraform 直接管理以确保基础设施与 TiDB 集群之间的一致性。集群版本和副本数可以通过 cluster.tf 文件中的 tidb-cluster module 参数来修改。

注意:

  1. pd:
  2. storageClassName: ebs-gp2
  3. tikv:
  4. stroageClassName: local-storage
  5. tidb:
  6. service:
  7. type: LoadBalancer
  8. annotations:
  9. service.beta.kubernetes.io/aws-load-balancer-internal: '0.0.0.0/0'
  10. service.beta.kubernetes.io/aws-load-balancer-type: nlb
  11. service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: >'true'
  12. separateSlowLog: true
  13. monitor:
  14. storage: 100Gi
  15. storageClassName: ebs-gp2
  16. persistent: true
  17. grafana:
  18. config:
  19. GF_AUTH_ANONYMOUS_ENABLED: "true"
  20. service:
  21. type: LoadBalancer

可以通过在 terraform.tfvars 中设置 operator_values 参数传入自定义的 内容来配置 TiDB Operator。示例如下:

  1. operator_values = "./operator_values.yaml"
  2. }

一个 tidb-cluster 模块的实例对应一个 TiDB 集群,可以通过编辑 clusters.tf 添加新的 tidb-cluster 模块实例来新增 TiDB 集群,示例如下:

  1. module example-cluster {
  2. source = "../modules/aws/tidb-cluster"
  3. eks = local.eks
  4. # The subnets of node pools of this TiDB cluster, required
  5. subnets = local.subnets
  6. # TiDB cluster name, required
  7. cluster_name = "example-cluster"
  8. # Helm values file
  9. override_values = file("example-cluster.yaml")
  10. # TiDB cluster version
  11. cluster_version = "v3.0.0"
  12. # SSH key of cluster nodes
  13. ssh_key_name = module.key-pair.key_name
  14. # PD replica number
  15. pd_count = 3
  16. # TiKV instance type
  17. pd_instance_type = "t2.xlarge"
  18. # TiKV replica number
  19. tikv_count = 3
  20. # TiKV instance type
  21. tikv_instance_type = "t2.xlarge"
  22. # The storage class used by TiKV, if the TiKV instance type do not have local SSD, you should change it to storage class
  23. # TiDB replica number
  24. tidb_count = 2
  25. # TiDB instance type
  26. tidb_instance_type = "t2.xlarge"
  27. # Monitor instance type
  28. monitor_instance_type = "t2.xlarge"
  29. # The version of tidb-cluster helm chart
  30. tidb_cluster_chart_version = "v1.0.0"
  31. # Decides whether or not to create the tidb-cluster helm release.
  32. # If this variable is set to false, you have to
  33. # install the helm release manually
  34. create_tidb_cluster_release = true
  35. }

可以通过 kubectl 获取新集群的监控系统地址与 TiDB 地址。假如希望让 Terraform 脚本输出这些地址,可以通过在 outputs.tf 中增加相关的输出项实现:

  1. output "example-cluster_tidb-hostname" {
  2. value = module.example-cluster.tidb_hostname
  3. }
  4. output "example-cluster_monitor-hostname" {
  5. value = module.example-cluster.monitor_hostname
  6. }

修改完成后,执行 terraform initterraform apply 创建集群。

最后,只要移除 tidb-cluster 模块调用,对应的 TiDB 集群就会被销毁,EC2 资源也会随之释放。

9. 仅管理基础设施

通过调整配置,可以控制 Terraform 脚本只创建 Kubernetes 集群和 TiDB Operator。操作步骤如下:

  • 修改 clusters.tf 中 TiDB 集群的 create_tidb_cluster_release 配置项:

    1. module "default-cluster" {
    2. ...
    3. create_tidb_cluster_release = false
    4. }

    如上所示,当 create_tidb_cluster_release 设置为 false 时,Terraform 脚本不会创建和修改 TiDB 集群,但仍会创建 TiDB 集群所需的计算和存储资源。此时,可以使用 Helm 等工具来独立管理集群。

注意:

在已经部署的集群上将 create_tidb_cluster_release 调整为 false 会导致已安装的 TiDB 集群被删除,对应的 TiDB 集群对象也会随之被删除。

10. 销毁集群

可以通过如下命令销毁集群:

  1. terraform destroy

注意:

  • 该操作会销毁 EKS 集群以及部署在该 EKS 集群上的所有 TiDB 集群。
  • 如果不再需要存储卷中的数据,在执行 terraform destroy 后,需要在 AWS 控制台手动删除 EBS 卷。

11. 管理多个 Kubernetes 集群

本节详细介绍了如何管理多个 Kubernetes 集群(EKS),并在每个集群上部署一个或更多 TiDB 集群。

上述文档中介绍的 Terraform 脚本组合了多个 Terraform 模块:

  • tidb-operator 模块,用于创建 EKS 集群并在 EKS 集群上安装配置 TiDB Operator
  • tidb-cluster 模块,用于创建 TiDB 集群所需的资源池并部署 TiDB 集群。
  • EKS 上的 TiDB 集群专用的 vpc 模块、key-pair模块和bastion 模块

管理多个 Kubernetes 集群的最佳实践是为每个 Kubernetes 集群创建一个单独的目录,并在新目录中自行组合上述 Terraform 模块。这种方式能够保证多个集群间的 Terraform 状态不会互相影响,也便于自由定制和扩展。下面是一个例子:

deploy/aws-staging/main.tf 的内容可以是:

  1. provider "aws" {
  2. region = "us-west-1"
  3. }
  4. # 创建一个 ssh key,用于登录堡垒机和 Kubernetes 节点
  5. module "key-pair" {
  6. source = "../modules/aws/key-pair"
  7. name = "another-eks-cluster"
  8. path = "${path.cwd}/credentials/"
  9. }
  10. # 创建一个新的 VPC
  11. module "vpc" {
  12. source = "../modules/aws/vpc"
  13. vpc_name = "another-eks-cluster"
  14. }
  15. # 在上面的 VPC 中创建一个 EKS 并部署 tidb-operator
  16. module "tidb-operator" {
  17. source = "../modules/aws/tidb-operator"
  18. eks_name = "another-eks-cluster"
  19. config_output_path = "credentials/"
  20. vpc_id = module.vpc.vpc_id
  21. ssh_key_name = module.key-pair.key_name
  22. }
  23. # 特殊处理,确保 helm 操作在 EKS 创建完毕后进行
  24. resource "local_file" "kubeconfig" {
  25. depends_on = [module.tidb-operator.eks]
  26. sensitive_content = module.tidb-operator.eks.kubeconfig
  27. filename = module.tidb-operator.eks.kubeconfig_filename
  28. }
  29. provider "helm" {
  30. alias = "eks"
  31. insecure = true
  32. install_tiller = false
  33. kubernetes {
  34. config_path = local_file.kubeconfig.filename
  35. }
  36. }
  37. # 在上面的 EKS 集群上创建一个 TiDB 集群
  38. module "tidb-cluster-a" {
  39. source = "../modules/aws/tidb-cluster"
  40. providers = {
  41. helm = "helm.eks"
  42. }
  43. cluster_name = "tidb-cluster-a"
  44. eks = module.tidb-operator.eks
  45. ssh_key_name = module.key-pair.key_name
  46. subnets = module.vpc.private_subnets
  47. }
  48. # 在上面的 EKS 集群上创建另一个 TiDB 集群
  49. module "tidb-cluster-b" {
  50. source = "../modules/aws/tidb-cluster"
  51. providers = {
  52. helm = "helm.eks"
  53. }
  54. cluster_name = "tidb-cluster-b"
  55. eks = module.tidb-operator.eks
  56. ssh_key_name = module.key-pair.key_name
  57. subnets = module.vpc.private_subnets
  58. }
  59. # 创建一台堡垒机
  60. module "bastion" {
  61. source = "../modules/aws/bastion"
  62. bastion_name = "another-eks-cluster-bastion"
  63. key_name = module.key-pair.key_name
  64. public_subnets = module.vpc.public_subnets
  65. vpc_id = module.vpc.vpc_id
  66. target_security_group_id = module.tidb-operator.eks.worker_security_group_id
  67. enable_ssh_to_workers = true
  68. }
  69. # 输出 tidb-cluster-a 的 TiDB 服务地址
  70. output "cluster-a_tidb-dns" {
  71. description = "tidb service endpoints"
  72. value = module.tidb-cluster-a.tidb_hostname
  73. }
  74. # 输出 tidb-cluster-b 的监控地址
  75. output "cluster-b_monitor-dns" {
  76. description = "tidb service endpoint"
  77. value = module.tidb-cluster-b.monitor_hostname
  78. }
  79. # 输出堡垒机 IP
  80. output "bastion_ip" {
  81. description = "Bastion IP address"
  82. value = module.bastion.bastion_ip
  83. }

上面的例子很容易进行定制,比如,假如不需要堡垒机,便可以删去对 bastion 模块的调用。同时,项目中提供的 Terraform 模块均设置了合理的默认值,因此在调用这些 Terraform 模块时,可以略去大部分的参数。

可以参考默认的 Terraform 脚本来定制每个模块的参数,也可以参考每个模块的 variables.tf 文件来了解所有可配置的参数。

另外,这些 Terraform 模块可以很容易地集成到自己的 Terraform 工作流中。假如对 Terraform 非常熟悉,这也是我们推荐的一种使用方式。