环境准备
Kubernetes 上的 TiDB 集群环境需求 | TiDB 文档中心
修改主机名称解析
cat >> /etc/hosts << EOF
192.168.66.21 k8s-master01
192.168.66.22 k8s-master02
192.168.66.23 k8s-master03
192.168.66.24 k8s-node01
192.168.66.25 k8s-node02
192.168.66.26 k8s-node03
192.168.66.27 k8s-node04
192.168.66.28 k8s-node05
EOF
设置主机名
hostnamectl set-hostname k8s-master01
hostnamectl 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
mkdir -p /data1/docker
安装完 Docker 服务以后,执行以下步骤:
- 将 Docker 的数据保存到一块单独的盘上,Docker 的数据主要包括镜像和容器日志数据。通过设置
--data-root
参数来实现:
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"data-root": "/data1/docker"
}
EOF
上面会将 Docker 的数据目录设置为 /data1/docker
。
-
设置 Docker daemon 的 ulimit。
- 创建 docker service 的 systemd drop-in 目录
/etc/systemd/system/docker.service.d
:
mkdir -p /etc/systemd/system/docker.service.d
- 创建
/etc/systemd/system/docker.service.d/limit-nofile.conf
文件,并配置LimitNOFILE
参数的值,取值范围为大于等于1048576
的数字即可。
cat > /etc/systemd/system/docker.service.d/limit-nofile.conf <<EOF [Service] LimitNOFILE=1048576 EOF
- 重新加载配置。
systemctl daemon-reload && systemctl restart docker
- 创建 docker service 的 systemd drop-in 目录
自启动开启
systemctl enable docker
Kubernetes 服务
[[创建高可用集群]]
其余node节点加入集群
kubeadm join 192.168.66.29:6553 --token ncll7c.kt4ycv9sfnygvbrw \
--discovery-token-ca-cert-hash sha256:b6ac15003f7968ab23da26015b377dfc8bae1922b1a3af0bd925634903d91421
全部节点加入集群成功
[root@k8s-master01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 NotReady control-plane,master 45m v1.23.6
k8s-master02 NotReady control-plane,master 44m v1.23.6
k8s-master03 NotReady control-plane,master 43m v1.23.6
k8s-node01 NotReady <none> 88s v1.23.6
k8s-node02 NotReady <none> 41s v1.23.6
k8s-node03 NotReady <none> 35s v1.23.6
k8s-node04 NotReady <none> 26s v1.23.6
k8s-node05 NotReady <none> 22s v1.23.6
安装网络插件
[[kubeadm初始化集群#安装网络插件]]
[root@localhost ~]# kubectl get pod -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-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 nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 17m v1.23.6
k8s-master02 Ready control-plane,master 7m46s v1.23.6
k8s-master03 Ready control-plane,master 8m33s v1.23.6
k8s-node01 Ready <none> 6m19s v1.23.6
k8s-node02 Ready <none> 6m13s v1.23.6
k8s-node03 Ready <none> 6m10s v1.23.6
k8s-node04 Ready <none> 6m7s v1.23.6
k8s-node05 Ready <none> 6m3s v1.23.6
持久化存储配置
TiDB 集群中 PD、TiKV、监控等组件以及 TiDB Binlog 和备份等工具都需要使用将数据持久化的存储。Kubernetes 上的数据持久化需要使用 PersistentVolume (PV)。Kubernetes 提供多种存储类型,主要分为两大类:
-
网络存储
-
存储介质不在当前节点,而是通过网络方式挂载到当前节点。一般有多副本冗余提供高可用保证,在节点出现故障时,对应网络存储可以再挂载到其它节点继续使用。
-
本地存储
-
存储介质在当前节点,通常能提供比网络存储更低的延迟,但没有多副本冗余,一旦节点出故障,数据就有可能丢失。如果是 IDC 服务器,节点故障可以一定程度上对数据进行恢复,但公有云上使用本地盘的虚拟机在节点故障后,数据是无法找回的。
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 40G node4-node5: TiFlash 30G node1-node2:backup 30G node3:monitoring 20G node4-node5: sharedssd 10G
1)准备本地存储
- 给 TiKV 数据使用的盘,可通过普通挂载方式将盘挂载到
/mnt/ssd
目录。 出于性能考虑,推荐 TiKV 独占一个磁盘,并且推荐磁盘类型为 SSD。
格式化和挂载
sudo mkfs.ext4 /dev/sdb
DISK_UUID=$(sudo blkid -s UUID -o value /dev/sdb)
sudo mkdir -p /mnt/ssd/$DISK_UUID
sudo 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/sde
DISK_UUID=$(sudo blkid -s UUID -o value /dev/sde)
sudo mkdir -p /mnt/flash/$DISK_UUID
sudo 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/sdc
DISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc)
sudo mkdir /mnt/$DISK_UUID
sudo 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/fstab
done
给监控数据使用的盘,可以参考步骤挂载盘,创建目录,并将新建的目录以 bind mount 方式挂载到 /mnt/monitoring
目录下。
1 个目录会对应创建 1 个 PV。每个 TiDB 集群的监控数据会使用 1 个 PV。
格式化和挂载
sudo mkfs.ext4 /dev/sdc
DISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc)
sudo mkdir /mnt/$DISK_UUID
sudo 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/fstab
done
给 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/sdc
DISK_UUID=$(sudo blkid -s UUID -o value /dev/sdc)
sudo mkdir /mnt/$DISK_UUID
sudo 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/fstab
done
2)部署 local-volume-provisioner 1.下载 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 AGE
local-volume-provisioner-dnqpz 1/1 Running 2 (5h48m ago) 2d17h
local-volume-provisioner-gjk79 1/1 Running 2 (5h48m ago) 2d17h
local-volume-provisioner-j68qs 1/1 Running 2 (5h48m ago) 2d17h
local-volume-provisioner-rrbh2 1/1 Running 2 (5h48m ago) 2d17h
local-volume-provisioner-xscmc 1/1 Running 4 (5h48m ago) 2d17h
local-pv-13b3dd 19Gi RWO Delete Available ssd-storage 5h48m
local-pv-25484854 19Gi RWO Delete Available ssd-storage 5h48m
local-pv-2ed1be21 19Gi RWO Delete Available ssd-storage 5h48m
local-pv-3f9ee4bc 19Gi RWO Delete Available ssd-storage 5h48m
local-pv-51c10edc 39Gi RWO Delete Available monitoring-storage 10m
local-pv-59b80edd 16Gi RWO Delete Available backup-storage 2d17h
local-pv-8d3be1ee 16Gi RWO Delete Available backup-storage 2d17h
local-pv-b76e3f5b 39Gi RWO Delete Available monitoring-storage 10m
local-pv-b9a07d47 16Gi RWO Delete Available backup-storage 2d17h
local-pv-bf3794de 19Gi RWO Delete Available backup-storage 9m5s
local-pv-c86c7ca3 39Gi RWO Delete Available shared-ssd-storage 5h12m
local-pv-d669b05 39Gi RWO Delete Available shared-ssd-storage 5h12m
local-pv-d8f00a6d 19Gi RWO Delete Available backup-storage 9m5s
local-pv-db4835ee 39Gi RWO Delete Available monitoring-storage 10m
local-pv-e46b50cf 19Gi RWO Delete Available backup-storage 9m5s
local-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 crd
NAME CREATED AT
backups.pingcap.com 2025-08-05T09:23:17Z
backupschedules.pingcap.com 2025-08-05T09:23:17Z
compactbackups.pingcap.com 2025-08-05T09:23:18Z
dmclusters.pingcap.com 2025-08-05T09:23:18Z
restores.pingcap.com 2025-08-05T09:23:18Z
tidbclusters.pingcap.com 2025-08-05T09:23:18Z
tidbdashboards.pingcap.com 2025-08-05T09:23:18Z
tidbinitializers.pingcap.com 2025-08-05T09:23:18Z
tidbmonitors.pingcap.com 2025-08-05T09:23:18Z
tidbngmonitorings.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-scheduler
scheduler:
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_cluster
cd /usr/local/tidb_cluster
编写TidbCluster资源配置文件
vim tidb-cluster.yaml
---
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
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/v1alpha1
kind: TidbInitializer
metadata:
name: advanced-tidb-init
namespace: tidb-cluster
spec:
image: tnir/mysqlclient
cluster:
namespace: tidb-cluster
name: advanced-tidb
initSql: |-
create database app;
tlsClientSecretName: advanced-tidb-tidb-initializer-client-secret
---
apiVersion: pingcap.com/v1alpha1
kind: TidbMonitor
metadata:
name: basic-monitor
namespace: tidb-cluster
spec:
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/v1alpha1
kind: TidbDashboard
metadata:
name: basic-bashboard
namespace: tidb-cluster
spec:
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-tidb
NAME READY STATUS RESTARTS AGE
advanced-tidb-discovery-64f99b76bc-j7gk9 1/1 Running 0 47m
advanced-tidb-pd-0 1/1 Running 0 47m
advanced-tidb-pd-1 1/1 Running 2 (46m ago) 47m
advanced-tidb-pd-2 1/1 Running 1 (46m ago) 47m
advanced-tidb-tidb-0 2/2 Running 0 44m
advanced-tidb-tidb-1 2/2 Running 0 44m
advanced-tidb-tidb-2 2/2 Running 0 44m
advanced-tidb-tikv-0 1/1 Running 0 45m
advanced-tidb-tikv-1 1/1 Running 0 45m
advanced-tidb-tikv-2 1/1 Running 0 45m
初始化 TiDB 集群
vim tidb-initializer.yaml
---
apiVersion: pingcap.com/v1alpha1
kind: TidbInitializer
metadata:
name: tidb-init
namespace: tidb-cluster
spec:
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-cluster
NAME READY STATUS RESTARTS AGE
advanced-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