Skip to content

Commit 606d58c

Browse files
committed
[ovn] Update backup/restore procedure
With current backup/restore uuids for the records are being changed and that's result into geneve tunnels to be disabled with the compute nodes and thus centralized SNAT traffic is impacted when ovn_controller are started post adoption on the networker nodes. The traffic remains impacted until ovn_controllers are started also on the compute nodes. So to fix this switch to use full db files for restoration after converting the DBs to standalone. With this also cleaned the unused resources. Resolves: #OSPRH-29914 Signed-off-by: Yatin Karel <ykarel@redhat.com>
1 parent 7c98be1 commit 606d58c

5 files changed

Lines changed: 281 additions & 359 deletions

File tree

docs_user/modules/proc_migrating-ovn-data.adoc

Lines changed: 99 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ Migrate the data in the OVN databases from the original {rhos_prev_long} deploym
1111
* The `OpenStackControlPlane` resource is created.
1212
* `NetworkAttachmentDefinition` custom resources (CRs) for the original cluster are defined. Specifically, the `internalapi` network is defined.
1313
* The original {networking_first_ref} and OVN `northd` are not running.
14-
* There is network routability between the control plane services and the adopted cluster.
1514
* The cloud is migrated to the Modular Layer 2 plug-in with Open Virtual Networking (ML2/OVN) mechanism driver.
15+
* SSH access is available to the original {rhos_prev_long} Controller nodes for direct database file access.
1616
* Define the following shell variables. Replace the example values with values that are correct for your environment:
1717
+
1818
----
@@ -24,28 +24,15 @@ ifeval::["{build}" == "downstream"]
2424
STORAGE_CLASS=local-storage
2525
OVSDB_IMAGE=registry.redhat.io/rhoso/openstack-ovn-base-rhel9:18.0
2626
endif::[]
27-
SOURCE_OVSDB_IP=172.17.0.100 # For IPv4
28-
SOURCE_OVSDB_IP=[fd00:bbbb::100] # For IPv6
2927
----
3028
+
3129
ifeval::["{build_variant}" == "ospdo"]
32-
Update the IP address value for `SOURCE_OVSDB_IP` to the internalApi IP address that is associated with the remaining RHOSP 17 controller VM. The IP address can be retrieved by using the following command:
33-
----
34-
$ $CONTROLLER_SSH ip a s enp4s0
35-
** Select the non /32 IP address
36-
----
3730
[NOTE]
3831
If you use a disconnected environment director Operator deployment, use
3932
`OVSDB_IMAGE=registry.redhat.io/rhoso/openstack-ovn-base-rhel9@sha256:967046c6bdb8f55c236085b5c5f9667f0dbb9f3ac52a6560dd36a6bfac051e1f`.
4033
For more information, see link:https://docs.redhat.com/en/documentation/red_hat_openstack_platform/17.1/html-single/deploying_an_overcloud_in_a_red_hat_openshift_container_platform_cluster_with_director_operator/index#proc_configuring-an-airgapped-environment_air-gapped-environment[Configuring an airgapped environment] in _Deploying an overcloud in a Red Hat OpenShift Container Platform cluster with director Operator_.
4134
endif::[]
42-
ifeval::["{build_variant}" != "ospdo"]
43-
To get the value to set `SOURCE_OVSDB_IP`, query the puppet-generated configurations in a Controller node:
44-
+
45-
----
46-
$ grep -rI 'ovn_[ns]b_conn' /var/lib/config-data/puppet-generated/
47-
----
48-
endif::[]
35+
* Ensure you have SSH access to the original {rhos_prev_long} Controller nodes. This procedure extracts database files directly from the controller filesystem.
4936

