Skip to content

Commit

Permalink
Automated cherry pick of #1867 upstream release 1.1 (#1878)
Browse files Browse the repository at this point in the history
* Enable TLS For MySQL Clients

* address comments
  • Loading branch information
weekface authored Mar 9, 2020
1 parent a0785f7 commit 306785d
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 175 deletions.
8 changes: 2 additions & 6 deletions charts/tidb-cluster/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,16 @@ config-file: |-
{{- if .Values.tidb.config }}
{{ .Values.tidb.config | indent 2 }}
{{- end -}}
{{- if or .Values.enableTLSCluster .Values.tidb.tlsClient.enabled }}
{{- if or .Values.enableTLSCluster (and .Values.tidb.tlsClient .Values.tidb.tlsClient.enabled) }}
[security]
{{- end -}}
{{- if .Values.enableTLSCluster }}
cluster-ssl-ca = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
cluster-ssl-cert = "/var/lib/tidb-tls/tls.crt"
cluster-ssl-key = "/var/lib/tidb-tls/tls.key"
{{- end -}}
{{- if .Values.tidb.tlsClient.enabled }}
{{- if .Values.tidb.tlsClient.secretName }}
{{- if and .Values.tidb.tlsClient .Values.tidb.tlsClient.enabled }}
ssl-ca = "/var/lib/tidb-server-tls/ca.crt"
{{- else }}
ssl-ca = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
{{- end }}
ssl-cert = "/var/lib/tidb-server-tls/tls.crt"
ssl-key = "/var/lib/tidb-server-tls/tls.key"
{{- end -}}
Expand Down
29 changes: 11 additions & 18 deletions charts/tidb-cluster/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -439,26 +439,19 @@ tidb:
list: ["whitelist-1"]

# Whether enable TLS connection between TiDB server and MySQL client.
# Note: TLS connection is not forced on the server side, plain connections are also accepted after enableing.
# https://pingcap.com/docs/stable/how-to/secure/enable-tls-clients/
tlsClient:
# When enabled, TiDB will accept TLS encrypted connections from MySQL client
# The steps to enable this feature:
# 1. Generate a TiDB server-side certificate and a client-side certifiacete for the TiDB cluster.
# There are multiple ways to generate certificates:
# - user-provided certificates: https://pingcap.com/docs/stable/how-to/secure/enable-tls-clients/
# - use the K8s built-in certificate signing system signed certificates: https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/
# - or use cert-manager signed certificates: https://cert-manager.io/
# 2. Create a K8s Secret object which contains the TiDB server-side certificate created above.
# The name of this Secret must be: <clusterName>-tidb-server-secret.
# kubectl create secret generic <clusterName>-tidb-server-secret --namespace=<namespace> --from-file=tls.crt=<path/to/tls.crt> --from-file=tls.key=<path/to/tls.key> --from-file=ca.crt=<path/to/ca.crt>
# 3. Then create the TiDB cluster with `tlsClient.enabled` set to `true`.
enabled: false
# # secretName is the name of the secret that stores user-defined tidb server certificate, key and ca...
# # If not specified but tls client is enabled, certificated signed by k8s is created automatically.
# # Create this secret with the following command:
# # kubectl create secret generic <secret-name> --namespace=<namespace> --from-file=tls.crt=<tidb server certificate file path> --from-file=tls.key=<tidb server key file path> --from-file=ca.crt=<ca file path>
# secretName: "demo-tidb-server-secret"

# Auto-generated certificate in k8s: https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/
# autoGenerated:
# # Extra SAN IP list
# extraSANIPList:
# - 1.1.1.1
# - 2.2.2.2
# # Extra SAN Domain list
# extraSANDomainList:
# - example1.com
# - example2.com

# mysqlClient is used to set password for TiDB
# it must has Python MySQL client installed
Expand Down
4 changes: 0 additions & 4 deletions pkg/apis/pingcap/v1alpha1/tidbcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,6 @@ func (tidb *TiDBSpec) IsAdvertiseAddressEnabled() bool {
return *tidb.EnableAdvertiseAddress
}

