From 6d67b8f108a9dd4941f584b0f48c1bd1e5112aa8 Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Wed, 10 Jun 2026 15:26:41 +0000 Subject: [PATCH 1/4] Support migration windows for BIND9 The IPs for the BIND9 servers may be in external registries or in other DNS configuration for zone delegation via glue records. This change is part of a series to verify the steps to maintaining records in both the RHOSO system and the legacy system to allow a staged migration of DNS infrastructure. Documentation is enhanced to: - Update the procedure for maintaining a migration window with legacy BIND9 servers, including a reference to additional steps after the standard adoption. - Add tasks to configure and enable the Designate service, including creating a LoadBalancer service for mDNS zone transfers. - Refine task names for clarity and removed unnecessary steps related to external binds secret verification. - Improve the patch file creation process for Designate CR to include necessary configurations for legacy BIND9 integration. Co-Authored-By: Claude Opus 4.6 --- .../assemblies/development_environment.adoc | 2 + .../proc_adopting-the-dns-service.adoc | 243 ++++++++++++++++++ .../designate_adoption/defaults/main.yaml | 3 + .../tasks/designate_external_binds.yaml | 71 +++++ .../tasks/designate_external_migrate.yaml | 39 +++ .../tasks/designate_external_teardown.yaml | 58 +++++ .../tasks/designate_intapi_mdns.yaml | 41 +++ .../roles/designate_adoption/tasks/main.yaml | 21 ++ 8 files changed, 478 insertions(+) create mode 100644 tests/roles/designate_adoption/tasks/designate_external_binds.yaml create mode 100644 tests/roles/designate_adoption/tasks/designate_external_migrate.yaml create mode 100644 tests/roles/designate_adoption/tasks/designate_external_teardown.yaml create mode 100644 tests/roles/designate_adoption/tasks/designate_intapi_mdns.yaml diff --git a/docs_dev/assemblies/development_environment.adoc b/docs_dev/assemblies/development_environment.adoc index d62da3911..40d39a94d 100644 --- a/docs_dev/assemblies/development_environment.adoc +++ b/docs_dev/assemblies/development_environment.adoc @@ -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 ---- diff --git a/docs_user/modules/proc_adopting-the-dns-service.adoc b/docs_user/modules/proc_adopting-the-dns-service.adoc index bea047bd3..702c8d9d8 100644 --- a/docs_user/modules/proc_adopting-the-dns-service.adoc +++ b/docs_user/modules/proc_adopting-the-dns-service.adoc @@ -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: @@ -320,3 +326,240 @@ $ oc patch openstackcontrolplane openstack --type=merge --patch-file /tmp/design ---- $ oc wait --for condition=Ready --timeout=600s designate.designate.openstack.org/designate ---- + +[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. + +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. + +.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: + `CONTROLLER1_SSH`, `CONTROLLER2_SSH`, and `CONTROLLER3_SSH`:: +Specifies the SSH connection variables for each legacy Controller that runs BIND9. 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= +$ 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. +==== + ++ +Reload the BIND9 configuration: ++ +---- +$ systemctl restart desginate-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="" port port="953" protocol="tcp" accept' +$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" port port="53" protocol="tcp" accept' +$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" 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: + + +---- +$ 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 connect the worker to the internalapi network so it can connect to 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 designate.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 -k /etc/designate/rndc-keys/default-rndc-0 status +---- ++ +where: + +``:: +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]. + +[id="completing-the-bind9-migration_{context}"] +== Completing the BIND9 migration + +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 designate.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 +---- diff --git a/tests/roles/designate_adoption/defaults/main.yaml b/tests/roles/designate_adoption/defaults/main.yaml index b308b486f..0c41261bc 100644 --- a/tests/roles/designate_adoption/defaults/main.yaml +++ b/tests/roles/designate_adoption/defaults/main.yaml @@ -1,2 +1,5 @@ designate_adoption: false +designate_external: false designate_retry_delay: 5 +designate_external_bind_controllers: [] +designate_external_binds: [] diff --git a/tests/roles/designate_adoption/tasks/designate_external_binds.yaml b/tests/roles/designate_adoption/tasks/designate_external_binds.yaml new file mode 100644 index 000000000..216b5f1f3 --- /dev/null +++ b/tests/roles/designate_adoption/tasks/designate_external_binds.yaml @@ -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 '/^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 diff --git a/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml b/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml new file mode 100644 index 000000000..949609141 --- /dev/null +++ b/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml @@ -0,0 +1,39 @@ +- name: Patch Designate CR to reference external binds secret and add internalapi network to the designate workers. + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc patch openstackcontrolplane openstack --type=merge --patch ' + spec: + designate: + template: + externalBindsSecret: designate-external-binds + designateWorker: + networkAttachments: + - designate + - internalapi + ' + register: designate_external_patch_results + changed_when: true + failed_when: designate_external_patch_results.rc != 0 + +- name: Wait for the designate service to reconcile after external binds patch + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate + register: designate_external_ready_result + until: designate_external_ready_result is success + retries: 60 + delay: "{{ designate_retry_delay }}" + +- name: Verify external BIND9 targets are in pool configuration + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc get configmap designate-pools-yaml-config-map -o jsonpath='{.data.pools\.yaml}' | grep -A5 'external-bind9' + register: external_bind9_pool_check + changed_when: false + failed_when: external_bind9_pool_check.rc != 0 diff --git a/tests/roles/designate_adoption/tasks/designate_external_teardown.yaml b/tests/roles/designate_adoption/tasks/designate_external_teardown.yaml new file mode 100644 index 000000000..517e8b6d1 --- /dev/null +++ b/tests/roles/designate_adoption/tasks/designate_external_teardown.yaml @@ -0,0 +1,58 @@ +- name: Remove externalBindsSecret reference from Designate CR + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc patch openstackcontrolplane openstack --type=json --patch ' + [{"op": "remove", "path": "/spec/designate/template/externalBindsSecret"}] + ' + register: designate_external_remove_results + changed_when: true + failed_when: designate_external_remove_results.rc != 0 + +- name: Wait for the designate service to reconcile after removing external binds + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate + register: designate_teardown_ready_result + until: designate_teardown_ready_result is success + retries: 60 + delay: "{{ designate_retry_delay }}" + +- name: Delete the external binds secret + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc delete secret designate-external-binds -n openstack + register: designate_external_secret_delete + changed_when: true + failed_when: designate_external_secret_delete.rc != 0 + +- name: Delete the mDNS LoadBalancer service + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc delete service designate-external-master -n openstack + register: designate_external_mdns_delete + changed_when: true + failed_when: designate_external_mdns_delete.rc != 0 + +- name: Revert the BIND9 configuration + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + echo "Reverting BIND9 reconfiguration" + for i in {1..3}; do + SSH_CMD=CONTROLLER${i}_SSH + if [ ! -z "${!SSH_CMD}" ]; then + echo "Reconfiguring bind on controller $i" + ${!SSH_CMD} cp /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf.pre-adoption-backup /var/lib/config-data/ansible-generated/designate/etc/named/rndc.conf + ${!SSH_CMD} cp /var/lib/config-data/ansible-generated/designate/etc/named/options.conf.pre-adoption-backup /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 diff --git a/tests/roles/designate_adoption/tasks/designate_intapi_mdns.yaml b/tests/roles/designate_adoption/tasks/designate_intapi_mdns.yaml new file mode 100644 index 000000000..08d3e4451 --- /dev/null +++ b/tests/roles/designate_adoption/tasks/designate_intapi_mdns.yaml @@ -0,0 +1,41 @@ +- name: Add a Service object for exposing mDNS to the legacy BIND9s + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + 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 diff --git a/tests/roles/designate_adoption/tasks/main.yaml b/tests/roles/designate_adoption/tasks/main.yaml index 2874446dc..ada972190 100644 --- a/tests/roles/designate_adoption/tasks/main.yaml +++ b/tests/roles/designate_adoption/tasks/main.yaml @@ -7,3 +7,24 @@ when: designate_adoption | bool ansible.builtin.include_tasks: file: designate_cr_config.yaml + +- name: Create external binds secret for legacy BIND9 servers + when: + - designate_adoption | bool + - designate_external | bool + ansible.builtin.include_tasks: + file: designate_external_binds.yaml + +- name: Configure mDNS LoadBalancer service for legacy BIND9 zone transfers + when: + - designate_adoption | bool + - designate_external | bool + ansible.builtin.include_tasks: + file: designate_intapi_mdns.yaml + +- name: Patch Designate CR with external binds and verify connectivity + when: + - designate_adoption | bool + - designate_external | bool + ansible.builtin.include_tasks: + file: designate_external_migrate.yaml From 6db8e3531228af8ed341681cf336bf70be24d3e6 Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Wed, 10 Jun 2026 15:26:41 +0000 Subject: [PATCH 2/4] Support migration windows for BIND9 The IPs for the BIND9 servers may be in external registries or in other DNS configuration for zone delegation via glue records. This change is part of a series to verify the steps to maintaining records in both the RHOSO system and the legacy system to allow a staged migration of DNS infrastructure. Documentation is enhanced to: - Update the procedure for maintaining a migration window with legacy BIND9 servers, including a reference to additional steps after the standard adoption. - Add tasks to configure and enable the Designate service, including creating a LoadBalancer service for mDNS zone transfers. - Refine task names for clarity and removed unnecessary steps related to external binds secret verification. - Improve the patch file creation process for Designate CR to include necessary configurations for legacy BIND9 integration. Co-Authored-By: Claude Opus 4.6 --- docs_user/modules/proc_adopting-the-dns-service.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs_user/modules/proc_adopting-the-dns-service.adoc b/docs_user/modules/proc_adopting-the-dns-service.adoc index 702c8d9d8..0fabad9d2 100644 --- a/docs_user/modules/proc_adopting-the-dns-service.adoc +++ b/docs_user/modules/proc_adopting-the-dns-service.adoc @@ -378,7 +378,7 @@ EOSECRETC + where: `CONTROLLER1_SSH`, `CONTROLLER2_SSH`, and `CONTROLLER3_SSH`:: -Specifies the SSH connection variables for each legacy Controller that runs BIND9. The script extracts credentials from each available Controller and automatically creates and applies the `designate-external-binds` secret in the `openstack` namespace. +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: + @@ -482,7 +482,7 @@ EOF_CAT $ oc apply -f /tmp/designate-external-mdns-svc.yaml ---- -. Patch the {dns_service} custom resource to reference the external binds secret and connect the worker to the internalapi network so it can connect to the external BIND9 servers. +. 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 ' From 51dd9ddf391039ca127a2c1a3fd3b0dd7cb9b8fe Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Wed, 22 Jul 2026 16:30:36 +0000 Subject: [PATCH 3/4] Split BIND9 migration-window procedures into their own modules Move "Maintaining a migration window with legacy BIND9 servers" and "Completing the BIND9 migration" out of proc_adopting-the-dns-service.adoc and into their own PROCEDURE modules, following the modular-docs procedure template instead of embedding them as sub-headings in another procedure. Co-Authored-By: Claude Sonnet 5 --- ...ting-openstack-control-plane-services.adoc | 4 + .../proc_adopting-the-dns-service.adoc | 237 ------------------ .../proc_completing-the-bind9-migration.adoc | 37 +++ ...tion-window-with-legacy-bind9-servers.adoc | 203 +++++++++++++++ 4 files changed, 244 insertions(+), 237 deletions(-) create mode 100644 docs_user/modules/proc_completing-the-bind9-migration.adoc create mode 100644 docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc diff --git a/docs_user/assemblies/assembly_adopting-openstack-control-plane-services.adoc b/docs_user/assemblies/assembly_adopting-openstack-control-plane-services.adoc index e8d333688..45d75ac5a 100644 --- a/docs_user/assemblies/assembly_adopting-openstack-control-plane-services.adoc +++ b/docs_user/assemblies/assembly_adopting-openstack-control-plane-services.adoc @@ -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] diff --git a/docs_user/modules/proc_adopting-the-dns-service.adoc b/docs_user/modules/proc_adopting-the-dns-service.adoc index 0fabad9d2..53914010c 100644 --- a/docs_user/modules/proc_adopting-the-dns-service.adoc +++ b/docs_user/modules/proc_adopting-the-dns-service.adoc @@ -326,240 +326,3 @@ $ oc patch openstackcontrolplane openstack --type=merge --patch-file /tmp/design ---- $ oc wait --for condition=Ready --timeout=600s designate.designate.openstack.org/designate ---- - -[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. - -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. - -.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: - `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= -$ 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. -==== - -+ -Reload the BIND9 configuration: -+ ----- -$ systemctl restart desginate-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="" port port="953" protocol="tcp" accept' -$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" port port="53" protocol="tcp" accept' -$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" 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: - + ----- -$ 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 designate.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 -k /etc/designate/rndc-keys/default-rndc-0 status ----- -+ -where: - -``:: -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]. - -[id="completing-the-bind9-migration_{context}"] -== Completing the BIND9 migration - -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 designate.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 ----- diff --git a/docs_user/modules/proc_completing-the-bind9-migration.adoc b/docs_user/modules/proc_completing-the-bind9-migration.adoc new file mode 100644 index 000000000..91fe55f58 --- /dev/null +++ b/docs_user/modules/proc_completing-the-bind9-migration.adoc @@ -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 designate.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 +---- diff --git a/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc b/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc new file mode 100644 index 000000000..a802c911d --- /dev/null +++ b/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc @@ -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. + +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. + +.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: + `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= +$ 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. +==== + ++ +Reload the BIND9 configuration: ++ +---- +$ systemctl restart desginate-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="" port port="953" protocol="tcp" accept' +$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" port port="53" protocol="tcp" accept' +$ firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="" 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: + + +---- +$ 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 designate.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 -k /etc/designate/rndc-keys/default-rndc-0 status +---- ++ +where: + +``:: +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]. From 9583a8693b058fdb955ffc019a556e2235cb94a5 Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Wed, 22 Jul 2026 16:41:13 +0000 Subject: [PATCH 4/4] Fix typo, CRD resource name parity, missing sed flag, and add RNDC verification test - Fix 'desginate' typo in systemctl restart command in migration-window doc - Use plural CRD name (designates.designate.openstack.org) in docs to match tests - Add missing -i flag to sed command in designate_external_binds.yaml - Add RNDC connectivity verification task to designate_external_migrate.yaml Co-Authored-By: Claude Opus 4.6 --- .../modules/proc_completing-the-bind9-migration.adoc | 2 +- ...a-migration-window-with-legacy-bind9-servers.adoc | 4 ++-- .../tasks/designate_external_binds.yaml | 2 +- .../tasks/designate_external_migrate.yaml | 12 ++++++++++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs_user/modules/proc_completing-the-bind9-migration.adoc b/docs_user/modules/proc_completing-the-bind9-migration.adoc index 91fe55f58..9f510c3ab 100644 --- a/docs_user/modules/proc_completing-the-bind9-migration.adoc +++ b/docs_user/modules/proc_completing-the-bind9-migration.adoc @@ -21,7 +21,7 @@ $ oc patch openstackcontrolplane openstack --type=json --patch ' . Wait for the {dns_service} to reconcile: + ---- -$ oc wait --for condition=Ready --timeout=300s designate.designate.openstack.org/designate +$ oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate ---- . Delete the external binds secret: diff --git a/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc b/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc index a802c911d..de7ef5713 100644 --- a/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc +++ b/docs_user/modules/proc_maintaining-a-migration-window-with-legacy-bind9-servers.adoc @@ -95,7 +95,7 @@ The `sed` commands in the shell script example are directed at default deploymen Reload the BIND9 configuration: + ---- -$ systemctl restart desginate-designatebackendbind9 +$ systemctl restart designate-designatebackendbind9 ---- + [NOTE] @@ -173,7 +173,7 @@ spec: . Wait for the {dns_service} to reconcile: + ---- -$ oc wait --for condition=Ready --timeout=300s designate.designate.openstack.org/designate +$ oc wait --for condition=Ready --timeout=300s designates.designate.openstack.org/designate ---- . Verify that the external BIND9 targets are included in the pool configuration: diff --git a/tests/roles/designate_adoption/tasks/designate_external_binds.yaml b/tests/roles/designate_adoption/tasks/designate_external_binds.yaml index 216b5f1f3..1d18092bf 100644 --- a/tests/roles/designate_adoption/tasks/designate_external_binds.yaml +++ b/tests/roles/designate_adoption/tasks/designate_external_binds.yaml @@ -62,7 +62,7 @@ ${!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 '/^options {/,/^};/{ + ${!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" diff --git a/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml b/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml index 949609141..53f30bf4f 100644 --- a/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml +++ b/tests/roles/designate_adoption/tasks/designate_external_migrate.yaml @@ -37,3 +37,15 @@ register: external_bind9_pool_check changed_when: false failed_when: external_bind9_pool_check.rc != 0 + +- name: Verify RNDC connectivity from designate worker to legacy BIND9 servers + ansible.builtin.shell: | + {{ shell_header }} + {{ oc_header }} + + oc exec -it $(oc get pods -l service=designate-worker -o name | head -1) -- \ + rndc -s {{ item }} -k /etc/designate/rndc-keys/default-rndc-0 status + register: rndc_connectivity_check + changed_when: false + failed_when: rndc_connectivity_check.rc != 0 + loop: "{{ designate_external_bind_controllers }}"