# 创建集群流程
TODO: 流程图
1. 用户在 console 上创建一个 tidb 机器，central server 接收到请求，往 MetaDB 中创建一条记录
2. central worker 查询 MetaDB cluster 表，调用 infra-api 创建 network 对象
3. infra-api network controller list-watch 到 network 对象的创建，调用 gardener 创建 shoot 对象
4. shoot 对象可以理解为一个 k8s 集群，gardener list-watch 到 shoot 对象的创建，会部署一个 k8s 集群
5. gardenlet 会先在 seed 集群中运行 k8s control-plane, 包括 etcd、k8s-apiserver 等等
6. control-plane ready 后，会创建两个 master node 用来运行 coredns、calico 等网络插件
7. infra-api 观察到 shoot apiserver ready 后，会往 shoot 集群中创建 tidb-operator、cert-manager、dbaas-proxy 等服务，一切完成后更新 network 为 ready 状态
8. central worker 发现 network ready 后调用 infra-api 创建 cluster 对象
9. infra-api list-watch 到 cluster 对象的创建，会往对应的 shoot 集群中创建 tidbcluster 对象
10. infra-api nodescaler controller 会根据 tidbcluster 的 spec 修改 shoot 对象上 spec.worker 字段，为 tidb 集群创建需要的 machine
11. shoot 集群中的 tidb-operator list-watch 到 tidbcluster 对象的创建，为 tidb、tikv、pd 等组件创建 asts 对象
12. infra-api cluster 对象为集群创建 public 和 private endpoint，一切 ready 后更新 cluster 的对象为 normal 状态

# 如何排查创建超时

在 ui 上可以看到集群创建的 3 个步骤，根据 ui 上执行的阶段排查对应的位置
1. 等待 infra 创建
2. provision node
3. 创建 tidb cluster

## 获取集群的 project-id 和 cluster-id
1. projectID 可以通过点击 ui 的 project，从浏览器的地址栏拿到
2. clusteriD 需要打开浏览器的 debug 模式，查看 get cluster 的请求，拿到返回结果的 cluster-id

## 排查 infra 创建超时
1. 获取 infra-api 的 kubeconfig, 下面的 server 地址是测试环境的 infra apiserver
> 在 base 集群里
```bash
kubectl get secret api-server-kubeconfig --template={{'.data.config'}} -n infra | base64 -D > ./infra-api-kubeconfig.yaml 
# 如果是 dev 环境
KUBECONFIG=./infra-api-kubeconfig.yaml kubectl config set-cluster infra --server=https://us-west-2.infra.shared.aws.tidbcloud.com:443
# 如果是 staging 环境
KUBECONFIG=./infra-api-kubeconfig.yaml kubectl config set-cluster infra --server=https://us-west-2.infra.staging.shared.aws.tidbcloud.com:443
```

2.  查看对应的 network 对象
```bash
KUBECONFIG=./infra-api-kubeconfig.yaml kubectl get network -n staging-<project-id>, NAME 由 <provider>-<region> 组成，SHOOT 为 gardener 集群中对应的 shoot 名称
1367526
NAME                 PHASE      SHOOT      BUCKET                                             AGE
aws-ap-northeast-1   Normal     d3fc4d48   dbaas-staging-ap-northeast-1-1369847559691367526   155m
aws-us-west-2        Creating   4a221015                                                      115m
gcp-us-west1         Normal     ab659d8a   dbaas-staging-us-west1-1369847559691367526         108m
```

