在 Kubernetes 中配置 TiDB 集群
本文档介绍了如何配置生产可用的 TiDB 集群。涵盖以下内容:
资源配置
部署前需要根据实际情况和需求,为 TiDB 集群各个组件配置资源,其中 PD、TiKV、TiDB 是 TiDB 集群的核心服务组件,在生产环境下它们的资源配置还需要按组件要求指定,具体参考:资源配置推荐。
为了保证 TiDB 集群的组件在 Kubernetes 中合理的调度和稳定的运行,建议为其设置 Guaranteed 级别的 QoS,通过在配置资源时让 limits 等于 requests 来实现, 具体参考:配置 QoS。
如果使用 NUMA 架构的 CPU,为了获得更好的性能,需要在节点上开启 Static
的 CPU 管理策略。为了 TiDB 集群组件能独占相应的 CPU 资源,除了为其设置上述 Guaranteed 级别的 QoS 外,还需要保证 CPU 的配额必须是大于或等于 1 的整数。具体参考: CPU 管理策略。
部署配置
通过配置 TidbCluster
CR 来配置 TiDB 集群。参考 TidbCluster 示例和 API 文档(示例和 API 文档请切换到当前使用的 TiDB Operator 版本)完成 TidbCluster CR (Custom Resource)。
集群名称
通过更改 TiDBCuster
CR 中的 metadata.name
来配置集群名称。
版本
正常情况下,集群内的各组件应该使用相同版本,所以一般建议配置 spec.<pd/tidb/tikv/pump/tiflash/ticdc>.baseImage
+ spec.version
即可。如果需要为不同的组件配置不同的版本,则可以配置 spec.<pd/tidb/tikv/pump/tiflash/ticdc>.version
。
相关参数的格式如下:
spec.version
,格式为imageTag
,例如v5.0.6
spec.<pd/tidb/tikv/pump/tiflash/ticdc>.baseImage
,格式为imageName
,例如pingcap/tidb
spec.<pd/tidb/tikv/pump/tiflash/ticdc>.version
,格式为imageTag
,例如v5.0.6
推荐配置
configUpdateStrategy
建议设置 spec.configUpdateStrategy: RollingUpdate
,开启配置自动更新特性,在每次配置更新时,自动对组件执行滚动更新,将修改后的配置应用到集群中。
enableDynamicConfiguration
建议通过设置 spec.enableDynamicConfiguration: true
配置 TiKV 的 --advertise-status-addr
启动参数。
版本支持:TiDB v4.0.1 及更高版本,TiDB Operator v1.1.1 及更高版本。
pvReclaimPolicy
建议设置 spec.pvReclaimPolicy: Retain
,确保 PVC 被删除后 PV 仍然保留,保证数据安全。
mountClusterClientSecret
PD 和 TiKV 支持配置 mountClusterClientSecret
。如果开启了集群组件间 TLS 支持,建议配置 spec.pd.mountClusterClientSecret: true
和 spec.tikv.mountClusterClientSecret: true
,这样 TiDB Operator 会自动将 ${cluster_name}-cluster-client-secret
证书挂载到 PD 和 TiKV 容器,方便使用 pd-ctl
和 tikv-ctl
。
存储
存储类型
如果需要设置存储类型,可以修改 ${cluster_name}/tidb-cluster.yaml
中各组件的 storageClassName
字段。关于 Kubernetes 集群支持哪些存储类型,请联系系统管理员确定。
另外,TiDB 集群不同组件对磁盘的要求不一样,所以部署集群前,要根据当前 Kubernetes 集群支持的存储类型以及使用场景,参考存储配置文档为 TiDB 集群各组件选择合适的存储类型。
多盘挂载
TiDB Operator 支持为 PD、TiDB、TiKV、TiCDC 挂载多块 PV,可以用于不同用途的数据写入。
每个组件都可以配置 storageVolumes
字段,用于描述用户自定义的多个 PV。
相关字段的含义如下:
storageVolume.name
:PV 的名称。storageVolume.storageClassName
:PV 使用哪一个 StorageClass。如果不配置,会使用 spec.pd/tidb/tikv.storageClassName。storageVolume.storageSize
:申请 PV 存储容量的大小。storageVolume.mountPath
:将 PV 挂载到容器的哪个目录。
例子:
pd:
baseImage: pingcap/pd
replicas: 1
# if storageClassName is not set, the default Storage Class of the Kubernetes cluster will be used
# storageClassName: local-storage
requests:
storage: "1Gi"
config:
log:
file:
filename: /var/log/pdlog/pd.log
level: "warn"
storageVolumes:
- name: log
storageSize: "2Gi"
mountPath: "/var/log/pdlog"
tidb:
baseImage: pingcap/tidb
replicas: 1
service:
type: ClusterIP
config:
log:
file:
filename: /var/log/tidblog/tidb.log
level: "warn"
storageVolumes:
- name: log
storageSize: "2Gi"
mountPath: "/var/log/tidblog"
tikv:
baseImage: pingcap/tikv
replicas: 1
# if storageClassName is not set, the default Storage Class of the Kubernetes cluster will be used
# storageClassName: local-storage
requests:
storage: "1Gi"
config:
storage:
# In basic examples, you can set this to avoid using too much storage.
reserve-space: "0MB"
rocksdb:
wal-dir: "/data_sbi/tikv/wal"
titan:
dirname: "/data_sbj/titan/data"
storageVolumes:
- name: wal
storageSize: "2Gi"
mountPath: "/data_sbi/tikv/wal"
- name: titan
storageSize: "2Gi"
mountPath: "/data_sbj/titan/data"
HostNetwork
PD、TiKV、TiDB、TiFlash、TiCDC 及 Pump 支持配置 Pod 使用宿主机上的网络命名空间 HostNetwork
。可通过配置 spec.hostNetwork: true
为所有受支持的组件开启,或通过为特定组件配置 hostNetwork: true
为单个或多个组件开启。
Discovery
TiDB Operator 会为每一个 TiDB 集群启动一个 Discovery 服务。Discovery 服务会为每个 PD Pod 返回相应的启动参数,来辅助 PD 集群启动。你可以通过 spec.discovery
配置 Discovery 服务的资源,详见容器资源管理。
spec.discovery
配置示例:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
version: v4.0.10
pvReclaimPolicy: Retain
discovery:
limits:
cpu: "0.2"
requests:
cpu: "0.2"
pd:
baseImage: pingcap/pd
replicas: 1
requests:
storage: "1Gi"
config: {}
...
集群拓扑
PD/TiKV/TiDB
默认示例的集群拓扑是:3 个 PD Pod,3 个 TiKV Pod,2 个 TiDB Pod。在该部署拓扑下根据数据高可用原则,TiDB Operator 扩展调度器要求 Kubernetes 集群中至少有 3 个节点。可以修改 replicas
配置来更改每个组件的 Pod 数量。
部署 TiFlash
如果要在集群中开启 TiFlash,需要在 ${cluster_name}/tidb-cluster.yaml
文件中配置 spec.pd.config.replication.enable-placement-rules: true
,并配置 spec.tiflash
:
pd:
config: |
...
[replication]
enable-placement-rules = true
tiflash:
baseImage: pingcap/tiflash
maxFailoverCount: 3
replicas: 1
storageClaims:
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
TiFlash 支持挂载多个 PV,如果要为 TiFlash 配置多个 PV,可以在 tiflash.storageClaims
下面配置多项,每一项可以分别配置 storage reqeust
和 storageClassName
,例如:
tiflash:
baseImage: pingcap/tiflash
maxFailoverCount: 3
replicas: 1
storageClaims:
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
- resources:
requests:
storage: 100Gi
storageClassName: local-storage
所有 PV 按照配置先后顺序分别挂载到容器内的 /data0
、/data1
等目录。TiFlash 有 4 个日志文件,其中 Proxy 日志打印到容器标准输出,另外 3 个日志存储在硬盘中,默认存储在 /data0
目录下,分别为 /data0/logs/flash_cluster_manager.log
、/data0/logs/error.log
、/data0/logs/server.log
,如果要修改日志存储路径,可以参考配置 TiFlash 配置参数进行修改。
部署 TiCDC
如果要在集群中开启 TiCDC,需要在 ${cluster_name}/tidb-cluster.yaml
文件中配置 spec.ticdc
:
ticdc:
baseImage: pingcap/ticdc
replicas: 3
config:
logLevel: info
配置 TiDB 组件
本节介绍如何配置 TiDB/TiKV/PD/TiFlash/TiCDC 的配置选项。
配置 TiDB 配置参数
你可以通过 TidbCluster CR 的 spec.tidb.config
来配置 TiDB 配置参数。
对于 TiDB Operator v1.1.6 及之后版本,请使用 TOML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
....
tidb:
image: pingcap/tidb:v5.0.6
imagePullPolicy: IfNotPresent
replicas: 1
service:
type: ClusterIP
config: |
split-table = true
oom-action = "log"
requests:
cpu: 1
对于 TiDB Operator v1.1.6 之前版本,请使用 YAML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
....
tidb:
image: pingcap/tidb:v5.0.6
imagePullPolicy: IfNotPresent
replicas: 1
service:
type: ClusterIP
config:
split-table: true
oom-action: "log"
requests:
cpu: 1
获取所有可以配置的 TiDB 配置参数,请参考 TiDB 配置文档。
配置 TiKV 配置参数
你可以通过 TidbCluster CR 的 spec.tikv.config
来配置 TiKV 配置参数。
对于 TiDB Operator v1.1.6 及之后版本,请使用 TOML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
....
tikv:
image: pingcap/tikv:v5.0.1
config: |
[storage]
[storage.block-cache]
capacity = "16GB"
replicas: 1
requests:
cpu: 2
对于 TiDB Operator v1.1.6 之前版本,请使用 YAML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
....
tikv:
image: pingcap/tikv:v5.0.1
config:
storage:
block-cache:
capacity: "16GB"
replicas: 1
requests:
cpu: 2
获取所有可以配置的 TiKV 配置参数,请参考 TiKV 配置文档
配置 PD 配置参数
你可以通过 TidbCluster CR 的 spec.pd.config
来配置 PD 配置参数。
对于 TiDB Operator v1.1.6 及之后版本,请使用 TOML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
.....
pd:
image: pingcap/pd:v5.0.1
config: |
lease = 3
enable-prevote = true
对于 TiDB Operator v1.1.6 之前版本,请使用 YAML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
.....
pd:
image: pingcap/pd:v5.0.1
config:
lease: 3
enable-prevote: true
获取所有可以配置的 PD 配置参数,请参考 PD 配置文档
配置 TiFlash 配置参数
你可以通过 TidbCluster CR 的 spec.tiflash.config
来配置 TiFlash 配置参数。
对于 TiDB Operator v1.1.6 及之后版本,请使用 TOML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
...
tiflash:
config:
config: |
[flash]
[flash.flash_cluster]
log = "/data0/logs/flash_cluster_manager.log"
[logger]
count = 10
level = "information"
errorlog = "/data0/logs/error.log"
log = "/data0/logs/server.log"
对于 TiDB Operator v1.1.6 之前版本,请使用 YAML 格式配置:
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
...
tiflash:
config:
config:
flash:
flash_cluster:
log: "/data0/logs/flash_cluster_manager.log"
logger:
count: 10
level: information
errorlog: "/data0/logs/error.log"
log: "/data0/logs/server.log"
获取所有可以配置的 TiFlash 配置参数,请参考 TiFlash 配置文档
配置 TiCDC 启动参数
你可以通过 TidbCluster CR 的 spec.ticdc.config
来配置 TiCDC 启动参数。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
...
ticdc:
config:
timezone: UTC
gcTTL: 86400
logLevel: info
获取所有可以配置的 TiCDC 启动参数,请参考 TiCDC 启动参数文档。
配置 PD、TiDB、TiKV、TiFlash 故障自动转移阈值
故障自动转移功能在 TiDB Operator 中默认开启。当 PD、TiDB、TiKV、TiFlash 这些组件的 Pod 或者其所在节点发生故障时,TiDB Operator 会触发故障自动转移,通过扩容相应组件补齐 Pod 副本数。
为避免故障自动转移功能创建太多 Pod,可以为每个组件配置故障自动转移时能扩容的 Pod 数量阈值,默认为 3
。如果配置为 0
,代表关闭这个组件的故障自动转移功能。配置示例如下:
pd:
maxFailoverCount: 3
tidb:
maxFailoverCount: 3
tikv:
maxFailoverCount: 3
tiflash:
maxFailoverCount: 3
配置 TiDB 平滑升级
滚动更新 TiDB 集群的过程中,在停止 TiDB Pod 之前,Kubernetes 会向 TiDB server 进程发送一个 TERM
信号。在收到 TERM
信号后,TiDB server 会尝试等待所有的连接关闭,不过 15 秒后会强制关闭所有连接并退出进程。
从 v1.1.2 版本开始,TiDB Operator 已经支持平滑升级 TiDB 集群。通过配置下面两个属性来实现平滑升级 TiDB 集群:
spec.tidb.terminationGracePeriodSeconds
:滚动更新的时候,删除旧的 TiDB Pod 最多容忍的时间,即过了这个时间,TiDB Pod 会被强制删除;spec.tidb.lifecycle
:设置 TiDB Pod 的preStop
Hook,在 TiDB server 停止之前执行的操作。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
name: basic
spec:
version: v5.0.6
pvReclaimPolicy: Retain
discovery: {}
pd:
baseImage: pingcap/pd
replicas: 1
requests:
storage: "1Gi"
config: {}
tikv:
baseImage: pingcap/tikv
replicas: 1
requests:
storage: "1Gi"
config: {}
tidb:
baseImage: pingcap/tidb
replicas: 1
service:
type: ClusterIP
config: {}
terminationGracePeriodSeconds: 60
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- "sleep 10 && kill -QUIT 1"
上述 YAML 文件中:
- 设置了删除 TiDB Pod 的最多容忍时间为 60 秒,如果 60 秒之内客户端仍然没有关闭连接的话,那么这些连接将会强制关闭。这个时间可根据需要进行调整;
- 设置
preStop
Hook 为sleep 10 && kill -QUIT 1
,这里 Pid 1 为 TiDB Pod 内 TiDB server 进程的 Pid。TiDB server 进程收到这个信号之后,会等待所有连接被客户端关闭之后才会退出。
Kubernetes 在删除 TiDB Pod 的同时,也会把该 TiDB 节点从 Service 的 Endpoints 中移除。这样就可以保证新的连接不会连接到该 TiDB 节点,但是由于此过程是异步的,所以可以在发送 Kill 信号之前 sleep 几秒钟,确保该 TiDB 节点从 Endpoints 中去掉。
配置 TiKV 平滑升级
TiKV 升级过程中,在重启 TiKV Pod 之前,TiDB Operator 会先驱逐 TiKV Pod 上的所有 Region leader。只有当驱逐完成(即 TiKV Pod 上的 Region leader 个数为 0)或者驱逐超时(默认 10 分钟)后,TiKV Pod 才会重启。
如果驱逐 Region leader 超时,重启 TiKV Pod 会导致部分请求失败或者延时增加。要避免此问题,你可以将超时时间 spec.tikv.evictLeaderTimeout
(默认 10 分钟)配置为一个更大的值,例如:
spec:
tikv:
evictLeaderTimeout: 10000m
配置 TiDB 慢查询日志持久卷
默认配置下,TiDB Operator 会新建名称为 slowlog
的 EmptyDir
卷来存储慢查询日志,slowlog
卷默认挂载到 /var/log/tidb
,慢查询日志通过 sidecar 容器打印到标准输出。
如果想使用单独的持久卷来存储慢查询日志,可以通过配置 spec.tidb.slowLogVolumeName
单独指定存储慢查询日志的持久卷名称,并在 spec.tidb.storageVolumes
或 spec.tidb.additionalVolumes
配置持久卷信息。下面分别演示使用 spec.tidb.storageVolumes
和 spec.tidb.additionalVolumes
配置持久卷。
spec.tidb.storageVolumes 配置
按照如下示例配置 TidbCluster
CR,TiDB Operator 将使用持久卷 ${volumeName}
存储慢查询日志,日志文件路径为:${mountPath}/${volumeName}
。spec.tidb.storageVolumes
字段的具体配置方式可参考多盘挂载。
tidb:
...
separateSlowLog: true # 可省略
slowLogVolumeName: ${volumeName}
storageVolumes:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
storageClassName: ${storageClass}
storageSize: "1Gi"
mountPath: ${mountPath}
spec.tidb.additionalVolumes 配置(从 v1.1.8 版本开始支持)
下面以 NFS 为例配置 spec.tidb.additionalVolumes
。TiDB Operator 将使用持久卷 ${volumeName}
存储慢查询日志,日志文件路径为:${mountPath}/${volumeName}
。具体支持的持久卷类型可参考 Persistent Volumes。
tidb:
...
separateSlowLog: true # 可省略
slowLogVolumeName: ${volumeName}
additionalVolumes:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
nfs:
server: 192.168.0.2
path: /nfs
additionalVolumeMounts:
# name 必须和 slowLogVolumeName 字段的值保持一致
- name: ${volumeName}
mountPath: ${mountPath}
配置 TiDB 服务
需要配置 spec.tidb.service
,TiDB Operator 才会为 TiDB 创建 Service。Service 可以根据场景配置不同的类型,比如 ClusterIP
、NodePort
、LoadBalancer
等。
通用配置
不用类型的 Service 有着部分通用的配置,包括:
spec.tidb.service.annotations
:添加到 Service 资源的 Annotation。spec.tidb.service.labels
:添加到 Service 资源的 Labels。
ClusterIP
ClusterIP
是通过集群的内部 IP 暴露服务,选择该类型的服务时,只能在集群内部访问,使用 ClusterIP 或者 Service 域名(${cluster_name}-tidb.${namespace}
)访问。
spec:
...
tidb:
service:
type: ClusterIP
NodePort
在没有 LoadBalancer 时,可选择通过 NodePort 暴露。NodePort 是通过节点的 IP 和静态端口暴露服务。通过请求 NodeIP + NodePort
,可以从集群的外部访问一个 NodePort 服务。
spec:
...
tidb:
service:
type: NodePort
# externalTrafficPolicy: Local
NodePort 有两种模式:
externalTrafficPolicy=Cluster
:集群所有的机器都会给 TiDB 分配 NodePort 端口,此为默认值使用
Cluster
模式时,可以通过任意一台机器的 IP 加 NodePort 访问 TiDB 服务,如果该机器上没有 TiDB Pod,则相应请求会转发到有 TiDB Pod 的机器上。externalTrafficPolicy=Local
:只有运行 TiDB 的机器会分配 NodePort 端口,用于访问本地的 TiDB 实例
LoadBalancer
若运行在有 LoadBalancer 的环境,比如 GCP/AWS 平台,建议使用云平台的 LoadBalancer 特性。
spec:
...
tidb:
service:
annotations:
cloud.google.com/load-balancer-type: "Internal"
externalTrafficPolicy: Local
type: LoadBalancer
访问 Kubernetes Service 文档,了解更多 Service 特性以及云平台 Load Balancer 支持。
高可用配置
TiDB 是分布式数据库,它的高可用需要做到在任一个物理拓扑节点发生故障时,不仅服务不受影响,还要保证数据也是完整和可用。下面分别具体说明这两种高可用的配置。
TiDB 服务高可用
通过 nodeSelector 调度实例
通过各组件配置的 nodeSelector
字段,可以约束组件的实例只能调度到特定的节点上。关于 nodeSelector
的更多说明,请参阅 nodeSelector。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
# ...
spec:
pd:
nodeSelector:
node-role.kubernetes.io/pd: true
# ...
tikv:
nodeSelector:
node-role.kubernetes.io/tikv: true
# ...
tidb:
nodeSelector:
node-role.kubernetes.io/tidb: true
# ...
通过 tolerations 调度实例
通过各组件配置的 tolerations
字段,可以允许组件的实例能够调度到带有与之匹配的污点 (Taint) 的节点上。关于污点与容忍度的更多说明,请参阅 Taints and Tolerations。
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
# ...
spec:
pd:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: pd
# ...
tikv:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: tikv
# ...
tidb:
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: tidb
# ...
通过 affinity 调度实例
配置 PodAntiAffinity
能尽量避免同一组件的不同实例部署到同一个物理拓扑节点上,从而达到高可用的目的。关于 Affinity 的使用说明,请参阅 Affinity & AntiAffinity。
下面是一个典型的高可用设置例子:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
# this term works when the nodes have the label named region
- weight: 10
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "region"
namespaces:
- ${namespace}
# this term works when the nodes have the label named zone
- weight: 20
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "zone"
namespaces:
- ${namespace}
# this term works when the nodes have the label named rack
- weight: 40
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "rack"
namespaces:
- ${namespace}
# this term works when the nodes have the label named kubernetes.io/hostname
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: ${cluster_name}
app.kubernetes.io/component: "pd"
topologyKey: "kubernetes.io/hostname"
namespaces:
- ${namespace}
数据的高可用
在开始数据高可用配置前,首先请阅读集群拓扑信息配置。该文档描述了 TiDB 集群数据高可用的实现原理。
在 Kubernetes 上支持数据高可用的功能,需要如下操作:
为 PD 设置拓扑位置 Label 集合
用 Kubernetes 集群 Node 节点上描述拓扑位置的 Label 集合替换
pd.config
配置项中里的location-labels
信息。为 TiKV 节点设置所在的 Node 节点的拓扑信息
TiDB Operator 会自动为 TiKV 获取其所在 Node 节点的拓扑信息,并调用 PD 接口将这些信息设置为 TiKV 的 store labels 信息,这样 TiDB 集群就能基于这些信息来调度数据副本。
如果当前 Kubernetes 集群的 Node 节点没有表示拓扑位置的 Label,或者已有的拓扑 Label 名字中带有
/
,可以通过下面的命令手动给 Node 增加标签:kubectl label node ${node_name} region=${region_name} zone=${zone_name} rack=${rack_name} kubernetes.io/hostname=${host_name}其中
region
、zone
、rack
、kubernetes.io/hostname
只是举例,要添加的 Label 名字和数量可以任意定义,只要符合规范且和pd.config
里的location-labels
设置的 Labels 保持一致即可。