作者: EugeneHuang 原文来源:https://tidb.net/blog/e75df577
环境准备
Kubernetes 上的 TiDB 集群环境需求 | TiDB 文档中心
修改主机名称解析
cat >> /etc/hosts << EOF192.168.66.21 k8s-master01192.168.66.22 k8s-master02192.168.66.23 k8s-master03192.168.66.24 k8s-node01192.168.66.25 k8s-node02192.168.66.26 k8s-node03192.168.66.27 k8s-node04192.168.66.28 k8s-node05EOF
复制代码
设置主机名
hostnamectl set-hostname k8s-master01hostnamectl set-hostname k8s-node01
复制代码
Docker 服务
[[docker -yum 安装]]
sudo yum install -y docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io
复制代码
[[挂载新磁盘]]10G 到 /data1/docker
安装完 Docker 服务以后,执行以下步骤:
将 Docker 的数据保存到一块单独的盘上,Docker 的数据主要包括镜像和容器日志数据。通过设置 --data-root 参数来实现:
上面会将 Docker 的数据目录设置为 /data1/docker。
设置 Docker daemon 的 ulimit。
创建 docker service 的 systemd drop-in 目录 /etc/systemd/system/docker.service.d:
创建 /etc/systemd/system/docker.service.d/limit-nofile.conf 文件,并配置 LimitNOFILE 参数的值,取值范围为大于等于 1048576 的数字即可。
重新加载配置。
自启动开启
Kubernetes 服务
[[创建高可用集群]]
其余 node 节点加入集群
kubeadm join 192.168.66.29:6553 --token ncll7c.kt4ycv9sfnygvbrw \ --discovery-token-ca-cert-hash sha256:b6ac15003f7968ab23da26015b377dfc8bae1922b1a3af0bd925634903d91421
复制代码
全部节点加入集群成功
[root@k8s-master01 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONk8s-master01 NotReady control-plane,master 45m v1.23.6k8s-master02 NotReady control-plane,master 44m v1.23.6k8s-master03 NotReady control-plane,master 43m v1.23.6k8s-node01 NotReady <none> 88s v1.23.6k8s-node02 NotReady <none> 41s v1.23.6k8s-node03 NotReady <none> 35s v1.23.6k8s-node04 NotReady <none> 26s v1.23.6k8s-node05 NotReady <none> 22s v1.23.6
复制代码
安装网络插件
[[kubeadm 初始化集群 # 安装网络插件]]
[root@localhost ~]# kubectl get pod -A -o wideNAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESkube-flannel kube-flannel-ds-4tp6b 1/1 Running 0 55s 192.168.66.23 k8s-master03 <none> <none>kube-flannel kube-flannel-ds-8p8wq 1/1 Running 0 55s 192.168.66.24 k8s-node01 <none> <none>kube-flannel kube-flannel-ds-f5wnt 1/1 Running 0 55s 192.168.66.22 k8s-master02 <none> <none>kube-flannel kube-flannel-ds-g4p4t 1/1 Running 0 55s 192.168.66.21 k8s-master01 <none> <none>kube-flannel kube-flannel-ds-jtlsj 1/1 Running 0 55s 192.168.66.28 k8s-node05 <none> <none>kube-flannel kube-flannel-ds-pcrfg 1/1 Running 0 55s 192.168.66.27 k8s-node04 <none> <none>kube-flannel kube-flannel-ds-pwn8q 1/1 Running 0 55s 192.168.66.26 k8s-node03 <none> <none>kube-flannel kube-flannel-ds-x4nkv 1/1 Running 0 55s 192.168.66.25 k8s-node02 <none> <none>
复制代码
[root@localhost ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONk8s-master01 Ready control-plane,master 17m v1.23.6k8s-master02 Ready control-plane,master 7m46s v1.23.6k8s-master03 Ready control-plane,master 8m33s v1.23.6k8s-node01 Ready <none> 6m19s v1.23.6k8s-node02 Ready <none> 6m13s v1.23.6k8s-node03 Ready <none> 6m10s v1.23.6k8s-node04 Ready <none> 6m7s v1.23.6k8s-node05 Ready <none> 6m3s v1.23.6
复制代码
持久化存储配置
TiDB 集群中 PD、TiKV、监控等组件以及 TiDB Binlog 和备份等工具都需要使用将数据持久化的存储。Kubernetes 上的数据持久化需要使用 PersistentVolume (PV)。Kubernetes 提供多种存储类型,主要分为两大类:
PV 一般由系统管理员或 volume provisioner 自动创建,PV 与 Pod 是通过 PersistentVolumeClaim (PVC) 进行关联的。普通用户在使用 PV 时并不需要直接创建 PV,而是通过 PVC 来申请使用 PV,对应的 volume provisioner 根据 PVC 创建符合要求的 PV,并将 PVC 与该 PV 进行绑定。
本地 PV 配置
Kubernetes 当前支持静态分配的本地存储。可使用 local-static-provisioner 项目中的 local-volume-provisioner 程序创建本地存储对象。
node1-node4: ssd 40Gnode4-node5: TiFlash 30Gnode1-node2:backup 30Gnode3:monitoring 20Gnode4-node5: sharedssd 10G
1) 准备本地存储
格式化和挂载
sudo mkfs.ext4 /dev/sdbDISK_UUID=$(sudo blkid -s UUID -o value /dev/sdb) sudo mkdir -p /mnt/ssd/$DISK_UUIDsudo mount -t ext4 /dev/sdb /mnt/ssd/$DISK_UUID
复制代码
持久挂载进入 /etc/fstab
echo UUID=`sudo blkid -s UUID -o value /dev/sdb` /mnt/ssd/$DISK_UUID ext4 defaults 0 2 | sudo tee -a /etc/fstab
复制代码
给 TiFlash 数据使用的盘
sudo mkfs.ext4 /dev/sdeDISK_UUID=$(sudo blkid -s UUID -o value /dev/sde)sudo mkdir -p /mnt/flash/$DISK_UUIDsudo mount -t ext4 /dev/sde /mnt/flash/$DISK_UUID
复制代码
echo UUID=`sudo blkid -s UUID -o value /dev/sde` /mnt/flash/$DISK_UUID ext4 defaults 0 2 | sudo tee -a /etc/fstab
复制代码
给 PD 数据使用的盘,可以参考步骤挂载盘,创建目录,并将新建的目录以 bind mount 方式挂载到 /mnt/sharedssd 目录下。1 个目录会对应创建 1 个 PV。每个 PD 会使用一个 PV。格式化和挂载
sudo mkfs.ext4 /dev/sdcDISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc) sudo mkdir /mnt/$DISK_UUIDsudo mount -t ext4 /dev/sdc /mnt/$DISK_UUID
复制代码
持久挂载进入 /etc/fstab
echo UUID=`sudo blkid -s UUID -o value /dev/sdc` /mnt/$DISK_UUID ext4 defaults 0 2 | sudo tee -a /etc/fstab
复制代码
创建多个目录并绑定挂载到发现目录中
for i in $(seq 1 5); do sudo mkdir -p /mnt/$DISK_UUID/vol${i} /mnt/sharedssd/$DISK_UUID_vol${i} sudo mount --bind /mnt/$DISK_UUID/vol${i} /mnt/sharedssd/$DISK_UUID_vol${i}done
复制代码
将挂载条目永久绑定到 /etc/fstab 中
for i in $(seq 1 5); do echo /mnt/$DISK_UUID/vol${i} /mnt/sharedssd/$DISK_UUID_vol${i} none bind 0 0 | sudo tee -a /etc/fstabdone
复制代码
给监控数据使用的盘,可以参考步骤挂载盘,创建目录,并将新建的目录以 bind mount 方式挂载到 /mnt/monitoring 目录下。1 个目录会对应创建 1 个 PV。每个 TiDB 集群的监控数据会使用 1 个 PV。格式化和挂载
sudo mkfs.ext4 /dev/sdcDISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc) sudo mkdir /mnt/$DISK_UUIDsudo mount -t ext4 /dev/sdc /mnt/$DISK_UUID
复制代码
持久挂载进入 /etc/fstab
echo UUID=`sudo blkid -s UUID -o value /dev/sdc` /mnt/$DISK_UUID ext4 defaults 0 2 | sudo tee -a /etc/fstab
复制代码
创建多个目录并绑定挂载到发现目录中
for i in $(seq 1 5); do sudo mkdir -p /mnt/$DISK_UUID/vol${i} /mnt/monitoring/$DISK_UUID_vol${i} sudo mount --bind /mnt/$DISK_UUID/vol${i} /mnt/monitoring/$DISK_UUID_vol${i}done
复制代码
将挂载条目永久绑定到 /etc/fstab 中
for i in $(seq 1 5); do echo /mnt/$DISK_UUID/vol${i} /mnt/monitoring/$DISK_UUID_vol${i} none bind 0 0 | sudo tee -a /etc/fstabdone
复制代码
给 TiDB Binlog 和备份数据使用的盘,可以参考步骤挂载盘,创建目录,并将新建的目录以 bind mount 方式挂载到 /mnt/backup 目录下。创建的目录个数取决于规划的 TiDB 集群数量、每个集群内的 Pump 数量及备份方式。1 个目录会对应创建 1 个 PV。每个 Pump 会使用 1 个 PV,每个 drainer 会使用 1 个 PV,所有 Ad-hoc 全量备份和所有定时全量备份会共用 1 个 PV。格式化和挂载
sudo mkfs.ext4 /dev/sdcDISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc)sudo mkdir /mnt/$DISK_UUIDsudo mount -t ext4 /dev/sdc /mnt/$DISK_UUID
复制代码
持久挂载进入 /etc/fstab
echo UUID=`sudo blkid -s UUID -o value /dev/sdc` /mnt/$DISK_UUID ext4 defaults 0 2 | sudo tee -a /etc/fstab
复制代码
创建多个目录并绑定挂载到发现目录中
for i in $(seq 1 3); do sudo mkdir -p /mnt/$DISK_UUID/vol${i} /mnt/backup/$DISK_UUID_vol${i} sudo mount --bind /mnt/$DISK_UUID/vol${i} /mnt/backup/$DISK_UUID_vol${i}done
复制代码
将挂载条目永久绑定到 /etc/fstab 中
for i in $(seq 1 3); do echo /mnt/$DISK_UUID/vol${i} /mnt/backup/$DISK_UUID_vol${i} none bind 0 0 | sudo tee -a /etc/fstabdone
复制代码
2) 部署 local-volume-provisioner1. 下载 local-volume-provisioner 部署文件。
wget https://raw.githubusercontent.com/pingcap/tidb-operator/v1.6.3/examples/local-pv/local-volume-provisioner.yaml
复制代码
3. 部署 local-volume-provisioner 程序。
kubectl apply -f local-volume-provisioner.yaml
复制代码
4. 检查 Pod 和 PV 状态。
kubectl get po -n kube-system -l app=local-volume-provisioner && \kubectl get pv | grep -e ssd-storage -e shared-ssd-storage -e monitoring-storage -e backup-storage -e flash-storage
复制代码
NAME READY STATUS RESTARTS AGElocal-volume-provisioner-dnqpz 1/1 Running 2 (5h48m ago) 2d17hlocal-volume-provisioner-gjk79 1/1 Running 2 (5h48m ago) 2d17hlocal-volume-provisioner-j68qs 1/1 Running 2 (5h48m ago) 2d17hlocal-volume-provisioner-rrbh2 1/1 Running 2 (5h48m ago) 2d17hlocal-volume-provisioner-xscmc 1/1 Running 4 (5h48m ago) 2d17hlocal-pv-13b3dd 19Gi RWO Delete Available ssd-storage 5h48mlocal-pv-25484854 19Gi RWO Delete Available ssd-storage 5h48mlocal-pv-2ed1be21 19Gi RWO Delete Available ssd-storage 5h48mlocal-pv-3f9ee4bc 19Gi RWO Delete Available ssd-storage 5h48mlocal-pv-51c10edc 39Gi RWO Delete Available monitoring-storage 10mlocal-pv-59b80edd 16Gi RWO Delete Available backup-storage 2d17hlocal-pv-8d3be1ee 16Gi RWO Delete Available backup-storage 2d17hlocal-pv-b76e3f5b 39Gi RWO Delete Available monitoring-storage 10mlocal-pv-b9a07d47 16Gi RWO Delete Available backup-storage 2d17hlocal-pv-bf3794de 19Gi RWO Delete Available backup-storage 9m5slocal-pv-c86c7ca3 39Gi RWO Delete Available shared-ssd-storage 5h12mlocal-pv-d669b05 39Gi RWO Delete Available shared-ssd-storage 5h12mlocal-pv-d8f00a6d 19Gi RWO Delete Available backup-storage 9m5slocal-pv-db4835ee 39Gi RWO Delete Available monitoring-storage 10mlocal-pv-e46b50cf 19Gi RWO Delete Available backup-storage 9m5slocal-pv-effbd590 39Gi RWO Delete Available shared-ssd-storage 5h12m
复制代码
修改 local-volume-provisioner 添加一个发现目录
vim local-volume-provisioner.yaml
复制代码
flash-storage: hostDir: /mnt/flash mountDir: /mnt/flash
复制代码
- mountPath: /mnt/flash mountPropagation: HostToContainer name: local-flash
- hostPath: path: /mnt/flash name: local-flash
复制代码
部署 TiDB Operator
先[[安装 Helm]]
创建 CRD
TiDB Operator 使用 Custom Resource Definition (CRD) 扩展 Kubernetes,所以要使用 TiDB Operator,必须先创建 TidbCluster 自定义资源类型。只需要在你的 Kubernetes 集群上创建一次即可:
kubectl create -f https://raw.githubusercontent.com/pingcap/tidb-operator/v1.6.3/manifests/crd.yaml
复制代码
显示如下信息表示 CRD 安装成功:
[root@k8s-master01 ~]# kubectl get crdNAME CREATED ATbackups.pingcap.com 2025-08-05T09:23:17Zbackupschedules.pingcap.com 2025-08-05T09:23:17Zcompactbackups.pingcap.com 2025-08-05T09:23:18Zdmclusters.pingcap.com 2025-08-05T09:23:18Zrestores.pingcap.com 2025-08-05T09:23:18Ztidbclusters.pingcap.com 2025-08-05T09:23:18Ztidbdashboards.pingcap.com 2025-08-05T09:23:18Ztidbinitializers.pingcap.com 2025-08-05T09:23:18Ztidbmonitors.pingcap.com 2025-08-05T09:23:18Ztidbngmonitorings.pingcap.com 2025-08-05T09:23:18Z
复制代码
自定义部署 TiDB Operator
在线部署 TiDB Operator
0. 配置 Helm repo 添加该仓库:
helm repo add pingcap https://charts.pingcap.org/
复制代码
查看查看当前支持的版本。
helm search repo -l tidb-operator
复制代码
1. 获取你要部署的 tidb-operator chart 中的 values.yaml 文件:
mkdir -p /usr/local/tidb-operator && \helm inspect values pingcap/tidb-operator --version=v1.6.3 > /usr/local/tidb-operator/values-tidb-operator.yaml
复制代码
2. 配置 TiDB Operator
vim /usr/local/tidb-operator/values-tidb-operator.yaml# 添加表示不部署 tidb-schedulerscheduler: create: false
复制代码
3. 部署 TiDB Operator 创建该 namespace。
kubectl create namespace tidb-admin
复制代码
部署
helm install tidb-operator pingcap/tidb-operator --namespace=tidb-admin --version=v1.6.3 -f /usr/local/tidb-operator/values-tidb-operator.yaml && \kubectl get po -n tidb-admin -l app.kubernetes.io/name=tidb-operator
复制代码
配置 TiDB 集群
为 TiDB 集群各个组件配置资源,其中 PD、TiKV、TiDB 是 TiDB 集群的核心服务组件
部署配置
创建一个专门放 tidb 集群配置文件目录
mkdir -p /usr/local/tidb_clustercd /usr/local/tidb_cluster
复制代码
编写 TidbCluster 资源配置文件
---apiVersion: pingcap.com/v1alpha1kind: TidbClustermetadata: name: advanced-tidb namespace: tidb-cluster
spec: version: "v8.5.2" timezone: UTC configUpdateStrategy: RollingUpdate helper: image: alpine:3.16.0 pvReclaimPolicy: Retain enableDynamicConfiguration: true tlsCluster: enabled: true pd: baseImage: pingcap/pd config: | [dashboard] internal-proxy = true replicas: 3 maxFailoverCount: 0 storageClassName: shared-ssd-storage requests: storage: 1Gi mountClusterClientSecret: true
tidb: baseImage: pingcap/tidb config: | graceful-wait-before-shutdown = 30 [performance] tcp-keep-alive = true replicas: 3 maxFailoverCount: 0 service: type: NodePort externalTrafficPolicy: Local tlsClient: enabled: true
tikv: baseImage: pingcap/tikv config: | [log.file] max-days = 30 max-backups = 30 replicas: 3 maxFailoverCount: 0 storageClassName: ssd-storage requests: storage: 39Gi mountClusterClientSecret: true
tiflash: baseImage: pingcap/tiflash maxFailoverCount: 0 replicas: 1 storageClaims: - resources: requests: storage: 29Gi storageClassName: flash-storage
tiproxy: baseImage: pingcap/tiproxy replicas: 3 version: v1.3.2 config: | [proxy] addr = "192.168.66.188:6000" max-connections = 100 [log] level = "info"
---apiVersion: pingcap.com/v1alpha1kind: TidbInitializermetadata: name: advanced-tidb-init namespace: tidb-clusterspec: image: tnir/mysqlclient cluster: namespace: tidb-cluster name: advanced-tidb initSql: |- create database app; tlsClientSecretName: advanced-tidb-tidb-initializer-client-secret---apiVersion: pingcap.com/v1alpha1kind: TidbMonitormetadata: name: basic-monitor namespace: tidb-clusterspec: clusters: - name: advanced-tidb persistent: true storageClassName: monitoring-storage storage: 10G prometheus: baseImage: prom/prometheus version: v2.27.1 service: type: NodePort grafana: baseImage: grafana/grafana version: 7.5.11 service: type: NodePort initializer: baseImage: pingcap/tidb-monitor-initializer version: v8.5.2 reloader: baseImage: pingcap/tidb-monitor-reloader version: v1.0.1 prometheusReloader: baseImage: quay.io/prometheus-operator/prometheus-config-reloader version: v0.49.0 imagePullPolicy: IfNotPresent
---apiVersion: pingcap.com/v1alpha1kind: TidbDashboardmetadata: name: basic-bashboard namespace: tidb-clusterspec: baseImage: pingcap/tidb-dashboard version: latest clusters: - name: advanced-tidb requests: storage: 10Gi storageClassName: monitoring-storage
复制代码
tiflash 配置可以参考[[部署 HTAP 存储引擎 TiFlash]]TiProxy 配置可以参考[[TiDB 集群部署负载均衡 TiProxy]]tidb server 开启 tls 配置参考[[为 MySQL 客户端开启 TLS]]监控配置参考[[部署 tidb 集群监控和告警]]
如果后面想修改配置
kubectl edit TidbCluster advanced-tidb -n tidb-cluster
复制代码
部署 TiDB 集群
1. 创建 Namespace:
kubectl create namespace tidb-cluster
复制代码
2. 部署 TiDB 集群:
kubectl apply -f tidb-cluster.yaml
复制代码
kubectl delete -f tidb-cluster.yaml
复制代码
查看 pod 状态
[root@k8s-master01 tidb_cluster]# kubectl get po -n tidb-cluster -l app.kubernetes.io/instance=advanced-tidbNAME READY STATUS RESTARTS AGEadvanced-tidb-discovery-64f99b76bc-j7gk9 1/1 Running 0 47madvanced-tidb-pd-0 1/1 Running 0 47madvanced-tidb-pd-1 1/1 Running 2 (46m ago) 47madvanced-tidb-pd-2 1/1 Running 1 (46m ago) 47madvanced-tidb-tidb-0 2/2 Running 0 44madvanced-tidb-tidb-1 2/2 Running 0 44madvanced-tidb-tidb-2 2/2 Running 0 44madvanced-tidb-tikv-0 1/1 Running 0 45madvanced-tidb-tikv-1 1/1 Running 0 45madvanced-tidb-tikv-2 1/1 Running 0 45m
复制代码
初始化 TiDB 集群
vim tidb-initializer.yaml
复制代码
---apiVersion: pingcap.com/v1alpha1kind: TidbInitializermetadata: name: tidb-init namespace: tidb-clusterspec: image: tnir/mysqlclient # imagePullPolicy: IfNotPresent cluster: namespace: tidb-cluster name: advanced-tidb initSql: |- create database app; # initSqlConfigMap: tidb-initsql passwordSecret: tidb-secret # permitHost: 172.6.5.8 # resources: # limits: # cpu: 1000m # memory: 500Mi # requests: # cpu: 100m # memory: 50Mi # timezone: "Asia/Shanghai"
复制代码
注意:spec.cluster.name 是集群的名称和上面部署的一致
初始化账号和密码设置
集群创建时默认会创建 root 账号,但是密码为空,这会带来一些安全性问题。可以通过如下步骤为 root 账号设置初始密码:通过下面命令创建 Secret 指定 root 账号密码:
kubectl create secret generic tidb-secret --from-literal=root=123456 --namespace=tidb-cluster
复制代码
执行初始化
kubectl apply -f tidb-initializer.yaml
复制代码
以上命令会自动创建一个初始化的 Job,该 Job 会尝试利用提供的 secret 给 root 账号创建初始密码,并且创建其它账号和密码(如果指定了的话)。初始化完成后 Pod 状态会变成 Completed,之后通过 MySQL 客户端登录时需要指定这里设置的密码。
[root@k8s-master01 tidb_cluster]# kubectl get pod -n tidb-clusterNAME READY STATUS RESTARTS AGEadvanced-tidb-tidb-initializer-774zp 0/1 Completed 0 4m36s
复制代码
访问 TiDB 集群
获取 TiDB Service 信息
kubectl get svc -n tidb-cluster
复制代码
获取 tidb-serve 分布所在节点
kubectl -n tidb-cluster get pods -l "app.kubernetes.io/component=tidb,app.kubernetes.io/instance=advanced-tidb" -ojsonpath="{range .items[*]}{.spec.nodeName}{'\n'}{end}"
复制代码
[[yum 安装 mysql-centos7]]安装 mysql 客户端测试连接 TIDB
不用安装 mysql 服务端,这里只需要 mysql 客户端
yum install -y mysql-community-client
复制代码
内部访问:
mysql -uroot -p123456 -h 10.99.92.240 -P4000
复制代码
外部访问,IP 写 tidb-serve 分布所在节点其中一个
mysql -uroot -p123456 -h 192.168.66.24 -P 32452
复制代码
评论