tidb-operator 安装 TiDB 集群
- 2024-04-26 北京
本文字数:10051 字
阅读完需:约 33 分钟
作者: WalterWj 原文来源:https://tidb.net/blog/f4b5256b
install tidb
硬件配置
# 停止并禁用 firewalld 防火墙服务systemctl stop firewalldsystemctl disable firewalld
# 设置 SELinux 为宽容模式setenforce 0sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 禁用交换分区swapoff -ased -i 's/^\(.*swap.*\)$/#\1/' /etc/fstab
# 加载网络桥接模块 br_netfiltermodprobe br_netfilter
# 创建并配置 Kubernetes 系统优化参数文件cat <<EOF > /etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.bridge.bridge-nf-call-arptables = 1net.core.somaxconn = 32768vm.swappiness = 0net.ipv4.tcp_syncookies = 0net.ipv4.ip_forward = 1fs.file-max = 1000000fs.inotify.max_user_watches = 1048576fs.inotify.max_user_instances = 1024net.ipv4.conf.all.rp_filter = 1net.ipv4.neigh.default.gc_thresh1 = 80000net.ipv4.neigh.default.gc_thresh2 = 90000net.ipv4.neigh.default.gc_thresh3 = 100000EOF
# 应用最新的系统配置sysctl --system
# 启用并启动 irqbalance 服务,用于改善系统中断处理systemctl enable irqbalancesystemctl start irqbalance
# 设置 CPU 性能模式为 "performance"cpupower frequency-set --governor performance
# 设置系统文件打开数限制cat <<EOF >> /etc/security/limits.confroot soft nofile 1048576root hard nofile 1048576root soft stack 10240EOF
# 再次应用最新的系统配置sysctl --system
# 配置 Kubelet 的工作目录echo "KUBELET_EXTRA_ARGS=--root-dir=/data1/kubelet" > /etc/sysconfig/kubelet# 重启 Kubelet 服务以应用更改systemctl restart kubelet
配置 Storage Class
这里使用本地 PV,官网推荐方法是使用挂载点方式来配置目录,相当于 TiDB OP 部署下,mount 目录。
服务器上没有多盘或者使用分区来挂盘,我们这里模拟挂载点:
# 创建必要的目录结构mkdir -p /mnt/k8s-backup/subdir /k8s-backup/mountmkdir -p /mnt/k8s-monitor/subdir /k8s-monitor/mountmkdir -p /mnt/k8s-ssd/subdir /k8s-ssd/mountmkdir -p /mnt/k8s-sharessd/subdir /k8s-sharessd/mountmkdir -p /mnt/k8s-data/subdir /k8s-data/mountmkdir -p /mnt/k8s-log/subdir /k8s-log/mount
# 等待文件系统更新sleep 1
# 将挂载信息加入到 fstab 文件,确保重启后自动挂载echo "/mnt/k8s-backup/subdir /k8s-backup/mount none bind 0 0" | sudo tee -a /etc/fstabecho "/mnt/k8s-monitor/subdir /k8s-monitor/mount none bind 0 0" | sudo tee -a /etc/fstabecho "/mnt/k8s-ssd/subdir /k8s-ssd/mount none bind 0 0" | sudo tee -a /etc/fstabecho "/mnt/k8s-sharessd/subdir /k8s-sharessd/mount none bind 0 0" | sudo tee -a /etc/fstabecho "/mnt/k8s-data/subdir /k8s-data/mount none bind 0 0" | sudo tee -a /etc/fstabecho "/mnt/k8s-log/subdir /k8s-log/mount none bind 0 0" | sudo tee -a /etc/fstab
# 立即挂载所有配置sudo mount -a
上面准备好之后,我们部署 local-volume-provisioner
local-volume-provisioner 的主要作用包括:
自动发现本地存储设备: 自动识别节点上的本地存储资源,如某个特定目录或分区。
创建 Persistent Volumes (PVs): 对于发现的每个本地存储设备,自动创建对应的 PV 对象。这样,用户就不需要手动为每个本地存储设备创建 PV。
监控和管理存储: 监控本地存储的状态,确保存储资源的健康和可用性。
部署 local-volume-provisioner
rm -rf local-volume-provisioner.yamlwget https://raw.githubusercontent.com/pingcap/tidb-operator/v1.5.2/examples/local-pv/local-volume-provisioner.yaml
# 修改配置中的 configmap 里面的 storage 信息。sed -i 's|/mnt/ssd|/k8s-ssd|g' local-volume-provisioner.yamlsed -i 's|/mnt/sharedssd|/k8s-sharessd|g' local-volume-provisioner.yamlsed -i 's|/mnt/monitoring|/k8s-monitor|g' local-volume-provisioner.yamlsed -i 's|/mnt/backup|/k8s-backup|g' local-volume-provisioner.yaml# 以上会给 tikv/pd/监控/备份使用# 默认 pv 使用的 delete 模式管理,生产可以修改配置为 Retain# 这里给 tidb 添加一个日志盘来做 data & 日志存储,添加以下内容:# 所有 StorageClass 添加下:allowVolumeExpansion: true---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: "log-storage"provisioner: "kubernetes.io/no-provisioner"volumeBindingMode: "WaitForFirstConsumer"allowVolumeExpansion: true---apiVersion: v1kind: ConfigMap... # 注意这里内容是省略的 log-storage: hostDir: /k8s-log mountDir: /k8s-log---apiVersion: apps/v1kind: DaemonSet... # 注意这里内容是省略的 volumeMounts: ... # 注意这里内容是省略的 - mountPath: /k8s-log name: local-log mountPropagation: "HostToContainer" volumes: ... # 注意这里内容是省略的 - name: local-log hostPath: path: /k8s-log
locall-volume-provisioner 配置说明:
这个配置文件包含了多个 Kubernetes 资源定义,用于配置本地存储卷的供应,特别是对于没有自动卷供应能力的存储类(StorageClass)。配置内容涉及存储类定义、配置映射、守护进程集(DaemonSet)以及相关的服务账户和角色绑定。以下是关于这些资源及其功能的简洁说明:
存储类(StorageClass)
文件定义了四个存储类:
monitoring-storagessd-storageshared-ssd-storagebackup-storage
这些存储类都使用 "kubernetes.io/no-provisioner" 作为供应器,这意味着它们不会自动供应存储。volumeBindingMode 设置为 "WaitForFirstConsumer",表示卷的绑定和动态供应将延迟到 Pod 引用它们为止。
配置映射(ConfigMap)
local-provisioner-config 是一个配置映射,为守护进程集提供配置。它包含了节点标签和存储类映射信息,指定了每个存储类对应的宿主目录 (hostDir) 和挂载目录 (mountDir)。
守护进程集(DaemonSet)
local-volume-provisioner 守护进程集用于部署一个运行在每个节点上的容器,这个容器负责将宿主机的目录供应为本地卷。它包括一些容器级的安全配置,并通过环境变量和挂载点配置来控制存储供应的行为。
服务账户和角色绑定
配置包括一个服务账户 local-storage-admin 和两个角色绑定,允许这个服务账户执行必要的 Kubernetes API 操作,如获取节点信息和管理持久卷。
核心修改配置项
- 存储路径修改:核心的修改项包括在 ConfigMap 的 storageClassMap 部分,将每个存储类的 hostDir 和 mountDir 修改为具体的路径,如 /k8s-ssd 等。
- 守护进程集的挂载点:在 DaemonSet 的容器配置中,volumeMounts 和 volumes 部分需要确保每个挂载点和宿主路径与 ConfigMap 中定义的路径相匹配。
这个配置整体上用于在不同的 Kubernetes 集群节点上提供特定的存储解决方案,支持没有动态供应能力的存储使用场景,适用于需要手动管理存储资源的环境。
应用
kubectl apply -f local-volume-provisioner.yaml
# 查看 volume 的管理 podkubectl get pod -n kube-system -l='app=local-volume-provisioner'NAME READY STATUS RESTARTS AGElocal-volume-provisioner-49mzb 1/1 Running 0 4m38slocal-volume-provisioner-ffrjn 1/1 Running 0 4m38slocal-volume-provisioner-kvgtq 1/1 Running 0 4m38s
# 如果发现目录下无任何挂载点,则不会创建任何 PV,那么输出将为空。$ kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGElocal-pv-20fa5bc3 196Gi RWO Delete Available monitoring-storage <unset> 97mlocal-pv-2a2ee5a6 196Gi RWO Delete Available ssd-storage <unset> 97mlocal-pv-73774db1 196Gi RWO Delete Available ssd-storage <unset> 97mlocal-pv-74b8243d 196Gi RWO Delete Available shared-ssd-storage <unset> 99mlocal-pv-771c997e 196Gi RWO Delete Available backup-storage <unset> 97mlocal-pv-9d4c16f 196Gi RWO Delete Available ssd-storage <unset> 99mlocal-pv-d3e9ec82 196Gi RWO Delete Available monitoring-storage <unset> 97mlocal-pv-e8d37976 196Gi RWO Delete Available shared-ssd-storage <unset> 97mlocal-pv-eda9391b 196Gi RWO Delete Available shared-ssd-storage <unset> 97mlocal-pv-f0c19cfb 196Gi RWO Delete Available backup-storage <unset> 97mlocal-pv-f1a2bef9 196Gi RWO Delete Available backup-storage <unset> 99mlocal-pv-f72512e5 196Gi RWO Delete Available monitoring-storage <unset> 99m
注意 STORAGECLASS,后续会使用。
以上,部署环境和盘已经都准备好了。
TiDB 安装
安装 helm
官网:https://helm.sh/docs/intro/install/
wget https://get.helm.sh/helm-v3.14.4-linux-amd64.tar.gz
tar -xzvf helm-v3.14.4-linux-amd64.tar.gz
install -m 755 linux-amd64/helm /usr/local/sbin/helm
CRD 安装
# 配置 helm repohelm repo add pingcap https://charts.pingcap.org/
helm search repo pingcap# 其他操作看官网 https://docs.pingcap.com/zh/tidb-in-kubernetes/stable/tidb-toolkit
# 创建 CRD# Custom Resource Definition。CRD 允许你在 Kubernetes 集群中定义自定义资源wget https://raw.githubusercontent.com/pingcap/tidb-operator/v1.5.2/manifests/crd.yaml# 使用 apply 会有超长问题,yaml 太大了kubectl create -f ./crd.yamlkubectl get crd
operator 安装
# 查到 chart_version,例如:v1.5.2helm search repo -l tidb-operator
export chart_version=v1.5.2mkdir -p ${HOME}/tidb-operator && \helm inspect values pingcap/tidb-operator --version=${chart_version} > ${HOME}/tidb-operator/values-tidb-operator.yaml
# 基本无需修改 values-tidb-operator.yaml,tidb-operator 相当于在线的 tiup,管理/检测 tidb-cluster 集群# 推荐安装到 tidb-admin namespaces 下,可以看到对应 manager 的 pod,查看 pod 日志可以排查定位 tidb 集群管理上的问题# !! TiDB Operator 默认会管理 Kubernetes 集群中的所有 TiDB 集群,如仅需其管理特定 namespace 下的集群,则可在 values.yaml 中设置 clusterScoped: false# !! 新版本下,scheduler.create 推荐关闭,使用 default schedule 即可sed -i -e '/scheduler:/,/create:/ s/create: true/create: false/' ${HOME}/tidb-operator/values-tidb-operator.yaml# !! 修改 Timezonesed -i 's/timezone: UTC/timezone: "Asia\/Shanghai"/g' values-tidb-operator.yamlsed -i '/env: \[\]/c\ env:\n - name: TZ\n value: Asia/Shanghai\' values-tidb-operator.yaml
kubectl create ns tidb-adminhelm install tidb-operator pingcap/tidb-operator --namespace=tidb-admin --version=${chart_version} -f ${HOME}/tidb-operator/values-tidb-operator.yaml && \kubectl get po -n tidb-admin -l app.kubernetes.io/name=tidb-operator
# 查看是否 OKkubectl get pod -n tidb-admin -owideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEStidb-controller-manager-86bb89ddd-m5svk 1/1 Running 0 15s 10.244.1.10 vm172-16-201-193 <none> <none>
k8s 节点打标签
和 tikv 的 label 类似,服务器打标签,让各个组件优先调度到对应服务器
$ kubectl get nodes -owideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEvm172-16-201-18 Ready control-plane 19h v1.29.3 172.16.201.18 <none> CentOS Linux 7 (Core) 3.10.0-1160.102.1.el7.x86_64 containerd://1.6.31vm172-16-201-193 Ready <none> 19h v1.29.3 172.16.201.193 <none> CentOS Linux 7 (Core) 3.10.0-1160.102.1.el7.x86_64 containerd://1.6.31vm172-16-201-226 Ready <none> 19h v1.29.3 172.16.201.226 <none> CentOS Linux 7 (Core) 3.10.0-1160.102.1.el7.x86_64 containerd://1.6.31
kubectl label node vm172-16-201-18 node-role.kubernetes.io/pd=truekubectl label node vm172-16-201-193 node-role.kubernetes.io/pd=truekubectl label node vm172-16-201-226 node-role.kubernetes.io/pd=true
kubectl label node vm172-16-201-18 node-role.kubernetes.io/tikv=truekubectl label node vm172-16-201-193 node-role.kubernetes.io/tikv=truekubectl label node vm172-16-201-226 node-role.kubernetes.io/tikv=true
kubectl label node vm172-16-201-18 node-role.kubernetes.io/tidb=truekubectl label node vm172-16-201-193 node-role.kubernetes.io/tidb=truekubectl label node vm172-16-201-226 node-role.kubernetes.io/tidb=true# 我们这里 3 个节点都运行各个组件进行调度
[root@vm172-16-201-18 tidb-operator]# kubectl get nodesNAME STATUS ROLES AGE VERSIONvm172-16-201-18 Ready control-plane,pd,tidb,tikv 19h v1.29.3vm172-16-201-193 Ready pd,tidb,tikv 19h v1.29.3vm172-16-201-226 Ready pd,tidb,tikv 19h v1.29.3
安装 tidb 集群
# get deploy yaml:https://github.com/pingcap/tidb-operator/blob/v1.5.2/examples/advanced/tidb-cluster.yaml,可以按照 operator 的版本你来选择模板wget https://raw.githubusercontent.com/pingcap/tidb-operator/v1.5.2/examples/advanced/tidb-cluster.yaml
配置文件修改:
name 集群名
namespace 放在哪个 namespace
version tidb 版本
pvReclaimPolicy pv 策略,生产推荐 Retain,我们这里改为 delete
requests 和 limit 下的 CPU 和 mem:cpu 里面 1000m = 1 vcore
service 配置下,这里是对外服务 ip
nodeSelector 打亲和,我们会对我们 k8s 打 label,然后这个配置相当于组件会往有这些 label 的节点去调度
storageClassName 之前 pv 的 classname,我们这里有
monitoring-storagessd-storageshared-ssd-storagebackup-storagedataSubDir pd/tikv/tiflash 的数据存储目录。默认是在 /var/lib/[pd tikv tiflash]. 配置这个之后,相当于在原来目录下,在创建一级目录,主要配合配置日志落盘使用的。这里配置为 “data”
config 里面配置每个组件的各种配置
spec.startScriptVersion: v2 ,新特性:诊断模式,使用 dig 命令替换 nslookup 命令来解析 DNS。
tidb 特殊一些,我们配置 path = “/tidb/data” 和 storageVolums
完整配置,去掉注释:
grep -Ev "#|$^" tidb-cluster.yamlapiVersion: pingcap.com/v1alpha1kind: TidbClustermetadata: name: tidb-wj namespace: tidbspec: version: "v7.5.1" timezone: UTC startScriptVersion: v2 configUpdateStrategy: RollingUpdate helper: image: alpine:3.16.0 pvReclaimPolicy: Delete enableDynamicConfiguration: true pd: baseImage: pingcap/pd env: - name: GRPC_DNS_RESOLVER value: native config: | [dashboard] internal-proxy = true [log] [log.file] filename = "/var/lib/pd/log/pd.log" max-days = 15 [replication] location-labels = ["host"] replicas: 3 maxFailoverCount: 0 requests: cpu: 1000m memory: 500Mi storage: 196Gi limits: cpu: 1000m memory: 1Gi service: type: NodePort nodeSelector: node-role.kubernetes.io/pd: "true" mountClusterClientSecret: true storageClassName: "shared-ssd-storage" dataSubDir: "data" tidb: baseImage: pingcap/tidb config: | path = "/data/tidb" [performance] tcp-keep-alive = true [log] slow-query-file = "/data/tidb/log/tidb-slow.log" [log.file] filename = "/data/tidb/log/tidb.log" max-backups = 15 replicas: 2 maxFailoverCount: 0 requests: cpu: 1000m memory: 1Gi limits: cpu: 1000m memory: 1Gi service: type: NodePort externalTrafficPolicy: Local nodeSelector: node-role.kubernetes.io/tidb: "true" separateSlowLog: false storageClassName: "tidb-storage" storageVolumes: - name: data storageClassName: log-storage storageSize: 196Gi mountPath: "/data/tidb" tikv: baseImage: pingcap/tikv env: - name: GRPC_DNS_RESOLVER value: native config: | log-level = "info" [log.file] filename = "/var/lib/tikv/log/tikv.log" log-level = "info" max-backups = 15 [resolved-ts] enable = false
[storage] reserve-space = "0MB" [storage.block-cache] capacity = "512MiB" replicas: 3 maxFailoverCount: 0 requests: cpu: 1000m memory: 1Gi storage: 196Gi limits: cpu: 2000m memory: 2Gi storage: 196Gi nodeSelector: node-role.kubernetes.io/tikv: "true" mountClusterClientSecret: true storageClassName: "ssd-storage" dataSubDir: "data"
部署 tidb
# create nskubectl create ns tidbkubectl apply -f tidb-cluster.yamlkubectl get all,pvc -n tidb
部署完成后,可以去任何一个节点上 (包含了 tidb/pd/tikv 的 POD 的) 查看目录使用情况:
tree /k8s-log//k8s-log/└── mount └── log ├── oom_record └── tidb.log
3 directories, 1 file[root@vm172-16-201-193 ~]# tree /k8s-log/ /k8s-sharessd/ /k8s-ssd//k8s-log/└── mount └── log ├── oom_record └── tidb.log/k8s-sharessd/├── mount│ ├── data│ │ ├── hot-region│ │ │ ├── 000001.log│ │ │ ├── CURRENT│ │ │ ├── LOCK│ │ │ ├── LOG│ │ │ └── MANIFEST-000000│ │ ├── join│ │ ├── member│ │ │ ├── snap│ │ │ │ └── db│ │ │ └── wal│ │ │ ├── 0000000000000000-0000000000000000.wal│ │ │ └── 0.tmp│ │ └── region-meta│ │ ├── 000001.log│ │ ├── CURRENT│ │ ├── LOCK│ │ ├── LOG│ │ └── MANIFEST-000000│ └── log│ └── pd.log└── subdir/k8s-ssd/├── mount│ ├── data│ │ ├── db│ │ │ ├── 000005.log│ │ │ ├── CURRENT│ │ │ ├── IDENTITY│ │ │ ├── LOCK│ │ │ ├── MANIFEST-000004│ │ │ ├── OPTIONS-000011│ │ │ └── OPTIONS-000013│ │ ├── import│ │ ├── last_tikv.toml│ │ ├── LOCK│ │ ├── raftdb.info│ │ ├── raft-engine│ │ │ ├── 0000000000000001.raftlog│ │ │ ├── 0000000000000001.rewrite│ │ │ └── LOCK│ │ ├── rocksdb.info│ │ └── snap│ └── log│ └── tikv.log└── subdir
20 directories, 31 files
这里部署 pd 和 tikv log 和 data 目录放置在同一级。
tidb-server 的日志放置对应 log-storage 挂载目录下
登录 TiDB
kubectl get all -n tidbNAME READY STATUS RESTARTS AGEpod/tidb-wj-discovery-5687bd8fc4-t45fk 1/1 Running 0 14mpod/tidb-wj-pd-0 1/1 Running 0 14mpod/tidb-wj-pd-1 1/1 Running 0 14mpod/tidb-wj-pd-2 1/1 Running 0 14mpod/tidb-wj-tidb-0 1/1 Running 0 14mpod/tidb-wj-tidb-1 1/1 Running 0 14mpod/tidb-wj-tikv-0 1/1 Running 0 14mpod/tidb-wj-tikv-1 1/1 Running 0 14mpod/tidb-wj-tikv-2 1/1 Running 0 14m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/tidb-wj-discovery ClusterIP 10.105.149.83 <none> 10261/TCP,10262/TCP 14mservice/tidb-wj-pd NodePort 10.102.173.121 <none> 2379:31166/TCP 14mservice/tidb-wj-pd-peer ClusterIP None <none> 2380/TCP,2379/TCP 14mservice/tidb-wj-tidb NodePort 10.102.58.180 <none> 4000:30321/TCP,10080:31912/TCP 14mservice/tidb-wj-tidb-peer ClusterIP None <none> 10080/TCP 14mservice/tidb-wj-tikv-peer ClusterIP None <none> 20160/TCP 14m
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/tidb-wj-discovery 1/1 1 1 14m
NAME DESIRED CURRENT READY AGEreplicaset.apps/tidb-wj-discovery-5687bd8fc4 1 1 1 14m
NAME READY AGEstatefulset.apps/tidb-wj-pd 3/3 14mstatefulset.apps/tidb-wj-tidb 2/2 14mstatefulset.apps/tidb-wj-tikv 3/3 14m
可以看到 service 中 TiDB 的 cluster ip 为 10.102.58.180
所以登录方式为:
mysql -uroot -h10.102.58.180 -P4000 -p
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/5d8915dc18f95afa2e984f806】。文章转载请联系作者。
TiDB 社区干货传送门
TiDB 社区官网:https://tidb.net/ 2021-12-15 加入
TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/







评论