你正在查看已归档的 TiDB 文档,该文档不再更新。

查看最新 LTS 版本文档

构建多个网络互通的 GCP GKE 集群

本文介绍了如何构建多个 GCP GKE 集群,并配置集群之间的网络互通,为跨 Kubernetes 集群部署 TiDB 集群作准备。

如果仅需要部署一个 TiDB 集群到一个 GCP GKE 集群,请参考在 GCP GKE 上部署 TiDB 集群文档。

环境准备

部署前,请确认已完成以下环境准备:

  • Helm 3:用于安装 TiDB Operator
  • gcloud:用于创建和管理 GCP 服务的命令行工具
  • 完成 GKE 快速入门 中的准备工作 (Before you begin)

配置 GCP 服务

使用以下命令,设置好你的 GCP 项目:

gcloud config set core/project <gcp-project>

第 1 步:创建网络

  1. 创建一个自定义子网的 VPC 网络。

    gcloud compute networks create ${network_name} --subnet-mode=custom
  2. 在新创建的 VPC 网络下创建三个属于不同 Region 的子网,子网的 CIDR block 相互不重叠。

    gcloud compute networks subnets create ${subnet_1} \ --region=${region_1} \ --network=${network_name} \ --range=10.0.0.0/16 \ --secondary-range pods=10.10.0.0/16,services=10.100.0.0/16
    gcloud compute networks subnets create ${subnet_2} \ --region=${region_2} \ --network=${network_name} \ --range=10.1.0.0/16 \ --secondary-range pods=10.11.0.0/16,services=10.101.0.0/16
    gcloud compute networks subnets create ${subnet_3} \ --region=${region_3} \ --network=${network_name} \ --range=10.2.0.0/16 \ --secondary-range pods=10.12.0.0/16,services=10.102.0.0/16

    ${subnet_1}${subnet_2}${subnet_3} 为三个不同子网的名字。

    参数 --range=10.0.0.0/16 指定集群的子网的 CIRD 块,所有集群的子网的 CIDR block 必须不相互重叠。

    参数 --secondary-range pods=10.11.0.0/16,services=10.101.0.0/16 中指定了 Kubernetes 的 Pod 与 Service 使用的 CIRD block,将会在后面使用到。

第 2 步:启动 Kubernetes 集群

创建三个 GKE 集群,每个集群使用上述创建的子网。

  1. 创建三个 GKE 集群,每个集群有一个默认的节点池:

    gcloud beta container clusters create ${cluster_1} \ --region ${region_1} --num-nodes 1 \ --network ${network_name} --subnetwork ${subnet_1} \ --cluster-dns clouddns --cluster-dns-scope vpc \ --cluster-dns-domain ${cluster_domain_1} --enable-ip-alias \ --cluster-secondary-range-name=pods --services-secondary-range-name=services
    gcloud beta container clusters create ${cluster_2} \ --region ${region_2} --num-nodes 1 \ --network ${network_name} --subnetwork ${subnet_2} \ --cluster-dns clouddns --cluster-dns-scope vpc \ --cluster-dns-domain ${cluster_domain_2} --enable-ip-alias \ --cluster-secondary-range-name=pods --services-secondary-range-name=services
    gcloud beta container clusters create ${cluster_3} \ --region ${region_3} --num-nodes 1 \ --network ${network_name} --subnetwork ${subnet_3} \ --cluster-dns clouddns --cluster-dns-scope vpc \ --cluster-dns-domain ${cluster_domain_3} --enable-ip-alias \ --cluster-secondary-range-name=pods --services-secondary-range-name=services

    上述命令中,${cluster_domain_n} 表示第 n 个集群的 cluster domain。在后续部署 TiDB 集群时,需要配置部署的 TidbCluster CR 中的 spec.clusterDomain

    使用 VPC 范围的 Cloud DNS 服务,使得集群可以解析其他集群的 Pod 和 Service 地址。

  2. 为每个集群创建 PD、TiKV 和 TiDB 使用的独立的节点池。

    以集群 1 为例:

    gcloud container node-pools create pd --cluster ${cluster_1} --machine-type n1-standard-4 --num-nodes=1 \ --node-labels=dedicated=pd --node-taints=dedicated=pd:NoSchedule gcloud container node-pools create tikv --cluster ${cluster_1} --machine-type n1-highmem-8 --num-nodes=1 \ --node-labels=dedicated=tikv --node-taints=dedicated=tikv:NoSchedule gcloud container node-pools create tidb --cluster ${cluster_1} --machine-type n1-standard-8 --num-nodes=1 \ --node-labels=dedicated=tidb --node-taints=dedicated=tidb:NoSchedule
  3. 获取每个集群的 Kubenetes context,后续当你使用 kubectl 命令操作特定的集群时,需要指定对应的 context。

    kubectl config get-contexts

    输出类似如下,其中的 NAME 项就是你后续需要使用的 context。

    CURRENT NAME CLUSTER AUTHINFO NAMESPACE * gke_pingcap_us-west1_tidb-1 gke_pingcap_us-west1_tidb-1 gke_pingcap_us-west1_tidb-1 gke_pingcap_us-west2_tidb-2 gke_pingcap_us-west2_tidb-2 gke_pingcap_us-west2_tidb-2 gke_pingcap_us-west3_tidb-3 gke_pingcap_us-west3_tidb-3 gke_pingcap_us-west3_tidb-3

    后文中,使用 ${context_1}${context_2}${context_3} 分别代表各个集群的 context。

