Skip to content

Commit a326f03

Browse files
committed
K8SPSMDB-1654: Vector search fixes/improvements
- Mongot statefulset shouldn't be created for config server replset. - Update mongot configuration to support changes in upstream. - Use mongot image provided by Percona.
1 parent 87cc227 commit a326f03

11 files changed

Lines changed: 157 additions & 59 deletions

File tree

build/mongot-entrypoint.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
#!/bin/bash
22

33
set -o errexit
4+
set -o xtrace
45

56
MONGO_SSL_DIR=${MONGO_SSL_DIR:-/etc/mongodb-ssl}
67

7-
if [ -f "${MONGO_SSL_DIR}/tls.key" ] && [ -f "${MONGO_SSL_DIR}/tls.crt" ]; then
8+
if [[ -f "${MONGO_SSL_DIR}/tls.key" ]] && [[ -f "${MONGO_SSL_DIR}/tls.crt" ]]; then
89
cat "${MONGO_SSL_DIR}/tls.key" "${MONGO_SSL_DIR}/tls.crt" >/tmp/tls.pem
910
fi
1011

12+
# mongot requires passwordFile only be readable by the owner
13+
# but K8s doesn't allow us to set ownership for the mounted secret
14+
if [[ -f /etc/users-secret/MONGODB_SEARCH_PASSWORD ]]; then
15+
cp /etc/users-secret/MONGODB_SEARCH_PASSWORD /tmp/MONGODB_SEARCH_PASSWORD
16+
chmod 400 /tmp/MONGODB_SEARCH_PASSWORD
17+
fi
18+
1119
exec "$@"

deploy/backup/restore.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ spec:
99
# withUsersAndRoles: true
1010
# namespaces:
1111
# - "db.collection"
12+
# nsFrom: "db1.col1"
13+
# nsTo: "db1.col2"
1214
# replsetRemapping:
1315
# rs0: shard0
1416
# rs1: shard1
@@ -37,4 +39,4 @@ spec:
3739
# azure:
3840
# credentialsSecret: SECRET-NAME
3941
# prefix: PREFIX-NAME
40-
# container: CONTAINER-NAME
42+
# container: CONTAINER-NAME

e2e-tests/functions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ perconalab/percona-server-mongodb-operator:main-mongod6.0
1111
perconalab/percona-server-mongodb-operator:main-mongod7.0
1212
perconalab/percona-server-mongodb-operator:main-mongod8.0'}
1313
IMAGE_BACKUP=${IMAGE_BACKUP:-"perconalab/percona-server-mongodb-operator:main-backup"}
14-
IMAGE_SEARCH=${IMAGE_SEARCH:-"mongodb/mongodb-community-search:latest"}
14+
IMAGE_SEARCH=${IMAGE_SEARCH:-"perconalab/percona-server-mongodb-mongot:0.51.0"}
1515
SKIP_BACKUPS_TO_AWS_GCP_AZURE=${SKIP_BACKUPS_TO_AWS_GCP_AZURE:-1}
1616
PMM_SERVER_VER=${PMM_SERVER_VER:-"9.9.9"}
1717
IMAGE_PMM_CLIENT=${IMAGE_PMM_CLIENT:-"percona/pmm-client:2.44.1-1"}

pkg/apis/psmdb/v1/psmdb_defaults.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ func (cr *PerconaServerMongoDB) CheckNSetDefaults(ctx context.Context, platform
698698
return errors.New("MCS is not available on this cluster")
699699
}
700700

701+
cr.setSearchDefaults(platform)
702+
701703
return nil
702704
}
703705

@@ -1284,3 +1286,30 @@ func (cr *PerconaServerMongoDB) setStorageAutoscalingDefaults() {
12841286
spec.GrowthStep = resource.MustParse("2Gi")
12851287
}
12861288
}
1289+
1290+
func (cr *PerconaServerMongoDB) setSearchDefaults(platform version.Platform) {
1291+
if cr.Spec.Search == nil {
1292+
return
1293+
}
1294+
1295+
var userId *int64
1296+
if platform == version.PlatformKubernetes {
1297+
userId = new(int64(1001))
1298+
}
1299+
1300+
if cr.Spec.Search.ContainerSecurityContext == nil {
1301+
cr.Spec.Search.ContainerSecurityContext = &corev1.SecurityContext{
1302+
RunAsNonRoot: new(true),
1303+
RunAsGroup: userId,
1304+
RunAsUser: userId,
1305+
}
1306+
}
1307+
1308+
if cr.Spec.Search.PodSecurityContext == nil {
1309+
cr.Spec.Search.PodSecurityContext = &corev1.PodSecurityContext{
1310+
RunAsUser: userId,
1311+
RunAsGroup: userId,
1312+
FSGroup: userId,
1313+
}
1314+
}
1315+
}