3. 查看 network 的 event 可以看到 network 对象的创建集群，如果只有 `Setup shoot ab659d8a successful` 说明在等待 shoot ready
```
KUBECONFIG=./infra-api-kubeconfig.yaml kubectl describe network gcp-us-west1 -n staging-1369847559691367526
Events:
  Type     Reason                         Age                 From                Message
  ----     ------                         ----                ----                -------
  Normal   EnsureShootCidr                10m                 network-controller  Ensure shoot cidr 172.30.128.0/17 successful
  Normal   SetUpShoot                     10m                 network-controller  Setup shoot ab659d8a successful
  Normal   EnsureCertManager              3m3s                network-controller  Waiting cert manager webhook ready
  Normal   EnsureCertManager              2m11s               network-controller  Ensure cert-manager successful
  Normal   EnsureStorageClass             2m11s               network-controller  Ensure storage class successful
  Normal   EnsureTiDBClusterSLIReporter   2m10s               network-controller  Ensure tidb cluster SLI reporter successful
  Normal   EnsureTiDBClusterReporter      2m10s               network-controller  Ensure tidb cluster reporter successful
  Warning  FailedGracefulShutdownWebhook  2m9s                network-controller  unable to load certificates from secret tidb-admin/webhook-cert-secret: Secret "webhook-cert-secret" not found
  Normal   EnsureGracefulShutdownWebhook  66s                 network-controller  Ensure graceful shutdown webhook successful
  Normal   EnsureBucket                   66s                 network-controller  Ensure bucket successful
  Normal   EnsureGCPNodeRoles             64s                 network-controller  Ensure gcp node roles successful
  Normal   EnsureLocalProxy               6s (x3 over 2m10s)  network-controller  Ensure local proxy successful
  Normal   EnsureKMS                      3s                  network-controller  Ensure kms successful
  Normal   EnsureGCPDnsZone               3s                  network-controller  Ensure gcp dns zone successful
  Normal   EnsureGCPVPCNetwork            3s                  network-controller  Ensure gcp vpc network successful
  Normal   ObserveLocalProxy              3s                  network-controller  Observe local proxy successful
  Normal   SuccessfulReconcile            3s                  network-controller  Successful reconcile network gcp-us-west1
```

4. 查看对应 shoot 的状态
    1. 获取 gardener 集群的 kubeconfig
    >在 base 集群下
    ```bash
    kubectl get secret -n garden garden-kubeconfig-for-admin --template={{'.data.kubeconfig'}} | base64 -D > ./garden-kubeconfig.yaml
    ```

    2. 查看 shoot 对象的 event, 重点看 event 和 Last Operation 即可，通常 shoot 无法 ready event 可以直接看出来原因，shoot 无法 ready 是最常见的错误，后面列出常见的 shoot 错误。
    ```bash
    KUBECONFIG=./garden-kubeconfig.yaml kubectl describe shoot <SHOOT> -n garden-<ENV>
    ```

## 排查 privision node 超时
1. 查看 shoot 对象的 event 通常也可以知道 machine 为什么创建不出来
2. 如果没有异常错误，创建时间超过 5 mins 的话可以通过查看 machine 对象或者 machine controller 的日志
   1. 获取 seed 集群的 kubeconfig
   2. 根据 provider 和 region 切换到对应的 seed 集群
   3. 查看 control-plane 的运行情况
      ```
      kubectl get po -n shoot--<ENV>--<SHOOT>
      NAME                                          READY   STATUS    RESTARTS   AGE
      cloud-controller-manager-5ddd87887b-x2b7g     1/1     Running   0          122m
      etcd-events-0                                 2/2     Running   0          124m
      etcd-main-0                                   2/2     Running   0          124m
      gardener-resource-manager-5c97d5f476-l66dq    1/1     Running   0          121m
      kube-apiserver-7484866cc-mmh75                2/2     Running   0          114m
      kube-controller-manager-69c986874b-kqvmp      1/1     Running   0          121m
      kube-scheduler-84bf47bb46-7jfhm               1/1     Running   0          121m
      kube-state-metrics-864f4546f5-s549t           1/1     Running   0          117m
      machine-controller-manager-6fc9d5d49f-jhj9j   1/1     Running   0          122m
      prometheus-0                                  4/4     Running   0          41m
      ```
    4. 查看 machine 对象的状态
      ```
      kubectl get machine -n shoot--<ENV>--<SHOOT>
      ```

## 排查创建 tidbcluster 对象超时
1. 排查 tidbcluster 对象需要访问 shoot k8s 集群，最常见的方式是访问 ops 平台的 k8s dashboard, 地址如下: 
```
https://ops-dev.tidbcloud.com/
https://ops-staging.tidbcloud.com/
https://ops.tidbcloud.com/
```
2. 点击 Orgs，选择对应的租户，进入集群列表页，点击 k8s dashboard
3. 进入 k8s dashboard 后，点击 pod 页，查看 pod 是否 pending，以及 pending 的原因等

## 常见超时原因

### NatGatewayLimitExceeded
在查看 shoot event 的时候可以看到调用 AWS 请求返回的错误，需要在 AWS quota 申请提高 quota，排查是否存在泄漏

### Request limit exceeded
调用 cloud API 导致的超时

### Node can not join apiserver
大概率是 kube-controler-manager 没有运行起来，查看对应 seed 集群中 garden namespace 的 pod 运行情况，查看是否有 crash 的 pod