配置防火墙规则

  1. 更新集群 1 的防火墙规则。

    1. 找到用于 GKE Pod 间通信的防火墙规则的名字,防火墙规则命名规则类似于:gke-${cluster_1}-${hash}-all

      gcloud compute firewall-rules list --filter='name~gke-${cluster_1}-.*-all'

      输出类似如下,其 NAME 项为规则的名字。

      NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED gke-${cluster_1}-b8b48366-all ${network} INGRESS 1000 tcp,udp,icmp,esp,ah,sctp False
    2. 更新该防火墙规则的 source range,加上另外两个集群的 Pod 网络的 CIDR block。

      gcloud compute firewall-rules update ${firewall_rule_name} --source-ranges 10.10.0.0/16,10.11.0.0/16,10.12.0.0/16

      你可以通过以下命令检查防火墙规则是否成功更新。

      gcloud compute firewall-rules describe ${firewall_rule_name}
  2. 按照步骤 1,更新集群 2 与集群 3 的防火墙规则。

第 3 步:验证网络连通性

在部署 TiDB 集群之前,你需要先验证多个集群之间的网络连通性。

  1. 将下面定义保存到 sample-nginx.yaml 文件。

    apiVersion: v1 kind: Pod metadata: name: sample-nginx labels: app: sample-nginx spec: hostname: sample-nginx subdomain: sample-nginx-peer containers: - image: nginx:1.21.5 imagePullPolicy: IfNotPresent name: nginx ports: - name: http containerPort: 80 restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: sample-nginx-peer spec: ports: - port: 80 selector: app: sample-nginx clusterIP: None
  2. 在三个集群对应的命名空间下部署 NGINX 服务。

    kubectl --context ${context_1} -n default apply -f sample-nginx.yaml kubectl --context ${context_2} -n default apply -f sample-nginx.yaml kubectl --context ${context_3} -n default apply -f sample-nginx.yaml
  3. 通过访问其他集群的 NGINX 服务,来验证网络是否连通。

    以验证集群 1 到集群 2 的网络连通性为例,执行以下命令。

    kubectl --context ${context_1} exec sample-nginx -- curl http://sample-nginx.sample-nginx-peer.default.svc.${cluster_domain_2}:80

    如果输出为 NGINX 的欢迎页面,那么就表明网络是正常连通的。

  4. 验证完成后,执行以下命令删除 NGINX 服务。

    kubectl --context ${context_1} -n default delete -f sample-nginx.yaml kubectl --context ${context_2} -n default delete -f sample-nginx.yaml kubectl --context ${context_3} -n default delete -f sample-nginx.yaml

第 4 步:部署 TiDB Operator

每个集群的 TidbCluster CR 由当前集群的 TiDB Operator 管理,因此每个集群都需要部署 TiDB Operator。

参考在 Kubernetes 上部署 TiDB Operator 部署 TiDB Operator 到每个 GKE 集群。区别在于,需要通过命令 kubectl --context ${context}helm --kube-context ${context} 为每个 GKE 集群部署 TiDB Operator。

第 5 步:部署 TiDB 集群

参考跨多个 Kubernetes 集群部署 TiDB 集群为每个集群部署一个 TidbCluster CR。需要注意的是:

例如,部署初始集群 TidbCluster CR 到集群 1 时,将 spec.clusterDomain 指定为 ${cluster_domain_1}:

apiVersion: pingcap.com/v1alpha1 kind: TidbCluster # ... spec: #.. clusterDomain: "${cluster_domain_1}"

探索更多