在 Kubernetes 上部署 TDengine 集群

作为面向云原生架构设计的时序数据库,TDengine 支持 Kubernetes 部署。这里介绍如何使用 YAML 文件一步一步从头创建一个 TDengine 集群,并重点介绍 Kubernetes 环境下 TDengine 的常用操作。

前置条件

要使用 Kubernetes 部署管理 TDengine 集群,需要做好如下准备工作。

  • 本文适用 Kubernetes v1.5 以上版本
  • 本文和下一章使用 minikube、kubectl 和 helm 等工具进行安装部署,请提前安装好相应软件
  • Kubernetes 已经安装部署并能正常访问使用或更新必要的容器仓库或其他服务

以下配置文件也可以从 GitHub 仓库 下载。

配置 Service 服务

创建一个 Service 配置文件:taosd-service.yaml,服务名称 metadata.name (此处为 “taosd”) 将在下一步中使用到。添加 TDengine 所用到的端口:

1. ---
2. apiVersion: v1
3. kind: Service
4. metadata:
5. name: "taosd"
6. labels:
7. app: "tdengine"
8. spec:
9. ports:
10. - name: tcp6030
11. protocol: "TCP"
12. port: 6030
13. - name: tcp6041
14. protocol: "TCP"
15. port: 6041
16. selector:
17. app: "tdengine"

有状态服务 StatefulSet

根据 Kubernetes 对各类部署的说明,我们将使用 StatefulSet 作为 TDengine 的服务类型。 创建文件 tdengine.yaml,其中 replicas 定义集群节点的数量为 3。节点时区为中国(Asia/Shanghai),每个节点分配 10G 标准(standard)存储。你也可以根据实际情况进行相应修改。

1. ---
2. apiVersion: apps/v1
3. kind: StatefulSet
4. metadata:
5. name: "tdengine"
6. labels:
7. app: "tdengine"
8. spec:
9. serviceName: "taosd"
10. replicas: 3
11. updateStrategy:
12. type: RollingUpdate
13. selector:
14. matchLabels:
15. app: "tdengine"
16. template:
17. metadata:
18. name: "tdengine"
19. labels:
20. app: "tdengine"
21. spec:
22. containers:
23. - name: "tdengine"
24. image: "tdengine/tdengine:3.0.0.0"
25. imagePullPolicy: "IfNotPresent"
26. ports:
27. - name: tcp6030
28. protocol: "TCP"
29. containerPort: 6030
30. - name: tcp6041
31. protocol: "TCP"
32. containerPort: 6041
33. env:
34. # POD_NAME for FQDN config
35. - name: POD_NAME
36. valueFrom:
37. fieldRef:
38. fieldPath: metadata.name
39. # SERVICE_NAME and NAMESPACE for fqdn resolve
40. - name: SERVICE_NAME
41. value: "taosd"
42. - name: STS_NAME
43. value: "tdengine"
44. - name: STS_NAMESPACE
45. valueFrom:
46. fieldRef:
47. fieldPath: metadata.namespace
48. # TZ for timezone settings, we recommend to always set it.
49. - name: TZ
50. value: "Asia/Shanghai"
51. # TAOS_ prefix will configured in taos.cfg, strip prefix and camelCase.
52. - name: TAOS_SERVER_PORT
53. value: "6030"
54. # Must set if you want a cluster.
55. - name: TAOS_FIRST_EP
56. value: "$(STS_NAME)-0.$(SERVICE_NAME).$(STS_NAMESPACE).svc.cluster.local:$(TAOS_SERVER_PORT)"
57. # TAOS_FQND should always be set in k8s env.
58. - name: TAOS_FQDN
59. value: "$(POD_NAME).$(SERVICE_NAME).$(STS_NAMESPACE).svc.cluster.local"
60. volumeMounts:
61. - name: taosdata
62. mountPath: /var/lib/taos
63. readinessProbe:
64. exec:
65. command:
66. - taos-check
67. initialDelaySeconds: 5
68. timeoutSeconds: 5000
69. livenessProbe:
70. exec:
71. command:
72. - taos-check
73. initialDelaySeconds: 15
74. periodSeconds: 20
75. volumeClaimTemplates:
76. - metadata:
77. name: taosdata
78. spec:
79. accessModes:
80. - "ReadWriteOnce"
81. storageClassName: "standard"
82. resources:
83. requests:
84. storage: "10Gi"

