Skip to content

Commit 103e2b9

Browse files
committed
galera: support mariabackup SST method
Make the SST method configurable in the galera custom resource, and allow both rsync and mariabackup methods. Mariabackup requires a database user's credentials to operate, so reuse the root db user for the time being. Jira: OSPRH-10195
1 parent 3d6a890 commit 103e2b9

File tree

11 files changed

+264
-12
lines changed

11 files changed

+264
-12
lines changed

api/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ spec:
7878
secret:
7979
description: Name of the secret to look for password keys
8080
type: string
81+
sst:
82+
default: rsync
83+
description: Snapshot State Transfer method to use for full node synchronization
84+
enum:
85+
- rsync
86+
- mariabackup
87+
type: string
8188
storageClass:
8289
description: Storage class to host the mariadb databases
8390
type: string

api/v1beta1/galera_types.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,21 @@ type GaleraSpecCore struct {
8080
// +kubebuilder:validation:Optional
8181
// Log Galera pod's output to disk
8282
LogToDisk bool `json:"logToDisk"`
83+
// +kubebuilder:validation:Optional
84+
// +kubebuilder:default=rsync
85+
// +kubebuilder:validation:Enum=rsync;mariabackup
86+
// Snapshot State Transfer method to use for full node synchronization
87+
SST GaleraSST `json:"sst"`
8388
}
8489

