Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CPDEV-98822] Remove default resolvConf from kubelet-config ConfigMap #619

Merged
merged 1 commit into from
Mar 20, 2024
Merged
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
5 changes: 4 additions & 1 deletion kubemarine/kubernetes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,10 @@ def init_first_control_plane(group: NodeGroup) -> None:
kubeconfig_filepath = fetch_admin_config(cluster)
summary.schedule_report(cluster.context, summary.SummaryItem.KUBECONFIG, kubeconfig_filepath)

# Invoke method from admission module for applying default PSS or privileged PSP if they are enabled
# Remove default resolvConf from kubelet-config ConfigMap for debian OS family
first_control_plane.call(components.patch_kubelet_configmap)

# Invoke method from admission module for applying the privileged PSP if it is enabled
first_control_plane.call(admission.apply_admission)

# Preparing join_dict to init other nodes
Expand Down
31 changes: 30 additions & 1 deletion kubemarine/kubernetes/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,26 @@ def create_kubeadm_patches_for_node(cluster: KubernetesCluster, node: NodeGroup)
defer.flush()


def patch_kubelet_configmap(control_plane: AbstractGroup[RunResult]) -> None:
"""
Apply W/A until https://github.com/kubernetes/kubeadm/issues/3034 is resolved
for all the supported Kubernetes versions.

:param control_plane: control plane to operate on
"""
# Make sure to check kubeadm_kubelet in the inventory.
cluster: KubernetesCluster = control_plane.cluster
kubeadm_config = KubeadmConfig(cluster)
if 'resolvConf' in kubeadm_config.maps['kubelet-config']:
return

configmap_name = _get_configmap_name(cluster, 'kubelet-config')
control_plane.sudo(
f'kubectl get cm -n kube-system {configmap_name} -o yaml '
'| grep -v "resolvConf:" '
'| sudo kubectl apply -f -')


def _upload_config(cluster: KubernetesCluster, control_plane: AbstractGroup[RunResult],
kubeadm_config: KubeadmConfig, remote_path: str,
*, patches_dir: str = '/etc/kubernetes/patches') -> None:
Expand Down Expand Up @@ -558,6 +578,8 @@ def _configmap_init_phase_uploader(configmap: str, upload_config: str) -> Callab
def upload(control_plane: DeferredGroup) -> None:
init_phase = CONFIGMAPS_CONSTANTS[configmap]['init_phase']
control_plane.run(f'sudo kubeadm init phase {init_phase} --config {upload_config}')
if configmap == 'kubelet-config':
patch_kubelet_configmap(control_plane)

return upload

Expand Down Expand Up @@ -937,8 +959,11 @@ def compare_configmap(cluster: KubernetesCluster, configmap: str) -> Optional[st

key = CONFIGMAPS_CONSTANTS[configmap]['key']
generated_config = yaml.safe_load(cfg)['data'][key]
if 'resolvConf' not in kubeadm_config.maps[configmap]:
generated_config = _filter_kubelet_configmap_resolv_conf(generated_config)

kubeadm_config.load(configmap, control_plane)
# Use loaded_maps that preserve original formatting
stored_config = kubeadm_config.loaded_maps[configmap].obj["data"][key]

if yaml.safe_load(generated_config) == yaml.safe_load(stored_config):
Expand Down Expand Up @@ -978,7 +1003,11 @@ def _detect_changes(logger: log.EnhancedLogger, old: str, new: str, fromfile: st


def _filter_etcd_initial_cluster_args(content: str) -> str:
return '\n'.join(filter(lambda ln: '--initial-cluster' not in ln, content.splitlines()))
return '\n'.join(ln for ln in content.splitlines() if '--initial-cluster' not in ln)


def _filter_kubelet_configmap_resolv_conf(content: str) -> str:
return '\n'.join(ln for ln in content.splitlines() if 'resolvConf:' not in ln)


def _restart_containers(cluster: KubernetesCluster, node: NodeGroup, components: Sequence[str]) -> None:
Expand Down
2 changes: 2 additions & 0 deletions kubemarine/patches/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
from typing import List

from kubemarine.core.patch import Patch
from kubemarine.patches.patch_kubelet_configmap import KubeletResolvConf

patches: List[Patch] = [
KubeletResolvConf(),
]
"""
List of patches that is sorted according to the Patch.priority() before execution.
Expand Down
45 changes: 45 additions & 0 deletions kubemarine/patches/patch_kubelet_configmap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from textwrap import dedent

from kubemarine.core.action import Action
from kubemarine.core.patch import RegularPatch
from kubemarine.core.resources import DynamicResources
from kubemarine.kubernetes import components


class TheAction(Action):
def __init__(self) -> None:
super().__init__("Remove default resolvConf from kubelet-config ConfigMap")

def run(self, res: DynamicResources) -> None:
cluster = res.cluster()
control_plane = cluster.nodes['control-plane'].get_first_member()

kubeadm_config = components.KubeadmConfig(cluster)
if 'resolvConf' in kubeadm_config.maps['kubelet-config']:
return cluster.log.info("KubeletConfiguration.resolvConf is redefined in the inventory. "
"Patch is not applicable.")

if 'resolvConf' not in kubeadm_config.load('kubelet-config', control_plane):
return cluster.log.info("KubeletConfiguration.resolvConf is already absent in the kubelet-config ConfigMap.")

control_plane.call(components.patch_kubelet_configmap)


class KubeletResolvConf(RegularPatch):
def __init__(self) -> None:
super().__init__("kubelet_resolvConf")

@property
def action(self) -> Action:
return TheAction()

@property
def description(self) -> str:
return dedent(
f"""\
If KubeletConfiguration.resolvConf is not redefined in the inventory,
remove it from the kubelet-config ConfigMap if present.

This is necessary for smoother migration of the operating systems.
""".rstrip()
)
Loading