Skip to content

Commit e0bced5

Browse files
authored
K8SPSMDB-926: Implement PiTR for physical restores (#1288)
* K8SPSMDB-926: Implement PiTR for physical restores * handle mongo version < 6.0 * implement recovering to latest oplog chunk * add test * fixes * more fixes * use custom PBM image * fix backup image
1 parent ac20eb0 commit e0bced5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+4261
-237
lines changed

build/physical-restore-ps-entry.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#!/bin/bash
2-
set -Eeuo pipefail
32

3+
set -Eeuo pipefail
44
set -o xtrace
55

6-
/opt/percona/pbm-agent &
6+
log=/tmp/pbm-agent.log
77

8+
/opt/percona/pbm-agent 2> ${log} &
89
/opt/percona/ps-entry.sh "$@"
910

1011
echo "Physical restore in progress"
11-
12+
cat ${log}
1213
sleep infinity

clientcmd/clientcmd.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package clientcmd
22

33
import (
4+
"context"
45
"io"
56

67
corev1 "k8s.io/api/core/v1"
@@ -42,9 +43,9 @@ func NewClient() (*Client, error) {
4243
}, nil
4344
}
4445

45-
func (c *Client) Exec(pod *corev1.Pod, containerName string, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
46-
// Prepare the API URL used to execute another process within the Pod. In
47-
// this case, we'll run a remote shell.
46+
func (c *Client) Exec(ctx context.Context, pod *corev1.Pod, containerName string, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
47+
// Prepare the API URL used to execute another process within the Pod.
48+
// In this case, we'll run a remote shell.
4849
req := c.client.RESTClient().
4950
Post().
5051
Namespace(pod.Namespace).
@@ -66,7 +67,7 @@ func (c *Client) Exec(pod *corev1.Pod, containerName string, command []string, s
6667
}
6768

6869
// Connect this process' std{in,out,err} to the remote shell process.
69-
return exec.Stream(remotecommand.StreamOptions{
70+
return exec.StreamWithContext(ctx, remotecommand.StreamOptions{
7071
Stdin: stdin,
7172
Stdout: stdout,
7273
Stderr: stderr,

config/crd/bases/psmdb.percona.com_perconaservermongodbrestores.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ spec:
132132
type: string
133133
pbmName:
134134
type: string
135+
pitrTarget:
136+
type: string
135137
state:
136138
type: string
137139
type: object

deploy/bundle.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ spec:
274274
type: string
275275
pbmName:
276276
type: string
277+
pitrTarget:
278+
type: string
277279
state:
278280
type: string
279281
type: object

deploy/crd.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ spec:
274274
type: string
275275
pbmName:
276276
type: string
277+
pitrTarget:
278+
type: string
277279
state:
278280
type: string
279281
type: object

deploy/cw-bundle.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ spec:
274274
type: string
275275
pbmName:
276276
type: string
277+
pitrTarget:
278+
type: string
277279
state:
278280
type: string
279281
type: object
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
switched to db myApp
2+
{ "_id" : , "x" : 100500 }
3+
{ "_id" : , "x" : 100500 }
4+
bye
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
switched to db myApp
2+
{ "_id" : , "x" : 100500 }
3+
{ "_id" : , "x" : 100500 }
4+
{ "_id" : , "x" : 100501 }
5+
bye
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
switched to db myApp
2+
{ "_id" : , "x" : 100500 }
3+
bye
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
annotations: {}
5+
generation: 1
6+
labels:
7+
app.kubernetes.io/component: cfg
8+
app.kubernetes.io/instance: some-name
9+
app.kubernetes.io/managed-by: percona-server-mongodb-operator
10+
app.kubernetes.io/name: percona-server-mongodb
11+
app.kubernetes.io/part-of: percona-server-mongodb
12+
app.kubernetes.io/replset: cfg
13+
name: some-name-cfg
14+
ownerReferences:
15+
- controller: true
16+
kind: PerconaServerMongoDB
17+
name: some-name
18+
spec:
19+
podManagementPolicy: OrderedReady
20+
replicas: 3
21+
revisionHistoryLimit: 10
22+
selector:
23+
matchLabels:
24+
app.kubernetes.io/component: cfg
25+
app.kubernetes.io/instance: some-name
26+
app.kubernetes.io/managed-by: percona-server-mongodb-operator
27+
app.kubernetes.io/name: percona-server-mongodb
28+
app.kubernetes.io/part-of: percona-server-mongodb
29+
app.kubernetes.io/replset: cfg
30+
serviceName: some-name-cfg
31+
template:
32+
metadata:
33+
annotations: {}
34+
labels:
35+
app.kubernetes.io/component: cfg
36+
app.kubernetes.io/instance: some-name
37+
app.kubernetes.io/managed-by: percona-server-mongodb-operator
38+
app.kubernetes.io/name: percona-server-mongodb
39+
app.kubernetes.io/part-of: percona-server-mongodb
40+
app.kubernetes.io/replset: cfg
41+
spec:
42+
affinity:
43+
podAntiAffinity:
44+
requiredDuringSchedulingIgnoredDuringExecution:
45+
- labelSelector:
46+
matchLabels:
47+
app.kubernetes.io/component: cfg
48+
app.kubernetes.io/instance: some-name
49+
app.kubernetes.io/managed-by: percona-server-mongodb-operator
50+
app.kubernetes.io/name: percona-server-mongodb
51+
app.kubernetes.io/part-of: percona-server-mongodb
52+
app.kubernetes.io/replset: cfg
53+
topologyKey: kubernetes.io/hostname
54+
containers:
55+
- args:
56+
- --bind_ip_all
57+
- --auth
58+
- --dbpath=/data/db
59+
- --port=27017
60+
- --replSet=cfg
61+
- --storageEngine=wiredTiger
62+
- --relaxPermChecks
63+
- --sslAllowInvalidCertificates
64+
- --clusterAuthMode=x509
65+
- --configsvr
66+
- --enableEncryption
67+
- --encryptionKeyFile=/etc/mongodb-encryption/encryption-key
68+
- --wiredTigerIndexPrefixCompression=true
69+
command:
70+
- /opt/percona/ps-entry.sh
71+
env:
72+
- name: SERVICE_NAME
73+
value: some-name
74+
- name: MONGODB_PORT
75+
value: "27017"
76+
- name: MONGODB_REPLSET
77+
value: cfg
78+
envFrom:
79+
- secretRef:
80+
name: internal-some-name-users
81+
optional: false
82+
imagePullPolicy: Always
83+
livenessProbe:
84+
exec:
85+
command:
86+
- /opt/percona/mongodb-healthcheck
87+
- k8s
88+
- liveness
89+
- --ssl
90+
- --sslInsecure
91+
- --sslCAFile
92+
- /etc/mongodb-ssl/ca.crt
93+
- --sslPEMKeyFile
94+
- /tmp/tls.pem
95+
- --startupDelaySeconds
96+
- "7200"
97+
failureThreshold: 4
98+
initialDelaySeconds: 60
99+
periodSeconds: 30
100+
successThreshold: 1
101+
timeoutSeconds: 10
102+
name: mongod
103+
ports:
104+
- containerPort: 27017
105+
name: mongodb
106+
protocol: TCP
107+
readinessProbe:
108+
failureThreshold: 3
109+
initialDelaySeconds: 10
110+
periodSeconds: 3
111+
successThreshold: 1
112+
tcpSocket:
113+
port: 27017
114+
timeoutSeconds: 2
115+
resources: {}
116+
securityContext:
117+
runAsNonRoot: true
118+
terminationMessagePath: /dev/termination-log
119+
terminationMessagePolicy: File
120+
volumeMounts:
121+
- mountPath: /data/db
122+
name: mongod-data
123+
- mountPath: /etc/mongodb-secrets
124+
name: some-name-mongodb-keyfile
125+
readOnly: true
126+
- mountPath: /etc/mongodb-ssl
127+
name: ssl
128+
readOnly: true
129+
- mountPath: /etc/mongodb-ssl-internal
130+
name: ssl-internal
131+
readOnly: true
132+
- mountPath: /opt/percona
133+
name: bin
134+
- mountPath: /etc/mongodb-encryption
135+
name: some-name-mongodb-encryption-key
136+
readOnly: true
137+
- mountPath: /etc/users-secret
138+
name: users-secret-file
139+
workingDir: /data/db
140+
- args:
141+
- -c
142+
- while true; do echo echo $(date -u) 'test' >> /dev/null; sleep 5;done
143+
command:
144+
- /bin/sh
145+
imagePullPolicy: Always
146+
name: cfg-sidecar-1
147+
resources: {}
148+
terminationMessagePath: /dev/termination-log
149+
terminationMessagePolicy: File
150+
- args:
151+
- pbm-agent-entrypoint
152+
command:
153+
- /opt/percona/pbm-entry.sh
154+
env:
155+
- name: PBM_AGENT_MONGODB_USERNAME
156+
valueFrom:
157+
secretKeyRef:
158+
key: MONGODB_BACKUP_USER
159+
name: internal-some-name-users
160+
optional: false
161+
- name: PBM_AGENT_MONGODB_PASSWORD
162+
valueFrom:
163+
secretKeyRef:
164+
key: MONGODB_BACKUP_PASSWORD
165+
name: internal-some-name-users
166+
optional: false
167+
- name: PBM_MONGODB_REPLSET
168+
value: cfg
169+
- name: PBM_MONGODB_PORT
170+
value: "27017"
171+
- name: PBM_AGENT_SIDECAR
172+
value: "true"
173+
- name: PBM_AGENT_SIDECAR_SLEEP
174+
value: "5"
175+
- name: SHARDED
176+
value: "TRUE"
177+
- name: POD_NAME
178+
valueFrom:
179+
fieldRef:
180+
apiVersion: v1
181+
fieldPath: metadata.name
182+
- name: PBM_MONGODB_URI
183+
value: mongodb://$(PBM_AGENT_MONGODB_USERNAME):$(PBM_AGENT_MONGODB_PASSWORD)@$(POD_NAME)
184+
imagePullPolicy: Always
185+
name: backup-agent
186+
resources: {}
187+
securityContext:
188+
runAsNonRoot: true
189+
terminationMessagePath: /dev/termination-log
190+
terminationMessagePolicy: File
191+
volumeMounts:
192+
- mountPath: /etc/mongodb-ssl
193+
name: ssl
194+
readOnly: true
195+
- mountPath: /opt/percona
196+
name: bin
197+
readOnly: true
198+
- mountPath: /data/db
199+
name: mongod-data
200+
dnsPolicy: ClusterFirst
201+
initContainers:
202+
- command:
203+
- /init-entrypoint.sh
204+
imagePullPolicy: Always
205+
name: mongo-init
206+
resources: {}
207+
terminationMessagePath: /dev/termination-log
208+
terminationMessagePolicy: File
209+
volumeMounts:
210+
- mountPath: /data/db
211+
name: mongod-data
212+
- mountPath: /opt/percona
213+
name: bin
214+
restartPolicy: Always
215+
schedulerName: default-scheduler
216+
securityContext: {}
217+
serviceAccount: default
218+
serviceAccountName: default
219+
terminationGracePeriodSeconds: 30
220+
volumes:
221+
- name: some-name-mongodb-keyfile
222+
secret:
223+
defaultMode: 288
224+
optional: false
225+
secretName: some-name-mongodb-keyfile
226+
- emptyDir: {}
227+
name: bin
228+
- name: some-name-mongodb-encryption-key
229+
secret:
230+
defaultMode: 288
231+
optional: false
232+
secretName: some-name-mongodb-encryption-key
233+
- name: ssl
234+
secret:
235+
defaultMode: 288
236+
optional: false
237+
secretName: some-name-ssl
238+
- name: ssl-internal
239+
secret:
240+
defaultMode: 288
241+
optional: true
242+
secretName: some-name-ssl-internal
243+
- name: users-secret-file
244+
secret:
245+
defaultMode: 420
246+
secretName: internal-some-name-users
247+
updateStrategy:
248+
rollingUpdate:
249+
partition: 0
250+
type: RollingUpdate
251+
volumeClaimTemplates:
252+
- metadata:
253+
name: mongod-data
254+
spec:
255+
accessModes:
256+
- ReadWriteOnce
257+
resources:
258+
requests:
259+
storage: 3Gi
260+
status:
261+
phase: Pending

0 commit comments

Comments
 (0)