pkg/controller/perconaservermongodb/search.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import (
2525
// search disabled the function deletes any previously created objects
2626
// and returns.
2727
func (r *ReconcilePerconaServerMongoDB) reconcileSearch(ctx context.Context, cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) error {
28+
if rs.ClusterRole == api.ClusterRoleConfigSvr {
29+
return nil
30+
}
31+
2832
if !cr.IsSearchEnabled() {
2933
return r.deleteSearch(ctx, cr, rs)
3034
}

pkg/controller/perconaservermongodb/status.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ func (r *ReconcilePerconaServerMongoDB) updateStatus(ctx context.Context, cr *ap
254254
if cr.Spec.Sharding.Enabled && cr.Status.Mongos.Status != api.AppStateReady {
255255
state = cr.Status.Mongos.Status
256256
}
257+
258+
if cr.IsSearchEnabled() {
259+
for rs, status := range cr.Status.Search {
260+
if status.Status != api.AppStateReady {
261+
state = status.Status
262+
log.V(1).Info("Mongot is not ready", "replset", rs, "state", state)
263+
break
264+
}
265+
}
266+
}
257267
}
258268

259269
if state != api.AppStateReady {

pkg/psmdb/vectorsearch/config.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong
8585
cfg := mongot.Config{
8686
SyncSource: mongot.ConfigSyncSource{
8787
ReplicaSet: mongot.ConfigReplicaSet{
88-
Username: string(api.RoleSearch),
89-
PasswordFile: usersSecretMountPath + "/" + api.EnvMongoDBSearchPassword,
88+
ScramAuth: &mongot.ConfigScramAuth{
89+
Username: string(api.RoleSearch),
90+
PasswordFile: "/tmp/" + api.EnvMongoDBSearchPassword,
91+
},
9092
},
9193
},
9294
Logging: mongot.ConfigLogging{
@@ -111,14 +113,6 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong
111113
},
112114
}
113115

114-
if cr.TLSEnabled() {
115-
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
116-
Mode: mongot.ConfigTLSModeMTLS,
117-
CertificateKeyFile: new(mongotTLSCertificatePath),
118-
CertificateAuthorityFile: new(mongotTLSCAPath),
119-
}
120-
}
121-
122116
hosts := make([]string, rs.Size)
123117
for i := range rs.Size {
124118
hosts[i] = mongodHostAndPort(cr, rs, i)
@@ -127,9 +121,33 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong
127121

128122
if sharding := cr.Spec.Sharding; sharding.Enabled && sharding.Mongos != nil {
129123
cfg.SyncSource.Router = &mongot.ConfigRouter{
130-
HostAndPort: mongosHostAndPort(cr),
131-
Username: string(api.RoleSearch),
132-
PasswordFile: usersSecretMountPath + "/" + api.EnvMongoDBSearchPassword,
124+
HostAndPort: mongosHostAndPort(cr),
125+
ScramAuth: &mongot.ConfigScramAuth{
126+
Username: string(api.RoleSearch),
127+
PasswordFile: "/tmp/" + api.EnvMongoDBSearchPassword,
128+
},
129+
}
130+
}
131+
132+
if cr.TLSEnabled() {
133+
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
134+
Mode: mongot.ConfigTLSModeMTLS,
135+
CertificateKeyFile: new(mongotTLSCertificatePath),
136+
CertificateAuthorityFile: new(mongotTLSCAPath),
137+
}
138+
139+
cfg.SyncSource.ReplicaSet.ScramAuth.TLS = &mongot.ScramAuthTLS{
140+
Enabled: true,
141+
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
142+
CertificateAuthorityFile: new(mongotTLSCAPath),
143+
}
144+
145+
if cfg.SyncSource.Router != nil {
146+
cfg.SyncSource.Router.ScramAuth.TLS = &mongot.ScramAuthTLS{
147+
Enabled: true,
148+
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
149+
CertificateAuthorityFile: new(mongotTLSCAPath),
150+
}
133151
}
134152
}
135153

pkg/psmdb/vectorsearch/config_test.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,15 @@ func newDefaultExpectedConfig() mongot.Config {
348348
"psmdb-rs0-1.psmdb-rs0.default.svc.cluster.local:27017",
349349
"psmdb-rs0-2.psmdb-rs0.default.svc.cluster.local:27017",
350350
},
351-
Username: "searchCoordinator",
352-
PasswordFile: "/etc/users-secret/MONGODB_SEARCH_PASSWORD",
351+
ScramAuth: &mongot.ConfigScramAuth{
352+
Username: "searchCoordinator",
353+
PasswordFile: "/tmp/MONGODB_SEARCH_PASSWORD",
354+
TLS: &mongot.ScramAuthTLS{
355+
Enabled: true,
356+
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
357+
CertificateAuthorityFile: new(mongotTLSCAPath),
358+
},
359+
},
353360
},
354361
},
355362
Storage: mongot.ConfigStorage{
@@ -427,10 +434,30 @@ net:
427434
expected: func() mongot.Config {
428435
cfg := newDefaultExpectedConfig()
429436
cfg.SyncSource.Router = &mongot.ConfigRouter{
430-
HostAndPort: []string{"psmdb-mongos.default.svc.cluster.local:27017"},
431-
Username: "searchCoordinator",
432-
PasswordFile: "/etc/users-secret/MONGODB_SEARCH_PASSWORD",
437+
HostAndPort: []string{"psmdb-mongos.default.svc.cluster.local:27017"},
438+
ScramAuth: &mongot.ConfigScramAuth{
439+
Username: "searchCoordinator",
440+
PasswordFile: "/tmp/MONGODB_SEARCH_PASSWORD",
441+
TLS: &mongot.ScramAuthTLS{
442+
Enabled: true,
443+
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
444+
CertificateAuthorityFile: new(mongotTLSCAPath),
445+
},
446+
},
447+
}
448+
return cfg
449+
}(),
450+
},
451+
"cluster TLS disabled leaves scramAuth and grpc TLS off": {
452+
mutateCR: func(cr *api.PerconaServerMongoDB) {
453+
cr.Spec.TLS = &api.TLSSpec{Mode: api.TLSModeDisabled}
454+
},
455+
expected: func() mongot.Config {
456+
cfg := newDefaultExpectedConfig()
457+
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
458+
Mode: mongot.ConfigTLSModeDisabled,
433459
}
460+
cfg.SyncSource.ReplicaSet.ScramAuth.TLS = nil
434461
return cfg
435462
}(),
436463
},