5037
.Procedure
5138
ifeval::["{build_variant}" == "ospdo"]
@@ -57,67 +44,97 @@ $ oc get vmi -n $<ospdo_namespace> -o jsonpath='{.items[0].metadata.labels.kubev
5744
+
5845
* Replace `<ospdo_namespace>` with your OSPdO namespace.
5946
endif::[]
60-
. Prepare a temporary `PersistentVolume` claim and the helper pod for the OVN backup. Adjust the storage requests for a large database, if needed:
47+
. Convert the OVN cluster databases to standalone format on the Controller node and copy them to the local system:
48+
+
49+
----
50+
# Set up variables for the controller SSH connection
51+
CONTROLLER1_SSH="ssh -i ~/.ssh/id_rsa heat-admin@$CONTROLLER_IP"
52+
53+
# Create working directory on controller and convert databases
54+
$CONTROLLER1_SSH sudo mkdir -p /tmp/ovn_standalone_conversion
55+
$CONTROLLER1_SSH sudo ovsdb-tool cluster-to-standalone /tmp/ovn_standalone_conversion/ovnnb_db.db /var/lib/openvswitch/ovn/ovnnb_db.db
56+
$CONTROLLER1_SSH sudo ovsdb-tool cluster-to-standalone /tmp/ovn_standalone_conversion/ovnsb_db.db /var/lib/openvswitch/ovn/ovnsb_db.db
57+
$CONTROLLER1_SSH sudo chmod 644 /tmp/ovn_standalone_conversion/ovn*.db
58+
59+
# Create local directory and copy converted databases
60+
mkdir -p /tmp/ovn_adoption_dbs
61+
CONTROLLER1_SCP=$(echo "$CONTROLLER1_SSH" | sed 's/^ssh/scp/')
62+
${CONTROLLER1_SCP}:/tmp/ovn_standalone_conversion/ovnnb_db.db /tmp/ovn_adoption_dbs/
63+
${CONTROLLER1_SCP}:/tmp/ovn_standalone_conversion/ovnsb_db.db /tmp/ovn_adoption_dbs/
64+
65+
# Cleanup on controller
66+
$CONTROLLER1_SSH sudo rm -rf /tmp/ovn_standalone_conversion
67+
----
68+
+
69+
70+
. Create the PersistentVolumeClaim resources that will be used by the OVN database pods:
6171
+
6272
----
73+
ifeval::["{build_variant}" != "ospdo"]
6374
$ oc apply -f - <<EOF
75+
endif::[]
76+
ifeval::["{build_variant}" == "ospdo"]
77+
$ oc apply -n $<ospdo_namespace> -f - <<EOF
78+
endif::[]
6479
---
65-
apiVersion: cert-manager.io/v1
66-
kind: Certificate
80+
apiVersion: v1
81+
kind: PersistentVolumeClaim
6782
metadata:
68-
name: ovn-data-cert
83+
name: ovndbcluster-nb-etc-ovn-ovsdbserver-nb-0
84+
labels:
85+
service: ovsdbserver-nb
6986
spec:
70-
commonName: ovn-data-cert
71-
secretName: ovn-data-cert
72-
issuerRef:
73-
name: rootca-internal
87+
accessModes:
88+
- ReadWriteOnce
89+
storageClassName: $STORAGE_CLASS
90+
resources:
91+
requests:
92+
storage: 10G
7493
---
7594
apiVersion: v1
7695
kind: PersistentVolumeClaim
7796
metadata:
78-
ifeval::["{build_variant}" == "ospdo"]
79-
namespace: $OSPDO_NAMESPACE
80-
endif::[]
81-
name: ovn-data
97+
name: ovndbcluster-sb-etc-ovn-ovsdbserver-sb-0
98+
labels:
99+
service: ovsdbserver-sb
82100
spec:
83-
storageClassName: $STORAGE_CLASS
84101
accessModes:
85102
- ReadWriteOnce
103+
storageClassName: $STORAGE_CLASS
86104
resources:
87105
requests:
88-
storage: 10Gi
106+
storage: 10G
107+
EOF
108+
----
109+
110+
. Create a helper pod to populate the PVCs with the converted databases:
111+
+
112+
----
113+
ifeval::["{build_variant}" != "ospdo"]
114+
$ oc apply -f - <<EOF
115+
endif::[]
116+
ifeval::["{build_variant}" == "ospdo"]
117+
$ oc apply -n $<ospdo_namespace> -f - <<EOF
118+
endif::[]
89119
---
90120
apiVersion: v1
91121
kind: Pod
92122
metadata:
93123
name: ovn-copy-data
94124
annotations:
95125
openshift.io/scc: anyuid
96-
ifeval::["{build_variant}" != "ospdo"]
97-
k8s.v1.cni.cncf.io/networks: internalapi
98-
endif::[]
99-
ifeval::["{build_variant}" == "ospdo"]
100-
'[{"name": "internalapi-static", "namespace": $<ospdo_namespace>, "ips": ["<internalapi-static-ips>"]}]'
101-
endif::[]
102126
labels:
103127
app: adoption
104-
ifeval::["{build_variant}" == "ospdo"]
105-
namespace: $OSPDO_NAMESPACE
106-
endif::[]
107128
spec:
108-
ifeval::["{build_variant}" == "ospdo"]
109-
nodeName: '{{ <ocp_node_holding_controller> }}'
110-
endif::[]
111129
containers:
112130
- image: $OVSDB_IMAGE
113131
command: [ "sh", "-c", "sleep infinity"]
114132
name: adoption
115133
volumeMounts:
116-
- mountPath: /backup
117-
name: ovn-data
118-
- mountPath: /etc/pki/tls/misc
119-
name: ovn-data-cert
120-
readOnly: true
134+
- mountPath: /nb-data
135+
name: nb-data
136+
- mountPath: /sb-data
137+
name: sb-data
121138
securityContext:
122139
allowPrivilegeEscalation: false
123140
capabilities:
@@ -126,62 +143,58 @@ endif::[]
126143
seccompProfile:
127144
type: RuntimeDefault
128145
volumes:
129-
- name: ovn-data
146+
- name: nb-data
130147
persistentVolumeClaim:
131-
claimName: ovn-data
132-
- name: ovn-data-cert
133-
secret:
134-
secretName: ovn-data-cert
148+
claimName: ovndbcluster-nb-etc-ovn-ovsdbserver-nb-0
149+
- name: sb-data
150+
persistentVolumeClaim:
151+
claimName: ovndbcluster-sb-etc-ovn-ovsdbserver-sb-0
135152
EOF
136153
----
137-
+
138-
ifeval::["{build_variant}" == "ospdo"]
139-
where:
140154

