diff --git a/roles/download/templates/kubeadm-images.yaml.j2 b/roles/download/templates/kubeadm-images.yaml.j2 index 452e1644d..b40f2269b 100644 --- a/roles/download/templates/kubeadm-images.yaml.j2 +++ b/roles/download/templates/kubeadm-images.yaml.j2 @@ -1,9 +1,9 @@ -apiVersion: kubeadm.k8s.io/v1beta3 +apiVersion: kubeadm.k8s.io/{{ kubeadm_config_api_version }} kind: InitConfiguration nodeRegistration: criSocket: {{ cri_socket }} --- -apiVersion: kubeadm.k8s.io/v1beta3 +apiVersion: kubeadm.k8s.io/{{ kubeadm_config_api_version }} kind: ClusterConfiguration imageRepository: {{ kube_image_repo }} kubernetesVersion: {{ kube_version }} diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml b/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml index 413d4946c..58a229816 100644 --- a/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml +++ b/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml @@ -32,7 +32,7 @@ - name: Create kubeadm ControlPlane config template: - src: "kubeadm-controlplane.{{ kubeadmConfig_api_version }}.yaml.j2" + src: "kubeadm-controlplane.yaml.j2" dest: "{{ kube_config_dir }}/kubeadm-controlplane.yaml" mode: "0640" backup: true diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml index 53babe9b1..5e8a677e5 100644 --- a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml +++ b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml @@ -88,13 +88,9 @@ kubeadm_config_api_fqdn: "{{ apiserver_loadbalancer_domain_name | default('lb-apiserver.kubernetes.local') }}" when: loadbalancer_apiserver is defined -- name: Set kubeadm api version to v1beta3 - set_fact: - kubeadmConfig_api_version: v1beta3 - - name: Kubeadm | Create kubeadm config template: - src: "kubeadm-config.{{ kubeadmConfig_api_version }}.yaml.j2" + src: "kubeadm-config.{{ kubeadm_config_api_version }}.yaml.j2" dest: "{{ kube_config_dir }}/kubeadm-config.yaml" mode: "0640" diff --git a/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta4.yaml.j2 b/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta4.yaml.j2 new file mode 100644 index 000000000..103ceba05 --- /dev/null +++ b/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta4.yaml.j2 @@ -0,0 +1,545 @@ +apiVersion: kubeadm.k8s.io/v1beta4 +kind: InitConfiguration +{% if kubeadm_token is defined %} +bootstrapTokens: +- token: "{{ kubeadm_token }}" + description: "kubespray kubeadm bootstrap token" + ttl: "24h" +{% endif %} +localAPIEndpoint: + advertiseAddress: {{ kube_apiserver_address }} + bindPort: {{ kube_apiserver_port }} +{% if kubeadm_certificate_key is defined %} +certificateKey: {{ kubeadm_certificate_key }} +{% endif %} +nodeRegistration: +{% if kube_override_hostname | default('') %} + name: "{{ kube_override_hostname }}" +{% endif %} +{% if 'kube_control_plane' in group_names and 'kube_node' not in group_names %} + taints: + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane +{% else %} + taints: [] +{% endif %} + criSocket: {{ cri_socket }} +{% if cloud_provider == "external" %} + kubeletExtraArgs: + - name: cloud-provider + value: external +{% endif %} +{% if kubeadm_patches | length > 0 %} +patches: + directory: {{ kubeadm_patches_dir }} +{% endif %} +--- +apiVersion: kubeadm.k8s.io/v1beta4 +kind: ClusterConfiguration +clusterName: {{ cluster_name }} +etcd: +{% if etcd_deployment_type != "kubeadm" %} + external: + endpoints: +{% for endpoint in etcd_access_addresses.split(',') %} + - {{ endpoint }} +{% endfor %} + caFile: {{ etcd_cert_dir }}/{{ kube_etcd_cacert_file }} + certFile: {{ etcd_cert_dir }}/{{ kube_etcd_cert_file }} + keyFile: {{ etcd_cert_dir }}/{{ kube_etcd_key_file }} +{% elif etcd_deployment_type == "kubeadm" %} + local: + imageRepository: "{{ etcd_image_repo | regex_replace("/etcd$","") }}" + imageTag: "{{ etcd_image_tag }}" + dataDir: "{{ etcd_data_dir }}" + extraArgs: + - name: metrics + value: {{ etcd_metrics }} + - name: election-timeout + value: "{{ etcd_election_timeout }}" + - name: heartbeat-interval + value: "{{ etcd_heartbeat_interval }}" + - name: auto-compaction-retention + value: "{{ etcd_compaction_retention }}" +{% if etcd_listen_metrics_urls is defined %} + - name: listen-metrics-urls + value: "{{ etcd_listen_metrics_urls }}" +{% endif %} +{% if etcd_snapshot_count is defined %} + - name: snapshot-count + value: "{{ etcd_snapshot_count }}" +{% endif %} +{% if etcd_quota_backend_bytes is defined %} + - name: quota-backend-bytes + value: "{{ etcd_quota_backend_bytes }}" +{% endif %} +{% if etcd_max_request_bytes is defined %} + - name: max-request-bytes + value: "{{ etcd_max_request_bytes }}" +{% endif %} +{% if etcd_log_level is defined %} + - name: log-level + value: "{{ etcd_log_level }}" +{% endif %} +{% for key, value in etcd_extra_vars.items() %} + - name: {{ key }} + value: "{{ value }}" +{% endfor %} + - name: + value: + serverCertSANs: +{% for san in etcd_cert_alt_names %} + - "{{ san }}" +{% endfor %} +{% for san in etcd_cert_alt_ips %} + - "{{ san }}" +{% endfor %} + peerCertSANs: +{% for san in etcd_cert_alt_names %} + - "{{ san }}" +{% endfor %} +{% for san in etcd_cert_alt_ips %} + - "{{ san }}" +{% endfor %} +{% endif %} +dns: + imageRepository: {{ coredns_image_repo | regex_replace('/coredns(?!/coredns).*$', '') }} + imageTag: {{ coredns_image_tag }} +networking: + dnsDomain: {{ dns_domain }} + serviceSubnet: "{{ kube_service_addresses }}{{ ',' + kube_service_addresses_ipv6 if enable_dual_stack_networks else '' }}" +{% if kube_network_plugin is defined and kube_network_plugin not in ["kube-ovn"] %} + podSubnet: "{{ kube_pods_subnet }}{{ ',' + kube_pods_subnet_ipv6 if enable_dual_stack_networks else '' }}" +{% endif %} +{% if kubeadm_feature_gates %} +featureGates: +{% for feature in kubeadm_feature_gates %} + {{ feature | replace("=", ": ") }} +{% endfor %} +{% endif %} +kubernetesVersion: {{ kube_version }} +{% if kubeadm_config_api_fqdn is defined %} +controlPlaneEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }} +{% else %} +controlPlaneEndpoint: {{ ip | default(fallback_ip) }}:{{ kube_apiserver_port }} +{% endif %} +certificatesDir: {{ kube_cert_dir }} +imageRepository: {{ kube_image_repo }} +apiServer: + extraArgs: +{% if kube_apiserver_etcd_compaction_interval is defined %} + - name: etcd-compaction-interval + value: "{{ kube_apiserver_etcd_compaction_interval }}" +{% endif %} +{% if kube_apiserver_pod_eviction_not_ready_timeout_seconds is defined %} + - name: default-not-ready-toleration-seconds + value: "{{ kube_apiserver_pod_eviction_not_ready_timeout_seconds }}" +{% endif %} +{% if kube_apiserver_pod_eviction_unreachable_timeout_seconds is defined %} + - name: default-unreachable-toleration-seconds + value: "{{ kube_apiserver_pod_eviction_unreachable_timeout_seconds }}" +{% endif %} +{% if kube_api_anonymous_auth is defined %} + - name: anonymous-auth + value: "{{ kube_api_anonymous_auth }}" +{% endif %} + - name: authorization-mode + value: "{{ authorization_modes | join(',') }}" + - name: bind-address + value: "{{ kube_apiserver_bind_address }}" +{% if kube_apiserver_enable_admission_plugins | length > 0 %} + - name: enable-admission-plugins + value: "{{ kube_apiserver_enable_admission_plugins | join(',') }}" +{% endif %} +{% if kube_apiserver_admission_control_config_file %} + - name: admission-control-config-file + value: "{{ kube_config_dir }}/admission-controls.yaml" +{% endif %} +{% if kube_apiserver_disable_admission_plugins | length > 0 %} + - name: disable-admission-plugins + value: "{{ kube_apiserver_disable_admission_plugins | join(',') }}" +{% endif %} + - name: apiserver-count + value: "{{ kube_apiserver_count }}" + - name: endpoint-reconciler-type + value: lease +{% if etcd_events_cluster_enabled %} + - name: etcd-servers-overrides + value: "/events#{{ etcd_events_access_addresses_semicolon }}" +{% endif %} + - name: service-node-port-range + value: "{{ kube_apiserver_node_port_range }}" + - name: service-cluster-ip-range + value: "{{ kube_service_addresses }}{{ ',' + kube_service_addresses_ipv6 if enable_dual_stack_networks else '' }}" + - name: kubelet-preferred-address-types + value: "{{ kubelet_preferred_address_types }}" + - name: profiling + value: "{{ kube_profiling }}" + - name: request-timeout + value: "{{ kube_apiserver_request_timeout }}" + - name: enable-aggregator-routing + value: "{{ kube_api_aggregator_routing }}" +{% if kube_apiserver_service_account_lookup %} + - name: service-account-lookup + value: "{{ kube_apiserver_service_account_lookup }}" +{% endif %} +{% if kube_oidc_auth | default(false) and kube_oidc_url is defined and kube_oidc_client_id is defined %} + - name: oidc-issuer-url + value: "{{ kube_oidc_url }}" + - name: oidc-client-id + value: "{{ kube_oidc_client_id }}" +{% if kube_oidc_ca_file is defined %} + - name: oidc-ca-file + value: "{{ kube_oidc_ca_file }}" +{% endif %} +{% if kube_oidc_username_claim is defined %} + - name: oidc-username-claim + value: "{{ kube_oidc_username_claim }}" +{% endif %} +{% if kube_oidc_groups_claim is defined %} + - name: oidc-groups-claim + value: "{{ kube_oidc_groups_claim }}" +{% endif %} +{% if kube_oidc_username_prefix is defined %} + - name: oidc-username-prefix + value: "{{ kube_oidc_username_prefix }}" +{% endif %} +{% if kube_oidc_groups_prefix is defined %} + - name: oidc-groups-prefix + value: "{{ kube_oidc_groups_prefix }}" +{% endif %} +{% endif %} +{% if kube_webhook_token_auth | default(false) %} + - name: authentication-token-webhook-config-file + value: "{{ kube_config_dir }}/webhook-token-auth-config.yaml" +{% endif %} +{% if kube_webhook_authorization | default(false) %} + - name: authorization-webhook-config-file + value: "{{ kube_config_dir }}/webhook-authorization-config.yaml" +{% endif %} +{% if kube_encrypt_secret_data %} + - name: encryption-provider-config + value: "{{ kube_cert_dir }}/secrets_encryption.yaml" +{% endif %} + - name: storage-backend + value: "{{ kube_apiserver_storage_backend }}" +{% if kube_api_runtime_config | length > 0 %} + - name: runtime-config + value: "{{ kube_api_runtime_config | join(',') }}" +{% endif %} + - name: allow-privileged + value: "true" +{% if kubernetes_audit or kubernetes_audit_webhook %} + - name: audit-policy-file + value: "{{ audit_policy_file }}" +{% endif %} +{% if kubernetes_audit %} + - name: audit-log-path + value: "{{ audit_log_path }}" + - name: audit-log-maxage + value: "{{ audit_log_maxage }}" + - name: audit-log-maxbackup + value: "{{ audit_log_maxbackups }}" + - name: audit-log-maxsize + value: "{{ audit_log_maxsize }}" +{% endif %} +{% if kubernetes_audit_webhook %} + - name: audit-webhook-config-file + value: "{{ audit_webhook_config_file }}" + - name: audit-webhook-mode + value: "{{ audit_webhook_mode }}" +{% if audit_webhook_mode == "batch" %} + - name: audit-webhook-batch-max-size + value: "{{ audit_webhook_batch_max_size }}" + - name: audit-webhook-batch-max-wait + value: "{{ audit_webhook_batch_max_wait }}" +{% endif %} +{% endif %} +{% for key in kube_kubeadm_apiserver_extra_args %} + - name: "{{ key }}" + value: "{{ kube_kubeadm_apiserver_extra_args[key] }}" +{% endfor %} +{% if kube_apiserver_feature_gates or kube_feature_gates %} + - name: feature-gates + value: "{{ kube_apiserver_feature_gates | default(kube_feature_gates, true) | join(',') }}" +{% endif %} +{% if tls_min_version is defined %} + - name: tls-min-version + value: "{{ tls_min_version }}" +{% endif %} +{% if tls_cipher_suites is defined %} + - name: tls-cipher-suites + value: "{% for tls in tls_cipher_suites %}{{ tls }}{{ ',' if not loop.last else '' }}{% endfor %}" +{% endif %} +{% if event_ttl_duration is defined %} + - name: event-ttl + value: "{{ event_ttl_duration }}" +{% endif %} +{% if kubelet_rotate_server_certificates %} + - name: kubelet-certificate-authority + value: "{{ kube_cert_dir }}/ca.crt" +{% endif %} +{% if kube_apiserver_tracing %} + - name: tracing-config-file + value: "{{ kube_config_dir }}/tracing/apiserver-tracing.yaml" +{% endif %} +{% if kubernetes_audit or kube_token_auth or kube_webhook_token_auth or apiserver_extra_volumes or ssl_ca_dirs | length %} + extraVolumes: +{% if kube_token_auth %} + - name: token-auth-config + hostPath: {{ kube_token_dir }} + mountPath: {{ kube_token_dir }} +{% endif %} +{% if kube_webhook_token_auth | default(false) %} + - name: webhook-token-auth-config + hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml + mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml +{% endif %} +{% if kube_webhook_authorization | default(false) %} + - name: webhook-authorization-config + hostPath: {{ kube_config_dir }}/webhook-authorization-config.yaml + mountPath: {{ kube_config_dir }}/webhook-authorization-config.yaml +{% endif %} +{% if kubernetes_audit or kubernetes_audit_webhook %} + - name: {{ audit_policy_name }} + hostPath: {{ audit_policy_hostpath }} + mountPath: {{ audit_policy_mountpath }} +{% if audit_log_path != "-" %} + - name: {{ audit_log_name }} + hostPath: {{ audit_log_hostpath }} + mountPath: {{ audit_log_mountpath }} + readOnly: false +{% endif %} +{% endif %} +{% if kube_apiserver_admission_control_config_file %} + - name: admission-control-configs + hostPath: {{ kube_config_dir }}/admission-controls + mountPath: {{ kube_config_dir }} + readOnly: false + pathType: DirectoryOrCreate +{% endif %} +{% if kube_apiserver_tracing %} + - name: tracing + hostPath: {{ kube_config_dir }}/tracing + mountPath: {{ kube_config_dir }}/tracing + readOnly: true + pathType: DirectoryOrCreate +{% endif %} +{% for volume in apiserver_extra_volumes %} + - name: {{ volume.name }} + hostPath: {{ volume.hostPath }} + mountPath: {{ volume.mountPath }} + readOnly: {{ volume.readOnly | d(not (volume.writable | d(false))) }} +{% endfor %} +{% if ssl_ca_dirs | length %} +{% for dir in ssl_ca_dirs %} + - name: {{ dir | regex_replace('^/(.*)$', '\\1' ) | regex_replace('/', '-') }} + hostPath: {{ dir }} + mountPath: {{ dir }} + readOnly: true +{% endfor %} +{% endif %} +{% endif %} + certSANs: +{% for san in apiserver_sans %} + - "{{ san }}" +{% endfor %} + timeoutForControlPlane: 5m0s +controllerManager: + extraArgs: + - name: node-monitor-grace-period + value: "{{ kube_controller_node_monitor_grace_period }}" + - name: node-monitor-period + value: "{{ kube_controller_node_monitor_period }}" +{% if kube_network_plugin is defined and kube_network_plugin not in ["kube-ovn"] %} + - name: cluster-cidr + value: "{{ kube_pods_subnet }}{{ ',' + kube_pods_subnet_ipv6 if enable_dual_stack_networks else '' }}" +{% endif %} + - name: service-cluster-ip-range + value: "{{ kube_service_addresses }}{{ ',' + kube_service_addresses_ipv6 if enable_dual_stack_networks else '' }}" +{% if kube_network_plugin is defined and kube_network_plugin == "calico" and not calico_ipam_host_local %} + - name: allocate-node-cidrs + value: "false" +{% else %} +{% if enable_dual_stack_networks %} + - name: node-cidr-mask-size-ipv4 + value: "{{ kube_network_node_prefix }}" + - name: node-cidr-mask-size-ipv6 + value: "{{ kube_network_node_prefix_ipv6 }}" +{% else %} + - name: node-cidr-mask-size + value: "{{ kube_network_node_prefix }}" +{% endif %} +{% endif %} + - name: profiling + value: "{{ kube_profiling }}" + - name: terminated-pod-gc-threshold + value: "{{ kube_controller_terminated_pod_gc_threshold }}" + - name: bind-address + value: "{{ kube_controller_manager_bind_address }}" + - name: leader-elect-lease-duration + value: "{{ kube_controller_manager_leader_elect_lease_duration }}" + - name: leader-elect-renew-deadline + value: "{{ kube_controller_manager_leader_elect_renew_deadline }}" +{% if kube_controller_feature_gates or kube_feature_gates %} + - name: feature-gates + value: "{{ kube_controller_feature_gates | default(kube_feature_gates, true) | join(',') }}" +{% endif %} +{% for key in kube_kubeadm_controller_extra_args %} + - name: "{{ key }}" + value: "{{ kube_kubeadm_controller_extra_args[key] }}" +{% endfor %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "gce"] %} + - name: cloud-provider + value: "{{ cloud_provider }}" + - name: cloud-config + value: "{{ kube_config_dir }}/cloud_config" +{% endif %} +{% if kube_network_plugin is defined and kube_network_plugin not in ["cloud"] %} + - name: configure-cloud-routes + value: "false" +{% endif %} +{% if kubelet_flexvolumes_plugins_dir is defined %} + - name: flex-volume-plugin-dir + value: "{{ kubelet_flexvolumes_plugins_dir }}" +{% endif %} +{% if tls_min_version is defined %} + - name: tls-min-version + value: "{{ tls_min_version }}" +{% endif %} +{% if tls_cipher_suites is defined %} + - name: tls-cipher-suites + value: "{% for tls in tls_cipher_suites %}{{ tls }}{{ ',' if not loop.last else '' }}{% endfor %}" +{% endif %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "gce"] or controller_manager_extra_volumes %} + extraVolumes: +{% if cloud_provider is defined and cloud_provider in ["openstack"] and openstack_cacert is defined %} + - name: openstackcacert + hostPath: "{{ kube_config_dir }}/openstack-cacert.pem" + mountPath: "{{ kube_config_dir }}/openstack-cacert.pem" +{% endif %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "gce"] %} + - name: cloud-config + hostPath: {{ kube_config_dir }}/cloud_config + mountPath: {{ kube_config_dir }}/cloud_config +{% endif %} +{% for volume in controller_manager_extra_volumes %} + - name: {{ volume.name }} + hostPath: {{ volume.hostPath }} + mountPath: {{ volume.mountPath }} + readOnly: {{ volume.readOnly | d(not (volume.writable | d(false))) }} +{% endfor %} +{% endif %} +scheduler: + extraArgs: + - name: bind-address + value: "{{ kube_scheduler_bind_address }}" + - name: config + value: "{{ kube_config_dir }}/kubescheduler-config.yaml" +{% if kube_scheduler_feature_gates or kube_feature_gates %} + - name: feature-gates + value: "{{ kube_scheduler_feature_gates | default(kube_feature_gates, true) | join(',') }}" +{% endif %} + - name: profiling + value: "{{ kube_profiling }}" +{% if kube_kubeadm_scheduler_extra_args | length > 0 %} +{% for key in kube_kubeadm_scheduler_extra_args %} + - name: "{{ key }}" + value: "{{ kube_kubeadm_scheduler_extra_args[key] }}" +{% endfor %} +{% endif %} +{% if tls_min_version is defined %} + - name: tls-min-version + value: "{{ tls_min_version }}" +{% endif %} +{% if tls_cipher_suites is defined %} + - name: tls-cipher-suites + value: "{% for tls in tls_cipher_suites %}{{ tls }}{{ ',' if not loop.last else '' }}{% endfor %}" +{% endif %} + extraVolumes: + - name: kubescheduler-config + hostPath: {{ kube_config_dir }}/kubescheduler-config.yaml + mountPath: {{ kube_config_dir }}/kubescheduler-config.yaml + readOnly: true +{% if scheduler_extra_volumes %} +{% for volume in scheduler_extra_volumes %} + - name: {{ volume.name }} + hostPath: {{ volume.hostPath }} + mountPath: {{ volume.mountPath }} + readOnly: {{ volume.readOnly | d(not (volume.writable | d(false))) }} +{% endfor %} +{% endif %} +--- +apiVersion: kubeproxy.config.k8s.io/v1alpha1 +kind: KubeProxyConfiguration +bindAddress: {{ kube_proxy_bind_address }} +clientConnection: + acceptContentTypes: {{ kube_proxy_client_accept_content_types }} + burst: {{ kube_proxy_client_burst }} + contentType: {{ kube_proxy_client_content_type }} + kubeconfig: {{ kube_proxy_client_kubeconfig }} + qps: {{ kube_proxy_client_qps }} +{% if kube_network_plugin is defined and kube_network_plugin not in ["kube-ovn"] %} +clusterCIDR: "{{ kube_pods_subnet }}{{ ',' + kube_pods_subnet_ipv6 if enable_dual_stack_networks else '' }}" +{% endif %} +configSyncPeriod: {{ kube_proxy_config_sync_period }} +conntrack: + maxPerCore: {{ kube_proxy_conntrack_max_per_core }} + min: {{ kube_proxy_conntrack_min }} + tcpCloseWaitTimeout: {{ kube_proxy_conntrack_tcp_close_wait_timeout }} + tcpEstablishedTimeout: {{ kube_proxy_conntrack_tcp_established_timeout }} +enableProfiling: {{ kube_proxy_enable_profiling }} +healthzBindAddress: {{ kube_proxy_healthz_bind_address }} +hostnameOverride: "{{ kube_override_hostname }}" +iptables: + masqueradeAll: {{ kube_proxy_masquerade_all }} + masqueradeBit: {{ kube_proxy_masquerade_bit }} + minSyncPeriod: {{ kube_proxy_min_sync_period }} + syncPeriod: {{ kube_proxy_sync_period }} +ipvs: + excludeCIDRs: {{ kube_proxy_exclude_cidrs }} + minSyncPeriod: {{ kube_proxy_min_sync_period }} + scheduler: {{ kube_proxy_scheduler }} + syncPeriod: {{ kube_proxy_sync_period }} + strictARP: {{ kube_proxy_strict_arp }} + tcpTimeout: {{ kube_proxy_tcp_timeout }} + tcpFinTimeout: {{ kube_proxy_tcp_fin_timeout }} + udpTimeout: {{ kube_proxy_udp_timeout }} +metricsBindAddress: {{ kube_proxy_metrics_bind_address }} +mode: {{ kube_proxy_mode }} +nodePortAddresses: {{ kube_proxy_nodeport_addresses }} +oomScoreAdj: {{ kube_proxy_oom_score_adj }} +portRange: {{ kube_proxy_port_range }} +{% if kube_proxy_feature_gates or kube_feature_gates %} +{% set feature_gates = ( kube_proxy_feature_gates | default(kube_feature_gates, true) ) %} +featureGates: +{% for feature in feature_gates %} + {{ feature | replace("=", ": ") }} +{% endfor %} +{% endif %} +{# DNS settings for kubelet #} +{% if enable_nodelocaldns %} +{% set kubelet_cluster_dns = [nodelocaldns_ip] %} +{% elif dns_mode in ['coredns'] %} +{% set kubelet_cluster_dns = [skydns_server] %} +{% elif dns_mode == 'coredns_dual' %} +{% set kubelet_cluster_dns = [skydns_server,skydns_server_secondary] %} +{% elif dns_mode == 'manual' %} +{% set kubelet_cluster_dns = [manual_dns_server] %} +{% else %} +{% set kubelet_cluster_dns = [] %} +{% endif %} +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +clusterDNS: +{% for dns_address in kubelet_cluster_dns %} +- {{ dns_address }} +{% endfor %} +{% if kubelet_feature_gates or kube_feature_gates %} +{% set feature_gates = ( kubelet_feature_gates | default(kube_feature_gates, true) ) %} +featureGates: +{% for feature in feature_gates %} + {{ feature | replace("=", ": ") }} +{% endfor %} +{% endif %} diff --git a/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 b/roles/kubernetes/control-plane/templates/kubeadm-controlplane.yaml.j2 similarity index 95% rename from roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 rename to roles/kubernetes/control-plane/templates/kubeadm-controlplane.yaml.j2 index 59759188d..24a6c23c0 100644 --- a/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 +++ b/roles/kubernetes/control-plane/templates/kubeadm-controlplane.yaml.j2 @@ -1,4 +1,4 @@ -apiVersion: kubeadm.k8s.io/v1beta3 +apiVersion: kubeadm.k8s.io/{{ kubeadm_config_api_version }} kind: JoinConfiguration discovery: {% if kubeadm_use_file_discovery %} diff --git a/roles/kubernetes/kubeadm/tasks/main.yml b/roles/kubernetes/kubeadm/tasks/main.yml index cb29e2a6a..6b575df0f 100644 --- a/roles/kubernetes/kubeadm/tasks/main.yml +++ b/roles/kubernetes/kubeadm/tasks/main.yml @@ -53,10 +53,6 @@ kubeadm_token: "{{ temp_token.stdout }}" when: kubeadm_token is not defined -- name: Set kubeadm api version to v1beta3 - set_fact: - kubeadmConfig_api_version: v1beta3 - - name: Get kubeconfig for join discovery process command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'" register: kubeconfig_file_discovery @@ -77,7 +73,7 @@ - name: Create kubeadm client config template: - src: "kubeadm-client.conf.{{ kubeadmConfig_api_version }}.j2" + src: "kubeadm-client.conf.j2" dest: "{{ kube_config_dir }}/kubeadm-client.conf" backup: true mode: "0640" diff --git a/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 b/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2 similarity index 95% rename from roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 rename to roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2 index 5016df9c3..a4e014ca7 100644 --- a/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 +++ b/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2 @@ -1,5 +1,5 @@ --- -apiVersion: kubeadm.k8s.io/v1beta3 +apiVersion: kubeadm.k8s.io/{{ kubeadm_config_api_version }} kind: JoinConfiguration discovery: {% if kubeadm_use_file_discovery %} diff --git a/roles/kubespray-defaults/defaults/main/main.yml b/roles/kubespray-defaults/defaults/main/main.yml index 939027f87..fc978e7d2 100644 --- a/roles/kubespray-defaults/defaults/main/main.yml +++ b/roles/kubespray-defaults/defaults/main/main.yml @@ -26,6 +26,10 @@ kube_version_min_required: v1.29.0 ## Kube Proxy mode One of ['iptables', 'ipvs'] kube_proxy_mode: ipvs +# Kubeadm config api version +# If kube_version is v1.31 or higher, it will be v1beta4, otherwise it will be v1beta3. +kubeadm_config_api_version: "{{ 'v1beta4' if kube_version is version('v1.31.0', '>=') else 'v1beta3' }}" + ## The timeout for init first control-plane kubeadm_init_timeout: 300s