Skip to content

Commit 7f35ac7

Browse files
horsgkech
authored andcommitted
K8SPSMDB-1504 Fix MongoDB Connection Leaks in PBM Operations (#2098)
* fix con * fix lint and add test * log pbm connection closing error & improve error message in e2e test * uniform error messages for e2e test --------- Co-authored-by: George Kechagias <[email protected]>
1 parent 3c82f03 commit 7f35ac7

File tree

7 files changed

+107
-7
lines changed

7 files changed

+107
-7
lines changed

e2e-tests/init-deploy/compare/statefulset_another-name-rs0.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,57 @@ spec:
161161
resources: {}
162162
terminationMessagePath: /dev/termination-log
163163
terminationMessagePolicy: File
164+
- args:
165+
- pbm-agent-entrypoint
166+
command:
167+
- /opt/percona/pbm-entry.sh
168+
env:
169+
- name: PBM_AGENT_MONGODB_USERNAME
170+
valueFrom:
171+
secretKeyRef:
172+
key: MONGODB_BACKUP_USER_ESCAPED
173+
name: internal-another-name-users
174+
optional: false
175+
- name: PBM_AGENT_MONGODB_PASSWORD
176+
valueFrom:
177+
secretKeyRef:
178+
key: MONGODB_BACKUP_PASSWORD_ESCAPED
179+
name: internal-another-name-users
180+
optional: false
181+
- name: PBM_MONGODB_REPLSET
182+
value: rs0
183+
- name: PBM_MONGODB_PORT
184+
value: "27017"
185+
- name: PBM_AGENT_SIDECAR
186+
value: "true"
187+
- name: PBM_AGENT_SIDECAR_SLEEP
188+
value: "5"
189+
- name: POD_NAME
190+
valueFrom:
191+
fieldRef:
192+
apiVersion: v1
193+
fieldPath: metadata.name
194+
- name: PBM_MONGODB_URI
195+
value: mongodb://$(PBM_AGENT_MONGODB_USERNAME):$(PBM_AGENT_MONGODB_PASSWORD)@localhost:$(PBM_MONGODB_PORT)
196+
- name: PBM_AGENT_TLS_ENABLED
197+
value: "false"
198+
imagePullPolicy: Always
199+
name: backup-agent
200+
resources: {}
201+
securityContext:
202+
runAsNonRoot: true
203+
runAsUser: 1001
204+
terminationMessagePath: /dev/termination-log
205+
terminationMessagePolicy: File
206+
volumeMounts:
207+
- mountPath: /etc/mongodb-ssl
208+
name: ssl
209+
readOnly: true
210+
- mountPath: /opt/percona
211+
name: bin
212+
readOnly: true
213+
- mountPath: /data/db
214+
name: mongod-data
164215
- args:
165216
- fluent-bit
166217
command:

e2e-tests/init-deploy/conf/another-name-rs0.yml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@ spec:
1111
tls:
1212
mode: disabled
1313
backup:
14-
enabled: false
15-
image: perconalab/percona-server-mongodb-operator:0.4.0-backup
16-
# storages:
17-
# tasks:
14+
enabled: true
15+
image: perconalab/percona-server-mongodb-operator:1.1.0-backup
16+
storages:
17+
gcp-cs-s3:
18+
type: s3
19+
s3:
20+
credentialsSecret: gcp-cs-secret
21+
region: us-east-1
22+
bucket: operator-testing
23+
prefix: psmdb-demand-backup-physical
24+
endpointUrl: https://storage.googleapis.com
25+
insecureSkipTLSVerify: false
1826
replsets:
1927
- name: rs0
2028
terminationGracePeriodSeconds: 300
@@ -70,4 +78,4 @@ spec:
7078
users: some-users
7179
logcollector:
7280
enabled: true
73-
image: perconalab/fluentbit:main-logcollector
81+
image: perconalab/fluentbit:main-logcollector

e2e-tests/init-deploy/run

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ compare_mongo_cmd "find" "myApp:myPass@$cluster-2.$cluster.$namespace"
7676
desc 'check number of connections'
7777
conn_count=$(run_mongo 'db.serverStatus().connections.current' "clusterAdmin:clusterAdmin123456@$cluster.$namespace" | egrep -v 'I NETWORK|W NETWORK|Error saving history file|Percona Server for MongoDB|connecting to:|Unable to reach primary for set|Implicit session:|versions do not match|bye')
7878
if [ ${conn_count} -gt ${max_conn} ]; then
79+
echo "error: connection count (${conn_count}) exceeds maximum allowed (${max_conn})"
7980
exit 1
8081
fi
8182

@@ -94,6 +95,7 @@ compare_mongo_cmd "find" "myApp:myPass@$cluster-2.$cluster.$namespace" "-2nd"
9495

9596
desc 'check if possible to create second cluster'
9697
cluster2="another-name-rs0"
98+
apply_s3_storage_secrets
9799
apply_cluster $test_dir/conf/$cluster2.yml
98100
desc 'check if all 3 Pods started'
99101
wait_for_running $cluster2 3
@@ -112,6 +114,15 @@ compare_mongo_cmd "find" "myApp:myPass@$cluster2-0.$cluster2.$namespace" "-3rd"
112114
compare_mongo_cmd "find" "myApp:myPass@$cluster2-1.$cluster2.$namespace" "-3rd"
113115
compare_mongo_cmd "find" "myApp:myPass@$cluster2-2.$cluster2.$namespace" "-3rd"
114116

117+
desc 'check number of connections with backup'
118+
max_conn=50
119+
sleep 300
120+
conn_count=$(run_mongo 'db.serverStatus().connections.current' "clusterAdmin:clusterAdmin123456@$cluster2.$namespace" | egrep -v 'I NETWORK|W NETWORK|Error saving history file|Percona Server for MongoDB|connecting to:|Unable to reach primary for set|Implicit session:|versions do not match|bye')
121+
if [ ${conn_count} -gt ${max_conn} ]; then
122+
echo "error: connection count (${conn_count}) exceeds maximum allowed (${max_conn}) with backup enabled"
123+
exit 1
124+
fi
125+
115126
desc 'check if mongod log files exist in pod'
116127
log_files=$(kubectl exec "${cluster2}-0" -c "mongod" -- ls "/data/db/logs" 2>/dev/null)
117128
if ! echo "$log_files" | grep -q 'mongod.log' || ! echo "$log_files" | grep -q 'mongod.full.log'; then

pkg/controller/perconaservermongodb/pbm.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ func (r *ReconcilePerconaServerMongoDB) reconcilePBMConfig(ctx context.Context,
122122
if err != nil {
123123
return errors.Wrap(err, "new PBM connection")
124124
}
125+
defer func() {
126+
if err := pbm.Close(ctx); err != nil {
127+
log.Error(err, "failed to close PBM connection")
128+
}
129+
}()
125130

126131
currentCfg, err := pbm.GetConfig(ctx)
127132
if err != nil && !backup.IsErrNoDocuments(err) {
@@ -324,7 +329,11 @@ func (r *ReconcilePerconaServerMongoDB) reconcilePiTRConfig(ctx context.Context,
324329
if err != nil {
325330
return errors.Wrap(err, "create pbm object")
326331
}
327-
defer pbm.Close(ctx)
332+
defer func() {
333+
if err := pbm.Close(ctx); err != nil {
334+
log.Error(err, "failed to close PBM connection")
335+
}
336+
}()
328337

329338
if err := enablePiTRIfNeeded(ctx, pbm, cr); err != nil {
330339
if backup.IsErrNoDocuments(err) {
@@ -594,6 +603,11 @@ func (r *ReconcilePerconaServerMongoDB) resyncPBMIfNeeded(ctx context.Context, c
594603
log.Error(err, "failed to open PBM connection")
595604
return
596605
}
606+
defer func() {
607+
if err := pbm.Close(ctx); err != nil {
608+
log.Error(err, "failed to close PBM connection")
609+
}
610+
}()
597611

598612
log.Info("starting resync for main storage")
599613

pkg/controller/perconaservermongodbrestore/logical.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ func (r *ReconcilePerconaServerMongoDBRestore) reconcileLogicalRestore(
3636
status.State = psmdbv1.RestoreStateWaiting
3737
return status, nil
3838
}
39-
defer pbmc.Close(ctx)
39+
defer func() {
40+
if err := pbmc.Close(ctx); err != nil {
41+
log.Error(err, "failed to close PBM connection")
42+
}
43+
}()
4044

4145
if status.State == psmdbv1.RestoreStateNew || status.State == psmdbv1.RestoreStateWaiting {
4246
// Disable PITR before restore

pkg/controller/perconaservermongodbrestore/physical.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ func (r *ReconcilePerconaServerMongoDBRestore) updatePBMConfigSecret(
800800
cluster *psmdbv1.PerconaServerMongoDB,
801801
bcp *psmdbv1.PerconaServerMongoDBBackup,
802802
) error {
803+
log := logf.FromContext(ctx)
804+
803805
secret := corev1.Secret{}
804806
err := r.client.Get(ctx, types.NamespacedName{Name: r.pbmConfigName(cluster), Namespace: cluster.Namespace}, &secret)
805807
if client.IgnoreNotFound(err) != nil {
@@ -810,6 +812,11 @@ func (r *ReconcilePerconaServerMongoDBRestore) updatePBMConfigSecret(
810812
if err != nil {
811813
return errors.Wrap(err, "new PBM connection")
812814
}
815+
defer func() {
816+
if err := pbmC.Close(ctx); err != nil {
817+
log.Error(err, "failed to close PBM connection")
818+
}
819+
}()
813820

814821
// PBM uses main storage to store restore metadata
815822
// regardless of backup storage. See PBM-1503.

pkg/controller/perconaservermongodbrestore/psmdb_restore_controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ func (r *ReconcilePerconaServerMongoDBRestore) resyncStorage(
406406
if err != nil {
407407
return errors.Wrap(err, "new PBM connection")
408408
}
409+
defer func() {
410+
if err := pbmC.Close(ctx); err != nil {
411+
log.Error(err, "failed to close PBM connection")
412+
}
413+
}()
409414

410415
// restore: backupSource
411416
if len(cr.Spec.BackupName) == 0 {

0 commit comments

Comments
 (0)