90+
// Supported SST type
91+
type GaleraSST string
92+
93+
const (
94+
RSync GaleraSST = "rsync"
95+
MariaBackup GaleraSST = "mariabackup"
96+
)
97+
8598
// GaleraAttributes holds startup information for a Galera host
8699
type GaleraAttributes struct {
87100
// Last recorded replication sequence number in the DB

config/crd/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ spec:
7878
secret:
7979
description: Name of the secret to look for password keys
8080
type: string
81+
sst:
82+
default: rsync
83+
description: Snapshot State Transfer method to use for full node synchronization
84+
enum:
85+
- rsync
86+
- mariabackup
87+
type: string
8188
storageClass:
8289
description: Storage class to host the mariadb databases
8390
type: string
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: mariadb.openstack.org/v1beta1
2+
kind: Galera
3+
metadata:
4+
name: openstack
5+
spec:
6+
secret: osp-secret
7+
storageClass: local-storage
8+
storageRequest: 500M
9+
replicas: 3
10+
sst: mariabackup

pkg/mariadb/volumes.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,183 @@ func getGaleraLogMount() corev1.VolumeMount {
229229
SubPath: "log",
230230
}
231231
}
232+
233+
func getGaleraVolumes(g *mariadbv1.Galera) []corev1.Volume {
234+
configTemplates := []corev1.KeyToPath{
235+
{
236+
Key: "my.cnf.in",
237+
Path: ".my.cnf.in",
238+
},
239+
{
240+
Key: "galera.cnf.in",
241+
Path: "galera.cnf.in",
242+
},
243+
{
244+
Key: mariadbv1.CustomServiceConfigFile,
245+
Path: mariadbv1.CustomServiceConfigFile,
246+
},
247+
}
248+
249+
if g.Spec.SST == mariadbv1.MariaBackup {
250+
configTemplates = append(configTemplates, corev1.KeyToPath{
251+
Key: "galera_sst_mariabackup.cnf.in",
252+
Path: "galera_sst_mariabackup.cnf.in",
253+
})
254+
}
255+
256+
volumes := []corev1.Volume{
257+
{
258+
Name: "secrets",
259+
VolumeSource: corev1.VolumeSource{
260+
Secret: &corev1.SecretVolumeSource{
261+
SecretName: g.Spec.Secret,
262+
Items: []corev1.KeyToPath{
263+
{
264+
Key: "DbRootPassword",
265+
Path: "dbpassword",
266+
},
267+
},
268+
},
269+
},
270+
},
271+
{
272+
Name: "kolla-config",
273+
VolumeSource: corev1.VolumeSource{
274+
ConfigMap: &corev1.ConfigMapVolumeSource{
275+
LocalObjectReference: corev1.LocalObjectReference{
276+
Name: g.Name + "-config-data",
277+
},
278+
Items: []corev1.KeyToPath{
279+
{
280+
Key: "config.json",
281+
Path: "config.json",
282+
},
283+
},
284+
},
285+
},
286+
},
287+
{
288+
Name: "kolla-config-init",
289+
VolumeSource: corev1.VolumeSource{
290+
ConfigMap: &corev1.ConfigMapVolumeSource{
291+
LocalObjectReference: corev1.LocalObjectReference{
292+
Name: g.Name + "-config-data",
293+
},
294+
Items: []corev1.KeyToPath{
295+
{
296+
Key: "init_config.json",
297+
Path: "config.json",
298+
},
299+
},
300+
},
301+
},
302+
},
303+
{
304+
Name: "pod-config-data",
305+
VolumeSource: corev1.VolumeSource{
306+
EmptyDir: &corev1.EmptyDirVolumeSource{},
307+
},
308+
},
309+
{
310+
Name: "config-data",
311+
VolumeSource: corev1.VolumeSource{
312+
ConfigMap: &corev1.ConfigMapVolumeSource{
313+
LocalObjectReference: corev1.LocalObjectReference{
314+
Name: g.Name + "-config-data",
315+
},
316+
Items: configTemplates,
317+
},
318+
},
319+
},
320+
{
321+
Name: "operator-scripts",
322+
VolumeSource: corev1.VolumeSource{
323+
ConfigMap: &corev1.ConfigMapVolumeSource{
324+
LocalObjectReference: corev1.LocalObjectReference{
325+
Name: g.Name + "-scripts",
326+
},
327+
Items: []corev1.KeyToPath{
328+
{
329+
Key: "mysql_bootstrap.sh",
330+
Path: "mysql_bootstrap.sh",
331+
},
332+
{
333+
Key: "mysql_probe.sh",
334+
Path: "mysql_probe.sh",
335+
},
336+
{
337+
Key: "detect_last_commit.sh",
338+
Path: "detect_last_commit.sh",
339+
},
340+
{
341+
Key: "detect_gcomm_and_start.sh",
342+
Path: "detect_gcomm_and_start.sh",
343+
},
344+
},
345+
},
346+
},
347+
},
348+
}
349+
350+
return volumes
351+
}
352+
353+
func getGaleraVolumeMounts(g *mariadbv1.Galera) []corev1.VolumeMount {
354+
volumeMounts := []corev1.VolumeMount{
355+
{
356+
MountPath: "/var/lib/mysql",
357+
Name: "mysql-db",
358+
}, {
359+
MountPath: "/var/lib/config-data",
360+
ReadOnly: true,
361+
Name: "config-data",
362+
}, {
363+
MountPath: "/var/lib/pod-config-data",
364+
Name: "pod-config-data",
365+
}, {
366+
MountPath: "/var/lib/secrets",
367+
ReadOnly: true,
368+
Name: "secrets",
369+
}, {
370+
MountPath: "/var/lib/operator-scripts",
371+
ReadOnly: true,
372+
Name: "operator-scripts",
373+
}, {
374+
MountPath: "/var/lib/kolla/config_files",
375+
ReadOnly: true,
376+
Name: "kolla-config",
377+
},
378+
}
379+
380+
return volumeMounts
381+
}
382+
383+
func getGaleraInitVolumeMounts(g *mariadbv1.Galera) []corev1.VolumeMount {
384+
volumeMounts := []corev1.VolumeMount{
385+
{
386+
MountPath: "/var/lib/mysql",
387+
Name: "mysql-db",
388+
}, {
389+
MountPath: "/var/lib/config-data",
390+
ReadOnly: true,
391+
Name: "config-data",
392+
}, {
393+
MountPath: "/var/lib/pod-config-data",
394+
Name: "pod-config-data",
395+
}, {
396+
MountPath: "/var/lib/secrets",
397+
ReadOnly: true,
398+
Name: "secrets",
399+
}, {
400+
MountPath: "/var/lib/operator-scripts",
401+
ReadOnly: true,
402+
Name: "operator-scripts",
403+
}, {
404+
MountPath: "/var/lib/kolla/config_files",
405+
ReadOnly: true,
406+
Name: "kolla-config-init",
407+
},
408+
}
409+
410+
return volumeMounts
411+
}

