refactor: unify inconsistent variables in apiserver endpoint (#13392)

This commit is contained in:
Dasmat Hansda
2026-10-12 06:25:22 +00:00
committed by GitHub
parent 7c57bc015d
commit 38f82cdce9
30 changed files with 170 additions and 192 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
---
- name: Kubernetes Apps | Wait for kube-apiserver
uri:
url: "{{ kube_apiserver_endpoint }}/healthz"
url: "{{ _kube_apiserver_local_endpoint }}/healthz"
validate_certs: false
client_cert: "{{ kube_apiserver_client_cert }}"
client_key: "{{ kube_apiserver_client_key }}"
@@ -1,7 +1,7 @@
---
- name: Kubernetes Apps | Wait for kube-apiserver
uri:
url: "{{ kube_apiserver_endpoint }}/healthz"
url: "{{ _kube_apiserver_local_endpoint }}/healthz"
validate_certs: false
client_cert: "{{ kube_apiserver_client_cert }}"
client_key: "{{ kube_apiserver_client_key }}"
+7 -24
View File
@@ -1,25 +1,4 @@
---
- name: Set external kube-apiserver endpoint
set_fact:
# noqa: jinja[spacing]
external_apiserver_address: >-
{%- if loadbalancer_apiserver is defined and loadbalancer_apiserver.address is defined -%}
{{ loadbalancer_apiserver.address }}
{%- elif kubeconfig_localhost_ansible_host is defined and kubeconfig_localhost_ansible_host -%}
{{ hostvars[groups['kube_control_plane'][0]].ansible_host }}
{%- else -%}
{{ kube_apiserver_access_address }}
{%- endif -%}
# noqa: jinja[spacing]
external_apiserver_port: >-
{%- if loadbalancer_apiserver is defined and loadbalancer_apiserver.address is defined and loadbalancer_apiserver.port is defined -%}
{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
{%- else -%}
{{ kube_apiserver_port }}
{%- endif -%}
tags:
- facts
- name: Create kube config dir for current/ansible become user
file:
path: "{{ ansible_env.HOME | default('/root') }}/.kube"
@@ -47,8 +26,8 @@
- name: Wait for k8s apiserver
wait_for:
host: "{{ kube_apiserver_access_address }}"
port: "{{ kube_apiserver_port }}"
host: "{{ _kube_apiserver_local_endpoint | urlsplit('hostname') }}"
port: "{{ _kube_apiserver_local_endpoint | urlsplit('port') | default(kube_apiserver_port, true) }}"
timeout: 180
- name: Create kubeconfig localhost artifacts
@@ -73,9 +52,13 @@
vars:
admin_kubeconfig: "{{ kubeadm_admin_kubeconfig.stdout | from_yaml }}"
context: "kubernetes-admin-{{ cluster_name }}@{{ cluster_name }}"
client_kubeconfig_endpoint: >-
{{ ('https://' ~ (hostvars[groups['kube_control_plane'][0]].ansible_host | ansible.utils.ipwrap) ~ ':' ~ kube_apiserver_port)
if (kubeconfig_localhost_ansible_host | default(false) and kube_apiserver_endpoint is not defined)
else _kube_apiserver_endpoint }}
override:
clusters:
- "{{ admin_kubeconfig['clusters'][0] | combine({'name': cluster_name, 'cluster': admin_kubeconfig['clusters'][0]['cluster'] | combine({'server': 'https://' + (external_apiserver_address | string | ansible.utils.ipwrap) + ':' + (external_apiserver_port | string)})}, recursive=true) }}"
- "{{ admin_kubeconfig['clusters'][0] | combine({'name': cluster_name, 'cluster': admin_kubeconfig['clusters'][0]['cluster'] | combine({'server': client_kubeconfig_endpoint})}, recursive=true) }}"
contexts:
- "{{ admin_kubeconfig['contexts'][0] | combine({'name': context, 'context': admin_kubeconfig['contexts'][0]['context'] | combine({'cluster': cluster_name})}, recursive=true) }}"
current-context: "{{ context }}"
@@ -106,7 +106,7 @@
- name: Control plane | wait for the apiserver to be running
uri:
url: "{{ kube_apiserver_endpoint }}/healthz"
url: "{{ _kube_apiserver_local_endpoint }}/healthz"
validate_certs: false
register: result
until: result.status == 200
@@ -1,16 +1,4 @@
---
- name: Set kubeadm_discovery_address
set_fact:
# noqa: jinja[spacing]
kubeadm_discovery_address: >-
{%- if "127.0.0.1" in kube_apiserver_endpoint or "localhost" in kube_apiserver_endpoint -%}
{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
{%- else -%}
{{ kube_apiserver_endpoint | regex_replace('https://', '') }}
{%- endif %}
tags:
- facts
- name: Obtain kubeadm certificate key for joining control planes nodes
when:
- not kube_external_ca_mode
@@ -31,8 +19,8 @@
- name: Wait for k8s apiserver
wait_for:
host: "{{ kubeadm_discovery_address | regex_replace('\\]?:\\d+$', '') | regex_replace('^\\[', '') }}"
port: "{{ kubeadm_discovery_address.split(':')[-1] }}"
host: "{{ _kube_apiserver_endpoint | urlsplit('hostname') }}"
port: "{{ _kube_apiserver_endpoint | urlsplit('port') | default(kube_apiserver_port, true) }}"
timeout: 180
@@ -36,8 +36,8 @@
- "localhost"
- "127.0.0.1"
- "::1"
- "{{ apiserver_loadbalancer_domain_name | d('') }}"
- "{{ loadbalancer_apiserver.address | d('') }}"
- "{{ _kube_apiserver_endpoint | urlsplit('hostname') }}"
- "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') }}"
- "{{ supplementary_addresses_in_ssl_keys }}"
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_access_ip') }}"
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_ip') }}"
@@ -87,12 +87,6 @@
when: kube_apiserver_tracing
notify: Control plane | Restart apiserver
# Nginx LB(default), If kubeadm_config_api_fqdn is defined, use other LB by kubeadm controlPlaneEndpoint.
- name: Set kubeadm_config_api_fqdn define
set_fact:
kubeadm_config_api_fqdn: "{{ apiserver_loadbalancer_domain_name }}"
when: loadbalancer_apiserver is defined
- name: Kubeadm | Create kubeadm config
template:
src: "kubeadm-config.v1beta4.yaml.j2"
@@ -116,8 +116,8 @@ featureGates:
{% endfor %}
{% endif %}
kubernetesVersion: v{{ kube_version }}
{% if kubeadm_config_api_fqdn is defined %}
controlPlaneEndpoint: "{{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}"
{% if kube_apiserver_endpoint is defined %}
controlPlaneEndpoint: "{{ _kube_apiserver_endpoint_netloc }}"
{% else %}
controlPlaneEndpoint: "{{ main_ip | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}"
{% endif %}
@@ -6,11 +6,7 @@ discovery:
kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml
{% else %}
bootstrapToken:
{% if kubeadm_config_api_fqdn is defined %}
apiServerEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
{% else %}
apiServerEndpoint: "{{ kubeadm_discovery_address }}"
{% endif %}
apiServerEndpoint: "{{ _kube_apiserver_endpoint_netloc }}"
token: {{ kubeadm_token }}
unsafeSkipCAVerification: true
{% endif %}
+7 -53
View File
@@ -1,16 +1,4 @@
---
- name: Set kubeadm_discovery_address
set_fact:
# noqa: jinja[spacing]
kubeadm_discovery_address: >-
{%- if "127.0.0.1" in kube_apiserver_endpoint or "localhost" in kube_apiserver_endpoint -%}
{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
{%- else -%}
{{ kube_apiserver_endpoint | replace("https://", "") }}
{%- endif %}
tags:
- facts
- name: Check if kubelet.conf exists
stat:
path: "{{ kube_config_dir }}/kubelet.conf"
@@ -104,25 +92,11 @@
lineinfile:
dest: "{{ kube_config_dir }}/kubelet.conf"
regexp: '^(\s+)server: https.*'
line: '\1server: {{ kube_apiserver_endpoint }}'
backrefs: true
backup: true
when:
- kubeadm_config_api_fqdn is not defined
- ('kube_control_plane' not in group_names)
- kubeadm_discovery_address != kube_apiserver_endpoint | replace("https://", "")
notify: Kubeadm | restart kubelet
- name: Update server field in kubelet kubeconfig - external lb
lineinfile:
dest: "{{ kube_config_dir }}/kubelet.conf"
regexp: '^(\s+)server: https.*'
line: '\1server: {{ kube_apiserver_endpoint }}'
line: '\1server: {{ _kube_apiserver_cluster_internal_endpoint }}'
backrefs: true
backup: true
when:
- ('kube_control_plane' not in group_names)
- loadbalancer_apiserver is defined
notify: Kubeadm | restart kubelet
- name: Get current resourceVersion of kube-proxy configmap
@@ -136,31 +110,14 @@
tags:
- kube-proxy
# FIXME(mattymo): Need to point to localhost, otherwise control plane nodes will all point
# incorrectly to first control plane node, creating SPoF.
- name: Update server field in kube-proxy kubeconfig
shell: >-
set -o pipefail && {{ kubectl }} get configmap kube-proxy -n kube-system -o yaml
| sed 's#server:.*#server: https://127.0.0.1:{{ kube_apiserver_port }}#g'
| {{ kubectl }} replace -f -
args:
executable: /bin/bash
run_once: true
delegate_to: "{{ groups['kube_control_plane'] | first }}"
delegate_facts: false
when:
- kubeadm_config_api_fqdn is not defined
- kubeadm_discovery_address != kube_apiserver_endpoint | replace("https://", "")
- kube_proxy_deployed
- loadbalancer_apiserver_localhost
tags:
- kube-proxy
- name: Update server field in kube-proxy kubeconfig - external lb
shell: >-
set -o pipefail && {{ kubectl }} get configmap kube-proxy -n kube-system -o yaml
| sed 's#server:.*#server: {{kube_apiserver_endpoint}}#g'
| {{ kubectl }} replace -f -
set -o pipefail &&
if ! {{ kubectl }} get configmap kube-proxy -n kube-system -o yaml | grep -Fq "server: {{ _kube_apiserver_cluster_internal_endpoint }}"; then
{{ kubectl }} get configmap kube-proxy -n kube-system -oyaml |
sed 's#server:.*#server: {{ _kube_apiserver_cluster_internal_endpoint }}#g' |
{{ kubectl }} replace -f -
fi
args:
executable: /bin/bash
run_once: true
@@ -168,7 +125,6 @@
delegate_facts: false
when:
- kube_proxy_deployed
- loadbalancer_apiserver is defined
tags:
- kube-proxy
@@ -196,8 +152,6 @@
delegate_to: "{{ groups['kube_control_plane'] | first }}"
delegate_facts: false
when:
- kubeadm_config_api_fqdn is not defined or loadbalancer_apiserver is defined
- kubeadm_discovery_address != kube_apiserver_endpoint | replace("https://", "") or loadbalancer_apiserver is defined
- kube_proxy_deployed
- original_configmap_resource_version.stdout != new_configmap_resource_version.stdout
tags:
@@ -7,11 +7,7 @@ discovery:
kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml
{% else %}
bootstrapToken:
{% if kubeadm_config_api_fqdn is defined %}
apiServerEndpoint: "{{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}"
{% else %}
apiServerEndpoint: "{{ kubeadm_discovery_address }}"
{% endif %}
apiServerEndpoint: "{{ _kube_apiserver_endpoint_netloc }}"
token: {{ kubeadm_token }}
{% if ca_cert_content is defined %}
caCertHashes:
+1 -1
View File
@@ -1,7 +1,7 @@
---
- name: Kubernetes Apps | Wait for kube-apiserver
uri:
url: "{{ kube_apiserver_endpoint }}/healthz"
url: "{{ _kube_apiserver_local_endpoint }}/healthz"
validate_certs: false
client_cert: "{{ kube_apiserver_client_cert }}"
client_key: "{{ kube_apiserver_client_key }}"
@@ -107,7 +107,7 @@
# When running this as the last phase ensure we wait for kube-apiserver to come up
- name: Preinstall | wait for the apiserver to be running
uri:
url: "{{ kube_apiserver_endpoint }}/healthz"
url: "{{ _kube_apiserver_local_endpoint }}/healthz"
validate_certs: false
register: result
until: result.status == 200
+13 -21
View File
@@ -655,28 +655,20 @@ first_kube_control_plane: "{{ groups['kube_control_plane'] | first }}"
kube_apiserver_address: "{{ hostvars[inventory_hostname]['main_ip'] }}"
kube_apiserver_access_address: "{{ hostvars[inventory_hostname]['main_access_ip'] }}"
first_kube_control_plane_address: "{{ hostvars[groups['kube_control_plane'][0]]['main_access_ip'] }}"
loadbalancer_apiserver_localhost: "{{ loadbalancer_apiserver is not defined }}"
# Loadbalancer configuration
loadbalancer_apiserver_localhost: "{{ kube_apiserver_endpoint is not defined and kube_apiserver_cluster_internal_endpoint is not defined }}"
loadbalancer_apiserver_type: "nginx"
# applied if only external loadbalancer_apiserver is defined, otherwise ignored
apiserver_loadbalancer_domain_name: "{{ 'localhost' if loadbalancer_apiserver_localhost else (loadbalancer_apiserver.address | d(undef())) }}"
kube_apiserver_global_endpoint: |-
{% if loadbalancer_apiserver is defined -%}
https://{{ apiserver_loadbalancer_domain_name | ansible.utils.ipwrap }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
{%- elif loadbalancer_apiserver_localhost -%}
https://localhost:{{ loadbalancer_apiserver_port | default(kube_apiserver_port) }}
{%- else -%}
https://{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
{%- endif %}
kube_apiserver_endpoint: |-
{% if loadbalancer_apiserver is defined -%}
https://{{ apiserver_loadbalancer_domain_name | ansible.utils.ipwrap }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
{%- elif ('kube_control_plane' not in group_names) and loadbalancer_apiserver_localhost -%}
https://localhost:{{ loadbalancer_apiserver_port | default(kube_apiserver_port) }}
{%- elif 'kube_control_plane' in group_names -%}
https://{{ kube_apiserver_bind_address | regex_replace('::', '127.0.0.1') | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
{%- else -%}
https://{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
{%- endif %}
loadbalancer_apiserver_port: "{{ kube_apiserver_port }}"
# Primary API endpoint for external access (e.g., kubectl).
# User should set this in their inventory if they have a Load Balancer.
# If not provided, resolved internally in vars.
kube_apiserver_endpoint: "{{ undef() }}"
# Internal endpoint for in-cluster traffic, including nodes and pods.
# Optional override; resolved internally in vars if not provided.
kube_apiserver_cluster_internal_endpoint: "{{ undef() }}"
kube_apiserver_client_cert: "{{ kube_cert_dir }}/ca.crt"
kube_apiserver_client_key: "{{ kube_cert_dir }}/ca.key"
@@ -81,3 +81,40 @@ ssl_ca_dirs_per_os_family:
RedHat:
- /etc/pki/tls
- /etc/pki/ca-trust
# Internal API server endpoints (cannot be overridden by inventory).
#
# _kube_apiserver_endpoint:
# External API server endpoint used for external access from outside the cluster
# (e.g., in admin kubeconfig written for localhost).
# Resolves to kube_apiserver_endpoint if defined; otherwise defaults to
# https://<first_control_plane_address>:<kube_apiserver_port>.
#
# _kube_apiserver_cluster_internal_endpoint:
# Internal endpoint used for in-cluster communication to the API server by
# cluster components, nodes (kubelet, kube-proxy), and pods (CNI plugins).
# If loadbalancer_apiserver_localhost is enabled, it points to the local load balancer
# proxy (https://127.0.0.1:<loadbalancer_apiserver_port>), otherwise falls back
# to _kube_apiserver_endpoint.
#
# _kube_apiserver_local_endpoint:
# Direct local endpoint to the kube-apiserver process running on the control plane node itself,
# bypassing any load balancer or proxy.
# Used on control plane nodes for local readiness checks, health checks (/healthz),
# and restart handlers.
#
# _kube_apiserver_endpoint_netloc:
# The <host>:<port> representation of _kube_apiserver_endpoint without the scheme.
# Used where kubeadm requires a host:port string (e.g. controlPlaneEndpoint, apiServerEndpoint).
_kube_apiserver_endpoint: >-
{{ kube_apiserver_endpoint if kube_apiserver_endpoint is defined
else 'https://' ~ (first_kube_control_plane_address | ansible.utils.ipwrap) ~ ':' ~ kube_apiserver_port }}
_kube_apiserver_cluster_internal_endpoint: >-
{{ kube_apiserver_cluster_internal_endpoint if kube_apiserver_cluster_internal_endpoint is defined
else (('https://127.0.0.1:' ~ loadbalancer_apiserver_port)
if loadbalancer_apiserver_localhost else _kube_apiserver_endpoint) }}
_kube_apiserver_local_endpoint: "https://{{ kube_apiserver_bind_address | regex_replace('^0\\.0\\.0\\.0$', '127.0.0.1') | regex_replace('^::$', '127.0.0.1') | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}"
_kube_apiserver_endpoint_netloc: "{{ _kube_apiserver_endpoint | urlsplit('netloc') }}"
+2 -2
View File
@@ -46,8 +46,8 @@
| select('defined')))
| unique }}"
no_proxy_prepare:
- "{{ apiserver_loadbalancer_domain_name | d('') }}"
- "{{ loadbalancer_apiserver.address if loadbalancer_apiserver is defined else '' }}"
- "{{ _kube_apiserver_endpoint | urlsplit('hostname') }}"
- "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') }}"
- "{{ hosts_with_no_proxy | map('extract', hostvars, morekeys=['main_access_ip']) }}"
- "{{ _hostnames }}"
- "{{ _hostnames | map('regex_replace', '$', '.' + dns_domain ) }}"
@@ -6,6 +6,6 @@ metadata:
name: kubernetes-services-endpoint
data:
{% if calico_bpf_enabled or loadbalancer_apiserver_localhost %}
KUBERNETES_SERVICE_HOST: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
KUBERNETES_SERVICE_PORT: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
KUBERNETES_SERVICE_HOST: "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') }}"
KUBERNETES_SERVICE_PORT: "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('port') }}"
{% endif %}
@@ -7,8 +7,8 @@ image:
repository: {{ cilium_image_repo }}
tag: {{ cilium_image_tag }}
k8sServiceHost: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
k8sServicePort: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
k8sServiceHost: "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') }}"
k8sServicePort: "{{ _kube_apiserver_cluster_internal_endpoint | urlsplit('port') }}"
ipv4:
enabled: {{ cilium_enable_ipv4 | to_json }}
@@ -5,7 +5,7 @@ clusters:
- name: cluster
cluster:
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
server: {{ kube_apiserver_endpoint }}
server: {{ _kube_apiserver_cluster_internal_endpoint }}
users:
- name: kube-router
user:
+31 -1
View File
@@ -9,13 +9,43 @@
- name: Fail if removed variables are used
vars:
# Always remove items from this list after the release in comments
removed_vars: []
removed_vars:
- apiserver_loadbalancer_domain_name # 2.33.0
- kube_apiserver_global_endpoint # 2.33.0
- kubeadm_config_api_fqdn # 2.33.0
- loadbalancer_apiserver # 2.33.0
removed_vars_found: "{{ query('varnames', '^(' + (removed_vars | join('|')) + ')$') }}"
assert:
that: removed_vars_found | length == 0
fail_msg: "Removed variables present: {{ removed_vars_found | join(', ') }}"
run_once: true
- name: Check kube_apiserver_endpoint format
assert:
that:
- kube_apiserver_endpoint | urlsplit('scheme') == 'https'
- kube_apiserver_endpoint | urlsplit('hostname') is not none
- kube_apiserver_endpoint | urlsplit('hostname') | length > 0
- kube_apiserver_endpoint | urlsplit('port') is not none
msg: "kube_apiserver_endpoint must be in the format 'https://<host>:<port>' (e.g., 'https://lb.example.com:6443')"
run_once: true
when:
- kube_apiserver_endpoint is defined
- not ignore_assert_errors
- name: Check kube_apiserver_cluster_internal_endpoint format
assert:
that:
- kube_apiserver_cluster_internal_endpoint | urlsplit('scheme') == 'https'
- kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') is not none
- kube_apiserver_cluster_internal_endpoint | urlsplit('hostname') | length > 0
- kube_apiserver_cluster_internal_endpoint | urlsplit('port') is not none
msg: "kube_apiserver_cluster_internal_endpoint must be in the format 'https://<host>:<port>' (e.g., 'https://lb.internal:6443')"
run_once: true
when:
- kube_apiserver_cluster_internal_endpoint is defined
- not ignore_assert_errors
- name: Stop if kube_control_plane group is empty
assert:
that: groups.get( 'kube_control_plane' ) != []