Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions en/enable-tls-for-mysql-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This document describes how to enable TLS for MySQL client of the TiDB cluster o

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

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.
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.

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

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

2. [Deploy the cluster](#step-2-deploy-the-tidb-cluster), and set `.spec.tidb.tlsClient.enabled` to `true`.

* 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`.
* 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).
Expand All @@ -30,11 +32,9 @@ To enable TLS for the MySQL client, perform the following steps:
>
> For an existing cluster, if you change `.spec.tidb.tlsClient.enabled` from `false` to `true`, the TiDB Pods will be rolling restarted.

3. [Configure the MySQL client to use an encrypted connection](#configure-the-mysql-client-to-use-an-encrypted-connection).

If you need to renew the existing TLS certificate, refer to [Renew and Replace the TLS Certificate](renew-tls-certificate.md).
3. [Configure the MySQL client to use an encrypted connection](#step-3-configure-the-mysql-client-to-use-a-tls-connection).

## Issue two sets of certificates for the TiDB cluster
## Step 1. Issue two sets of certificates for the TiDB cluster

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

Expand Down Expand Up @@ -508,7 +508,7 @@ You can generate multiple sets of client-side certificates. At least one set of
>
> 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.

## Deploy the TiDB cluster
## Step 2. Deploy the TiDB cluster

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

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

## Configure the MySQL client to use an encrypted connection
## Step 3. Configure the MySQL client to use a TLS connection

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).

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

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

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

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).

When not relying on client certificates the following is sufficient:

``` shell
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
```

``` shell
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-ca=client-ca.crt
```

## Troubleshooting

The X.509 certificates are stored in Kubernetes secrets. To inspect them, use commands similar to `kubectl -n ${namespace} get secret`.

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.

To check these secret mounts from inside the container, run the following command:

``` shell
kubectl exec -n ${cluster_name} --stdin=true --tty=true ${cluster_name}-tidb-0 -c tidb -- /bin/sh
```

The contents of the TLS directories is as follows:

``` shell
sh-5.1# ls -l /var/lib/*tls
/var/lib/tidb-server-tls:
total 0
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key

/var/lib/tidb-tls:
total 0
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
```

The output of `kubectl -n ${cluster_name} logs ${cluster_name}-tidb-0 -c tidb` is as follows:

```
[2025/09/25 12:23:19.739 +00:00] [INFO] [server.go:291] ["mysql protocol server secure connection is enabled"] ["client verification enabled"=true]
```

## Reload certificates

The certificate reload process depends on how you generate certificates:
Expand Down
2 changes: 1 addition & 1 deletion en/restore-data-using-tidb-lightning.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ If TLS between components has been enabled on the target TiDB cluster (`spec.tls

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.

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`.
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`.

> **Note:**
>
Expand Down
121 changes: 72 additions & 49 deletions zh/enable-tls-for-mysql-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

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

> **注意:**
>
> 创建的 Secret 对象必须符合上述命名规范,否则将导致 TiDB 集群部署失败。

2. 部署集群,设置 `.spec.tidb.tlsClient.enabled` 属性为 `true`:
其中,颁发证书的方式有多种,本文档提供两种方式,用户也可以根据需要为 TiDB 集群颁发证书,这两种方式分别为:

- [使用 `cfssl` 系统颁发证书](#使用-cfssl-系统颁发证书)
- [使用 `cert-manager` 系统颁发证书](#使用-cert-manager-颁发证书)

当需要更新已有 TLS 证书时,可参考[更新和替换 TLS 证书](renew-tls-certificate.md)。

2. [部署集群](#第二步部署-tidb-集群),设置 `.spec.tidb.tlsClient.enabled` 属性为 `true`:

* 如需跳过作为 MySQL 客户端的内部组件(如 TidbInitializer、Dashboard、Backup、Restore)的 TLS 认证,你可以给集群对应的 `TidbCluster` 加上 `tidb.tidb.pingcap.com/skip-tls-when-connect-tidb="true"` 的 annotation。
* 如需关闭 TiDB 服务端对客户端 CA 证书的认证,你可以设置 `.spec.tidb.tlsClient.disableClientAuthn` 属性为 `true`,即在[配置 TiDB 服务端启用安全连接](https://docs.pingcap.com/zh/tidb/stable/enable-tls-between-clients-and-servers#配置-tidb-服务端启用安全连接) 中不设置 ssl-ca 参数。
Expand All @@ -23,23 +30,14 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。
>
> 已部署的集群 `.spec.tidb.tlsClient.enabled` 属性从 `false` 改为 `true`,将导致 TiDB Pod 滚动重启。

3. 配置 MySQL 客户端使用加密连接。

其中,颁发证书的方式有多种,本文档提供两种方式,用户也可以根据需要为 TiDB 集群颁发证书,这两种方式分别为:

- 使用 `cfssl` 系统颁发证书;
- 使用 `cert-manager` 系统颁发证书;

当需要更新已有 TLS 证书时,可参考[更新和替换 TLS 证书](renew-tls-certificate.md)。
3. [配置 MySQL 客户端使用加密连接](#第三步配置-mysql-客户端使用-tls-连接)。

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

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

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

{{< copyable "shell-regular" >}}

``` shell
mkdir -p ~/bin
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
Expand Down Expand Up @@ -109,8 +107,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
```
Expand All @@ -119,8 +115,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
cfssl print-defaults csr > server.json
```
Expand Down Expand Up @@ -150,8 +144,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

最后生成 Server 端证书:

{{< copyable "shell-regular" >}}

``` shell
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
```
Expand All @@ -160,8 +152,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
cfssl print-defaults csr > client.json
```
Expand All @@ -177,8 +167,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

最后生成 Client 端证书:

{{< copyable "shell-regular" >}}

``` shell
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
```
Expand All @@ -187,8 +175,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
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
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
Expand All @@ -213,8 +199,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
mkdir -p cert-manager
cd cert-manager
Expand Down Expand Up @@ -264,8 +248,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f tidb-server-issuer.yaml
```
Expand Down Expand Up @@ -333,8 +315,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f tidb-server-cert.yaml
```
Expand Down Expand Up @@ -377,8 +357,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f tidb-client-cert.yaml
```
Expand Down Expand Up @@ -516,8 +494,6 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

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

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f tidb-components-client-cert.yaml
```
Expand Down Expand Up @@ -640,50 +616,97 @@ summary: 在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。

2. 部署 TiDB 集群:

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f tidb-cluster.yaml
```

3. 集群备份:

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f backup.yaml
```

4. 集群恢复:

{{< copyable "shell-regular" >}}

``` shell
kubectl apply -f restore.yaml
```

## 第三步:配置 MySQL 客户端使用加密连接
## 第三步:配置 MySQL 客户端使用 TLS 连接

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

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

{{< copyable "shell-regular" >}}

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

{{< copyable "shell-regular" >}}

``` shell
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-cert=client-tls.crt --ssl-key=client-tls.key --ssl-ca=client-ca.crt
```

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

如果不使用 Client 证书,可以运行以下命令:

``` shell
kubectl get secret -n ${namespace} ${cluster_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
```

``` shell
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-ca=client-ca.crt
```

## 故障排查

X.509 证书存储在 Kubernetes Secret 中。可以使用类似下面的命令查看这些 Secret:

```shell
kubectl -n ${namespace} get secret
```

这些 Secret 会被挂载到容器内。可以通过查看 Pod 描述中的 **Volumes** 部分来确认挂载的卷信息:

```shell
kubectl -n ${namespace} describe pod ${podname}
```

要在容器内部检查这些 Secret 挂载情况,可以运行以下命令:

```shell
kubectl exec -n ${cluster_name} --stdin=true --tty=true ${cluster_name}-tidb-0 -c tidb -- /bin/sh
```

在容器内查看 TLS 目录的内容:

```shell
sh-5.1# ls -l /var/lib/*tls
/var/lib/tidb-server-tls:
total 0
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key

/var/lib/tidb-tls:
total 0
lrwxrwxrwx. 1 root root 13 Sep 25 12:23 ca.crt -> ..data/ca.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.crt -> ..data/tls.crt
lrwxrwxrwx. 1 root root 14 Sep 25 12:23 tls.key -> ..data/tls.key
```

检查 TiDB 容器日志以确认 TLS 已启用,示例命令及输出如下:

```shell
kubectl -n ${cluster_name} logs ${cluster_name}-tidb-0 -c tidb
```

```
[2025/09/25 12:23:19.739 +00:00] [INFO] [server.go:291] ["mysql protocol server secure connection is enabled"] ["client verification enabled"=true]
```

## 重新加载证书

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