refactor: extract DNS configuration from kubernetes/preinstall into dns_config role (#13603)

Extract tasks related to host DNS management from kubernetes/preinstall
into a new kubernetes/dns_config role.

Previously, kubernetes/preinstall was re-invoked at the end of cluster
playbooks with dns_late: true to apply resolvconf changes after cluster
DNS came up. Because of this reuse, several unrelated tasks in preinstall
were guarded with 'when: not dns_late'.

Move resolvconf, systemd-resolved, networkmanager-dns, and dhclient tasks,
along with their associated templates, facts, variables, and handlers, into
kubernetes/dns_config. Update cluster.yml, upgrade_cluster.yml, scale.yml,
and reset.yml to invoke the new role directly and remove dns_late guards.

Signed-off-by: Dasmat13 <gptdasmat@gmail.com>
This commit is contained in:
Dasmat Hansda
2026-10-30 13:51:55 +00:00
committed by GitHub
parent a3d30ad42c
commit c219d80df9
26 changed files with 374 additions and 354 deletions
@@ -18,39 +18,6 @@
tags:
- facts
- name: Check resolvconf
command: which resolvconf
register: resolvconf
failed_when: false
changed_when: false
check_mode: false
- name: Check existence of /etc/resolvconf/resolv.conf.d
stat:
path: /etc/resolvconf/resolv.conf.d
get_attributes: false
get_checksum: false
get_mime: false
failed_when: false
register: resolvconfd_path
- name: Check status of /etc/resolv.conf
stat:
path: /etc/resolv.conf
follow: false
get_attributes: false
get_checksum: false
get_mime: false
failed_when: false
register: resolvconf_stat
# Used in vars/
- name: Fetch resolv.conf
when: resolvconf_stat.stat.exists
slurp:
src: /etc/resolv.conf
register: resolvconf_slurp
- name: NetworkManager | Check if host has NetworkManager
# noqa command-instead-of-module - Should we use service_facts for this?
command: systemctl is-active --quiet NetworkManager.service
@@ -59,87 +26,6 @@
changed_when: false
check_mode: false
- name: Check systemd-resolved
# noqa command-instead-of-module - Should we use service_facts for this?
command: systemctl is-active systemd-resolved
register: systemd_resolved_enabled
failed_when: false
changed_when: false
check_mode: false
- name: Set default dns if remove_default_searchdomains is false
set_fact:
default_searchdomains: ["default.svc.{{ dns_domain }}", "svc.{{ dns_domain }}"]
when: not remove_default_searchdomains | default() | bool or (remove_default_searchdomains | default() | bool and searchdomains | length == 0)
- name: Set dns facts
set_fact:
resolvconf: >-
{%- if resolvconf.rc == 0 and resolvconfd_path.stat.isdir is defined and resolvconfd_path.stat.isdir -%}true{%- else -%}false{%- endif -%}
- name: Check if kubelet is configured
stat:
path: "{{ kube_config_dir }}/kubelet.env"
get_attributes: false
get_checksum: false
get_mime: false
register: kubelet_configured
changed_when: false
- name: Check if early DNS configuration stage
set_fact:
dns_early: "{{ not kubelet_configured.stat.exists }}"
- name: Target resolv.conf files
set_fact:
resolvconffile: /etc/resolv.conf
base: >-
{%- if resolvconf | bool -%}/etc/resolvconf/resolv.conf.d/base{%- endif -%}
head: >-
{%- if resolvconf | bool -%}/etc/resolvconf/resolv.conf.d/head{%- endif -%}
when: ansible_facts['os_family'] != "Flatcar" and not is_fedora_coreos
- name: Target temporary resolvconf cloud init file (Flatcar Container Linux by Kinvolk / Fedora CoreOS)
set_fact:
resolvconffile: /tmp/resolveconf_cloud_init_conf
when: ansible_facts['os_family'] == "Flatcar" or is_fedora_coreos
- name: Check if /etc/dhclient.conf exists
stat:
path: /etc/dhclient.conf
get_attributes: false
get_checksum: false
get_mime: false
register: dhclient_stat
- name: Target dhclient conf file for /etc/dhclient.conf
set_fact:
dhclientconffile: /etc/dhclient.conf
when: dhclient_stat.stat.exists
- name: Check if /etc/dhcp/dhclient.conf exists
stat:
path: /etc/dhcp/dhclient.conf
get_attributes: false
get_checksum: false
get_mime: false
register: dhcp_dhclient_stat
- name: Target dhclient conf file for /etc/dhcp/dhclient.conf
set_fact:
dhclientconffile: /etc/dhcp/dhclient.conf
when: dhcp_dhclient_stat.stat.exists
- name: Target dhclient hook file for Red Hat family
set_fact:
dhclienthookfile: /etc/dhcp/dhclient.d/zdnsupdate.sh
when: ansible_facts['os_family'] == "RedHat"
- name: Target dhclient hook file for Debian family
set_fact:
dhclienthookfile: /etc/dhcp/dhclient-exit-hooks.d/zdnsupdate
when: ansible_facts['os_family'] == "Debian"
- name: Set etcd vars if using kubeadm mode
set_fact:
etcd_cert_dir: "{{ kube_cert_dir }}"
@@ -102,15 +102,6 @@
msg: "Hostname must consist of lower case alphanumeric characters, '.' or '-', and must start and end with an alphanumeric character"
when: not ignore_assert_errors
- name: Stop if /etc/resolv.conf has no configured nameservers
assert:
that: configured_nameservers | length>0
fail_msg: "nameserver should not be empty in /etc/resolv.conf"
when:
- upstream_dns_servers | length == 0
- not disable_host_nameservers
- dns_mode in ['coredns', 'coredns_dual']
- name: Stop if download_localhost is enabled for Flatcar Container Linux
assert:
that: ansible_facts['os_family'] != "Flatcar"
@@ -1,57 +0,0 @@
---
- name: Create temporary resolveconf cloud init file
command: cp -f /etc/resolv.conf "{{ resolvconffile }}"
when: ansible_facts['os_family'] == "Flatcar"
- name: Add domain/search/nameservers/options to resolv.conf
blockinfile:
path: "{{ resolvconffile }}"
block: |-
domain {{ dns_domain }}
search {{ (default_searchdomains + searchdomains) | join(' ') }}
{% for item in nameserverentries %}
nameserver {{ item }}
{% endfor %}
options ndots:{{ ndots }} timeout:{{ dns_timeout }} attempts:{{ dns_attempts }}
state: present
insertbefore: BOF
create: true
backup: "{{ not resolvconf_stat.stat.islnk }}"
marker: "# Ansible entries {mark}"
mode: "0644"
notify: Preinstall | propagate resolvconf to k8s components
- name: Remove search/domain/nameserver options before block
replace:
path: "{{ item[0] }}"
regexp: '^{{ item[1] }}[^#]*(?=# Ansible entries BEGIN)'
backup: "{{ not resolvconf_stat.stat.islnk }}"
with_nested:
- "{{ [resolvconffile, base | default(''), head | default('')] | select | list }}"
- [ 'search\s', 'nameserver\s', 'domain\s', 'options\s' ]
notify: Preinstall | propagate resolvconf to k8s components
- name: Remove search/domain/nameserver options after block
replace:
path: "{{ item[0] }}"
regexp: '(# Ansible entries END\n(?:(?!^{{ item[1] }}).*\n)*)(?:^{{ item[1] }}.*\n?)+'
replace: '\1'
backup: "{{ not resolvconf_stat.stat.islnk }}"
with_nested:
- "{{ [resolvconffile, base | default(''), head | default('')] | select | list }}"
- [ 'search\s', 'nameserver\s', 'domain\s', 'options\s' ]
notify: Preinstall | propagate resolvconf to k8s components
- name: Get temporary resolveconf cloud init file content
command: cat {{ resolvconffile }}
register: cloud_config
when: ansible_facts['os_family'] == "Flatcar"
- name: Persist resolvconf cloud init file
template:
dest: "{{ resolveconf_cloud_init_conf }}"
src: resolvconf.j2
owner: root
mode: "0644"
notify: Preinstall | propagate resolvconf to k8s components
when: ansible_facts['os_family'] == "Flatcar"
@@ -1,15 +0,0 @@
---
- name: Create systemd-resolved drop-in directory
file:
state: directory
name: /etc/systemd/resolved.conf.d/
mode: "0755"
- name: Write Kubespray DNS settings to systemd-resolved
template:
src: resolved.conf.j2
dest: /etc/systemd/resolved.conf.d/kubespray.conf
owner: root
group: root
mode: "0644"
notify: Preinstall | Restart systemd-resolved
@@ -1,38 +0,0 @@
---
- name: NetworkManager | Add nameservers to NM configuration
community.general.ini_file:
path: /etc/NetworkManager/conf.d/dns.conf
section: global-dns-domain-*
option: servers
value: "{{ nameserverentries | join(',') }}"
mode: '0600'
backup: "{{ leave_etc_backup_files }}"
when:
- ('127.0.0.53' not in nameserverentries
or systemd_resolved_enabled.rc != 0)
notify: Preinstall | update resolvconf for networkmanager
- name: Set default dns if remove_default_searchdomains is false
set_fact:
default_searchdomains: ["default.svc.{{ dns_domain }}", "svc.{{ dns_domain }}"]
when: not remove_default_searchdomains | default() | bool or (remove_default_searchdomains | default() | bool and searchdomains | default([]) | length==0)
- name: NetworkManager | Add DNS search to NM configuration
community.general.ini_file:
path: /etc/NetworkManager/conf.d/dns.conf
section: global-dns
option: searches
value: "{{ (default_searchdomains | default([]) + searchdomains) | join(',') }}"
mode: '0600'
backup: "{{ leave_etc_backup_files }}"
notify: Preinstall | update resolvconf for networkmanager
- name: NetworkManager | Add DNS options to NM configuration
community.general.ini_file:
path: /etc/NetworkManager/conf.d/dns.conf
section: global-dns
option: options
value: "ndots:{{ ndots }},timeout:{{ dns_timeout }},attempts:{{ dns_attempts }}"
mode: '0600'
backup: "{{ leave_etc_backup_files }}"
notify: Preinstall | update resolvconf for networkmanager
@@ -1,38 +0,0 @@
---
- name: Configure dhclient to supersede search/domain/nameservers
blockinfile:
# 1 is the 2nd item of a tuple in items()
block: |-
{% for key, val in dhclient_supersede.items() | rejectattr(1, '==', []) -%}
{% if key == "domain-name-servers" -%}
supersede {{ key }} {{ val | join(',') }};
{% else -%}
supersede {{ key }} "{{ val | join('","') }}";
{% endif -%}
{% endfor %}
path: "{{ dhclientconffile }}"
create: true
state: present
insertbefore: BOF
backup: "{{ leave_etc_backup_files }}"
marker: "# Ansible entries {mark}"
mode: "0644"
notify: Preinstall | propagate resolvconf to k8s components
- name: Configure dhclient hooks for resolv.conf (non-RH)
template:
src: dhclient_dnsupdate.sh.j2
dest: "{{ dhclienthookfile }}"
owner: root
mode: "0755"
notify: Preinstall | propagate resolvconf to k8s components
when: ansible_facts['os_family'] not in [ "RedHat", "Suse" ]
- name: Configure dhclient hooks for resolv.conf (RH-only)
template:
src: dhclient_dnsupdate_rh.sh.j2
dest: "{{ dhclienthookfile }}"
owner: root
mode: "0755"
notify: Preinstall | propagate resolvconf to k8s components
when: ansible_facts['os_family'] == "RedHat"
@@ -1,18 +0,0 @@
---
# These tasks will undo changes done by kubespray in the past if needed (e.g. when upgrading from kubespray 2.0.x
# or when changing resolvconf_mode)
- name: Remove kubespray specific config from dhclient config
blockinfile:
path: "{{ dhclientconffile }}"
state: absent
backup: "{{ leave_etc_backup_files }}"
marker: "# Ansible entries {mark}"
notify: Preinstall | propagate resolvconf to k8s components
- name: Remove kubespray specific dhclient hook
file:
path: "{{ dhclienthookfile }}"
state: absent
notify: Preinstall | propagate resolvconf to k8s components
@@ -3,47 +3,20 @@
- name: Disable swap
import_tasks: 0010-swapoff.yml
when:
- not dns_late
- kubelet_fail_swap_on
- name: Set facts
import_tasks: 0020-set_facts.yml
tags:
- resolvconf
- facts
- name: Check settings
import_tasks: 0040-verify-settings.yml
when:
- not dns_late
tags:
- asserts
- name: Create directories
import_tasks: 0050-create_directories.yml
when:
- not dns_late
- name: Apply resolvconf settings
import_tasks: 0060-resolvconf.yml
when:
- dns_mode != 'none'
- resolvconf_mode == 'host_resolvconf'
- systemd_resolved_enabled.rc != 0
- networkmanager_enabled.rc != 0
tags:
- bootstrap_os
- resolvconf
- name: Apply systemd-resolved settings
import_tasks: 0061-systemd-resolved.yml
when:
- dns_mode != 'none'
- resolvconf_mode == 'host_resolvconf'
- systemd_resolved_enabled.rc == 0
tags:
- bootstrap_os
- resolvconf
- name: Apply networkmanager unmanaged devices settings
import_tasks: 0062-networkmanager-unmanaged-devices.yml
@@ -52,58 +25,18 @@
tags:
- bootstrap_os
- name: Apply networkmanager DNS settings
import_tasks: 0063-networkmanager-dns.yml
when:
- dns_mode != 'none'
- resolvconf_mode == 'host_resolvconf'
- networkmanager_enabled.rc == 0
tags:
- bootstrap_os
- resolvconf
- name: Apply system configurations
import_tasks: 0080-system-configurations.yml
when:
- not dns_late
tags:
- bootstrap_os
- name: Configure NTP
import_tasks: 0081-ntp-configurations.yml
when:
- not dns_late
- ntp_enabled
tags:
- bootstrap_os
- name: Configure dhclient
import_tasks: 0100-dhclient-hooks.yml
when:
- dns_mode != 'none'
- resolvconf_mode == 'host_resolvconf'
- dhclientconffile is defined
- ansible_facts['os_family'] != "Flatcar"
tags:
- bootstrap_os
- resolvconf
- name: Configure dhclient dhclient hooks
import_tasks: 0110-dhclient-hooks-undo.yml
when:
- dns_mode != 'none'
- resolvconf_mode != 'host_resolvconf'
- dhclientconffile is defined
- ansible_facts['os_family'] != "Flatcar"
tags:
- bootstrap_os
- resolvconf
# We need to make sure the network is restarted early enough so that docker can later pick up the correct system
# nameservers and search domains
- name: Flush handlers
meta: flush_handlers
- name: Check if we are running inside a Azure VM
stat:
path: /var/lib/waagent/
@@ -111,8 +44,6 @@
get_checksum: false
get_mime: false
register: azure_check
when:
- not dns_late
tags:
- bootstrap_os