141-
<ocp_node_holding_controller>::
142-
Specifies the {OpenStackShort} node that contains the Controller node.
143-
endif::[]
144-
145-
. Wait for the pod to be ready:
155+
. Wait for the helper pod to be ready:
146156
+
147157
----
148158
ifeval::["{build_variant}" != "ospdo"]
149159
$ oc wait --for=condition=Ready pod/ovn-copy-data --timeout=30s
150160
endif::[]
151161
ifeval::["{build_variant}" == "ospdo"]
152-
$ oc wait --for=condition=Ready -n $OSPDO_NAMESPACE pod/ovn-copy-data --timeout=30s
162+
$ oc wait --for=condition=Ready pod/ovn-copy-data -n $<ospdo_namespace> --timeout=30s
153163
endif::[]
154164
----
155165

156-
. If the podified internalapi cidr is different than the source internalapi cidr, add an iptables accept rule on the Controller nodes:
166+
. Copy the converted standalone databases to the PVCs:
157167
+
158168
----
159-
$ $CONTROLLER1_SSH sudo iptables -I INPUT -s {PODIFIED_INTERNALAPI_NETWORK} -p tcp -m tcp --dport 6641 -m conntrack --ctstate NEW -j ACCEPT
160-
$ $CONTROLLER1_SSH sudo iptables -I INPUT -s {PODIFIED_INTERNALAPI_NETWORK} -p tcp -m tcp --dport 6642 -m conntrack --ctstate NEW -j ACCEPT
169+
ifeval::["{build_variant}" != "ospdo"]
170+
$ oc cp /tmp/ovn_adoption_dbs/ovnnb_db.db ovn-copy-data:/nb-data/ovnnb_db.db
171+
$ oc cp /tmp/ovn_adoption_dbs/ovnsb_db.db ovn-copy-data:/sb-data/ovnsb_db.db
172+
endif::[]
173+
ifeval::["{build_variant}" == "ospdo"]
174+
$ oc cp /tmp/ovn_adoption_dbs/ovnnb_db.db ovn-copy-data:/nb-data/ovnnb_db.db -n $<ospdo_namespace>
175+
$ oc cp /tmp/ovn_adoption_dbs/ovnsb_db.db ovn-copy-data:/sb-data/ovnsb_db.db -n $<ospdo_namespace>
176+
endif::[]
161177
----
162178