func (tidb *TiDBSpec) IsUserGeneratedCertificate() bool {
return tidb.IsTLSClientEnabled() && tidb.TLSClient.SecretName != ""
}

func (tidb *TiDBSpec) ShouldSeparateSlowLog() bool {
separateSlowLog := tidb.SeparateSlowLog
if separateSlowLog == nil {
Expand Down
29 changes: 10 additions & 19 deletions pkg/apis/pingcap/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,27 +604,18 @@ type PumpStatus struct {
// TiDBTLSClient can enable TLS connection between TiDB server and MySQL client
type TiDBTLSClient struct {
// When enabled, TiDB will accept TLS encrypted connections from MySQL client
// The steps to enable this feature:
// 1. Generate a TiDB server-side certificate and a client-side certifiacete for the TiDB cluster.
// There are multiple ways to generate certificates:
// - user-provided certificates: https://pingcap.com/docs/stable/how-to/secure/enable-tls-clients/
// - use the K8s built-in certificate signing system signed certificates: https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/
// - or use cert-manager signed certificates: https://cert-manager.io/
// 2. Create a K8s Secret object which contains the TiDB server-side certificate created above.
// The name of this Secret must be: <clusterName>-tidb-server-secret.
// kubectl create secret generic <clusterName>-tidb-server-secret --namespace=<namespace> --from-file=tls.crt=<path/to/tls.crt> --from-file=tls.key=<path/to/tls.key> --from-file=ca.crt=<path/to/ca.crt>
// 3. Set Enabled to `true`.
// +optional
Enabled bool `json:"enabled,omitempty"`

// Secret name which stores user-defined TiDB Server certificate, key and ca
// +optional
SecretName string `json:"secretName,omitempty"`

// Auto-generated certificate
// +optional
AutoGenerated *TiDBAutoGeneratedCertificate `json:"autoGenerated,omitempty"`
}

// TiDBAutoGeneratedCertificate is TiDB auto-generated certificate
type TiDBAutoGeneratedCertificate struct {
// Extra SAN IP list
// +optional
ExtraSANIPList []string `json:"extraSANIPList,omitempty"`

// Extra SAN Domain list
// +optional
ExtraSANDomainList []string `json:"extraSANDomainList,omitempty"`
}

// +genclient
Expand Down
33 changes: 1 addition & 32 deletions pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 6 additions & 95 deletions pkg/manager/member/tidb_member_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,6 @@ func (tmm *tidbMemberManager) syncTiDBStatefulSetForTidbCluster(tc *v1alpha1.Tid
return err
}
}
if tc.Spec.TiDB.IsTLSClientEnabled() && !tc.Spec.TiDB.IsUserGeneratedCertificate() {
err := tmm.syncTiDBServerCerts(tc)
if err != nil {
return err
}
err = tmm.syncTiDBClientCerts(tc)
if err != nil {
return err
}
}
err = tmm.setControl.CreateStatefulSet(tc, newTiDBSet)
if err != nil {
return err
Expand Down Expand Up @@ -270,80 +260,6 @@ func (tmm *tidbMemberManager) syncTiDBClusterCerts(tc *v1alpha1.TidbCluster) err
return tmm.certControl.Create(controller.GetOwnerRef(tc), certOpts)
}

// syncTiDBServerCerts creates the cert pair for TiDB if not exist, the cert
// pair is used to communicate with DB clients with encrypted connections
func (tmm *tidbMemberManager) syncTiDBServerCerts(tc *v1alpha1.TidbCluster) error {
suffix := "tidb-server"
ns := tc.GetNamespace()
tcName := tc.GetName()
svcName := controller.TiDBMemberName(tcName)

if tmm.certControl.CheckSecret(ns, svcName) {
return nil
}

svc, err := tmm.svcLister.Services(ns).Get(svcName)
if err != nil {
return err
}

hostList := []string{
svcName,
fmt.Sprintf("%s.%s", svcName, ns),
fmt.Sprintf("%s.%s.svc", svcName, ns),
"localhost",
}
ipList := []string{
"127.0.0.1", "::1",
svc.Spec.ClusterIP,
}

if tc.Spec.TiDB.TLSClient.AutoGenerated != nil {
hostList = append(hostList, tc.Spec.TiDB.TLSClient.AutoGenerated.ExtraSANDomainList...)
ipList = append(ipList, tc.Spec.TiDB.TLSClient.AutoGenerated.ExtraSANIPList...)
}

certOpts := &controller.TiDBClusterCertOptions{
Namespace: ns,
Instance: tcName,
CommonName: svcName,
HostList: hostList,
IPList: ipList,
Component: "tidb",
Suffix: suffix,
}

return tmm.certControl.Create(controller.GetOwnerRef(tc), certOpts)
}

// syncTiDBClientCerts creates the cert pair for TiDB if not exist, the cert
// pair is used for DB clients to connect to TiDB server with encrypted connections
func (tmm *tidbMemberManager) syncTiDBClientCerts(tc *v1alpha1.TidbCluster) error {
suffix := "tidb-client"
ns := tc.GetNamespace()
tcName := tc.GetName()
commonName := fmt.Sprintf("%s-%s", tcName, suffix)

if tmm.certControl.CheckSecret(ns, commonName) {
return nil
}

hostList := []string{
commonName,
}

certOpts := &controller.TiDBClusterCertOptions{
Namespace: ns,
Instance: tcName,
CommonName: commonName,
HostList: hostList,
Component: "tidb",
Suffix: suffix,
}

return tmm.certControl.Create(controller.GetOwnerRef(tc), certOpts)
}

func (tmm *tidbMemberManager) syncTiDBService(tc *v1alpha1.TidbCluster) error {

newSvc := getNewTiDBServiceOrNil(tc)
Expand Down Expand Up @@ -441,11 +357,7 @@ func getTiDBConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) {
if config.Security == nil {
config.Security = &v1alpha1.Security{}
}
if tc.Spec.TiDB.IsUserGeneratedCertificate() {
config.Security.SSLCA = pointer.StringPtr(path.Join(serverCertPath, tlsSecretRootCAKey))
} else {
config.Security.SSLCA = pointer.StringPtr(serviceAccountCAPath)
}
config.Security.SSLCA = pointer.StringPtr(path.Join(serverCertPath, tlsSecretRootCAKey))
config.Security.SSLCert = pointer.StringPtr(path.Join(serverCertPath, corev1.TLSCertKey))
config.Security.SSLKey = pointer.StringPtr(path.Join(serverCertPath, corev1.TLSPrivateKeyKey))
}
Expand Down Expand Up @@ -635,12 +547,7 @@ func getNewTiDBSetForTidbCluster(tc *v1alpha1.TidbCluster, cm *corev1.ConfigMap)
})
}
if tc.Spec.TiDB.IsTLSClientEnabled() {
var secretName string
if tc.Spec.TiDB.IsUserGeneratedCertificate() {
secretName = tc.Spec.TiDB.TLSClient.SecretName
} else {
secretName = fmt.Sprintf("%s-%s", controller.TiDBMemberName(tcName), "server")
}
secretName := tlsClientSecretName(tc)
vols = append(vols, corev1.Volume{
Name: "tidb-server-tls", VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
Expand Down Expand Up @@ -911,6 +818,10 @@ func tidbStatefulSetIsUpgrading(podLister corelisters.PodLister, set *apps.State
return false, nil
}

func tlsClientSecretName(tc *v1alpha1.TidbCluster) string {
return fmt.Sprintf("%s-server-secret", controller.TiDBMemberName(tc.Name))
}

type FakeTiDBMemberManager struct {
err error
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/manager/member/tidb_member_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@ func TestGetTiDBConfigMap(t *testing.T) {
Data: map[string]string{
"startup-script": "",
"config-file": `[security]
ssl-ca = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
ssl-ca = "/var/lib/tidb-server-tls/ca.crt"
ssl-cert = "/var/lib/tidb-server-tls/tls.crt"
ssl-key = "/var/lib/tidb-server-tls/tls.key"
cluster-ssl-ca = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
Expand Down

0 comments on commit 306785d

Please sign in to comment.