pkg/psmdb/vectorsearch/mongot/config.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,53 @@ type EmbeddingConfig struct {
1818
}
1919

2020
type ConfigSyncSource struct {
21-
ReplicaSet ConfigReplicaSet `json:"replicaSet" yaml:"replicaSet"`
22-
Router *ConfigRouter `json:"router,omitempty" yaml:"router,omitempty"`
23-
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
21+
ReplicaSet ConfigReplicaSet `json:"replicaSet" yaml:"replicaSet"`
22+
Router *ConfigRouter `json:"router,omitempty" yaml:"router,omitempty"`
23+
ReplicationReader *ConfigReplicationReader `json:"replicationReader,omitempty" yaml:"replicationReader,omitempty"`
2424
}
2525

26-
type ConfigRouter struct {
27-
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
28-
Username string `json:"username,omitempty" yaml:"username,omitempty"`
29-
PasswordFile string `json:"passwordFile,omitempty" yaml:"passwordFile,omitempty"`
30-
TLS *bool `json:"tls,omitempty" yaml:"tls,omitempty"`
31-
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
32-
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
26+
type ConfigReplicationReader struct {
27+
ReadPreference *string `json:"readPreference,omitempty" yaml:"readPreference,omitempty"`
28+
TagSets [][]ConfigTag `json:"tagSets,omitempty" yaml:"tagSets,omitempty"`
3329
}
3430

35-
type ConfigReplicaSet struct {
36-
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
37-
Username string `json:"username,omitempty" yaml:"username,omitempty"`
38-
PasswordFile string `json:"passwordFile,omitempty" yaml:"passwordFile,omitempty"`
39-
TLS *bool `json:"tls,omitempty" yaml:"tls,omitempty"`
40-
ReadPreference *string `json:"readPreference,omitempty" yaml:"readPreference,omitempty"`
41-
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
42-
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
31+
type ConfigTag struct {
32+
Name string `json:"name" yaml:"name,omitempty"`
33+
Value string `json:"value" yaml:"value,omitempty"`
34+
}
35+
36+
type ScramAuthTLS struct {
37+
Enabled bool `json:"enabled" yaml:"enabled,omitempty"`
38+
TLSCertificateKeyFile *string `json:"tlsCertificateKeyFile,omitempty" yaml:"tlsCertificateKeyFile,omitempty"`
39+
TLSCertificateKeyFilePasswordFile *string `json:"tlsCertificateKeyFilePasswordFile,omitempty" yaml:"tlsCertificateKeyFilePasswordFile,omitempty"`
40+
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
41+
}
42+
43+
type ConfigScramAuth struct {
44+
Username string `json:"username" yaml:"username,omitempty"`
45+
PasswordFile string `json:"passwordFile" yaml:"passwordFile,omitempty"`
46+
TLS *ScramAuthTLS `json:"tls,omitempty" yaml:"tls,omitempty"`
47+
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
4348
}
4449

4550
type ConfigX509 struct {
51+
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
4652
TLSCertificateKeyFile *string `json:"tlsCertificateKeyFile,omitempty" yaml:"tlsCertificateKeyFile,omitempty"`
4753
TLSCertificateKeyFilePasswordFile *string `json:"tlsCertificateKeyFilePasswordFile,omitempty" yaml:"tlsCertificateKeyFilePasswordFile,omitempty"`
4854
}
4955

56+
type ConfigRouter struct {
57+
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
58+
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
59+
ScramAuth *ConfigScramAuth `json:"scramAuth,omitempty" yaml:"scramAuth,omitempty"`
60+
}
61+
62+
type ConfigReplicaSet struct {
63+
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
64+
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
65+
ScramAuth *ConfigScramAuth `json:"scramAuth,omitempty" yaml:"scramAuth,omitempty"`
66+
}
67+
5068
type ConfigStorage struct {
5169
DataPath string `json:"dataPath" yaml:"dataPath"`
5270
}

pkg/psmdb/vectorsearch/statefulset.go

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,6 @@ func mongotContainer(cr *api.PerconaServerMongoDB, search *api.SearchSpec) corev
190190
Name: dataVolumeName,
191191
MountPath: dataMountPath,
192192
},
193-
{
194-
Name: cr.Spec.Secrets.GetInternalKey(cr),
195-
MountPath: config.MongodSecretsDir,
196-
ReadOnly: true,
197-
},
198193
{
199194
Name: configVolumeName,
200195
MountPath: configMountPath,
@@ -216,8 +211,7 @@ func mongotContainer(cr *api.PerconaServerMongoDB, search *api.SearchSpec) corev
216211
}
217212

218213
mongotCmd := []string{
219-
"mongot-community/mongot",
220-
"--config=" + configMountPath + "/" + configFileName,
214+
"mongot", "--config=" + configMountPath + "/" + configFileName,
221215
}
222216

223217
if flags := jvmFlags(search); len(flags) > 0 {
@@ -279,25 +273,13 @@ func mongotProbe(override *corev1.Probe) *corev1.Probe {
279273
// it falls back to the inline EmptyDir / HostPath source, matching how
280274
// pkg/psmdb handles mongod's data volume.
281275
func podVolumes(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec, search *api.SearchSpec) ([]corev1.Volume, []corev1.PersistentVolumeClaim) {
282-
fvar := false
283-
284276
volumes := []corev1.Volume{
285277
{
286278
Name: config.BinVolumeName,
287279
VolumeSource: corev1.VolumeSource{
288280
EmptyDir: &corev1.EmptyDirVolumeSource{},
289281
},
290282
},
291-
{
292-
Name: cr.Spec.Secrets.GetInternalKey(cr),
293-
VolumeSource: corev1.VolumeSource{
294-
Secret: &corev1.SecretVolumeSource{
295-
SecretName: cr.Spec.Secrets.GetInternalKey(cr),
296-
DefaultMode: new(secretFileMode),
297-
Optional: &fvar,
298-
},
299-
},
300-
},
301283
{
302284
Name: configVolumeName,
303285
VolumeSource: corev1.VolumeSource{

0 commit comments

Comments
 (0)