templates/galera/bin/mysql_bootstrap.sh

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/bin/bash
2-
set +eux
2+
set -eu
3+
4+
init_error() {
5+
echo "Container initialization failed at $(caller)." >&2
6+
}
7+
trap init_error ERR
38

49
if [ -e /var/lib/mysql/mysql ]; then
510
echo -e "Database already exists. Reuse it."
@@ -31,20 +36,26 @@ fi
3136
PODNAME=$(hostname -f | cut -d. -f1,2)
3237
PODIPV4=$(grep "${PODNAME}" /etc/hosts | grep -v ':' | cut -d$'\t' -f1)
3338
PODIPV6=$(grep "${PODNAME}" /etc/hosts | grep ':' | cut -d$'\t' -f1)
39+
if [[ "" = "${PODIPV6}" ]]; then
40+
PODIP="${PODIPV4}"
41+
IPSTACK="IPV4"
42+
else
43+
PODIP="[::]"
44+
IPSTACK="IPV6"
45+
fi
46+
47+
# mariabackup: default credentials if no configuration was provided
48+
: ${MARIABACKUP_USER=root}
49+
: ${MARIABACKUP_PASSWORD=$DB_ROOT_PASSWORD}
3450

3551
cd /var/lib/config-data/default
3652
for cfg in *.cnf.in; do
3753
if [ -s "${cfg}" ]; then
38-
39-
if [[ "" = "${PODIPV6}" ]]; then
40-
PODIP="${PODIPV4}"
41-
IPSTACK="IPV4"
42-
else
43-
PODIP="[::]"
44-
IPSTACK="IPV6"
45-
fi
46-
4754
echo "Generating config file from template ${cfg}, will use ${IPSTACK} listen address of ${PODIP}"
48-
sed -e "s/{ PODNAME }/${PODNAME}/" -e "s/{ PODIP }/${PODIP}/" -e "s/{ SSL_CIPHER }/${SSL_CIPHER}/" "/var/lib/config-data/default/${cfg}" > "/var/lib/config-data/generated/${cfg%.in}"
55+
# replace all occurrences of "{ xxx }" with their value from environment
56+
awk '{
57+
patsplit($0,markers,/{ (PODNAME|PODIP|SSL_CIPHER|MARIABACKUP_USER|MARIABACKUP_PASSWORD) }/);
58+
for(i in markers){ m=markers[i]; gsub(/\W/,"",m); gsub(markers[i], ENVIRON[m])};
59+
}' "/var/lib/config-data/default/${cfg}" > "/var/lib/config-data/generated/${cfg%.in}"
4960
fi
5061
done

templates/galera/bin/mysql_probe.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set -u
33

44
# This secret is mounted by k8s and always up to date
5-
read -s -u 3 3< /var/lib/secrets/dbpassword MYSQL_PWD || true
5+
read -s -u 3 3< <(cat /var/lib/secrets/dbpassword; echo) MYSQL_PWD
66
export MYSQL_PWD
77

88
PROBE_USER=root

templates/galera/config/config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
"perm": "0644",
2929
"optional": true
3030
},
31+
{
32+
"source": "/var/lib/pod-config-data/galera_sst_mariabackup.cnf",
33+
"dest": "/etc/my.cnf.d/galera_mariabackup.cnf",
34+
"owner": "root",
35+
"perm": "0644",
36+
"optional": true
37+
},
3138
{
3239
"source": "/var/lib/operator-scripts",
3340
"dest": "/usr/local/bin",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[mysqld]
2+
wsrep_sst_method = mariabackup
3+
wsrep_sst_auth = root:{ MARIABACKUP_PASSWORD }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"command": "/usr/bin/true",
3+
"permissions": [
4+
{
5+
"path": "/var/lib/mysql",
6+
"owner": "mysql:mysql",
7+
"recurse": "true"
8+
}
9+
]
10+
}

0 commit comments

Comments
 (0)