Skip to content

Commit 79df9ff

Browse files
authored
enable-tls-for-mysql-client: Add info about TLS without client certs (#2942) (#2960)
1 parent deb857f commit 79df9ff

File tree

3 files changed

+129
-61
lines changed

3 files changed

+129
-61
lines changed

en/enable-tls-for-mysql-client.md

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This document describes how to enable TLS for MySQL client of the TiDB cluster o
99

1010
To enable TLS for the MySQL client, perform the following steps:
1111

12-
1. [Issue two sets of certificates](#issue-two-sets-of-certificates-for-the-tidb-cluster): a set of server-side certificates for TiDB server, and a set of client-side certificates for MySQL client. Create two Secret objects, `${cluster_name}-tidb-server-secret` and `${cluster_name}-tidb-client-secret`, respectively including these two sets of certificates.
12+
1. [Issue two sets of certificates](#step-1-issue-two-sets-of-certificates-for-the-tidb-cluster): a set of server-side certificates for TiDB server, and a set of client-side certificates for MySQL client. Create two Secret objects, `${cluster_name}-tidb-server-secret` and `${cluster_name}-tidb-client-secret`, respectively including these two sets of certificates.
1313

1414
> **Note:**
1515
>
@@ -20,7 +20,9 @@ To enable TLS for the MySQL client, perform the following steps:
2020
- [Using the `cfssl` system](#using-cfssl)
2121
- [Using the `cert-manager` system](#using-cert-manager)
2222

23-
2. [Deploy the cluster](#deploy-the-tidb-cluster), and set `.spec.tidb.tlsClient.enabled` to `true`.
23+
If you need to renew the existing TLS certificate, refer to [Renew and Replace the TLS Certificate](renew-tls-certificate.md).
24+
25+
2. [Deploy the cluster](#step-2-deploy-the-tidb-cluster), and set `.spec.tidb.tlsClient.enabled` to `true`.
2426

2527
* To skip TLS authentication for internal components that serve as the MySQL client (such as TidbInitializer, Dashboard, Backup, and Restore), you can add the `tidb.tidb.pingcap.com/skip-tls-when-connect-tidb="true"` annotation to the cluster's corresponding `TidbCluster`.
2628
* To disable the client CA certificate authentication on the TiDB server, you can set `.spec.tidb.tlsClient.disableClientAuthn` to `true`. This means skipping setting the `ssl-ca` parameter when you [configure TiDB server to enable secure connections](https://docs.pingcap.com/tidb/stable/enable-tls-between-clients-and-servers#configure-tidb-server-to-use-secure-connections).
@@ -30,11 +32,9 @@ To enable TLS for the MySQL client, perform the following steps:
3032
>
3133
> For an existing cluster, if you change `.spec.tidb.tlsClient.enabled` from `false` to `true`, the TiDB Pods will be rolling restarted.
3234
33-
3. [Configure the MySQL client to use an encrypted connection](#configure-the-mysql-client-to-use-an-encrypted-connection).
34-
35-
If you need to renew the existing TLS certificate, refer to [Renew and Replace the TLS Certificate](renew-tls-certificate.md).
35+
3. [Configure the MySQL client to use an encrypted connection](#step-3-configure-the-mysql-client-to-use-a-tls-connection).
3636

37-
## Issue two sets of certificates for the TiDB cluster
37+
## Step 1. Issue two sets of certificates for the TiDB cluster
3838

3939
This section describes how to issue certificates for the TiDB cluster using two methods: `cfssl` and `cert-manager`.
4040

@@ -508,7 +508,7 @@ You can generate multiple sets of client-side certificates. At least one set of
508508
>
509509
> TiDB server's TLS is compatible with the MySQL protocol. When the certificate content is changed, the administrator needs to manually execute the SQL statement `alter instance reload tls` to refresh the content.
510510

511-
## Deploy the TiDB cluster
511+
## Step 2. Deploy the TiDB cluster
512512

513513
In this step, you create a TiDB cluster and perform the following operations:
514514

@@ -636,16 +636,16 @@ In this step, you create a TiDB cluster and perform the following operations:
636636
kubectl apply -f restore.yaml
637637
```
638638

639-
## Configure the MySQL client to use an encrypted connection
639+
## Step 3. Configure the MySQL client to use a TLS connection
640640

641641
To connect the MySQL client with the TiDB cluster, use the client-side certificate created above and take the following methods. For details, refer to [Configure the MySQL client to use encrypted connections](https://docs.pingcap.com/tidb/stable/enable-tls-between-clients-and-servers#configure-the-mysql-client-to-use-encrypted-connections).
642642

643643
Execute the following command to acquire the client-side certificate and connect to the TiDB server:
644644

645645
``` shell
646-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.crt}' | base64 --decode > client-tls.crt
647-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.key}' | base64 --decode > client-tls.key
648-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
646+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.crt}' | base64 --decode > client-tls.crt
647+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.key}' | base64 --decode > client-tls.key
648+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
649649
```
650650

651651
``` shell
@@ -654,6 +654,51 @@ mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-cert=client-tls.crt --s
654654

655655
Finally, to verify whether TLS is successfully enabled, refer to [checking the current connection](https://docs.pingcap.com/tidb/stable/enable-tls-between-clients-and-servers#check-whether-the-current-connection-uses-encryption).
656656

657+
When not relying on client certificates the following is sufficient:
658+
659+
``` shell
660+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
661+
```
662+
663+
``` shell
664+
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-ca=client-ca.crt
665+
```
666+
667+
## Troubleshooting
668+
669+
The X.509 certificates are stored in Kubernetes secrets. To inspect them, use commands similar to `kubectl -n ${namespace} get secret`.
670+
671+
These secrets are mounted into the containers. To view the volume mounts, check the **Volumes** section in the output of the `kubectl -n ${namespace} describe pod ${podname}` command.
672+
673+
To check these secret mounts from inside the container, run the following command:
674+
675+
``` shell
676+
kubectl exec -n ${cluster_name} --stdin=true --tty=true ${cluster_name}-tidb-0 -c tidb -- /bin/sh
677+
```
678+
679+
The contents of the TLS directories is as follows:
680+
681+
``` shell
682+
sh-5.1# ls -l /var/lib/*tls
683+
/var/lib/tidb-server-tls:
684+
total 0
685+
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
686+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
687+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
688+
689+
/var/lib/tidb-tls:
690+
total 0
691+
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
692+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
693+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
694+
```
695+
696+
The output of `kubectl -n ${cluster_name} logs ${cluster_name}-tidb-0 -c tidb` is as follows:
697+
698+
```
699+
[2025/09/25 12:23:19.739 +00:00] [INFO] [server.go:291] ["mysql protocol server secure connection is enabled"] ["client verification enabled"=true]
700+
```
701+
657702
## Reload certificates
658703

659704
The certificate reload process depends on how you generate certificates:

en/restore-data-using-tidb-lightning.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ If TLS between components has been enabled on the target TiDB cluster (`spec.tls
5656

5757
If the target TiDB cluster has enabled TLS for the MySQL client (`spec.tidb.tlsClient.enabled: true`), and the corresponding client-side certificate is configured (the Kubernetes Secret object is `${cluster_name}-tidb-client-secret`), you can configure `tlsClient.enabled: true` in `values.yaml` to enable TiDB Lightning to connect to the TiDB server using TLS.
5858

59-
To use different client certificates to connect to the TiDB server, refer to [Issue two sets of certificates for the TiDB cluster](enable-tls-for-mysql-client.md#issue-two-sets-of-certificates-for-the-tidb-cluster) to generate the client-side certificate for TiDB Lightning, and configure the corresponding Kubernetes secret object in `tlsCluster.tlsClientSecretName` in `values.yaml`.
59+
To use different client certificates to connect to the TiDB server, refer to [Issue two sets of certificates for the TiDB cluster](enable-tls-for-mysql-client.md#step-1-issue-two-sets-of-certificates-for-the-tidb-cluster) to generate the client-side certificate for TiDB Lightning, and configure the corresponding Kubernetes secret object in `tlsCluster.tlsClientSecretName` in `values.yaml`.
6060

6161
> **Note:**
6262
>

zh/enable-tls-for-mysql-client.md

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
77

88
本文主要描述了在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。TiDB Operator 从 v1.1 开始已经支持为 Kubernetes 上 TiDB 集群开启 MySQL 客户端 TLS。开启步骤为:
99

10-
1. 为 TiDB Server 颁发一套 Server 端证书,为 MySQL Client 颁发一套 Client 端证书。并创建两个 Secret 对象,Secret 名字分别为:`${cluster_name}-tidb-server-secret``${cluster_name}-tidb-client-secret`,分别包含前面创建的两套证书;
10+
1. [为 TiDB Server 颁发一套 Server 端证书](#第一步为-tidb-集群颁发两套证书),为 MySQL Client 颁发一套 Client 端证书。并创建两个 Secret 对象,Secret 名字分别为:`${cluster_name}-tidb-server-secret``${cluster_name}-tidb-client-secret`,分别包含前面创建的两套证书;
1111

1212
> **注意:**
1313
>
1414
> 创建的 Secret 对象必须符合上述命名规范,否则将导致 TiDB 集群部署失败。
1515
16-
2. 部署集群,设置 `.spec.tidb.tlsClient.enabled` 属性为 `true`
16+
其中,颁发证书的方式有多种,本文档提供两种方式,用户也可以根据需要为 TiDB 集群颁发证书,这两种方式分别为:
17+
18+
- [使用 `cfssl` 系统颁发证书](#使用-cfssl-系统颁发证书)
19+
- [使用 `cert-manager` 系统颁发证书](#使用-cert-manager-颁发证书)
20+
21+
当需要更新已有 TLS 证书时,可参考[更新和替换 TLS 证书](renew-tls-certificate.md)
22+
23+
2. [部署集群](#第二步部署-tidb-集群),设置 `.spec.tidb.tlsClient.enabled` 属性为 `true`
1724

1825
* 如需跳过作为 MySQL 客户端的内部组件(如 TidbInitializer、Dashboard、Backup、Restore)的 TLS 认证,你可以给集群对应的 `TidbCluster` 加上 `tidb.tidb.pingcap.com/skip-tls-when-connect-tidb="true"` 的 annotation。
1926
* 如需关闭 TiDB 服务端对客户端 CA 证书的认证,你可以设置 `.spec.tidb.tlsClient.disableClientAuthn` 属性为 `true`,即在[配置 TiDB 服务端启用安全连接](https://docs.pingcap.com/zh/tidb/stable/enable-tls-between-clients-and-servers#配置-tidb-服务端启用安全连接) 中不设置 ssl-ca 参数。
@@ -23,23 +30,14 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
2330
>
2431
> 已部署的集群 `.spec.tidb.tlsClient.enabled` 属性从 `false` 改为 `true`,将导致 TiDB Pod 滚动重启。
2532
26-
3. 配置 MySQL 客户端使用加密连接。
27-
28-
其中,颁发证书的方式有多种,本文档提供两种方式,用户也可以根据需要为 TiDB 集群颁发证书,这两种方式分别为:
29-
30-
- 使用 `cfssl` 系统颁发证书;
31-
- 使用 `cert-manager` 系统颁发证书;
32-
33-
当需要更新已有 TLS 证书时,可参考[更新和替换 TLS 证书](renew-tls-certificate.md)
33+
3. [配置 MySQL 客户端使用加密连接](#第三步配置-mysql-客户端使用-tls-连接)
3434

3535
## 第一步:为 TiDB 集群颁发两套证书
3636

3737
### 使用 `cfssl` 系统颁发证书
3838

3939
1. 首先下载 `cfssl` 软件并初始化证书颁发机构:
4040

41-
{{< copyable "shell-regular" >}}
42-
4341
``` shell
4442
mkdir -p ~/bin
4543
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
@@ -109,8 +107,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
109107

110108
4. 使用定义的选项生成 CA:
111109

112-
{{< copyable "shell-regular" >}}
113-
114110
``` shell
115111
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
116112
```
@@ -119,8 +115,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
119115

120116
首先生成默认的 `server.json` 文件:
121117

122-
{{< copyable "shell-regular" >}}
123-
124118
``` shell
125119
cfssl print-defaults csr > server.json
126120
```
@@ -150,8 +144,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
150144

151145
最后生成 Server 端证书:
152146

153-
{{< copyable "shell-regular" >}}
154-
155147
``` shell
156148
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
157149
```
@@ -160,8 +152,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
160152

161153
首先生成默认的 `client.json` 文件:
162154

163-
{{< copyable "shell-regular" >}}
164-
165155
``` shell
166156
cfssl print-defaults csr > client.json
167157
```
@@ -177,8 +167,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
177167

178168
最后生成 Client 端证书:
179169

180-
{{< copyable "shell-regular" >}}
181-
182170
``` shell
183171
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
184172
```
@@ -187,8 +175,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
187175

188176
到这里假设你已经按照上述文档把两套证书都创建好了。通过下面的命令为 TiDB 集群创建 Secret 对象:
189177

190-
{{< copyable "shell-regular" >}}
191-
192178
``` shell
193179
kubectl create secret generic ${cluster_name}-tidb-server-secret --namespace=${namespace} --from-file=tls.crt=server.pem --from-file=tls.key=server-key.pem --from-file=ca.crt=ca.pem
194180
kubectl create secret generic ${cluster_name}-tidb-client-secret --namespace=${namespace} --from-file=tls.crt=client.pem --from-file=tls.key=client-key.pem --from-file=ca.crt=ca.pem
@@ -213,8 +199,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
213199

214200
首先创建一个目录保存 `cert-manager` 创建证书所需文件:
215201

216-
{{< copyable "shell-regular" >}}
217-
218202
``` shell
219203
mkdir -p cert-manager
220204
cd cert-manager
@@ -264,8 +248,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
264248

265249
最后执行下面的命令进行创建:
266250

267-
{{< copyable "shell-regular" >}}
268-
269251
``` shell
270252
kubectl apply -f tidb-server-issuer.yaml
271253
```
@@ -333,8 +315,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
333315

334316
通过执行下面的命令来创建证书:
335317

336-
{{< copyable "shell-regular" >}}
337-
338318
``` shell
339319
kubectl apply -f tidb-server-cert.yaml
340320
```
@@ -377,8 +357,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
377357

378358
通过执行下面的命令来创建证书:
379359

380-
{{< copyable "shell-regular" >}}
381-
382360
``` shell
383361
kubectl apply -f tidb-client-cert.yaml
384362
```
@@ -516,8 +494,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
516494

517495
2. 通过执行下面的命令来创建证书:
518496

519-
{{< copyable "shell-regular" >}}
520-
521497
``` shell
522498
kubectl apply -f tidb-components-client-cert.yaml
523499
```
@@ -640,50 +616,97 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
640616

641617
2. 部署 TiDB 集群:
642618

643-
{{< copyable "shell-regular" >}}
644-
645619
``` shell
646620
kubectl apply -f tidb-cluster.yaml
647621
```
648622

649623
3. 集群备份:
650624

651-
{{< copyable "shell-regular" >}}
652-
653625
``` shell
654626
kubectl apply -f backup.yaml
655627
```
656628

657629
4. 集群恢复:
658630

659-
{{< copyable "shell-regular" >}}
660-
661631
``` shell
662632
kubectl apply -f restore.yaml
663633
```
664634

665-
## 第三步:配置 MySQL 客户端使用加密连接
635+
## 第三步:配置 MySQL 客户端使用 TLS 连接
666636

667637
可以根据[官网文档](https://docs.pingcap.com/zh/tidb/stable/enable-tls-between-clients-and-servers#配置-mysql-client-使用安全连接)提示,使用上面创建的 Client 证书,通过下面的方法连接 TiDB 集群:
668638

669639
获取 Client 证书的方式并连接 TiDB Server 的方法是:
670640

671-
{{< copyable "shell-regular" >}}
672-
673641
``` shell
674-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.crt}' | base64 --decode > client-tls.crt
675-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.key}' | base64 --decode > client-tls.key
676-
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
642+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.crt}' | base64 --decode > client-tls.crt
643+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.tls\.key}' | base64 --decode > client-tls.key
644+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
677645
```
678646

679-
{{< copyable "shell-regular" >}}
680-
681647
``` shell
682648
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-cert=client-tls.crt --ssl-key=client-tls.key --ssl-ca=client-ca.crt
683649
```
684650

685651
最后请参考[官网文档](https://docs.pingcap.com/zh/tidb/stable/enable-tls-between-clients-and-servers#检查当前连接是否是加密连接)来验证是否正确开启了 TLS。
686652

653+
如果不使用 Client 证书,可以运行以下命令:
654+
655+
``` shell
656+
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
657+
```
658+
659+
``` shell
660+
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-ca=client-ca.crt
661+
```
662+
663+
## 故障排查
664+
665+
X.509 证书存储在 Kubernetes Secret 中。可以使用类似下面的命令查看这些 Secret:
666+
667+
```shell
668+
kubectl -n ${namespace} get secret
669+
```
670+
671+
这些 Secret 会被挂载到容器内。可以通过查看 Pod 描述中的 **Volumes** 部分来确认挂载的卷信息:
672+
673+
```shell
674+
kubectl -n ${namespace} describe pod ${podname}
675+
```
676+
677+
要在容器内部检查这些 Secret 挂载情况,可以运行以下命令:
678+
679+
```shell
680+
kubectl exec -n ${cluster_name} --stdin=true --tty=true ${cluster_name}-tidb-0 -c tidb -- /bin/sh
681+
```
682+
683+
在容器内查看 TLS 目录的内容:
684+
685+
```shell
686+
sh-5.1# ls -l /var/lib/*tls
687+
/var/lib/tidb-server-tls:
688+
total 0
689+
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
690+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
691+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
692+
693+
/var/lib/tidb-tls:
694+
total 0
695+
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
696+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
697+
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
698+
```
699+
700+
检查 TiDB 容器日志以确认 TLS 已启用,示例命令及输出如下:
701+
702+
```shell
703+
kubectl -n ${cluster_name} logs ${cluster_name}-tidb-0 -c tidb
704+
```
705+
706+
```
707+
[2025/09/25 12:23:19.739 +00:00] [INFO] [server.go:291] ["mysql protocol server secure connection is enabled"] ["client verification enabled"=true]
708+
```
709+
687710
## 重新加载证书
688711

689712
重新加载证书的方式取决于证书的生成方式:
@@ -707,4 +730,4 @@ SHOW GLOBAL STATUS LIKE 'Ssl\_server\_not\_%';
707730
| Ssl_server_not_before | Jan 24 07:59:47 2025 UTC |
708731
+-----------------------+--------------------------+
709732
2 rows in set (0.011 sec)
710-
```
733+
```

0 commit comments

Comments
 (0)