docs(book):增加技术细节、自定义sc、修复dns和版本号错误说明
6
docs/book.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[book]
|
||||
authors = ["Yu Sun"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "EdgeManager开发指北"
|
||||
15
docs/src/SUMMARY.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Summary
|
||||
|
||||
[项目简介](introduction.md)
|
||||
|
||||
[系统配置](system.md)
|
||||
|
||||
# 测试
|
||||
|
||||
- [集群搭建](tests/cluster.md)
|
||||
- [运行多节点TimescaleDB服务](tests/tsdb.md)
|
||||
- [技术细节](tests/details.md)
|
||||
- [常见问题](tests/questions/questions.md)
|
||||
- [Pods无法清除](tests/questions/terminating.md)
|
||||
- [Pods创建失败](tests/questions/failed_pod.md)
|
||||
- [使用物理内存作持久化存储](tests/questions/ram.md)
|
||||
3
docs/src/introduction.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 项目简介
|
||||
|
||||
待补充,请阅读其他内容。
|
||||
43
docs/src/system.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 系统配置
|
||||
|
||||
> 建议在开发环境、测试环境和生产环境均应用该页面中建议的设置。
|
||||
>
|
||||
> 如果使用集群,则每台机器都应应用该页面中建议的设置。
|
||||
|
||||
## OS安装
|
||||
|
||||
关键参数:
|
||||
|
||||
1. Ubuntu Server 22.04.1 LTS
|
||||
2. minimized安装
|
||||
3. 磁盘挂载不要选LVM方式
|
||||
4. 关闭swap(`/etc/fstab`去掉对应行后重启生效)
|
||||
|
||||
## 更改时区为一致
|
||||
|
||||
```bash
|
||||
sudo timedatectl set-timezone Asia/Shanghai
|
||||
```
|
||||
|
||||
## 内核调优
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
echo '
|
||||
net.ipv4.tcp_max_tw_buckets = 20000
|
||||
net.core.somaxconn = 65535
|
||||
net.ipv4.tcp_max_syn_backlog = 262144
|
||||
net.core.netdev_max_backlog = 30000
|
||||
fs.file-max = 6815744
|
||||
net.netfilter.nf_conntrack_max = 2621440
|
||||
' | sudo tee -a /etc/sysctl.conf
|
||||
echo '
|
||||
* soft nofile 1024000
|
||||
* hard nofile 1024000
|
||||
root soft nofile 1024000
|
||||
root hard nofile 1024000
|
||||
' | sudo tee -a /etc/security/limits.conf
|
||||
```
|
||||
|
||||
然后`sudo reboot`重启服务器。
|
||||
145
docs/src/tests/cluster.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# 集群搭建
|
||||
|
||||
> 操作系统的安装和配置请参照[系统配置](../system.md)章节。
|
||||
|
||||
## hostname配置
|
||||
|
||||
可通过`hostname`命令检查当前服务器的hostname。
|
||||
|
||||
在一切开始之前,首先要确保4台物理机的hostname分别为:`an`、`dn0`、`dn1`和`dn2`。
|
||||
|
||||
其中,`an`代表多节点TimescaleDB集群中的Access Node(接入节点),`dnx`则代表Data Node(数据节点)。
|
||||
|
||||
在安装操作系统时,可以一并设置hostname。如果有改变hostname的需要,可以类似这样操作:
|
||||
|
||||
```bash
|
||||
sudo hostnamectl set-hostname an
|
||||
```
|
||||
|
||||
则hostname会被改为`an`(**即时生效**)。
|
||||
|
||||
## hosts配置
|
||||
|
||||
可通过编辑`/etc/hosts`文件,将局域网内hostname和IP地址的映射关系写入,此处不赘述具体步骤。
|
||||
|
||||
> 需确保集群内每一节点都可以**正确地**将其他节点的hostname解析为对应的IP地址。
|
||||
|
||||
## MicroK8s安装
|
||||
|
||||
```bash
|
||||
sudo snap install microk8s --classic --channel=1.25
|
||||
```
|
||||
|
||||
> MicroK8s安装也可以在Ubuntu安装过程勾选完成。
|
||||
>
|
||||
> 1.25版本对最新内核的cgroup v2识别可能有问题(`microk8s.inspect`会[提示warning](https://github.com/canonical/microk8s/issues/3375)),忽略即可,并不影响集群稳定性。
|
||||
|
||||
将当前用户加入`microk8s`用户组方便管理:
|
||||
|
||||
```bash
|
||||
sudo usermod -a -G microk8s $USER
|
||||
sudo chown -f -R $USER ~/.kube
|
||||
newgrp microk8s
|
||||
```
|
||||
|
||||
gcr镜像无法在祖国大陆直接获取,[使用阿里云替代](https://microk8s.io/docs/registry-private#configure-registry-mirrors-7),但截至该文档编写时,官方文档提供的解决方法[有问题](https://github.com/canonical/microk8s/issues/472#issuecomment-1256947878),可以用下述方法替代:
|
||||
|
||||
```bash
|
||||
sed -i 's#k8s.gcr.io#registry.aliyuncs.com/google_containers#g' /var/snap/microk8s/current/args/containerd-template.toml
|
||||
sudo snap restart microk8s
|
||||
```
|
||||
|
||||
确认K8s是否已经正常运行:
|
||||
|
||||
```bash
|
||||
microk8s.status -w
|
||||
```
|
||||
|
||||
如无异常,片刻后会显示如下内容:
|
||||
|
||||
```pre
|
||||
microk8s is running
|
||||
high-availability: no
|
||||
datastore master nodes: 127.0.0.1:19001
|
||||
datastore standby nodes: none
|
||||
addons:
|
||||
enabled:
|
||||
ha-cluster # (core) Configure high availability on the current node
|
||||
disabled:
|
||||
community # (core) The community addons repository
|
||||
dashboard # (core) The Kubernetes dashboard
|
||||
dns # (core) CoreDNS
|
||||
gpu # (core) Automatic enablement of Nvidia CUDA
|
||||
helm # (core) Helm 2 - the package manager for Kubernetes
|
||||
helm3 # (core) Helm 3 - Kubernetes package manager
|
||||
host-access # (core) Allow Pods connecting to Host services smoothly
|
||||
hostpath-storage # (core) Storage class; allocates storage from host directory
|
||||
ingress # (core) Ingress controller for external access
|
||||
mayastor # (core) OpenEBS MayaStor
|
||||
metallb # (core) Loadbalancer for your Kubernetes cluster
|
||||
metrics-server # (core) K8s Metrics Server for API access to service metrics
|
||||
prometheus # (core) Prometheus operator for monitoring and logging
|
||||
rbac # (core) Role-Based Access Control for authorisation
|
||||
registry # (core) Private image registry exposed on localhost:32000
|
||||
storage # (core) Alias to hostpath-storage add-on, deprecated
|
||||
```
|
||||
|
||||
此外,为了方便拉取`docker.io`上的镜像,最好配置使用[阿里云的镜像加速器](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors):
|
||||
|
||||
```bash
|
||||
echo '
|
||||
server = "https://registry-1.docker.io"
|
||||
|
||||
[host."https://r3vfmoy2.mirror.aliyuncs.com"]
|
||||
capabilities = ["pull", "resolve"]
|
||||
' | tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml
|
||||
sudo snap restart microk8s
|
||||
```
|
||||
|
||||
重复上述步骤使得MicroK8s在每台服务器上得以妥善安装配置。
|
||||
|
||||
## 组建集群
|
||||
|
||||
组建集群的详细步骤可以参考[官方文档](https://microk8s.io/docs/clustering),但需**注意**:
|
||||
|
||||
1. `microk8s join`之前,需要在每个node的`/etc/hosts`中加入其他node的信息
|
||||
2. 每个节点加入后,token会过期,需要再次`microk8s add-node`获取新的token
|
||||
|
||||
## 启用Helm3扩展
|
||||
|
||||
> Helm3扩展自MicroK8s v1.25开始已经默认开启,无需手动安装。
|
||||
|
||||
同样是祖国大陆受GFW限制的问题,如果直接`microk8s.enable helm3`是从官方拉取文件安装Helm3,速度极慢且中途易出现下载中断。
|
||||
|
||||
可以把对应的安装脚本里的文件位置指向华为云的镜像:
|
||||
|
||||
```bash
|
||||
sed 's#https://get.helm.sh#https://mirrors.huaweicloud.com/helm/v3.8.0#' /var/snap/microk8s/common/addons/core/addons/helm3/enable | SNAP=/snap/microk8s/current SNAP_DATA=/var/snap/microk8s/current SNAP_ARCH=amd64 bash
|
||||
```
|
||||
|
||||
运行完毕后再执行`microk8s.status`即可看到Helm3扩展已启用。
|
||||
|
||||
## 后续配置
|
||||
|
||||
由于我们要使用Helm来作为包管理器,而helm会读取K8s的`config`文件,如果不加设置,默认会使用`/var/snap/microk8s/current/credentials/client.config`,但由于安全性问题,会被警告:
|
||||
|
||||
```pre
|
||||
WARNING: Kubernetes configuration file is group-readable. This is insecure.
|
||||
```
|
||||
|
||||
所以我们需要创建用户级别的配置文件并赋予正确的文件权限:
|
||||
|
||||
```bash
|
||||
microk8s config > ~/.kube/config
|
||||
chmod go-r ~/.kube/config
|
||||
```
|
||||
|
||||
为便于操作,再将常用命令做一下`alias`:
|
||||
|
||||
```bash
|
||||
echo '
|
||||
alias kubectl="microk8s kubectl"
|
||||
alias helm="microk8s helm3 --kubeconfig ~/.kube/config"
|
||||
' | tee -a ~/.bash_aliases
|
||||
```
|
||||
|
||||
89
docs/src/tests/details.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# 技术细节
|
||||
|
||||
## 0. 如何确保集群的access-node/data-node pods运行于我们期望的物理节点上?
|
||||
|
||||
首先要明确一个概念,由于需要对Access Node和Data Node进行区分,TimescaleDB集群其实是一个有状态的应用。
|
||||
|
||||
有状态应用借助K8s的[StatefulSet workload](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)可以很便捷的部署。
|
||||
|
||||
但很久以前TimescaleDB官方维护的multinodes版本Helm仓库里对于Access Node的节点选择并没有清晰定义。
|
||||
|
||||
[`charts/templates/statefulset-timescaledb-accessnode.yaml`](https://github.com/timescale/helm-charts/blob/29b589c96821a3f9ffe890cd775d7da471007aa0/charts/timescaledb-multinode/templates/statefulset-timescaledb-accessnode.yaml#L117-L118):
|
||||
|
||||
```yaml
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
```
|
||||
|
||||
[`charts/values.yaml`](https://github.com/timescale/helm-charts/blob/29b589c96821a3f9ffe890cd775d7da471007aa0/charts/timescaledb-multinode/values.yaml#L91):
|
||||
|
||||
```yaml
|
||||
nodeSelector: {}
|
||||
```
|
||||
|
||||
咱就是说,直接就摆烂了。
|
||||
|
||||
这直接导致多个接入节点和数据节点的pods很大概率错误地尝试分配在同一个物理节点上,由于资源冲突,最终造成随机的某(几)个节点创建失败。
|
||||
|
||||
按照[我们之前对hostname的定义](cluster.md#hostname配置),最后将`charts/templates/statefulset-timescaledb-accessnode.yaml`里对应部分改为:
|
||||
|
||||
```yaml
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: an
|
||||
```
|
||||
|
||||
解决了这个问题。
|
||||
|
||||
`kubernetes.io/hostname`是K8s的一个保留label,通过如下命令可以查看:
|
||||
|
||||
```bash
|
||||
kubectl get no --show-labels=true
|
||||
```
|
||||
|
||||

|
||||
|
||||
这里有一个复杂情况,如果设定的Data Node数目超过了节点数目,亦或是其中某个节点挂掉,集群的Access Node或者Data Node是会尝试漂移到某个节点上的,也就是某些节点上会启动多于一个TimescaleDB实例。这是我们不想看到的。
|
||||
|
||||
在Helm chart中妥善设置节点亲和性可以有效解决这个问题:
|
||||
|
||||
`charts/templates/statefulset-timescaledb-accessnode.yaml`:
|
||||
|
||||
```yaml
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/hostname
|
||||
operator: In
|
||||
values:
|
||||
- an
|
||||
```
|
||||
|
||||
`charts/templates/statefulset-timescaledb-datanode.yaml`:
|
||||
|
||||
```yaml
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/hostname
|
||||
operator: NotIn
|
||||
values:
|
||||
- an
|
||||
```
|
||||
|
||||
核心思想是使用`requiredDuringSchedulingIgnoredDuringExecution`替代`preferredDuringSchedulingIgnoredDuringExecution`策略,以实现强制性的调度[^note]。
|
||||
|
||||
[^note]: <https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/#schedule-a-Pod-using-required-node-affinity>
|
||||
|
||||
## 1. TimescaleDB集群的多节点间操作是如何实现免密码认证的?
|
||||
|
||||
PostgreSQL有一个[Password file](https://www.postgresql.org/docs/current/libpq-pgpass.html)的设定,通过一个`.pgpass`来进行一些免密认证。
|
||||
|
||||
TimescaleDB可以复用这个文件,但是必须在PostgreSQL的配置文件中以[`timescaledb.passfile`](https://docs.timescale.com/timescaledb/latest/how-to-guides/configuration/timescaledb-config/#timescaledb-passfile-string)字段的形式提供。
|
||||
|
||||
打个比方,应用层中使用[`create-distributed-hypertable()`](https://docs.timescale.com/api/latest/distributed-hypertables/create_distributed_hypertable/#create-distributed-hypertable)函数创建分布式超表的时候,其是不允许将密码传参提供的,这个时候就一定要环境中提供免密认证,使得各个nodes之间可以自由连通。
|
||||
|
||||
而[`add_data_node()`](https://docs.timescale.com/api/latest/distributed-hypertables/add_data_node/)函数则可以直接传参指定密码,因其为环境部署过程中可能需要的。但是出于安全性考虑,也**不建议**这样做。
|
||||
BIN
docs/src/tests/get_all.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/src/tests/node_label.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
docs/src/tests/psql.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
33
docs/src/tests/questions/failed_pod.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Pods创建失败
|
||||
|
||||
## 问题描述
|
||||
|
||||
使用`kubectl get all -l release=tsdb` 发现有单个数据节点或`(1个数据节点 + 1个接入节点)`的pods的状态是某种error,`kubectl describe`之后发现类似下面的报错:
|
||||
|
||||
```pre
|
||||
Events:
|
||||
Type Reason Age From Message
|
||||
---- ------ ---- ---- -------
|
||||
Normal Pulled 4m34s (x2 over 4m48s) kubelet Container image "timescale/timescaledb-ha:pg14.5-ts2.8.0-patroni-static-primary-latest" already present on machine
|
||||
...
|
||||
Warning MissingClusterDNS 7s (x8 over 39s) kubelet pod: "tsdb-timescaledb-data-1_default(62ba2d9e-6cff-4446-aa2b-ae46f5948997)". kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to "Default" policy.
|
||||
```
|
||||
|
||||
## 解决方案
|
||||
|
||||
很容易误会是没有启用`core/dns`扩展所致,但事实上我们已经[启用了](../tsdb.md#安装必要扩展addons)改扩展。
|
||||
|
||||
`charts/templates/svc-timescaledb-data.yaml`文件中的相关定义为:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
clusterIP: None
|
||||
```
|
||||
|
||||
而K8s其实是允许定义Headless Services的[^note],就是通过将`.spec.clusterIP`指定为`"None"`。
|
||||
|
||||
所以问题其实是:**没有能够正确应用Selector把pod分配到正确的节点上**。
|
||||
|
||||
具体的设置方法可参照[技术细节](../details.md#0-如何确保集群的access-node-pod运行于我们设定的物理节点上)。
|
||||
|
||||
[^note]: <https://kubernetes.io/docs/concepts/services-networking/service/#headless-services>
|
||||
3
docs/src/tests/questions/questions.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 常见问题
|
||||
|
||||
本章节用于记录测试过程中常见问题及解决方案。
|
||||
38
docs/src/tests/questions/ram.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 使用物理内存作持久化存储
|
||||
|
||||
首先划分一块足够的内存空间并挂载:
|
||||
|
||||
```bash
|
||||
sudo mkdir -pm777 /mnt/ramdisk
|
||||
sudo mount -t ramfs -o size=10G ramdisk /mnt/ramdisk
|
||||
```
|
||||
|
||||
> **需要在每个节点上都如法炮制**。
|
||||
|
||||
创建新的StorageClass:
|
||||
|
||||
```bash
|
||||
kubectl apply -f ram-hostpath-sc.yaml
|
||||
```
|
||||
|
||||
重新启动集群服务的时候,使用命令行传参的方式覆盖默认(`values.yaml`)设置。
|
||||
|
||||
```bash
|
||||
helm install tsdb --set persistentVolume.size=8G --set persistentVolume.storageClass=ram-hostpath .
|
||||
```
|
||||
|
||||
Microk8s的hostpath storage有bug,新创建的PV权限并非`777`,会导致StatefulSet的pods全部启动失败。暂时只能在每个节点上手动设置权限:
|
||||
|
||||
```bash
|
||||
sudo chmod -R 777 /mnt/ramdisk/
|
||||
```
|
||||
|
||||
之后静等对应的pods自动重启。
|
||||
|
||||
[移除集群](../tsdb.html#移除集群)的操作不再赘述。
|
||||
|
||||
如要清除创建的StorageClass:
|
||||
|
||||
```bash
|
||||
kubectl delete sc/ram-hostpath
|
||||
```
|
||||
BIN
docs/src/tests/questions/sandbox.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
27
docs/src/tests/questions/terminating.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Pods无法清除
|
||||
|
||||
## 问题描述
|
||||
|
||||
执行`helm uninstall`或者`kubectl delete`等命令的时候发现pods无法删除:
|
||||
|
||||

|
||||
|
||||
使用`kubectl describe`观察详情的时候发现通讯失败(但Sandbox其实已经被清除了):
|
||||
|
||||

|
||||
|
||||
## 解决方案
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
for p in $(kubectl get pods | grep Terminating | awk '{print $1}'); do kubectl delete pod $p --grace-period=0 --force; done
|
||||
```
|
||||
|
||||
如果运行上面的命令后仍有pod处于`Unknown`状态,大胆清除[^note]:
|
||||
|
||||
```bash
|
||||
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
|
||||
```
|
||||
|
||||
[^note]: <https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/#delete-pods>
|
||||
BIN
docs/src/tests/questions/terminating.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/src/tests/show_nodes.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/src/tests/timescaledb-multi.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
115
docs/src/tests/tsdb.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# 运行多节点TimescaleDB服务
|
||||
|
||||
在[上一章节](cluster.md)中,我们完成了基本的K8s集群搭建并启用了Helm3扩展以便于利用helm charts便捷部署应用于其上。
|
||||
|
||||
接下来说明如何配置一个测试用集群。
|
||||
|
||||
> 注意,生产环境中的配置可以参考本章,但不应照搬;
|
||||
>
|
||||
> 本章中的配置仅提供**最简易**环境并论证运维**可行性**,性能和稳定性方面均**无法胜任生产环境**。
|
||||
|
||||
## 安装必要扩展(Addons)
|
||||
|
||||
运行以下命令,并耐心等待自动配置完成:
|
||||
|
||||
```bash
|
||||
microk8s enable dns hostpath-storage metallb
|
||||
```
|
||||
|
||||
`dns`是必需的,因为Data Nodes上运行的TimescaleDB实例作为[Headless Services](questions/failed_pod.md#解决方案),本身是没有为它们提供IP的。如果没有K8s内建的DNS服务,根本就无法根据pod name获取到具体的IP,也就是说这些pods间无法通讯,数据库集群会创建失败。
|
||||
|
||||
其中,`hostpath-storage`是microk8s自带的一个PV(**P**ersistent**V**olumes,持久化存储)插件,其为开发者提供了动态供应(dynamic provisioning)的PV。
|
||||
|
||||
简单来讲,用户通过helm charts或其他方式每创建一个带有PVC(**P**ersistent**V**olume**C**laim)的pod,动态供应者(dynamic provisioner)就会为其自动创建一个可用的PV。
|
||||
|
||||
> **禁止在生产环境中使用hostpath-storage!**
|
||||
>
|
||||
> 由hostpath-storage提供的PV并不支持数据在节点间迁移,所以只能用于开发/测试环境。
|
||||
|
||||
`metallb`则是轻量级的为bare-metal服务器上提供负载均衡的解决方案。
|
||||
|
||||
> bare-metal特指比如IoT场景这种局域网中互连的服务器们,即区别于“云上”的虚拟服务器(**V**irtual **P**rivate **S**erver, VPS)。
|
||||
|
||||
启用metallb扩展时,命令行会提示输入IP网段来创建一个地址池,当service类型为`LoadBalancer`时,metallb会从已创建的地址池中挑选一个IP来作为服务的`EXTERNAL-IP`。
|
||||
|
||||
> 应为metallb提供**与host同一层的**IP地址,因其可以直接在局域网内被直接访问,而无需额外的DNS服务。
|
||||
>
|
||||
> 但**不应重复使用节点的IP**,会导致network traffic,造成节点间无法通讯,集群不能正常工作。
|
||||
>
|
||||
> 这也为**部署于K8s集群外的应用**(比如EdgeManager)提供了访问集群内服务的支撑。
|
||||
|
||||
指定网段时可以使用`-`符号连接两个IP地址来表示一个区间。比如也可以使用这种方式在启用扩展时直接创建地址池:
|
||||
|
||||
```bash
|
||||
microk8s.enable metallb:192.168.0.198-192.168.0.199
|
||||
```
|
||||
|
||||
运行完毕后,`192.168.0.198`和`192.168.0.199`均会被加入地址池中。metallb一般会挑选第一个,当第一个地址不可用时则顺序替换为下一个地址。
|
||||
|
||||
## 启动集群
|
||||
|
||||
先拉取代码仓库:
|
||||
|
||||
```bash
|
||||
git pull http://118.195.187.246:10030/ysun/EdgeManager.git
|
||||
```
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
# 进入位于项目根目录的charts目录内
|
||||
cd EdgeManager/charts
|
||||
helm install tsdb .
|
||||
```
|
||||
|
||||
## 移除集群
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
helm uninstall tsdb
|
||||
```
|
||||
|
||||
但`helm uninstall`并不会丧心病狂地删除持久化的数据,因此如果想**彻底删除**这些数据,可以用以下命令删除PVC:
|
||||
|
||||
```bash
|
||||
kubectl delete $(kubectl get pvc -l release=tsdb -o name)
|
||||
```
|
||||
|
||||
稍后对应的PV也会被清除(因为我们之前使用的PV插件`hostpath-storage`是dynamic provisioner)。
|
||||
|
||||
> 如果需要重新部署服务,建议使用`kubectl get pv`确定PV已经完全被释放后再进行。
|
||||
|
||||
## 验证集群状态
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
kubectl get all -l release=tsdb
|
||||
```
|
||||
|
||||

|
||||
|
||||
图中可见,`192.168.0.198`即为metallb提供的可供集群外部应用访问的IP。
|
||||
|
||||
验证Access Node上是否成功加入了数据节点:
|
||||
|
||||
```bash
|
||||
kubectl exec -ti $(kubectl get pod -l timescaleNodeType=access -o name) -c timescaledb -- psql -d scada -c 'select node_name from timescaledb_information.data_nodes'
|
||||
```
|
||||
|
||||

|
||||
|
||||
尝试从另外一台物理机访问该多节点TimescaleDB集群:
|
||||
|
||||

|
||||
|
||||
至此,集群已经可以正常使用了。
|
||||
|
||||
## 部署图
|
||||
|
||||
该测试环境的部署结构[^note]为:
|
||||
|
||||

|
||||
|
||||
[^note]: <https://docs.timescale.com/timescaledb/latest/overview/timescale-kubernetes/#multi-node-distributed-timescaledb>
|
||||