使用 kubectl 命令部署 TDengine 集群

顺序执行以下命令。

1. kubectl apply -f taosd-service.yaml
2. kubectl apply -f tdengine.yaml

上面的配置将生成一个三节点的 TDengine 集群,dnode 为自动配置,可以使用 show dnodes 命令查看当前集群的节点:

1. kubectl exec -i -t tdengine-0 -- taos -s "show dnodes"
2. kubectl exec -i -t tdengine-1 -- taos -s "show dnodes"
3. kubectl exec -i -t tdengine-2 -- taos -s "show dnodes"

输出如下:

1. taos> show dnodes
2. id   |            endpoint            | vnodes | support_vnodes |   status   |       create_time       |              note              |
3. ============================================================================================================================================
4. 1 | tdengine-0.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:14:57.285 |                                |
5. 2 | tdengine-1.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:11.302 |                                |
6. 3 | tdengine-2.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:23.290 |                                |
7. Query OK, 3 rows in database (0.003655s)

使能端口转发

利用 kubectl 端口转发功能可以使应用可以访问 Kubernetes 环境运行的 TDengine 集群。

1. kubectl port-forward tdengine-0 6041:6041 &

使用 curl 命令验证 TDengine REST API 使用的 6041 接口。

1. $ curl -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql
2. Handling connection for 6041
3. {"code":0,"column_meta":[["name","VARCHAR",64],["create_time","TIMESTAMP",8],["vgroups","SMALLINT",2],["ntables","BIGINT",8],["replica","TINYINT",1],["strict","VARCHAR",4],["duration","VARCHAR",10],["keep","VARCHAR",32],["buffer","INT",4],["pagesize","INT",4],["pages","INT",4],["minrows","INT",4],["maxrows","INT",4],["comp","TINYINT",1],["precision","VARCHAR",2],["status","VARCHAR",10],["retention","VARCHAR",60],["single_stable","BOOL",1],["cachemodel","VARCHAR",11],["cachesize","INT",4],["wal_level","TINYINT",1],["wal_fsync_period","INT",4],["wal_retention_period","INT",4],["wal_retention_size","BIGINT",8],["wal_roll_period","INT",4],["wal_segment_size","BIGINT",8]],"data":[["information_schema",null,null,16,null,null,null,null,null,null,null,null,null,null,null,"ready",null,null,null,null,null,null,null,null,null,null],["performance_schema",null,null,10,null,null,null,null,null,null,null,null,null,null,null,"ready",null,null,null,null,null,null,null,null,null,null]],"rows":2}

使用 dashboard 进行图形化管理

minikube 提供 dashboard 命令支持图形化管理界面。

1. $ minikube dashboard
2. * Verifying dashboard health ...
3. * Launching proxy ...
4. * Verifying proxy health ...
5. * Opening http://127.0.0.1:46617/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
6. http://127.0.0.1:46617/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

对于某些公有云环境,minikube 绑定在 127.0.0.1 IP 地址上无法通过远程访问,需要使用 kubectl proxy 命令将端口映射到 0.0.0.0 IP 地址上,再通过浏览器访问虚拟机公网 IP 和端口以及相同的 dashboard URL 路径即可远程访问 dashboard。

1. $ kubectl proxy --accept-hosts='^.*$' --address='0.0.0.0'

集群扩容

TDengine 集群支持自动扩容:

1. kubectl scale statefulsets tdengine --replicas=4

上面命令行中参数 --replica=4 表示要将 TDengine 集群扩容到 4 个节点,执行后首先检查 POD 的状态:

1. kubectl get pods -l app=tdengine