163-
. Back up your OVN databases:
164-
* If you did not enable TLS everywhere, run the following command:
179+
. Remove the helper pod now that the data is in the PVCs:
165180
+
166181
----
167182
ifeval::["{build_variant}" != "ospdo"]
168-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client backup tcp:$SOURCE_OVSDB_IP:6641 > /backup/ovs-nb.db"
169-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client backup tcp:$SOURCE_OVSDB_IP:6642 > /backup/ovs-sb.db"
183+
$ oc delete pod ovn-copy-data
170184
endif::[]
171185
ifeval::["{build_variant}" == "ospdo"]
172-
$ oc exec -n $OSPDO_NAMESPACE ovn-copy-data -- bash -c "ovsdb-client backup tcp:$SOURCE_OVSDB_IP:6641 > /backup/ovs-nb.db"
173-
$ oc exec -n $OSPDO_NAMESPACE ovn-copy-data -- bash -c "ovsdb-client backup tcp:$SOURCE_OVSDB_IP:6642 > /backup/ovs-sb.db"
186+
$ oc delete pod ovn-copy-data -n $<ospdo_namespace>
174187
endif::[]
175188
----
176-
+
177-
* If you enabled TLS everywhere, run the following command:
189+
190+
. Clean up the local temporary files:
178191
+
179192
----
180-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client backup --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$SOURCE_OVSDB_IP:6641 > /backup/ovs-nb.db"
181-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client backup --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$SOURCE_OVSDB_IP:6642 > /backup/ovs-sb.db"
193+
$ rm -f /tmp/ovn_adoption_dbs/ovn*.db
194+
$ rmdir /tmp/ovn_adoption_dbs
182195
----
183196

184-
. Start the control plane OVN database services prior to import, with `northd` disabled:
197+
. Start the control plane OVN database services. The databases will automatically load the converted data that was populated in the PVCs:
185198
+
186199
----
187200
$ oc patch openstackcontrolplane openstack --type=merge --patch '
@@ -200,70 +213,27 @@ spec:
200213
dbType: SB
201214
storageRequest: 10G
202215
networkAttachment: internalapi
203-
ovnNorthd:
204-
replicas: 0
205216
'
206217
----
207-
208-
. Wait for the OVN database services to reach the `Running` phase:
209-
+
210-
----
211-
$ oc wait --for=jsonpath='{.status.phase}'=Running pod --selector=service=ovsdbserver-nb
212-
$ oc wait --for=jsonpath='{.status.phase}'=Running pod --selector=service=ovsdbserver-sb
213-
----
214-
215-
. Fetch the OVN database IP addresses on the `clusterIP` service network:
216-
+
217-
----
218-
PODIFIED_OVSDB_NB_IP=$(oc get svc --selector "statefulset.kubernetes.io/pod-name=ovsdbserver-nb-0" -ojsonpath='{.items[0].spec.clusterIP}')
219-
PODIFIED_OVSDB_SB_IP=$(oc get svc --selector "statefulset.kubernetes.io/pod-name=ovsdbserver-sb-0" -ojsonpath='{.items[0].spec.clusterIP}')
220-
----
221-
222-
. If you are using IPv6, adjust the address to the format expected by `ovsdb-*` tools:
223-
+
224-
----
225-
PODIFIED_OVSDB_NB_IP=[$PODIFIED_OVSDB_NB_IP]
226-
PODIFIED_OVSDB_SB_IP=[$PODIFIED_OVSDB_SB_IP]
227-
----
228-
229-
. Upgrade the database schema for the backup files:
230-
.. If you did not enable TLS everywhere, use the following command:
231-
+
232-
----
233-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client get-schema tcp:$PODIFIED_OVSDB_NB_IP:6641 > /backup/ovs-nb.ovsschema && ovsdb-tool convert /backup/ovs-nb.db /backup/ovs-nb.ovsschema"
234-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client get-schema tcp:$PODIFIED_OVSDB_SB_IP:6642 > /backup/ovs-sb.ovsschema && ovsdb-tool convert /backup/ovs-sb.db /backup/ovs-sb.ovsschema"
235-
----
236-
237-
.. If you enabled TLS everywhere, use the following command:
238218
+
239-
----
240-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client get-schema --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$PODIFIED_OVSDB_NB_IP:6641 > /backup/ovs-nb.ovsschema && ovsdb-tool convert /backup/ovs-nb.db /backup/ovs-nb.ovsschema"
241-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client get-schema --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$PODIFIED_OVSDB_SB_IP:6642 > /backup/ovs-sb.ovsschema && ovsdb-tool convert /backup/ovs-sb.db /backup/ovs-sb.ovsschema"
242-
----
243-
244-
. Restore the database backup to the new OVN database servers:
245-
.. If you did not enable TLS everywhere, use the following command:
246-
+
247-
----
248-
ifeval::["{build_variant}" != "ospdo"]
249-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client restore tcp:$PODIFIED_OVSDB_NB_IP:6641 < /backup/ovs-nb.db"
250-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client restore tcp:$PODIFIED_OVSDB_SB_IP:6642 < /backup/ovs-sb.db"
251-
endif::[]
252-
----
219+
[NOTE]
220+
The OVN database pods will automatically handle schema conversion during startup and form a proper 3-replica cluster with the preserved data.
253221

