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
26 changes: 26 additions & 0 deletions pkg/common/utils/resource/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package resource

import (
"fmt"
"strconv"
"strings"

Expand Down Expand Up @@ -543,6 +544,31 @@ func NewBaseMainContainer(dcr *v1.DorisCluster, config map[string]interface{}, c
// use liveness as startup, when in debugging mode will not be killed
c.StartupProbe = startupProbe(livenessPort, spec.StartTimeout, health_api_path, commands, liveProbeType)
c.ReadinessProbe = readinessProbe(readnessPort, health_api_path, commands, readinessProbeType)

// When TLS is enabled, replace HTTPGet readiness probe with Exec curl that carries client certs.
// In mTLS mode (tls_verify_mode=verify_fail_if_no_peer_cert), the HTTPS endpoint requires
// client certificates. Kubernetes HTTPGet probes cannot provide client certs, so we use
// an Exec probe with curl instead. This is compatible with both TLS and mTLS modes.
enableTLS := GetString(config, ENABLE_TLS_KEY)
if enableTLS == "true" && c.ReadinessProbe != nil && c.ReadinessProbe.HTTPGet != nil {
caCert := GetString(config, TLS_CA_CERTIFICATE_PATH_KEY)
clientCert := GetString(config, TLS_CERTIFICATE_PATH_KEY)
clientKey := GetString(config, TLS_PRIVATE_KEY_PATH_KEY)
curlCmd := fmt.Sprintf(
"curl --fail --silent --output /dev/null --cacert %s --cert %s --key %s https://localhost:%d%s",
caCert, clientCert, clientKey, readnessPort, health_api_path,
)
c.ReadinessProbe = &corev1.Probe{
PeriodSeconds: 5,
FailureThreshold: 3,
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"bash", "-c", curlCmd},
},
},
}
}

c.Lifecycle = lifeCycle(prestopScript)

return c
Expand Down
11 changes: 10 additions & 1 deletion pkg/controller/sub_controller/fe/prepare_modify.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/apache/doris-operator/pkg/common/utils/resource"
sc "github.com/apache/doris-operator/pkg/controller/sub_controller"
appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -119,7 +120,15 @@ func (fc *Controller) dropObserverBySqlClient(ctx context.Context, k8sclient cli
Port: strconv.FormatInt(int64(queryPort), 10),
Database: "mysql",
}
masterDBClient, err := mysql.NewDorisMasterSqlDB(dbConf, nil, nil)

// check if TLS is enabled in FE config and find the corresponding secret
tlsConfig, secretName := fc.FindSecretTLSConfig(maps, targetDCR)
var tlsSecret *corev1.Secret
if tlsConfig != nil && secretName != "" {
tlsSecret, _ = k8s.GetSecret(ctx, k8sclient, targetDCR.Namespace, secretName)
}

masterDBClient, err := mysql.NewDorisMasterSqlDB(dbConf, tlsConfig, tlsSecret)
if err != nil {
klog.Errorf("NewDorisMasterSqlDB failed, get fe node connection err:%s", err.Error())
return err
Expand Down
38 changes: 38 additions & 0 deletions pkg/controller/sub_controller/sub_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
dorisv1 "github.com/apache/doris-operator/api/doris/v1"
utils "github.com/apache/doris-operator/pkg/common/utils"
"github.com/apache/doris-operator/pkg/common/utils/k8s"
"github.com/apache/doris-operator/pkg/common/utils/mysql"
"github.com/apache/doris-operator/pkg/common/utils/resource"
"github.com/apache/doris-operator/pkg/common/utils/set"
appv1 "k8s.io/api/apps/v1"
Expand All @@ -32,6 +33,8 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"k8s.io/klog/v2"
"path"
"path/filepath"
"sigs.k8s.io/controller-runtime/pkg/client"
"strconv"
"strings"
Expand Down Expand Up @@ -280,6 +283,41 @@ func (d *SubDefaultController) CheckSecretExist(ctx context.Context, dcr *dorisv
}
}

// FindSecretTLSConfig reads TLS configuration from FE config map and returns
// the TLS config and secret name for establishing TLS-enabled MySQL connections.
func (d *SubDefaultController) FindSecretTLSConfig(feConfMap map[string]interface{}, dcr *dorisv1.DorisCluster) (*mysql.TLSConfig, string) {
enableTLS := resource.GetString(feConfMap, resource.ENABLE_TLS_KEY)
if enableTLS == "" {
return nil, ""
}

caCertFile := resource.GetString(feConfMap, resource.TLS_CA_CERTIFICATE_PATH_KEY)
clientCertFile := resource.GetString(feConfMap, resource.TLS_CERTIFICATE_PATH_KEY)
clientKeyFile := resource.GetString(feConfMap, resource.TLS_PRIVATE_KEY_PATH_KEY)
caFileName := path.Base(caCertFile)
clientCertFileName := path.Base(clientCertFile)
clientKeyFileName := path.Base(clientKeyFile)

caCertDir := filepath.Dir(caCertFile)
secretName := ""
if dcr.Spec.FeSpec != nil {
for _, sn := range dcr.Spec.FeSpec.Secrets {
if sn.MountPath == caCertDir {
secretName = sn.SecretName
break
}
}
}

tlsConfig := &mysql.TLSConfig{
CAFileName: caFileName,
ClientCertFileName: clientCertFileName,
ClientKeyFileName: clientKeyFileName,
}

return tlsConfig, secretName
}

// CheckSharedPVC verifies two points:
// 1. Whether the SharePVC exists
// 2. Whether the AccessMode of the SharePVC is ReadWriteMany
Expand Down
Loading