Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs_dev/assemblies/development_environment.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ done

oc delete --wait=false pod ovn-copy-data || true
oc delete --wait=false pod mariadb-copy-data || true
oc delete secret designate-external-binds || true
oc delete service designate-external-master || true
oc delete secret osp-secret || true
----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ include::../modules/proc_adopting-telemetry-services.adoc[leveloffset=+1]

include::../modules/proc_adopting-the-dns-service.adoc[leveloffset=+1]

include::../modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc[leveloffset=+1]

include::../modules/proc_completing-the-bind9-migration.adoc[leveloffset=+1]

include::../modules/proc_adopting-autoscaling.adoc[leveloffset=+1]

include::../modules/proc_pulling-configuration-from-a-tripleo-deployment.adoc[leveloffset=+1]
Expand Down
6 changes: 6 additions & 0 deletions docs_user/modules/proc_adopting-the-dns-service.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
[role="_abstract"]
To adopt the {dns_first_ref}, you patch an existing `OpenStackControlPlane` custom resource (CR) where the {dns_service} is disabled. The patch starts the service with the configuration parameters that are provided by the {rhos_prev_long} ({OpenStackShort}) environment.

[NOTE]
====
If your {rhos_prev_long} deployment uses BIND9 servers that you want to serve DNS during and after adoption, you can include them as external back ends with the new operator-managed BIND9 instances. In this staged migration model, both the legacy BIND9 servers and the new cluster-hosted BIND9 StatefulSet serve the same pool concurrently. This avoids a disruptive DNS switchover and allows external DNS registries and delegations to be updated to reference the new nameservers later.
After completing the standard adoption procedure, see xref:maintaining-a-migration-window-with-legacy-bind9-servers_{context}[Maintaining a migration window with legacy BIND9 servers] for the additional steps required to enable this transition window.
====

.Procedure

. Create an alias for the `openstack` command:
Expand Down
37 changes: 37 additions & 0 deletions docs_user/modules/proc_completing-the-bind9-migration.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
:_mod-docs-content-type: PROCEDURE
[id="completing-the-bind9-migration_{context}"]

= Completing the BIND9 migration

[role="_abstract"]
After external DNS registries and delegations have been updated to reference
the new {rhos_long} nameservers, remove the legacy BIND9 servers from the
{dns_service} pool to complete the BIND9 migration.

.Procedure

. Remove the external binds secret reference from the {dns_service} custom resource:
+
----
$ oc patch openstackcontrolplane openstack --type=json --patch '
[{"op": "remove", "path": "/spec/designate/template/externalBindsSecret"}]
'
----

. Wait for the {dns_service} to reconcile:
+
----
$ oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate
----

. Delete the external binds secret:
+
----
$ oc delete secret designate-external-binds -n openstack
----

. Delete the mDNS LoadBalancer service:
+
----
$ oc delete service designate-external-master -n openstack
----
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
:_mod-docs-content-type: PROCEDURE
[id="maintaining-a-migration-window-with-legacy-bind9-servers_{context}"]

= Maintaining a migration window with legacy BIND9 servers

[role="_abstract"]
A complete immediate switchover of all DNS servers to {rhos_long} requires all DNS clients to be updated with the new addresses of the DNS servers. This may be DNS registry entries, `glue records` in other DNS zone tables or configuration in OpenStack servers. In deployments where this cannot be done immediately, this procedure configures the existing DNS servers to be used and updated until all references to them can be migrated to the {rhos_long} DNS services.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A complete immediate switchover of all DNS servers to {rhos_long} requires all DNS clients to be updated with the new addresses of the DNS servers. This may be DNS registry entries, `glue records` in other DNS zone tables or configuration in OpenStack servers. In deployments where this cannot be done immediately, this procedure configures the existing DNS servers to be used and updated until all references to them can be migrated to the {rhos_long} DNS services.
Transition to {rhos_long} DNS services gradually when a complete, immediate switchover isn't possible. This keeps existing DNS servers active and updated while you migrate external references, registry entries, and client configurations over time.


