diff --git a/documentation/Installation.md b/documentation/Installation.md index 911a30e2d..d4ab661cf 100644 --- a/documentation/Installation.md +++ b/documentation/Installation.md @@ -1092,25 +1092,26 @@ In the `services.kubeadm` section, you can override the original settings for ku For more information about these settings, refer to the official Kubernetes documentation at [https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file). By default, the installer uses the following parameters: -| Parameter | Default Value | Description | -|-------------------------------------------------------|----------------------------------------------------------|--------------------------------------------------------------------------------------------------| -|kubernetesVersion | `v1.28.12` | | -|controlPlaneEndpoint | `{{ cluster_name }}:6443` | | -|networking.podSubnet | `10.128.0.0/14` for IPv4 or `fd02::/48` for IPv6 | | -|networking.serviceSubnet | `172.30.0.0/16` for IPv4 or `fd03::/112` for IPv6 | | -|apiServer.certSANs | List with all nodes internal IPs, external IPs and names | Custom SANs are only appended to, but do not override the default list | -|apiServer.extraArgs.enable-admission-plugins | `NodeRestriction` | | -|apiServer.extraArgs.feature-gates | | `PodSecurity=true` is added for Kubernetes < v1.28 if [RBAC pss](#rbac-pss) is enabled | -|apiServer.extraArgs.admission-control-config-file | `/etc/kubernetes/pki/admission.yaml` | Provided default value **overrides** custom value if [RBAC pss](#rbac-pss) is enabled. | -|apiServer.extraArgs.profiling | `false` | | -|apiServer.extraArgs.audit-log-path | `/var/log/kubernetes/audit/audit.log` | | -|apiServer.extraArgs.audit-policy-file | `/etc/kubernetes/audit-policy.yaml` | | -|apiServer.extraArgs.audit-log-maxage | `30` | | -|apiServer.extraArgs.audit-log-maxbackup | `10` | | -|apiServer.extraArgs.audit-log-maxsize | `100` | | -|scheduler.extraArgs.profiling | `false` | | -|controllerManager.extraArgs.profiling | `false` | | -|controllerManager.extraArgs.terminated-pod-gc-threshold| `1000` | | +| Parameter | Default Value | Description | +|---------------------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------| +| kubernetesVersion | `v1.28.12` | | +| controlPlaneEndpoint | `{{ cluster_name }}:6443` | | +| networking.podSubnet | `10.128.0.0/14` for IPv4 or `fd02::/48` for IPv6 | | +| networking.serviceSubnet | `172.30.0.0/16` for IPv4 or `fd03::/112` for IPv6 | | +| apiServer.certSANs | List with all nodes internal IPs, external IPs and names | Custom SANs are only appended to, but do not override the default list | +| apiServer.extraArgs.enable-admission-plugins | `NodeRestriction` | | +| apiServer.extraArgs.feature-gates | | `PodSecurity=true` is added for Kubernetes < v1.28 if [RBAC pss](#rbac-pss) is enabled | +| apiServer.extraArgs.admission-control-config-file | `/etc/kubernetes/pki/admission.yaml` | Provided default value **overrides** custom value if [RBAC pss](#rbac-pss) is enabled. | +| apiServer.extraArgs.profiling | `false` | | +| apiServer.extraArgs.audit-log-path | `/var/log/kubernetes/audit/audit.log` | | +| apiServer.extraArgs.audit-policy-file | `/etc/kubernetes/audit-policy.yaml` | | +| apiServer.extraArgs.audit-log-maxage | `30` | | +| apiServer.extraArgs.audit-log-maxbackup | `10` | | +| apiServer.extraArgs.audit-log-maxsize | `100` | | +| scheduler.extraArgs.profiling | `false` | | +| controllerManager.extraArgs.profiling | `false` | | +| controllerManager.extraArgs.terminated-pod-gc-threshold | `1000` | | +| featureGates.ControlPlaneKubeletLocalMode | `true` | Provided for Kubernetes version >= 1.31 | The following is an example of kubeadm defaults override: @@ -2093,11 +2094,11 @@ By default, the installer installs the following thirdparties with the following services: thirdparties: /usr/bin/kubeadm: - source: 'https://storage.googleapis.com/kubernetes-release/release/{{k8s-version}}/bin/linux/amd64/kubeadm' + source: 'https://dl.k8s.io/{{k8s-version}}/bin/linux/amd64/kubeadm' /usr/bin/kubelet: - source: 'https://storage.googleapis.com/kubernetes-release/release/{{k8s-version}}/bin/linux/amd64/kubelet' + source: 'https://dl.k8s.io/{{k8s-version}}/bin/linux/amd64/kubelet' /usr/bin/kubectl: - source: 'https://storage.googleapis.com/kubernetes-release/release/{{k8s-version}}/bin/linux/amd64/kubectl' + source: 'https://dl.k8s.io/{{k8s-version}}/bin/linux/amd64/kubectl' group: control-plane /usr/bin/calicoctl: source: 'https://github.com/projectcalico/calico/releases/download/{{calico-version}}/calicoctl-linux-amd64' @@ -6142,3 +6143,33 @@ The tables below shows the correspondence of versions that are supported and is | | kubernetesui/dashboard | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | Required only if Kubernetes Dashboard plugin is set to be installed. | | | kubernetesui/metrics-scraper | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | Required only if Kubernetes Dashboard plugin is set to be installed. | | | rancher/local-path-provisioner | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | Required only if local-path provisioner plugin is set to be installed. | + +## Default Dependent Components Versions for Kubernetes Versions v1.31.1 +| Type | Name | Versions | | | | | | | Note | +|----------|----------------------------------------------------------------|------------------|------------------------------|--------------|--------------|-------------------|-----------|-----------|------------------------------------------------------------------------------------------------------------| +| | | CentOS RHEL 7.5+ | CentOS RHEL Oracle Linux 8.4 | Ubuntu 20.04 | Ubuntu 22.04 | Oracle Linux 7.5+ | RHEL 8.6+ | RockyLinux 8.6+ | | +| binaries | kubeadm | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | SHA1: 0a682af6436ce4e7188f93ddeebff5c2f3be1592 | +| | kubelet | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | SHA1: fc7d0a9859c97ec2a2a4ac9ec1814b131e8d875f | +| | kubectl | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | SHA1: a0fd9dc942f533e2bdeaa4b2691fc408e334f922 | +| | calicoctl | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | SHA1: 80f164a8248b8fa501f35f12cbcac0b059e665e2 Required only if calico is installed. | +| | crictl | v1.30.0 | v1.30.0 | v1.30.0 | v1.30.0 | v1.30.0 | v1.30.0 | v1.30.0 | SHA1: c81e76d5d4bf64d6b513485490722d2fc0a9a83b | +| rpms | containerd.io | 1.6.* | 1.6.* | 1.6.* | 1.6.* | 1.6.* | 1.6.* | 1.6.* | | +| | haproxy/rh-haproxy | 1.8 | 1.8 | 2.* | 2.* | 1.8 | 1.8 | 1.8 | Required only if balancers are presented in the deployment scheme. | +| | keepalived | 1.3 | 2.1 | 2.* | 2.* | 1.3 | 2.1 | 2.1 | Required only if VRRP is presented in the deployment scheme. | +| images | registry.k8s.io/kube-apiserver | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | | +| | registry.k8s.io/kube-controller-manager | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | | +| | registry.k8s.io/kube-proxy | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | | +| | registry.k8s.io/kube-scheduler | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | v1.31.1 | | +| | registry.k8s.io/coredns | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | | +| | registry.k8s.io/pause | 3.10 | 3.10 | 3.10 | 3.10 | 3.10 | 3.10 | 3.10 | | +| | registry.k8s.io/etcd | 3.5.15-0 | 3.5.15-0 | 3.5.15-0 | 3.5.15-0 | 3.5.15-0 | 3.5.15-0 | 3.5.15-0 | | +| | calico/typha | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | Required only if Typha is enabled in Calico config. | +| | calico/cni | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | | +| | calico/node | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | | +| | calico/kube-controllers | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | | +| | calico/apiserver | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | v3.28.1 | Required only if API server is enabled in Calico config. | +| | registry.k8s.io/ingress-nginx/controller | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | v1.11.1 | | +| | registry.k8s.io/kube-webhook-certgen | v1.4.1 | v1.4.1 | v1.4.1 | v1.4.1 | v1.4.1 | v1.4.1 | v1.4.1 | | +| | kubernetesui/dashboard | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | v2.7.0 | Required only if Kubernetes Dashboard plugin is set to be installed. | +| | kubernetesui/metrics-scraper | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | v1.0.8 | Required only if Kubernetes Dashboard plugin is set to be installed. | +| | rancher/local-path-provisioner | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | v0.0.27 | Required only if local-path provisioner plugin is set to be installed. | diff --git a/documentation/Maintenance.md b/documentation/Maintenance.md index d2b8f43bd..4a2aed1dc 100644 --- a/documentation/Maintenance.md +++ b/documentation/Maintenance.md @@ -752,11 +752,11 @@ The procedure recovers thirdparties based on the `cluster.yaml`. If rpm thirdpar restore_plan: thirdparties: /usr/bin/kubeadm: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubeadm + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubeadm /usr/bin/kubelet: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubelet + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubelet /usr/bin/kubectl: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubectl + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubectl /usr/bin/calicoctl: source: https://github.com/projectcalico/calicoctl/releases/download/v3.14.1/calicoctl-linux-amd64 ``` diff --git a/examples/procedure.yaml/full-restore.yaml b/examples/procedure.yaml/full-restore.yaml index 7d47be3fe..cb2210354 100644 --- a/examples/procedure.yaml/full-restore.yaml +++ b/examples/procedure.yaml/full-restore.yaml @@ -12,11 +12,11 @@ restore_plan: peer_cacert: /etc/kubernetes/pki/etcd/ca.crt thirdparties: /usr/bin/kubeadm: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubeadm + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubeadm /usr/bin/kubelet: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubelet + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubelet /usr/bin/kubectl: - source: https://storage.googleapis.com/kubernetes-release/release/v1.18.8/bin/linux/amd64/kubectl + source: https://dl.k8s.io/v1.18.8/bin/linux/amd64/kubectl /opt/cni/cni-plugins-linux.tgz: source: https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz /usr/bin/calicoctl: diff --git a/kubemarine/core/resources.py b/kubemarine/core/resources.py index 2f611035a..d5c2471f5 100644 --- a/kubemarine/core/resources.py +++ b/kubemarine/core/resources.py @@ -462,6 +462,7 @@ def enrichment_functions(self) -> List[c.EnrichmentFunction]: # * kubemarine.sysctl.enrich_inventory kubemarine.kubernetes.enrich_inventory, kubemarine.admission.enrich_inventory, + kubemarine.kubernetes.enrich_control_plane_kubelet_local_mode, # Depends on kubemarine.core.defaults.apply_defaults kubemarine.kubernetes_accounts.enrich_inventory, # Depends on kubemarine.kubernetes.enrich_inventory diff --git a/kubemarine/kubernetes/__init__.py b/kubemarine/kubernetes/__init__.py index 70a4a87e6..e560d0b27 100644 --- a/kubemarine/kubernetes/__init__.py +++ b/kubemarine/kubernetes/__init__.py @@ -188,6 +188,18 @@ def enrich_inventory(cluster: KubernetesCluster) -> None: enrich_kube_proxy(cluster) +@enrichment(EnrichmentStage.FULL) +def enrich_control_plane_kubelet_local_mode(cluster: KubernetesCluster) -> None: + inventory = cluster.inventory + + kubeadm = inventory["services"]["kubeadm"] + if components.control_plane_kubelet_local_mode(cluster): + feature_gates = kubeadm.get("featureGates", {}) + if 'ControlPlaneKubeletLocalMode' not in feature_gates: + feature_gates['ControlPlaneKubeletLocalMode'] = True + kubeadm["featureGates"] = feature_gates + + def enrich_kube_proxy(cluster: KubernetesCluster) -> None: inventory = cluster.inventory diff --git a/kubemarine/kubernetes/components.py b/kubemarine/kubernetes/components.py index e4e24d3d2..388a8cd25 100644 --- a/kubemarine/kubernetes/components.py +++ b/kubemarine/kubernetes/components.py @@ -208,6 +208,10 @@ def kube_proxy_overwrites_higher_system_values(cluster: KubernetesCluster) -> bo return kubernetes_minor_release_at_least(cluster.inventory, "v1.29") +def control_plane_kubelet_local_mode(cluster: KubernetesCluster) -> bool: + return kubernetes_minor_release_at_least(cluster.inventory, "v1.31") + + def kubernetes_minor_release_at_least(inventory: dict, minor_version: str) -> bool: kubernetes_version = inventory["services"]["kubeadm"]["kubernetesVersion"] return utils.version_key(kubernetes_version)[0:2] >= utils.minor_version_key(minor_version) diff --git a/kubemarine/procedures/check_paas.py b/kubemarine/procedures/check_paas.py index 299acbe7e..390209f77 100755 --- a/kubemarine/procedures/check_paas.py +++ b/kubemarine/procedures/check_paas.py @@ -1511,7 +1511,11 @@ def kubernetes_admission_status(cluster: KubernetesCluster) -> None: kubeadm_config = components.KubeadmConfig(cluster) cluster_config = kubeadm_config.load('kubeadm-config', first_control_plane) + # Check if extraArgs is a list of dictionaries or a dictionary apiserver_actual_args = cluster_config["apiServer"]["extraArgs"] + if isinstance(apiserver_actual_args, list): + # Convert list of dictionaries to a single dictionary + apiserver_actual_args = {arg['name']: arg['value'] for arg in apiserver_actual_args} actual_state = "disabled" if "admission-control-config-file" in apiserver_actual_args and ( diff --git a/kubemarine/procedures/upgrade.py b/kubemarine/procedures/upgrade.py index 5bb6ed472..e1265fd05 100755 --- a/kubemarine/procedures/upgrade.py +++ b/kubemarine/procedures/upgrade.py @@ -93,6 +93,20 @@ def edit_kube_proxy_conntrack_min(kube_proxy_cm: dict) -> dict: preconfigure_components.append('kube-proxy') preconfigure_functions['kube-proxy'] = edit_kube_proxy_conntrack_min + if kubernetes.components.control_plane_kubelet_local_mode(cluster): + + # featureGates field is changed for kubernetes >= 1.31 + # See kubernetes.enrich_control_plane_kubelet_local_mode() for details + def apply_kubelet_local_mode(cluster_config: dict) -> dict: + feature_gates = cluster.inventory["services"]["kubeadm"].get("featureGates") + if feature_gates is not None: + cluster_config["featureGates"] = feature_gates + + return cluster_config + + preconfigure_components.append('kube-apiserver') + preconfigure_functions['kubeadm-config'] = apply_kubelet_local_mode + if preconfigure_components: upgrade_group.call(kubernetes.components.reconfigure_components, components=preconfigure_components, edit_functions=preconfigure_functions) diff --git a/kubemarine/resources/configurations/compatibility/internal/kubernetes_images.yaml b/kubemarine/resources/configurations/compatibility/internal/kubernetes_images.yaml index c1584f733..d28333de5 100644 --- a/kubemarine/resources/configurations/compatibility/internal/kubernetes_images.yaml +++ b/kubemarine/resources/configurations/compatibility/internal/kubernetes_images.yaml @@ -41,6 +41,8 @@ kube-apiserver: version: v1.30.1 v1.30.3: version: v1.30.3 + v1.31.1: + version: v1.31.1 kube-controller-manager: v1.26.3: version: v1.26.3 @@ -82,6 +84,8 @@ kube-controller-manager: version: v1.30.1 v1.30.3: version: v1.30.3 + v1.31.1: + version: v1.31.1 kube-scheduler: v1.26.3: version: v1.26.3 @@ -123,6 +127,8 @@ kube-scheduler: version: v1.30.1 v1.30.3: version: v1.30.3 + v1.31.1: + version: v1.31.1 kube-proxy: v1.26.3: version: v1.26.3 @@ -164,6 +170,8 @@ kube-proxy: version: v1.30.1 v1.30.3: version: v1.30.3 + v1.31.1: + version: v1.31.1 pause: v1.26.3: version: '3.9' @@ -205,6 +213,8 @@ pause: version: '3.9' v1.30.3: version: '3.9' + v1.31.1: + version: '3.10' etcd: v1.26.3: version: 3.5.6-0 @@ -246,6 +256,8 @@ etcd: version: 3.5.12-0 v1.30.3: version: 3.5.12-0 + v1.31.1: + version: 3.5.15-0 coredns/coredns: v1.26.3: version: v1.9.3 @@ -287,3 +299,5 @@ coredns/coredns: version: v1.11.1 v1.30.3: version: v1.11.1 + v1.31.1: + version: v1.11.3 diff --git a/kubemarine/resources/configurations/compatibility/internal/packages.yaml b/kubemarine/resources/configurations/compatibility/internal/packages.yaml index e879d4436..e34f949c2 100644 --- a/kubemarine/resources/configurations/compatibility/internal/packages.yaml +++ b/kubemarine/resources/configurations/compatibility/internal/packages.yaml @@ -45,6 +45,8 @@ containerd: version_debian: 1.6.* v1.30.3: version_debian: 1.6.* + v1.31.1: + version_debian: 1.6.* containerdio: v1.26.3: version_rhel: 1.6* @@ -126,6 +128,10 @@ containerdio: version_rhel: 1.6* version_rhel8: 1.6* version_rhel9: 1.6* + v1.31.1: + version_rhel: 1.6* + version_rhel8: 1.6* + version_rhel9: 1.6* haproxy: version_rhel: 1.8* version_rhel8: 1.8* diff --git a/kubemarine/resources/configurations/compatibility/internal/plugins.yaml b/kubemarine/resources/configurations/compatibility/internal/plugins.yaml index 95ba434db..f36c893df 100644 --- a/kubemarine/resources/configurations/compatibility/internal/plugins.yaml +++ b/kubemarine/resources/configurations/compatibility/internal/plugins.yaml @@ -45,6 +45,8 @@ calico: version: v3.27.3 v1.30.3: version: v3.28.1 + v1.31.1: + version: v3.28.1 nginx-ingress-controller: v1.26.3: version: v1.4.0 @@ -106,6 +108,9 @@ nginx-ingress-controller: v1.30.3: version: v1.11.1 webhook-version: v1.4.1 + v1.31.1: + version: v1.11.1 + webhook-version: v1.4.1 kubernetes-dashboard: v1.26.3: version: v2.7.0 @@ -167,6 +172,9 @@ kubernetes-dashboard: v1.30.3: version: v2.7.0 metrics-scraper-version: v1.0.8 + v1.31.1: + version: v2.7.0 + metrics-scraper-version: v1.0.8 local-path-provisioner: v1.26.3: version: v0.0.23 @@ -228,3 +236,6 @@ local-path-provisioner: v1.30.3: version: v0.0.27 busybox-version: 1.34.1 + v1.31.1: + version: v0.0.27 + busybox-version: 1.34.1 diff --git a/kubemarine/resources/configurations/compatibility/internal/thirdparties.yaml b/kubemarine/resources/configurations/compatibility/internal/thirdparties.yaml index eaab64c8f..8ca725d20 100644 --- a/kubemarine/resources/configurations/compatibility/internal/thirdparties.yaml +++ b/kubemarine/resources/configurations/compatibility/internal/thirdparties.yaml @@ -42,6 +42,8 @@ kubeadm: sha1: 85385f4b78b79bd1cd4d1ad5244422d372d5f758 v1.30.3: sha1: f840e75f5dc1001ebdd7e286c0e87e1090df011b + v1.31.1: + sha1: 0a682af6436ce4e7188f93ddeebff5c2f3be1592 kubelet: v1.26.3: sha1: 5fe320fedaabb91d3770da19135412b7454bb28b @@ -83,6 +85,8 @@ kubelet: sha1: c62da6ab918b8e56d7c9b77e642ffc73ffdbffac v1.30.3: sha1: fbae53efc43ec715a45b05415294ab991ea087a2 + v1.31.1: + sha1: fc7d0a9859c97ec2a2a4ac9ec1814b131e8d875f kubectl: v1.26.3: sha1: 56916d87c3caef05489db932fd9e48d32ebdf634 @@ -124,6 +128,8 @@ kubectl: sha1: bced94239f1dbdb04d3a661a067bf9587865b6e8 v1.30.3: sha1: 097d6b02fabb284418a9c95ea81fa86fc3c85bb7 + v1.31.1: + sha1: a0fd9dc942f533e2bdeaa4b2691fc408e334f922 calicoctl: # calicoctl version is duplicated from kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml # It also corresponds to the plugin version in kubemarine/resources/configurations/compatibility/internal/plugins.yaml @@ -187,6 +193,9 @@ calicoctl: v1.30.3: version: v3.28.1 sha1: 80f164a8248b8fa501f35f12cbcac0b059e665e2 + v1.31.1: + version: v3.28.1 + sha1: 80f164a8248b8fa501f35f12cbcac0b059e665e2 crictl: # crictl version is duplicated from kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml # for backward compatibility with clusters in a private environment. @@ -250,3 +259,6 @@ crictl: v1.30.3: version: v1.30.0 sha1: c81e76d5d4bf64d6b513485490722d2fc0a9a83b + v1.31.1: + version: v1.30.0 + sha1: c81e76d5d4bf64d6b513485490722d2fc0a9a83b diff --git a/kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml b/kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml index c4a3b7d60..6b3749200 100644 --- a/kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml +++ b/kubemarine/resources/configurations/compatibility/kubernetes_versions.yaml @@ -10,6 +10,8 @@ kubernetes_versions: supported: true v1.30: supported: true + v1.31: + supported: true compatibility_map: # This section should be changed manually. v1.26.3: @@ -132,7 +134,12 @@ compatibility_map: kubernetes-dashboard: v2.7.0 local-path-provisioner: v0.0.27 crictl: v1.30.0 - + v1.31.1: + calico: v3.28.1 + nginx-ingress-controller: v1.11.1 + kubernetes-dashboard: v2.7.0 + local-path-provisioner: v0.0.27 + crictl: v1.30.0 # After any change, please run scripts/thirdparties/sync.py # The following optional keys are supported in addition to the 5 required software keys: diff --git a/kubemarine/resources/configurations/globals.yaml b/kubemarine/resources/configurations/globals.yaml index 8ed0df7eb..b14e1409a 100644 --- a/kubemarine/resources/configurations/globals.yaml +++ b/kubemarine/resources/configurations/globals.yaml @@ -128,19 +128,19 @@ thirdparties: /usr/bin/kubeadm: software_name: kubeadm source_prefix: - public: https://storage.googleapis.com/kubernetes-release/release + public: https://dl.k8s.io private: '{registry}/kubernetes/kubeadm' relative_path: '{version}/bin/linux/amd64/kubeadm' /usr/bin/kubelet: software_name: kubelet source_prefix: - public: https://storage.googleapis.com/kubernetes-release/release + public: https://dl.k8s.io private: '{registry}/kubernetes/kubelet' relative_path: '{version}/bin/linux/amd64/kubelet' /usr/bin/kubectl: software_name: kubectl source_prefix: - public: https://storage.googleapis.com/kubernetes-release/release + public: https://dl.k8s.io private: '{registry}/kubernetes/kubectl' relative_path: '{version}/bin/linux/amd64/kubectl' /usr/bin/calicoctl: diff --git a/kubemarine/resources/schemas/definitions/services/kubeadm.json b/kubemarine/resources/schemas/definitions/services/kubeadm.json index f9ca992ef..8d3a5ca59 100644 --- a/kubemarine/resources/schemas/definitions/services/kubeadm.json +++ b/kubemarine/resources/schemas/definitions/services/kubeadm.json @@ -48,7 +48,10 @@ "$ref": "#/definitions/Etcd" }, "apiVersion": {"type": ["string"], "default": "kubeadm.k8s.io/v1beta2"}, - "kind": {"enum": ["ClusterConfiguration"], "default": "ClusterConfiguration"} + "kind": {"enum": ["ClusterConfiguration"], "default": "ClusterConfiguration"}, + "featureGates": { + "$ref": "#/definitions/FeatureGates" + } }, "definitions": { "ApiServer": { @@ -172,6 +175,15 @@ }, "required": ["name", "hostPath", "mountPath"], "additionalProperties": false + }, + "FeatureGates": { + "type": "object", + "properties": { + "ControlPlaneKubeletLocalMode": { + "type": "boolean" + } + }, + "additionalProperties": true } } } diff --git a/test/unit/core/test_env.py b/test/unit/core/test_env.py index 825a4d5bc..b345d2a86 100644 --- a/test/unit/core/test_env.py +++ b/test/unit/core/test_env.py @@ -156,7 +156,7 @@ def test_kubernetes_version_env_variable(self): inventory = self.resources.working_inventory self.assertEqual(kubernetes_version, inventory['services']['kubeadm']['kubernetesVersion']) - expected_source = (f'https://storage.googleapis.com/kubernetes-release/release/' + expected_source = (f'https://dl.k8s.io/' f'{kubernetes_version}/bin/linux/amd64/kubeadm') self.assertEqual(expected_source, inventory['services']['thirdparties']['/usr/bin/kubeadm']['source']) @@ -183,7 +183,7 @@ def test_kubernetes_version_upgrade_env_variable(self): inventory = self.resources.working_inventory self.assertEqual(after, inventory['services']['kubeadm']['kubernetesVersion']) - self.assertEqual(f'https://storage.googleapis.com/kubernetes-release/release/{after}/bin/linux/amd64/kubeadm', + self.assertEqual(f'https://dl.k8s.io/{after}/bin/linux/amd64/kubeadm', inventory['services']['thirdparties']['/usr/bin/kubeadm']['source']) self.assertEqual('containerd_new', inventory['services']['packages']['associations']['rhel']['containerd']['package_name']) diff --git a/test/unit/test_kubernetes_components.py b/test/unit/test_kubernetes_components.py index 9a1bdb2f2..012c4279e 100644 --- a/test/unit/test_kubernetes_components.py +++ b/test/unit/test_kubernetes_components.py @@ -123,6 +123,40 @@ def _test_merge_with_inventory(self, config: dict): self.assertEqual(True, config.get('nested', {}).get('untouched')) self.assertEqual([2], config.get('array')) + def test_kubelet_local_mode_enrichment(self): + # No featureGates for kubernetes <= 1.30 + inventory = demo.generate_inventory(**demo.ALLINONE) + inventory['services'].setdefault('kubeadm', {})['kubernetesVersion'] = 'v1.30.3' + cluster = demo.new_cluster(inventory) + kubeadm = cluster.inventory['services']['kubeadm'] + self.assertIsNone(kubeadm.get('featureGates')) + + # Enriched featureGates.ControlPlaneKubeletLocalMode=true for kubernetes 1.31+ + inventory = demo.generate_inventory(**demo.ALLINONE) + inventory['services'].setdefault('kubeadm', {})['kubernetesVersion'] = 'v1.31.1' + cluster = demo.new_cluster(inventory) + kubeadm = cluster.inventory['services']['kubeadm'] + self.assertIsNotNone(kubeadm.get('featureGates')) + self.assertTrue(kubeadm['featureGates'].get('ControlPlaneKubeletLocalMode')) + + # Enriched featureGates.ControlPlaneKubeletLocalMode=true for kubernetes 1.31+ with not empty featureGates + inventory = demo.generate_inventory(**demo.ALLINONE) + inventory['services'].setdefault('kubeadm', {})['kubernetesVersion'] = 'v1.31.1' + inventory['services'].setdefault('kubeadm', {}).setdefault('featureGates', {})['foo'] = 'bar' + cluster = demo.new_cluster(inventory) + kubeadm = cluster.inventory['services']['kubeadm'] + self.assertIsNotNone(kubeadm.get('featureGates')) + self.assertEqual('bar', kubeadm['featureGates'].get('foo')) + self.assertTrue(kubeadm['featureGates'].get('ControlPlaneKubeletLocalMode')) + + # Do not change featureGates.ControlPlaneKubeletLocalMode=true for kubernetes 1.31+ if value is overridden + inventory = demo.generate_inventory(**demo.ALLINONE) + inventory['services'].setdefault('kubeadm', {})['kubernetesVersion'] = 'v1.31.1' + inventory['services'].setdefault('kubeadm', {}).setdefault('featureGates', {})['ControlPlaneKubeletLocalMode'] = False + cluster = demo.new_cluster(inventory) + kubeadm = cluster.inventory['services']['kubeadm'] + self.assertIsNotNone(kubeadm.get('featureGates')) + self.assertFalse(kubeadm['featureGates'].get('ControlPlaneKubeletLocalMode')) class WaitForPodsTest(unittest.TestCase): def setUp(self):