输出如下:

1. NAME         READY   STATUS    RESTARTS   AGE
2. tdengine-0   1/1     Running   0          161m
3. tdengine-1   1/1     Running   0          161m
4. tdengine-2   1/1     Running   0          32m
5. tdengine-3   1/1     Running   0          32m

此时 POD 的状态仍然是 Running,TDengine 集群中的 dnode 状态要等 POD 状态为 ready 之后才能看到:

1. kubectl exec -i -t tdengine-3 -- taos -s "show dnodes"

扩容后的四节点 TDengine 集群的 dnode 列表:

1. taos> show dnodes
2. id   |            endpoint            | vnodes | support_vnodes |   status   |       create_time       |              note              |
3. ============================================================================================================================================
4. 1 | tdengine-0.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:14:57.285 |                                |
5. 2 | tdengine-1.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:11.302 |                                |
6. 3 | tdengine-2.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:23.290 |                                |
7. 4 | tdengine-3.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:33:16.039 |                                |
8. Query OK, 4 rows in database (0.008377s)

集群缩容

由于 TDengine 集群在扩缩容时会对数据进行节点间迁移,使用 kubectl 命令进行缩容需要首先使用 “drop dnodes” 命令,节点删除完成后再进行 Kubernetes 集群缩容。

注意:由于 Kubernetes Statefulset 中 Pod 的只能按创建顺序逆序移除,所以 TDengine drop dnode 也需要按照创建顺序逆序移除,否则会导致 Pod 处于错误状态。

1. $ kubectl exec -i -t tdengine-0 -- taos -s "drop dnode 4"
1. $ kubectl exec -it tdengine-0 -- taos -s "show dnodes"

3. taos> show dnodes
4. id   |            endpoint            | vnodes | support_vnodes |   status   |       create_time       |              note              |
5. ============================================================================================================================================
6. 1 | tdengine-0.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:14:57.285 |                                |
7. 2 | tdengine-1.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:11.302 |                                |
8. 3 | tdengine-2.taosd.default.sv... |      0 |            256 | ready      | 2022-08-10 13:15:23.290 |                                |
9. Query OK, 3 rows in database (0.004861s)

确认移除成功后(使用 kubectl exec -i -t tdengine-0 — taos -s “show dnodes” 查看和确认 dnode 列表),使用 kubectl 命令移除 POD:

1. kubectl scale statefulsets tdengine --replicas=3

最后一个 POD 将会被删除。使用命令 kubectl get pods -l app=tdengine 查看POD状态:

1. $ kubectl get pods -l app=tdengine
2. NAME READY STATUS RESTARTS AGE
3. tdengine-0 1/1 Running 0 4m7s
4. tdengine-1 1/1 Running 0 3m55s
5. tdengine-2 1/1 Running 0 2m28s

POD删除后,需要手动删除PVC,否则下次扩容时会继续使用以前的数据导致无法正常加入集群。

1. $ kubectl delete pvc taosdata-tdengine-3

此时的集群状态是安全的,需要时还可以再次进行扩容:

1. $ kubectl scale statefulsets tdengine --replicas=4
2. statefulset.apps/tdengine scaled
3. it@k8s-2:~/TDengine-Operator/src/tdengine$ kubectl get pods -l app=tdengine
4. NAME READY STATUS RESTARTS AGE
5. tdengine-0 1/1 Running 0 35m
6. tdengine-1 1/1 Running 0 34m
7. tdengine-2 1/1 Running 0 12m
8. tdengine-3 0/1 ContainerCreating 0 4s
9. it@k8s-2:~/TDengine-Operator/src/tdengine$ kubectl get pods -l app=tdengine
10. NAME READY STATUS RESTARTS AGE
11. tdengine-0 1/1 Running 0 35m
12. tdengine-1 1/1 Running 0 34m
13. tdengine-2 1/1 Running 0 12m
14. tdengine-3 0/1 Running 0 7s
15. it@k8s-2:~/TDengine-Operator/src/tdengine$ kubectl exec -it tdengine-0 -- taos -s "show dnodes"