If your {rhos_prev_long} deployment uses BIND9 servers that should continue serving DNS during adoption, follow this procedure after completing the standard {dns_service} adoption. The designate worker sends RNDC commands and DNS NOTIFY messages to the legacy servers, which pull zone data from the mDNS service through AXFR on port 5354.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If your {rhos_prev_long} deployment uses BIND9 servers that should continue serving DNS during adoption, follow this procedure after completing the standard {dns_service} adoption. The designate worker sends RNDC commands and DNS NOTIFY messages to the legacy servers, which pull zone data from the mDNS service through AXFR on port 5354.
If your {rhos_prev_long} deployment uses BIND9 servers that need to stay active during adoption, follow these steps after completing the standard {dns_service} adoption. The Designate worker sends RNDC commands and DNS NOTIFY messages to your legacy servers, which then fetch zone updates from the mDNS service via AXFR on port 5354.


.Procedure

. Extract RNDC credentials from each legacy {rhos_prev_long} Controller that runs BIND9 and create the `designate-external-binds` secret. Run the following script from the adoption host:
+
----
$ binddata_file=/tmp/binddata.yaml
$ rm $binddata_file
$ for i in {1..3}; do
SSH_CMD=CONTROLLER${i}_SSH
if [ ! -z "${!SSH_CMD}" ]; then
echo "Extracting RNDC credentials from controller $i"
RNDC_SECRET=$(${!SSH_CMD} sudo grep secret /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/"/, "", $2); gsub(/;/, "", $2); print $2}')
RNDC_KEYNAME=$(${!SSH_CMD} sudo grep '^key' /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/"/, "", $2); print $2}' | cut -f 1)
RNDC_ALGORITHM=$(${!SSH_CMD} sudo grep algorithm /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/;/, "", $2); print $2}')
CONTROLLER_IP=$(${!SSH_CMD} sudo grep 'internal_api\"' /etc/puppet/hieradata/net_ip_map.json | awk '{gsub(/"/, "", $2); gsub(/,/, "", $2); print $2}')
cat << BINDATACR >> "$binddata_file"
- name: controller-$i
address: $CONTROLLER_IP
rndcsecret: $RNDC_SECRET
rndckeyname: $RNDC_KEYNAME
rndcalgorithm: $RNDC_ALGORITHM
BINDATACR
fi
done
$ if [ -s "$binddata_file" ]; then
external_binds_secret_file=/tmp/external_binds_secret.yaml
cat << EOSECRETC > "$external_binds_secret_file"
apiVersion: v1
kind: Secret
metadata:
name: designate-external-binds
namespace: openstack
type: Opaque
stringData:
default: |
$(cat "$binddata_file")
EOSECRETC
oc apply -f "$external_binds_secret_file"
fi
----
+
where:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
where:
where:

`CONTROLLER1_SSH`, `CONTROLLER2_SSH`, and `CONTROLLER3_SSH`::

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`CONTROLLER1_SSH`, `CONTROLLER2_SSH`, and `CONTROLLER3_SSH`::
`CONTROLLER1_SSH`, `CONTROLLER2_SSH`, and `CONTROLLER3_SSH`::

Environment variables that you export before running the script, each set to the SSH connection command for a legacy Controller that runs BIND9, for example `CONTROLLER1_SSH="ssh root@192.0.2.10"`. The script does not reference these names directly; it builds each name from the loop index (`CONTROLLER${i}_SSH`) and reads its value through bash indirection (`${!SSH_CMD}`), skipping any Controller whose variable is not set. The script extracts credentials from each available Controller and automatically creates and applies the `designate-external-binds` secret in the `openstack` namespace.

. Reconfigure the legacy BIND9 instances to accept RNDC connections and zone transfers from the new {rhos_long} deployment. On each legacy Controller, modify the BIND9 configuration. Because the `options` and `controls` blocks cannot be reopened, use the following commands to add the required configuration in-place:
+

[subs="+quotes"]
----
$ INTERNALAPI_CIDR=<internalapi_subnet>
$ for i in {1..3}; do
SSH_CMD=CONTROLLER${i}_SSH
if [ ! -z "${!SSH_CMD}" ]; then
echo "Reconfiguring bind on controller $i"
CONTROLLER_IP=$(${!SSH_CMD} sudo grep 'internal_api\"' /etc/puppet/hieradata/net_ip_map.json | awk '{gsub(/"/, "", $2); gsub(/,/, "", $2); print $2}')
${!SSH_CMD} cp -n /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf.pre-adoption-backup
${!SSH_CMD} "sed -i 's:inet [0-9.]* allow { [0-9./]*; }:inet ${CONTROLLER_IP} allow { ${INTERNALAPI_CIDR}; }:' /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf"
${!SSH_CMD} cp -n /var/lib/config-data/ansible-generated/designate/etc/named/options.conf /var/lib/config-data/ansible-generated/designate/etc/named/options.conf.pre-adoption-backup
${!SSH_CMD} "sed -i 's:allow.notify.*};:allow-notify { $INTERNALAPI_CIDR; };:' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
${!SSH_CMD} "sed -i '/allow.transfer:/d' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
${!SSH_CMD} "sed -i '/^options {/,/^};/{
/^};/ i\\\tallow-transfer { '"$INTERNALAPI_CIDR"'; };
}' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
done
----
+
where:

