构建多个网络互通的 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}"

探索更多

文档内容是否有帮助?