k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubeadm/app/componentconfigs/kubelet.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package componentconfigs 18 19 import ( 20 "path/filepath" 21 22 "github.com/pkg/errors" 23 clientset "k8s.io/client-go/kubernetes" 24 "k8s.io/klog/v2" 25 kubeletconfig "k8s.io/kubelet/config/v1beta1" 26 "k8s.io/utils/ptr" 27 28 kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" 29 kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" 30 "k8s.io/kubernetes/cmd/kubeadm/app/constants" 31 ) 32 33 const ( 34 // KubeletGroup is a pointer to the used API group name for the kubelet config 35 KubeletGroup = kubeletconfig.GroupName 36 37 // kubeletReadOnlyPort specifies the default insecure http server port 38 // 0 will disable insecure http server. 39 kubeletReadOnlyPort int32 = 0 40 41 // kubeletRotateCertificates specifies the default value to enable certificate rotation 42 kubeletRotateCertificates = true 43 44 // kubeletAuthenticationAnonymousEnabled specifies the default value to disable anonymous access 45 kubeletAuthenticationAnonymousEnabled = false 46 47 // kubeletAuthenticationWebhookEnabled set the default value to enable authentication webhook 48 kubeletAuthenticationWebhookEnabled = true 49 50 // kubeletHealthzBindAddress specifies the default healthz bind address 51 kubeletHealthzBindAddress = "127.0.0.1" 52 53 // kubeletSystemdResolverConfig specifies the default resolver config when systemd service is active 54 kubeletSystemdResolverConfig = "/run/systemd/resolve/resolv.conf" 55 ) 56 57 // kubeletHandler is the handler instance for the kubelet component config 58 var kubeletHandler = handler{ 59 GroupVersion: kubeletconfig.SchemeGroupVersion, 60 AddToScheme: kubeletconfig.AddToScheme, 61 CreateEmpty: func() kubeadmapi.ComponentConfig { 62 return &kubeletConfig{ 63 configBase: configBase{ 64 GroupVersion: kubeletconfig.SchemeGroupVersion, 65 }, 66 } 67 }, 68 fromCluster: kubeletConfigFromCluster, 69 } 70 71 func kubeletConfigFromCluster(h *handler, clientset clientset.Interface, _ *kubeadmapi.ClusterConfiguration) (kubeadmapi.ComponentConfig, error) { 72 configMapName := constants.KubeletBaseConfigurationConfigMap 73 klog.V(1).Infof("attempting to download the KubeletConfiguration from ConfigMap %q", configMapName) 74 cm, err := h.fromConfigMap(clientset, configMapName, constants.KubeletBaseConfigurationConfigMapKey, true) 75 if err != nil { 76 return nil, errors.Wrapf(err, "could not download the kubelet configuration from ConfigMap %q", 77 configMapName) 78 } 79 return cm, nil 80 } 81 82 // kubeletConfig implements the kubeadmapi.ComponentConfig interface for kubelet 83 type kubeletConfig struct { 84 configBase 85 config kubeletconfig.KubeletConfiguration 86 } 87 88 func (kc *kubeletConfig) DeepCopy() kubeadmapi.ComponentConfig { 89 result := &kubeletConfig{} 90 kc.configBase.DeepCopyInto(&result.configBase) 91 kc.config.DeepCopyInto(&result.config) 92 return result 93 } 94 95 func (kc *kubeletConfig) Marshal() ([]byte, error) { 96 return kc.configBase.Marshal(&kc.config) 97 } 98 99 func (kc *kubeletConfig) Unmarshal(docmap kubeadmapi.DocumentMap) error { 100 return kc.configBase.Unmarshal(docmap, &kc.config) 101 } 102 103 func (kc *kubeletConfig) Get() interface{} { 104 return &kc.config 105 } 106 107 func (kc *kubeletConfig) Set(cfg interface{}) { 108 kc.config = *cfg.(*kubeletconfig.KubeletConfiguration) 109 } 110 111 func (kc *kubeletConfig) Default(cfg *kubeadmapi.ClusterConfiguration, _ *kubeadmapi.APIEndpoint, nodeRegOpts *kubeadmapi.NodeRegistrationOptions) { 112 const kind = "KubeletConfiguration" 113 114 if kc.config.FeatureGates == nil { 115 kc.config.FeatureGates = map[string]bool{} 116 } 117 118 if kc.config.StaticPodPath == "" { 119 kc.config.StaticPodPath = kubeadmapiv1.DefaultManifestsDir 120 } else if kc.config.StaticPodPath != kubeadmapiv1.DefaultManifestsDir { 121 warnDefaultComponentConfigValue(kind, "staticPodPath", kubeadmapiv1.DefaultManifestsDir, kc.config.StaticPodPath) 122 } 123 124 clusterDNS := "" 125 dnsIP, err := constants.GetDNSIP(cfg.Networking.ServiceSubnet) 126 if err != nil { 127 clusterDNS = kubeadmapiv1.DefaultClusterDNSIP 128 } else { 129 clusterDNS = dnsIP.String() 130 } 131 132 if kc.config.ClusterDNS == nil { 133 kc.config.ClusterDNS = []string{clusterDNS} 134 } else if len(kc.config.ClusterDNS) != 1 || kc.config.ClusterDNS[0] != clusterDNS { 135 warnDefaultComponentConfigValue(kind, "clusterDNS", []string{clusterDNS}, kc.config.ClusterDNS) 136 } 137 138 if kc.config.ClusterDomain == "" { 139 kc.config.ClusterDomain = cfg.Networking.DNSDomain 140 } else if cfg.Networking.DNSDomain != "" && kc.config.ClusterDomain != cfg.Networking.DNSDomain { 141 warnDefaultComponentConfigValue(kind, "clusterDomain", cfg.Networking.DNSDomain, kc.config.ClusterDomain) 142 } 143 144 // Require all clients to the kubelet API to have client certs signed by the cluster CA 145 clientCAFile := filepath.Join(cfg.CertificatesDir, constants.CACertName) 146 if kc.config.Authentication.X509.ClientCAFile == "" { 147 kc.config.Authentication.X509.ClientCAFile = clientCAFile 148 } else if kc.config.Authentication.X509.ClientCAFile != clientCAFile { 149 warnDefaultComponentConfigValue(kind, "authentication.x509.clientCAFile", clientCAFile, kc.config.Authentication.X509.ClientCAFile) 150 } 151 152 if kc.config.Authentication.Anonymous.Enabled == nil { 153 kc.config.Authentication.Anonymous.Enabled = ptr.To(kubeletAuthenticationAnonymousEnabled) 154 } else if *kc.config.Authentication.Anonymous.Enabled { 155 warnDefaultComponentConfigValue(kind, "authentication.anonymous.enabled", kubeletAuthenticationAnonymousEnabled, *kc.config.Authentication.Anonymous.Enabled) 156 } 157 158 // On every client request to the kubelet API, execute a webhook (SubjectAccessReview request) to the API server 159 // and ask it whether the client is authorized to access the kubelet API 160 if kc.config.Authorization.Mode == "" { 161 kc.config.Authorization.Mode = kubeletconfig.KubeletAuthorizationModeWebhook 162 } else if kc.config.Authorization.Mode != kubeletconfig.KubeletAuthorizationModeWebhook { 163 warnDefaultComponentConfigValue(kind, "authorization.mode", kubeletconfig.KubeletAuthorizationModeWebhook, kc.config.Authorization.Mode) 164 } 165 166 // Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API 167 if kc.config.Authentication.Webhook.Enabled == nil { 168 kc.config.Authentication.Webhook.Enabled = ptr.To(kubeletAuthenticationWebhookEnabled) 169 } else if !*kc.config.Authentication.Webhook.Enabled { 170 warnDefaultComponentConfigValue(kind, "authentication.webhook.enabled", kubeletAuthenticationWebhookEnabled, *kc.config.Authentication.Webhook.Enabled) 171 } 172 173 // Serve a /healthz webserver on localhost:10248 that kubeadm can talk to 174 if kc.config.HealthzBindAddress == "" { 175 kc.config.HealthzBindAddress = kubeletHealthzBindAddress 176 } else if kc.config.HealthzBindAddress != kubeletHealthzBindAddress { 177 warnDefaultComponentConfigValue(kind, "healthzBindAddress", kubeletHealthzBindAddress, kc.config.HealthzBindAddress) 178 } 179 180 if kc.config.HealthzPort == nil { 181 kc.config.HealthzPort = ptr.To[int32](constants.KubeletHealthzPort) 182 } else if *kc.config.HealthzPort != constants.KubeletHealthzPort { 183 warnDefaultComponentConfigValue(kind, "healthzPort", constants.KubeletHealthzPort, *kc.config.HealthzPort) 184 } 185 186 if kc.config.ReadOnlyPort != kubeletReadOnlyPort { 187 warnDefaultComponentConfigValue(kind, "readOnlyPort", kubeletReadOnlyPort, kc.config.ReadOnlyPort) 188 } 189 190 // We cannot show a warning for RotateCertificates==false and we must hardcode it to true. 191 // There is no way to determine if the user has set this or not, given the field is a non-pointer. 192 kc.config.RotateCertificates = kubeletRotateCertificates 193 194 if len(kc.config.CgroupDriver) == 0 { 195 klog.V(1).Infof("the value of KubeletConfiguration.cgroupDriver is empty; setting it to %q", constants.CgroupDriverSystemd) 196 kc.config.CgroupDriver = constants.CgroupDriverSystemd 197 } 198 }