`CONTROLLER_IP`::
Specifies the `internalapi` IP address of the legacy Controller. You can be retrieve this from `/etc/puppet/hieradata/net_ip_map.json` on each Controller.

`internalapi_subnet`::
Specifies the `internalapi` subnet in CIDR notation, for example `172.17.0.0/24`.
This is a CIDR range represents the network from which RHOSO designate worker
pods send requests.

+
[NOTE]
====
The `sed` commands in the shell script example are directed at default deployments. If customizations are made to the deployment, either modify these commands or perform the modifications directly.
====

+

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+

Reload the BIND9 configuration:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Reload the BIND9 configuration:
. Reload the BIND9 configuration:

+
----
$ systemctl restart designate-designatebackendbind9
----
+
[NOTE]
====
You can edit the BIND9 configuration directly because the legacy {OpenStackPreviousInstaller} control plane is being decommissioned and no longer manages these files.
====

. Open the firewall on each legacy Controller to allow RNDC and DNS traffic from the {rhos_long} pods:
+
[subs="+quotes"]
----
$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<internalapi_subnet>" port port="953" protocol="tcp" accept'
$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<internalapi_subnet>" port port="53" protocol="tcp" accept'
$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<internalapi_subnet>" port port="53" protocol="udp" accept'
$ firewall-cmd --reload
----

. Create a LoadBalancer service to expose the mDNS service on the internalapi
network so that the legacy BIND9 servers can perform AXFR zone transfers:
+

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+
+

----
$ cat << EOF_CAT > /tmp/designate-external-mdns-svc.yaml
apiVersion: v1
kind: Service
metadata:
namespace: openstack
name: designate-external-master
labels:
service: designate-mdns
designate.openstack.org/external_master: "true"
annotations:
core.openstack.org/ingress_create: "false"
metallb.io/ip-allocated-from-pool: internalapi
metallb.universe.tf/address-pool: internalapi
metallb.universe.tf/allow-shared-ip: internalapi
metallb.universe.tf/loadBalancerIPs: 172.17.0.80
designate.openstack.org/external_pool: default
spec:
selector:
service: designate-mdns
ports:
- name: dns-tcp
port: 5354
protocol: TCP
targetPort: 5354
- name: dns
port: 5354
protocol: UDP
targetPort: 5354
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
type: LoadBalancer
EOF_CAT
$ oc apply -f /tmp/designate-external-mdns-svc.yaml
----

. Patch the {dns_service} custom resource to reference the external binds secret and attach the designate worker to the internalapi network so that it can reach the external BIND9 servers:
+
----
$ oc patch openstackcontrolplane openstack --type=merge --patch '
spec:
designate:
template:
externalBindsSecret: designate-external-binds
designateWorker:
networkAttachments:
- designate
- internalapi
'
----

. Wait for the {dns_service} to reconcile:
+
----
$ oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate
----

. Verify that the external BIND9 targets are included in the pool configuration:
+
----
$ oc get configmap designate-pools-yaml-config-map -o jsonpath='{.data.pools\.yaml}' | grep -A5 'external-bind9'
----
+
The output should list the external BIND9 servers you configured in the external binds secret.

. Verify RNDC connectivity from the designate worker pods to the legacy BIND9 servers:
+
[subs="+quotes"]
----
$ oc exec -it $(oc get pods -l service=designate-worker -o name | head -1) -- \
rndc -s <controller_internalapi_ip> -k /etc/designate/rndc-keys/default-rndc-0 status
----
+
where:

`<controller_internalapi_ip>`::
Specifies the internalapi IP address of a legacy BIND9 server.
+
A successful response indicates that the designate worker can manage the external BIND9 server.