254-
.. If you enabled TLS everywhere, use the following command:
222+
. Wait for the OVN database services to start up:
255223
+
256224
----
257-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client restore --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$PODIFIED_OVSDB_NB_IP:6641 < /backup/ovs-nb.db"
258-
$ oc exec ovn-copy-data -- bash -c "ovsdb-client restore --ca-cert=/etc/pki/tls/misc/ca.crt --private-key=/etc/pki/tls/misc/tls.key --certificate=/etc/pki/tls/misc/tls.crt ssl:$PODIFIED_OVSDB_SB_IP:6642 < /backup/ovs-sb.db"
225+
$ oc wait pod --for condition=Ready --selector=service=ovsdbserver-nb --timeout=300s
226+
$ oc wait pod --for condition=Ready --selector=service=ovsdbserver-sb --timeout=300s
259227
----
260228

261-
. Check that the data was successfully migrated by running the following commands against the new database servers, for example:
229+
. Verify that the data was successfully migrated
262230
+
263231
----
264232
$ oc exec -it ovsdbserver-nb-0 -- ovn-nbctl show
233+
$ oc exec -it ovsdbserver-sb-0 -- ovn-sbctl show
265234
$ oc exec -it ovsdbserver-sb-0 -- ovn-sbctl list Chassis
266235
----
236+
+
267237

268238
. Start the control plane `ovn-northd` service to keep both OVN databases in sync:
269239
+
@@ -297,15 +267,12 @@ spec:
297267
[NOTE]
298268
Running OVN gateways on {OpenShiftShort} nodes might be prone to data plane downtime during Open vSwitch upgrades. Consider running OVN gateways on dedicated `Networker` data plane nodes for production deployments instead.
299269

300-
. Delete the `ovn-data` helper pod and the temporary `PersistentVolumeClaim` that is used to store OVN database backup files:
301-
+
302-
----
303-
$ oc delete --ignore-not-found=true pod ovn-copy-data
304-
$ oc delete --ignore-not-found=true pvc ovn-data
305-
----
270+
. The migration is now complete.
271+
272+
Consider creating a backup of the current state for rollback purposes:
306273
+
307274
[NOTE]
308-
Consider taking a snapshot of the `ovn-data` helper pod and the temporary `PersistentVolumeClaim` before deleting them. For more information, see link:{defaultOCPURL}/storage/index#lvms-about-volume-snapsot_logical-volume-manager-storage[About volume snapshots] in _OpenShift Container Platform storage overview_.
275+
The OVN databases now contain the migrated data with preserved UUIDs. Consider taking a snapshot of the database PVCs for backup purposes. For more information, see link:{defaultOCPURL}/storage/index#lvms-about-volume-snapsot_logical-volume-manager-storage[About volume snapshots] in _OpenShift Container Platform storage overview_.
309276

310277
. Stop the adopted OVN database servers:
311278
+
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1 @@
1-
- name: delete adoption helper pod and pvc
2-
ansible.builtin.shell: |
3-
{{ shell_header }}
4-
{{ oc_header }}
5-
oc delete --ignore-not-found=true pod ovn-copy-data
6-
oc delete --ignore-not-found=true certificate ovn-data-cert
7-
oc delete --ignore-not-found=true secret ovn-data-cert
8-
{% if storage_reclaim_policy.lower() == "delete" %}oc delete pvc --ignore-not-found=true ovn-data{% endif %}
1+
---

0 commit comments

Comments
 (0)