为 MySQL 客户端开启 TLS

本文主要描述了在 Kubernetes 上如何为 TiDB 集群的 MySQL 客户端开启 TLS。开启步骤为:

  1. 为 TiDB Server 颁发一套 Server 端证书,为 MySQL Client 颁发一套 Client 端证书。并创建两个 Secret 对象,Secret 名字分别为:${tidb_group_name}-tidb-server-secret${tidb_group_name}-tidb-client-secret,分别包含前面创建的两套证书;

  2. 部署集群,设置 TiDBGroup.spec.template.spec.security.tls.mysql.enabled 属性为 true

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

其中,颁发证书的方式有多种,本文档介绍了使用 cert-manager 系统颁发证书。你也可以根据需要为 TiDB 集群颁发证书。

当需要更新已有 TLS 证书时,可参考更新和替换 TLS 证书

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

  1. 安装 cert-manager。

    请参考官网安装:cert-manager installation on Kubernetes

  2. 创建一个 Issuer 用于给 TiDB 集群颁发证书。

    为了配置 cert-manager 颁发证书,必须先创建 Issuer 资源。

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

    mkdir -p cert-manager cd cert-manager

    然后创建一个 tidb-server-issuer.yaml 文件,输入以下内容:

    apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: ${cluster_name}-selfsigned-ca-issuer namespace: ${namespace} spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: ${cluster_name}-ca namespace: ${namespace} spec: secretName: ${cluster_name}-ca-secret commonName: "TiDB CA" isCA: true duration: 87600h # 10yrs renewBefore: 720h # 30d issuerRef: name: ${cluster_name}-selfsigned-ca-issuer kind: Issuer --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: ${cluster_name}-cert-issuer namespace: ${namespace} spec: ca: secretName: ${cluster_name}-ca-secret

    上面的文件创建三个对象:

    • 一个 SelfSigned 类型的 Issuer 对象(用于生成 CA 类型 Issuer 所需要的 CA 证书);
    • 一个 Certificate 对象,isCa 属性设置为 true
    • 一个可以用于颁发 TiDB Server TLS 证书的 Issuer。

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

    kubectl apply -f tidb-server-issuer.yaml
  3. 创建 Server 端证书。

    cert-manager 中,Certificate 资源表示证书接口,该证书将由上面创建的 Issuer 颁发并保持更新。

    首先来创建 Server 端证书,创建一个 tidb-server-cert.yaml 文件,并输入以下内容:

    apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: ${tidb_group_name}-tidb-server-secret namespace: ${namespace} spec: secretName: ${tidb_group_name}-tidb-server-secret duration: 8760h # 365d renewBefore: 360h # 15d subject: organizations: - PingCAP commonName: "TiDB" usages: - server auth dnsNames: - "${tidb_group_name}-tidb" - "${tidb_group_name}-tidb.${namespace}" - "${tidb_group_name}-tidb.${namespace}.svc" - "*.${tidb_group_name}-tidb" - "*.${tidb_group_name}-tidb.${namespace}" - "*.${tidb_group_name}-tidb.${namespace}.svc" - "*.${tidb_group_name}-tidb-peer" - "*.${tidb_group_name}-tidb-peer.${namespace}" - "*.${tidb_group_name}-tidb-peer.${namespace}.svc" ipAddresses: - 127.0.0.1 - ::1 issuerRef: name: ${cluster_name}-cert-issuer kind: Issuer group: cert-manager.io

    其中 ${cluster_name} 为集群的名字,${tidb_group_name}TiDBGroup 的名字:

    • spec.secretName 请设置为 ${tidb_group_name}-tidb-server-secret
    • usages 请添加上 server auth
    • dnsNames 需要填写这 6 个 DNS,根据需要可以填写其他 DNS:
      • ${tidb_group_name}-tidb
      • ${tidb_group_name}-tidb.${namespace}
      • ${tidb_group_name}-tidb.${namespace}.svc
      • *.${tidb_group_name}-tidb
      • *.${tidb_group_name}-tidb.${namespace}
      • *.${tidb_group_name}-tidb.${namespace}.svc
      • *.${tidb_group_name}-tidb-peer
      • *.${tidb_group_name}-tidb-peer.${namespace}
      • *.${tidb_group_name}-tidb-peer.${namespace}.svc
    • ipAddresses 需要填写这两个 IP,根据需要可以填写其他 IP:
      • 127.0.0.1
      • ::1
    • issuerRef 请填写上面创建的 Issuer;
    • 其他属性请参考 cert-manager API

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

    kubectl apply -f tidb-server-cert.yaml

    创建这个对象以后,cert-manager 会生成一个名字为 ${tidb_group_name}-tidb-server-secret 的 Secret 对象供 TiDB Server 使用。

  4. 创建 Client 端证书。

    创建一个 tidb-client-cert.yaml 文件,并输入以下内容:

    apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: ${tidb_group_name}-tidb-client-secret namespace: ${namespace} spec: secretName: ${tidb_group_name}-tidb-client-secret duration: 8760h # 365d renewBefore: 360h # 15d subject: organizations: - PingCAP commonName: "TiDB" usages: - client auth issuerRef: name: ${cluster_name}-cert-issuer kind: Issuer group: cert-manager.io

    其中 ${cluster_name} 为集群的名字,${tidb_group_name}TiDBGroup 的名字:

    • spec.secretName 请设置为 ${tidb_group_name}-tidb-client-secret
    • usages 请添加上 client auth
    • dnsNamesipAddresses 不需要填写;
    • issuerRef 请填写上面创建的 Issuer;
    • 其他属性请参考 cert-manager API

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

    kubectl apply -f tidb-client-cert.yaml

    创建这个对象以后,cert-manager 会生成一个名字为 ${tidb_group_name}-tidb-client-secret 的 Secret 对象供 TiDB Client 使用。

第二步:部署 TiDBGroup

以下配置示例展示如何创建一个启用了 MySQL TLS 的 TiDBGroup

apiVersion: core.pingcap.com/v1alpha1 kind: TiDBGroup metadata: name: tidb spec: cluster: name: tls version: v8.5.2 replicas: 1 template: spec: security: tls: mysql: enabled: true config: | [security] cluster-verify-cn = ["TiDB"]

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

可以根据官网文档提示,使用上面创建的 Client 证书,通过下面的方法连接 TiDB 集群:

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

kubectl get secret -n ${namespace} ${tidb_group_name}-tidb-client-secret -ojsonpath='{.data.tls\.crt}' | base64 --decode > client-tls.crt kubectl get secret -n ${namespace} ${tidb_group_name}-tidb-client-secret -ojsonpath='{.data.tls\.key}' | base64 --decode > client-tls.key kubectl get secret -n ${namespace} ${tidb_group_name}-tidb-client-secret -ojsonpath='{.data.ca\.crt}' | base64 --decode > client-ca.crt
mysql --comments -uroot -p -P 4000 -h ${tidb_host} --ssl-cert=client-tls.crt --ssl-key=client-tls.key --ssl-ca=client-ca.crt

最后请参考官网文档来验证是否正确开启了 TLS。

文档内容是否有帮助?