diff --git a/docs/api-references/docs.md b/docs/api-references/docs.md
index da31adcd78..24549c7591 100644
--- a/docs/api-references/docs.md
+++ b/docs/api-references/docs.md
@@ -2894,6 +2894,55 @@ CrdKind
+
DashboardConfig
+
+
+(Appears on:
+PDConfig)
+
+
+
DashboardConfig is the configuration for tidb-dashboard.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+tidb_cacert_path
+
+string
+
+ |
+
+ |
+
+
+
+tidb_cert_path
+
+string
+
+ |
+
+ |
+
+
+
+tidb_key_path
+
+string
+
+ |
+
+ |
+
+
+
Experimental
@@ -4104,6 +4153,19 @@ namespaces.
Optional: Defaults to true
+
+
+dashboard
+
+
+DashboardConfig
+
+
+ |
+
+(Optional)
+ |
+
PDFailureMember
diff --git a/examples/selfsigned-tls/tidb-client-cert.yaml b/examples/selfsigned-tls/tidb-client-cert.yaml
new file mode 100644
index 0000000000..df740c27ed
--- /dev/null
+++ b/examples/selfsigned-tls/tidb-client-cert.yaml
@@ -0,0 +1,21 @@
+apiVersion: cert-manager.io/v1alpha2
+kind: Certificate
+metadata:
+ name: tidb-client-cert
+spec:
+ secretName: tls-tidb-client-secret # -tidb-client-secret
+ subject:
+ organizationalUnits:
+ - "TiDB Operator"
+ organization:
+ - "PingCAP"
+ duration: "8760h" # 364 days
+ # If you want verify server cert Common Name (e.g. --ssl-verify-server-cert
+ # flag in MySQL CLI), you must configure the HostName you used to connect the
+ # server here.
+ commonName: "tls-tidb-client"
+ usages:
+ - "client auth"
+ issuerRef:
+ name: selfsigned-cert-issuer
+ kind: Issuer
diff --git a/manifests/crd.yaml b/manifests/crd.yaml
index 3fc5ece117..e4960293b4 100644
--- a/manifests/crd.yaml
+++ b/manifests/crd.yaml
@@ -1344,6 +1344,7 @@ spec:
type: string
cluster-version:
type: string
+ dashboard: {}
election-interval:
description: ElectionInterval is the interval for etcd Raft
election.
diff --git a/pkg/apis/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/pingcap/v1alpha1/openapi_generated.go
index b73f574aeb..5c3381c522 100644
--- a/pkg/apis/pingcap/v1alpha1/openapi_generated.go
+++ b/pkg/apis/pingcap/v1alpha1/openapi_generated.go
@@ -1674,11 +1674,16 @@ func schema_pkg_apis_pingcap_v1alpha1_PDConfig(ref common.ReferenceCallback) com
Format: "",
},
},
+ "dashboard": {
+ SchemaProps: spec.SchemaProps{
+ Ref: ref("github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.DashboardConfig"),
+ },
+ },
},
},
},
Dependencies: []string{
- "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDLogConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDMetricConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDNamespaceConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDReplicationConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDScheduleConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDSecurityConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDServerConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDStoreLabel"},
+ "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.DashboardConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDLogConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDMetricConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDNamespaceConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDReplicationConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDScheduleConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDSecurityConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDServerConfig", "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.PDStoreLabel"},
}
}
diff --git a/pkg/apis/pingcap/v1alpha1/pd_config.go b/pkg/apis/pingcap/v1alpha1/pd_config.go
index 29b56875dd..f3b2e6612f 100644
--- a/pkg/apis/pingcap/v1alpha1/pd_config.go
+++ b/pkg/apis/pingcap/v1alpha1/pd_config.go
@@ -118,6 +118,16 @@ type PDConfig struct {
// Optional: Defaults to true
// +optional
NamespaceClassifier string `toml:"namespace-classifier,omitempty" json:"namespace-classifier,omitempty"`
+
+ // +optional
+ Dashboard *DashboardConfig `toml:"dashboard,omitempty" json:"dashboard,omitempty"`
+}
+
+// DashboardConfig is the configuration for tidb-dashboard.
+type DashboardConfig struct {
+ TiDBCAPath string `toml:"tidb-cacert-path,omitempty" json:"tidb_cacert_path,omitempty"`
+ TiDBCertPath string `toml:"tidb-cert-path,omitempty" json:"tidb_cert_path,omitempty"`
+ TiDBKeyPath string `toml:"tidb-key-path,omitempty" json:"tidb_key_path,omitempty"`
}
// PDLogConfig serializes log related config in toml/json.
diff --git a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go
index f7a95863f7..f9f0a39fcc 100644
--- a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go
@@ -594,6 +594,22 @@ func (in *CrdKinds) DeepCopy() *CrdKinds {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DashboardConfig) DeepCopyInto(out *DashboardConfig) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardConfig.
+func (in *DashboardConfig) DeepCopy() *DashboardConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(DashboardConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DataResource) DeepCopyInto(out *DataResource) {
*out = *in
@@ -1104,6 +1120,11 @@ func (in *PDConfig) DeepCopyInto(out *PDConfig) {
}
}
}
+ if in.Dashboard != nil {
+ in, out := &in.Dashboard, &out.Dashboard
+ *out = new(DashboardConfig)
+ **out = **in
+ }
return
}
diff --git a/pkg/manager/member/pd_member_manager.go b/pkg/manager/member/pd_member_manager.go
index 932fc9130c..a316d3b53e 100644
--- a/pkg/manager/member/pd_member_manager.go
+++ b/pkg/manager/member/pd_member_manager.go
@@ -38,7 +38,8 @@ import (
const (
// pdClusterCertPath is where the cert for inter-cluster communication stored (if any)
- pdClusterCertPath = "/var/lib/pd-tls"
+ pdClusterCertPath = "/var/lib/pd-tls"
+ tidbClientCertPath = "/var/lib/tidb-client-tls"
)
type pdMemberManager struct {
@@ -513,6 +514,11 @@ func getNewPDSetForTidbCluster(tc *v1alpha1.TidbCluster, cm *corev1.ConfigMap) (
Name: "pd-tls", ReadOnly: true, MountPath: "/var/lib/pd-tls",
})
}
+ if tc.Spec.TiDB.IsTLSClientEnabled() {
+ volMounts = append(volMounts, corev1.VolumeMount{
+ Name: "tidb-client-tls", ReadOnly: true, MountPath: tidbClientCertPath,
+ })
+ }
vols := []corev1.Volume{
annVolume,
@@ -546,6 +552,15 @@ func getNewPDSetForTidbCluster(tc *v1alpha1.TidbCluster, cm *corev1.ConfigMap) (
},
})
}
+ if tc.Spec.TiDB.IsTLSClientEnabled() {
+ vols = append(vols, corev1.Volume{
+ Name: "tidb-client-tls", VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: util.TiDBClientTLSSecretName(tc.Name),
+ },
+ },
+ })
+ }
storageRequest, err := controller.ParseStorageRequest(tc.Spec.PD.Requests)
if err != nil {
@@ -688,6 +703,14 @@ func getPDConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) {
config.Security.CertPath = path.Join(pdClusterCertPath, corev1.TLSCertKey)
config.Security.KeyPath = path.Join(pdClusterCertPath, corev1.TLSPrivateKeyKey)
}
+ if tc.Spec.TiDB.IsTLSClientEnabled() {
+ if config.Dashboard == nil {
+ config.Dashboard = &v1alpha1.DashboardConfig{}
+ }
+ config.Dashboard.TiDBCAPath = path.Join(tidbClientCertPath, tlsSecretRootCAKey)
+ config.Dashboard.TiDBCertPath = path.Join(tidbClientCertPath, corev1.TLSCertKey)
+ config.Dashboard.TiDBKeyPath = path.Join(tidbClientCertPath, corev1.TLSPrivateKeyKey)
+ }
confText, err := MarshalTOML(config)
if err != nil {