.Next steps
When external DNS registries and delegations are updated to reference the new nameservers, remove the legacy servers from the pool. For more information, see xref:completing-the-bind9-migration_{context}[Completing the BIND9 migration].
3 changes: 3 additions & 0 deletions tests/roles/designate_adoption/defaults/main.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
designate_adoption: false
designate_external: false
designate_retry_delay: 5
designate_external_bind_controllers: []
designate_external_binds: []
71 changes: 71 additions & 0 deletions tests/roles/designate_adoption/tasks/designate_external_binds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
- name: Extract RNDC credentials from legacy controllers
ansible.builtin.shell: |
{{ shell_header }}
{{ oc_header }}

echo "Extracting BIND9 data from legacy controllers"
binddata_file=/tmp/binddata.yaml
rm -f $binddata_file
for i in {1..3}; do
SSH_CMD=CONTROLLER${i}_SSH
if [ ! -z "${!SSH_CMD}" ]; then
echo "Extracting RNDC credentials from controller $i"
RNDC_SECRET=$(${!SSH_CMD} sudo grep secret /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/"/, "", $2); gsub(/;/, "", $2); print $2}')
RNDC_KEYNAME=$(${!SSH_CMD} sudo grep '^key' /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/"/, "", $2); print $2}' | cut -f 1)
RNDC_ALGORITHM=$(${!SSH_CMD} sudo grep algorithm /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf | awk '{gsub(/;/, "", $2); print $2}')
CONTROLLER_IP=$(${!SSH_CMD} sudo grep 'internal_api\"' /etc/puppet/hieradata/net_ip_map.json | awk '{gsub(/"/, "", $2); gsub(/,/, "", $2); print $2}')
echo "address: $CONTROLLER_IP"
echo "rndcsecret: $RNDC_SECRET"
echo "rndckeyname: $RNDC_KEYNAME"
echo "rndcalgorithm: $RNDC_ALGORITHM"

cat << BINDATACR >> "$binddata_file"
- name: controller-$i
address: $CONTROLLER_IP
rndcsecret: $RNDC_SECRET
rndckeyname: $RNDC_KEYNAME
rndcalgorithm: $RNDC_ALGORITHM
BINDATACR
fi
done

if [ -s "$binddata_file" ]; then
external_binds_secret_file=/tmp/external_binds_secret.yaml
cat << EOSECRETC > "$external_binds_secret_file"
apiVersion: v1
kind: Secret
metadata:
name: designate-external-binds
namespace: openstack
type: Opaque
stringData:
default: |
$(cat "$binddata_file")
EOSECRETC

oc apply -f "$external_binds_secret_file"
fi

- name: Reconfigure Legacy BIND9 instances to talk with Designate on Internal API network.
ansible.builtin.shell: |
{{ shell_header }}
{{ oc_header }}
echo "Configuring BIND9 to integrate via internalapi"
INTERNALAPI_CIDR="{{ internalapi_cidr }}"
for i in {1..3}; do
SSH_CMD=CONTROLLER${i}_SSH
if [ ! -z "${!SSH_CMD}" ]; then
echo "Reconfiguring bind on controller $i"
CONTROLLER_IP=$(${!SSH_CMD} sudo grep 'internal_api\"' /etc/puppet/hieradata/net_ip_map.json | awk '{gsub(/"/, "", $2); gsub(/,/, "", $2); print $2}')
${!SSH_CMD} cp -n /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf.pre-adoption-backup
${!SSH_CMD} "sed -i 's:inet [0-9.]* allow { [0-9./]*; }:inet ${CONTROLLER_IP} allow { ${INTERNALAPI_CIDR}; }:' /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf"
${!SSH_CMD} cp -n /var/lib/config-data/ansible-generated/designate/etc/named/options.conf /var/lib/config-data/ansible-generated/designate/etc/named/options.conf.pre-adoption-backup
${!SSH_CMD} "sed -i 's:allow.notify.*};:allow-notify { $INTERNALAPI_CIDR; };:' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
${!SSH_CMD} "sed -i '/allow.transfer:/d' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
${!SSH_CMD} "sed -i '/^options {/,/^};/{
/^};/ i\\\tallow-transfer { '"$INTERNALAPI_CIDR"'; };
}' /var/lib/config-data/ansible-generated/designate/etc/named/options.conf"
echo "Restarting bind on controller $i"
${!SSH_CMD} systemctl restart designate-designatebackendbind9
fi
done
Loading
Loading