k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubeadm/app/phases/kubelet/flags.go (about) 1 /* 2 Copyright 2018 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 kubelet 18 19 import ( 20 "fmt" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "github.com/pkg/errors" 26 27 "k8s.io/klog/v2" 28 29 nodeutil "k8s.io/component-helpers/node/util" 30 kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" 31 "k8s.io/kubernetes/cmd/kubeadm/app/constants" 32 "k8s.io/kubernetes/cmd/kubeadm/app/images" 33 kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" 34 ) 35 36 type kubeletFlagsOpts struct { 37 nodeRegOpts *kubeadmapi.NodeRegistrationOptions 38 pauseImage string 39 registerTaintsUsingFlags bool 40 } 41 42 // GetNodeNameAndHostname obtains the name for this Node using the following precedence 43 // (from lower to higher): 44 // - actual hostname 45 // - NodeRegistrationOptions.Name (same as "--node-name" passed to "kubeadm init/join") 46 // - "hostname-override" flag in NodeRegistrationOptions.KubeletExtraArgs 47 // It also returns the hostname or an error if getting the hostname failed. 48 func GetNodeNameAndHostname(cfg *kubeadmapi.NodeRegistrationOptions) (string, string, error) { 49 hostname, err := nodeutil.GetHostname("") 50 nodeName := hostname 51 if cfg.Name != "" { 52 nodeName = cfg.Name 53 } 54 if name, idx := kubeadmapi.GetArgValue(cfg.KubeletExtraArgs, "hostname-override", -1); idx > -1 { 55 nodeName = name 56 } 57 return nodeName, hostname, err 58 } 59 60 // WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet. 61 // Used at "kubeadm init" and "kubeadm join" time. 62 func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.ClusterConfiguration, nodeReg *kubeadmapi.NodeRegistrationOptions, registerTaintsUsingFlags bool, kubeletDir string) error { 63 flagOpts := kubeletFlagsOpts{ 64 nodeRegOpts: nodeReg, 65 pauseImage: images.GetPauseImage(cfg), 66 registerTaintsUsingFlags: registerTaintsUsingFlags, 67 } 68 stringMap := buildKubeletArgs(flagOpts) 69 argList := kubeadmutil.ArgumentsToCommand(stringMap, nodeReg.KubeletExtraArgs) 70 envFileContent := fmt.Sprintf("%s=%q\n", constants.KubeletEnvFileVariableName, strings.Join(argList, " ")) 71 72 return writeKubeletFlagBytesToDisk([]byte(envFileContent), kubeletDir) 73 } 74 75 // buildKubeletArgsCommon takes a kubeletFlagsOpts object and builds based on that a slice of arguments 76 // that are common to both Linux and Windows 77 func buildKubeletArgsCommon(opts kubeletFlagsOpts) []kubeadmapi.Arg { 78 kubeletFlags := []kubeadmapi.Arg{} 79 kubeletFlags = append(kubeletFlags, kubeadmapi.Arg{Name: "container-runtime-endpoint", Value: opts.nodeRegOpts.CRISocket}) 80 81 // This flag passes the pod infra container image (e.g. "pause" image) to the kubelet 82 // and prevents its garbage collection 83 if opts.pauseImage != "" { 84 kubeletFlags = append(kubeletFlags, kubeadmapi.Arg{Name: "pod-infra-container-image", Value: opts.pauseImage}) 85 } 86 87 if opts.registerTaintsUsingFlags && opts.nodeRegOpts.Taints != nil && len(opts.nodeRegOpts.Taints) > 0 { 88 taintStrs := []string{} 89 for _, taint := range opts.nodeRegOpts.Taints { 90 taintStrs = append(taintStrs, taint.ToString()) 91 } 92 kubeletFlags = append(kubeletFlags, kubeadmapi.Arg{Name: "register-with-taints", Value: strings.Join(taintStrs, ",")}) 93 } 94 95 // Pass the "--hostname-override" flag to the kubelet only if it's different from the hostname 96 nodeName, hostname, err := GetNodeNameAndHostname(opts.nodeRegOpts) 97 if err != nil { 98 klog.Warning(err) 99 } 100 if nodeName != hostname { 101 klog.V(1).Infof("setting kubelet hostname-override to %q", nodeName) 102 kubeletFlags = append(kubeletFlags, kubeadmapi.Arg{Name: "hostname-override", Value: nodeName}) 103 } 104 105 return kubeletFlags 106 } 107 108 // writeKubeletFlagBytesToDisk writes a byte slice down to disk at the specific location of the kubelet flag overrides file 109 func writeKubeletFlagBytesToDisk(b []byte, kubeletDir string) error { 110 kubeletEnvFilePath := filepath.Join(kubeletDir, constants.KubeletEnvFileName) 111 fmt.Printf("[kubelet-start] Writing kubelet environment file with flags to file %q\n", kubeletEnvFilePath) 112 113 // creates target folder if not already exists 114 if err := os.MkdirAll(kubeletDir, 0700); err != nil { 115 return errors.Wrapf(err, "failed to create directory %q", kubeletDir) 116 } 117 if err := os.WriteFile(kubeletEnvFilePath, b, 0644); err != nil { 118 return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", kubeletEnvFilePath) 119 } 120 return nil 121 } 122 123 // buildKubeletArgs takes a kubeletFlagsOpts object and builds based on that a slice of arguments 124 // that should be given to the local kubelet daemon. 125 func buildKubeletArgs(opts kubeletFlagsOpts) []kubeadmapi.Arg { 126 return buildKubeletArgsCommon(opts) 127 }