17. taos> show dnodes
18. id | endpoint | vnodes | support_vnodes | status | create_time | offline reason |
19. ======================================================================================================================================
20. 1 | tdengine-0.taosd.default.sv... | 0 | 4 | ready | 2022-07-25 17:38:49.012 | |
21. 2 | tdengine-1.taosd.default.sv... | 1 | 4 | ready | 2022-07-25 17:39:01.517 | |
22. 5 | tdengine-2.taosd.default.sv... | 0 | 4 | ready | 2022-07-25 18:01:36.479 | |
23. 6 | tdengine-3.taosd.default.sv... | 0 | 4 | ready | 2022-07-25 18:13:54.411 | |
24. Query OK, 4 row(s) in set (0.001348s)

清理 TDengine 集群

完整移除 TDengine 集群,需要分别清理 statefulset、svc、configmap、pvc。

1. kubectl delete statefulset -l app=tdengine
2. kubectl delete svc -l app=tdengine
3. kubectl delete pvc -l app=tdengine
4. kubectl delete configmap taoscfg

常见错误

错误一

未进行 “drop dnode” 直接进行缩容,由于 TDengine 尚未删除节点,缩容 pod 导致 TDengine 集群中部分节点处于 offline 状态。

1. $ kubectl exec -it tdengine-0 -- taos -s "show dnodes"

3. taos> show dnodes
4. id | endpoint | vnodes | support_vnodes | status | create_time | offline reason |
5. ======================================================================================================================================
6. 1 | tdengine-0.taosd.default.sv... | 0 | 4 | ready | 2022-07-25 17:38:49.012 | |
7. 2 | tdengine-1.taosd.default.sv... | 1 | 4 | ready | 2022-07-25 17:39:01.517 | |
8. 5 | tdengine-2.taosd.default.sv... | 0 | 4 | offline | 2022-07-25 18:01:36.479 | status msg timeout |
9. 6 | tdengine-3.taosd.default.sv... | 0 | 4 | offline | 2022-07-25 18:13:54.411 | status msg timeout |
10. Query OK, 4 row(s) in set (0.001323s)

错误二

TDengine 集群会持有 replica 参数,如果缩容后的节点数小于这个值,集群将无法使用:

创建一个库使用 replica 参数为 2,插入部分数据:

1. kubectl exec -i -t tdengine-0 -- \
2. taos -s \
3. "create database if not exists test replica 2;
4. use test;
5. create table if not exists t1(ts timestamp, n int);
6. insert into t1 values(now, 1)(now+1s, 2);"

缩容到单节点:

1. kubectl scale statefulsets tdengine --replicas=1

在 TDengine CLI 中的所有数据库操作将无法成功。

1. taos> show dnodes;
2. id   |           end_point            | vnodes | cores  |   status   | role  |       create_time       |      offline reason      |
3. ======================================================================================================================================
4. 1 | tdengine-0.taosd.default.sv... |      2 |     40 | ready      | any   | 2021-06-01 15:55:52.562 |                          |
5. 2 | tdengine-1.taosd.default.sv... |      1 |     40 | offline    | any   | 2021-06-01 15:56:07.212 | status msg timeout       |
6. Query OK, 2 row(s) in set (0.000845s)

8. taos> show dnodes;
9. id   |           end_point            | vnodes | cores  |   status   | role  |       create_time       |      offline reason      |
10. ======================================================================================================================================
11. 1 | tdengine-0.taosd.default.sv... |      2 |     40 | ready      | any   | 2021-06-01 15:55:52.562 |                          |
12. 2 | tdengine-1.taosd.default.sv... |      1 |     40 | offline    | any   | 2021-06-01 15:56:07.212 | status msg timeout       |
13. Query OK, 2 row(s) in set (0.000837s)

15. taos> use test;
16. Database changed.

18. taos> insert into t1 values(now, 3);

20. DB error: Unable to resolve FQDN (0.013874s)