mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	Merge pull request #19498 from pwittrock/nodelabels
Node labels: Remove node-labels-file command line option. Change --n…
This commit is contained in:
		| @@ -84,8 +84,7 @@ type KubeletServer struct { | ||||
| 	NetworkPluginDir               string | ||||
| 	NetworkPluginName              string | ||||
| 	VolumePluginDir                string | ||||
| 	NodeLabels                     []string | ||||
| 	NodeLabelsFile                 string | ||||
| 	NodeLabels                     string | ||||
| 	NodeStatusUpdateFrequency      time.Duration | ||||
| 	OOMScoreAdj                    int | ||||
| 	PodCIDR                        string | ||||
| @@ -165,8 +164,7 @@ func NewKubeletServer() *KubeletServer { | ||||
| 		NetworkPluginDir:            "/usr/libexec/kubernetes/kubelet-plugins/net/exec/", | ||||
| 		NetworkPluginName:           "", | ||||
| 		VolumePluginDir:             "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/", | ||||
| 		NodeLabels:                  []string{}, | ||||
| 		NodeLabelsFile:              "", | ||||
| 		NodeLabels:                  "", | ||||
| 		NodeStatusUpdateFrequency:   10 * time.Second, | ||||
| 		OOMScoreAdj:                 qos.KubeletOOMScoreAdj, | ||||
| 		PodInfraContainerImage:      kubetypes.PodInfraContainerImage, | ||||
| @@ -241,8 +239,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { | ||||
| 	fs.StringVar(&s.MasterServiceNamespace, "master-service-namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") | ||||
| 	fs.IPVar(&s.ClusterDNS, "cluster-dns", s.ClusterDNS, "IP address for a cluster DNS server.  If set, kubelet will configure all containers to use this for DNS resolution in addition to the host's DNS servers") | ||||
| 	fs.DurationVar(&s.StreamingConnectionIdleTimeout, "streaming-connection-idle-timeout", s.StreamingConnectionIdleTimeout, "Maximum time a streaming connection can be idle before the connection is automatically closed.  Example: '5m'") | ||||
| 	fs.StringSliceVar(&s.NodeLabels, "node-label", []string{}, "add labels when registering the node in the cluster, the flag can be used multiple times (key=value)") | ||||
| 	fs.StringVar(&s.NodeLabelsFile, "node-labels-file", "", "the path to a yaml or json file containing a series of key pair labels to apply on node registration") | ||||
| 	fs.StringVar(&s.NodeLabels, "node-labels", s.NodeLabels, "<Warning: Alpha feature> Labels to add when registering the node in the cluster.  Labels must be specified as a json map of key:value pairs.") | ||||
| 	fs.DurationVar(&s.NodeStatusUpdateFrequency, "node-status-update-frequency", s.NodeStatusUpdateFrequency, "Specifies how often kubelet posts node status to master. Note: be cautious when changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller. Default: 10s") | ||||
| 	fs.IntVar(&s.ImageGCHighThresholdPercent, "image-gc-high-threshold", s.ImageGCHighThresholdPercent, "The percent of disk usage after which image garbage collection is always run. Default: 90%") | ||||
| 	fs.IntVar(&s.ImageGCLowThresholdPercent, "image-gc-low-threshold", s.ImageGCLowThresholdPercent, "The percent of disk usage before which image garbage collection is never run. Lowest disk usage to garbage collect to. Default: 80%") | ||||
|   | ||||
| @@ -215,7 +215,6 @@ func UnsecuredKubeletConfig(s *options.KubeletServer) (*KubeletConfig, error) { | ||||
| 		NetworkPluginName:         s.NetworkPluginName, | ||||
| 		NetworkPlugins:            ProbeNetworkPlugins(s.NetworkPluginDir), | ||||
| 		NodeLabels:                s.NodeLabels, | ||||
| 		NodeLabelsFile:            s.NodeLabelsFile, | ||||
| 		NodeStatusUpdateFrequency: s.NodeStatusUpdateFrequency, | ||||
| 		OOMAdjuster:               oom.NewOOMAdjuster(), | ||||
| 		OSInterface:               kubecontainer.RealOS{}, | ||||
| @@ -692,8 +691,7 @@ type KubeletConfig struct { | ||||
| 	NetworkPluginName              string | ||||
| 	NetworkPlugins                 []network.NetworkPlugin | ||||
| 	NodeName                       string | ||||
| 	NodeLabels                     []string | ||||
| 	NodeLabelsFile                 string | ||||
| 	NodeLabels                     string | ||||
| 	NodeStatusUpdateFrequency      time.Duration | ||||
| 	OOMAdjuster                    *oom.OOMAdjuster | ||||
| 	OSInterface                    kubecontainer.OSInterface | ||||
| @@ -783,7 +781,6 @@ func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod | ||||
| 		kc.DiskSpacePolicy, | ||||
| 		kc.Cloud, | ||||
| 		kc.NodeLabels, | ||||
| 		kc.NodeLabelsFile, | ||||
| 		kc.NodeStatusUpdateFrequency, | ||||
| 		kc.ResourceContainer, | ||||
| 		kc.OSInterface, | ||||
|   | ||||
| @@ -114,8 +114,7 @@ kubelet | ||||
|       --network-plugin="": <Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle | ||||
|       --network-plugin-dir="/usr/libexec/kubernetes/kubelet-plugins/net/exec/": <Warning: Alpha feature> The full path of the directory in which to search for network plugins | ||||
|       --node-ip=<nil>: IP address of the node. If set, kubelet will use this IP address for the node | ||||
|       --node-label=[]: add labels when registering the node in the cluster, the flag can be used multiple times (key=value) | ||||
|       --node-labels-file="": the path to a yaml or json file containing a series of key pair labels to apply on node registration | ||||
|       --node-labels="": <Warning: Alpha feature> Labels to add when registering the node in the cluster.  Labels must be specified as a json map of key:value pairs. | ||||
|       --node-status-update-frequency=10s: Specifies how often kubelet posts node status to master. Note: be cautious when changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller. Default: 10s | ||||
|       --oom-score-adj=-999: The oom-score-adj value for kubelet process. Values must be within the range [-1000, 1000] | ||||
|       --outofdisk-transition-frequency=5m0s: Duration for which the kubelet has to wait before transitioning out of out-of-disk node condition status. Default: 5m0s | ||||
| @@ -144,7 +143,7 @@ kubelet | ||||
|       --volume-plugin-dir="/usr/libexec/kubernetes/kubelet-plugins/volume/exec/": <Warning: Alpha feature> The full path of the directory in which to search for additional third party volume plugins | ||||
| ``` | ||||
|  | ||||
| ###### Auto generated by spf13/cobra on 29-Dec-2015 | ||||
| ###### Auto generated by spf13/cobra on 11-Jan-2016 | ||||
|  | ||||
|  | ||||
| <!-- BEGIN MUNGE: GENERATED_ANALYTICS --> | ||||
|   | ||||
| @@ -225,8 +225,7 @@ no-headers | ||||
| no-suggestions | ||||
| node-instance-group | ||||
| node-ip | ||||
| node-label | ||||
| node-labels-file | ||||
| node-labels | ||||
| node-monitor-grace-period | ||||
| node-monitor-period | ||||
| node-name | ||||
|   | ||||
| @@ -17,7 +17,6 @@ limitations under the License. | ||||
| package kubelet | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| @@ -33,6 +32,7 @@ import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"encoding/json" | ||||
| 	"github.com/golang/glog" | ||||
| 	cadvisorapi "github.com/google/cadvisor/info/v1" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| @@ -168,8 +168,7 @@ func NewMainKubelet( | ||||
| 	imageGCPolicy ImageGCPolicy, | ||||
| 	diskSpacePolicy DiskSpacePolicy, | ||||
| 	cloud cloudprovider.Interface, | ||||
| 	nodeLabels []string, | ||||
| 	nodeLabelsFile string, | ||||
| 	nodeLabels string, | ||||
| 	nodeStatusUpdateFrequency time.Duration, | ||||
| 	resourceContainer string, | ||||
| 	osInterface kubecontainer.OSInterface, | ||||
| @@ -292,7 +291,6 @@ func NewMainKubelet( | ||||
| 		cloud:                          cloud, | ||||
| 		nodeRef:                        nodeRef, | ||||
| 		nodeLabels:                     nodeLabels, | ||||
| 		nodeLabelsFile:                 nodeLabelsFile, | ||||
| 		nodeStatusUpdateFrequency:      nodeStatusUpdateFrequency, | ||||
| 		resourceContainer:              resourceContainer, | ||||
| 		os:                             osInterface, | ||||
| @@ -512,10 +510,7 @@ type Kubelet struct { | ||||
| 	nodeInfo               predicates.NodeInfo | ||||
|  | ||||
| 	// a list of node labels to register | ||||
| 	nodeLabels []string | ||||
|  | ||||
| 	// the path to a yaml or json file container series of node labels | ||||
| 	nodeLabelsFile string | ||||
| 	nodeLabels string | ||||
|  | ||||
| 	// Last timestamp when runtime responded on ping. | ||||
| 	// Mutex is used to protect this value. | ||||
| @@ -1025,77 +1020,23 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) { | ||||
| 	return node, nil | ||||
| } | ||||
|  | ||||
| // getNodeLabels is just a wrapper method for the two below, not to duplicate above | ||||
| // getNodeLabels extracts the node labels specified on the command line | ||||
| func (kl *Kubelet) getNodeLabels() (map[string]string, error) { | ||||
| 	var err error | ||||
| 	labels := make(map[string]string, 0) | ||||
|  | ||||
| 	if kl.nodeLabelsFile != "" { | ||||
| 		labels, err = kl.retrieveNodeLabelsFile(kl.nodeLabelsFile) | ||||
| 		if err != nil { | ||||
| 			return labels, err | ||||
| 		} | ||||
| 	} | ||||
| 	// step: apply the command line label - permitted to override those from file | ||||
| 	if len(kl.nodeLabels) > 0 { | ||||
| 		nl, err := kl.retrieveNodeLabels(kl.nodeLabels) | ||||
| 		if err != nil { | ||||
| 			return labels, err | ||||
| 		} | ||||
| 		for k, v := range nl { | ||||
| 			if vl, found := labels[k]; found { | ||||
| 				glog.Warningf("the --node-label %s=%s option will overwrite %s from node-labels-file", k, v, vl) | ||||
| 			} | ||||
| 			labels[k] = v | ||||
| 		} | ||||
| 	if kl.nodeLabels == "" { | ||||
| 		return labels, nil | ||||
| 	} | ||||
| 	rawLabels := make(map[string]json.Number, 0) | ||||
|  | ||||
| 	return labels, nil | ||||
| } | ||||
|  | ||||
| // retrieveNodeLabels extracts the node labels specified on the command line | ||||
| func (kl *Kubelet) retrieveNodeLabels(labels []string) (map[string]string, error) { | ||||
| 	nodeLabels := make(map[string]string, 0) | ||||
|  | ||||
| 	for _, label := range labels { | ||||
| 		items := strings.Split(label, "=") | ||||
| 		if len(items) != 2 { | ||||
| 			return nodeLabels, fmt.Errorf("--node-label %s, should be in the form key=pair", label) | ||||
| 		} | ||||
| 		nodeLabels[strings.TrimSpace(items[0])] = strings.TrimSpace(items[1]) | ||||
| 	} | ||||
|  | ||||
| 	return nodeLabels, nil | ||||
| } | ||||
|  | ||||
| // retrieveNodeLabelsFile reads in and parses the yaml or json node labels file | ||||
| func (kl *Kubelet) retrieveNodeLabelsFile(path string) (map[string]string, error) { | ||||
| 	labels := make(map[string]string, 0) | ||||
| 	kps := make(map[string]interface{}, 0) | ||||
|  | ||||
| 	fd, err := os.Open(path) | ||||
| 	err := yaml.NewYAMLOrJSONDecoder(strings.NewReader(kl.nodeLabels), 12).Decode(&rawLabels) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer fd.Close() | ||||
|  | ||||
| 	err = yaml.NewYAMLOrJSONDecoder(bufio.NewReader(fd), 12).Decode(&kps) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("the --node-labels-file %s content is invalid, %s", path, err) | ||||
| 		return nil, fmt.Errorf("the --node-labels content '%s' is invalid, %s", kl.nodeLabels, err) | ||||
| 	} | ||||
|  | ||||
| 	for k, v := range kps { | ||||
| 		// we ONLY accept key=value pairs, no complex types | ||||
| 		switch v.(type) { | ||||
| 		case string: | ||||
| 			labels[k] = v.(string) | ||||
| 		case float64: | ||||
| 			labels[k] = fmt.Sprintf("%d", v.(float64)) | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("--node-labels-file only supports key:string, not complex values e.g arrays, maps") | ||||
| 		} | ||||
| 	// Parse the labels | ||||
| 	for k, v := range rawLabels { | ||||
| 		labels[k] = v.String() | ||||
| 	} | ||||
|  | ||||
| 	return labels, nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3701,41 +3701,42 @@ func TestGetNodeLabels(t *testing.T) { | ||||
| 	kubelet := newTestKubelet(t).kubelet | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		Expecting    map[string]string | ||||
| 		LabelOptions []string | ||||
| 		FileContent  string | ||||
| 		Ok           bool | ||||
| 		Expecting  map[string]string | ||||
| 		NodeLabels string | ||||
| 		Ok         bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			Ok:           true, | ||||
| 			Expecting:    map[string]string{"key1": "pair1", "key2": "pair2", "key3": "pair3", "key4": "pair4", "key5": "pair5"}, | ||||
| 			LabelOptions: []string{"key5=pair5"}, | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| key2: pair2 | ||||
| key3: pair3 | ||||
| key4: pair4 | ||||
| `, | ||||
| 		}, { | ||||
| 			Ok:           true, | ||||
| 			Expecting:    map[string]string{"key1": "pair1", "key2": "override"}, | ||||
| 			LabelOptions: []string{"key2=override"}, | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| key2: pair2 | ||||
| `, | ||||
| 			Expecting: map[string]string{"key1": "value1", "key2": "2", "key3": "3.3"}, | ||||
| 			NodeLabels: `--- | ||||
| key1: value1 | ||||
| key2: 2 | ||||
| key3: 3.3`, | ||||
| 			Ok: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Expecting: nil, | ||||
| 			NodeLabels: `--- | ||||
| key11: value11 | ||||
| key12: 12 | ||||
| key13: 13.3 | ||||
| key14: | ||||
|   nested_key: nested_value`, | ||||
| 			Ok: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Expecting:  map[string]string{"key21": "value21", "key22": "22", "key23": "23.3"}, | ||||
| 			NodeLabels: `{"key21": "value21", "key22": "22", "key23": "23.3"}`, | ||||
| 			Ok:         true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Expecting:  nil, | ||||
| 			NodeLabels: `{"key31": "value31", "key32": "32", "key33": "33.3", "key34": {"nested_key": "nested_value"}}`, | ||||
| 			Ok:         false, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for i, test := range testCases { | ||||
| 		fd := createTestNodeLabelFile(t, test.FileContent) | ||||
| 		defer func(f *os.File) { | ||||
| 			os.Remove(f.Name()) | ||||
| 		}(fd) | ||||
|  | ||||
| 		kubelet.nodeLabels = test.LabelOptions | ||||
| 		kubelet.nodeLabelsFile = fd.Name() | ||||
|  | ||||
| 		kubelet.nodeLabels = test.NodeLabels | ||||
| 		list, err := kubelet.getNodeLabels() | ||||
| 		if test.Ok && err != nil { | ||||
| 			t.Errorf("test case %d should not have failed, error: %s", i, err) | ||||
| @@ -3746,127 +3747,6 @@ key2: pair2 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRetrieveNodeLabels(t *testing.T) { | ||||
| 	kubelet := newTestKubelet(t).kubelet | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		Expecting    map[string]string | ||||
| 		LabelOptions []string | ||||
| 		Ok           bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			Expecting:    map[string]string{"key1": "pair1", "key2": "pair2", "key3": "pair3", "key4": "pair4"}, | ||||
| 			LabelOptions: []string{"key1=pair1", "key2=pair2", "key3=pair3", "key4=pair4"}, | ||||
| 			Ok:           true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Expecting:    map[string]string{"key1": "pair1"}, | ||||
| 			LabelOptions: []string{"key1=pair1", "key2paiwdsr2"}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for i, test := range testCases { | ||||
| 		list, err := kubelet.retrieveNodeLabels(test.LabelOptions) | ||||
| 		if test.Ok && err != nil { | ||||
| 			t.Errorf("test case %d should not have failed, error: %s", i, err) | ||||
| 		} | ||||
| 		if !reflect.DeepEqual(test.Expecting, list) { | ||||
| 			t.Errorf("test case %d are not the same, %v ~ %v", i, list, test.Expecting) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRetrieveNodeLabelsFile(t *testing.T) { | ||||
| 	kubelet := newTestKubelet(t).kubelet | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		Expecting   map[string]string | ||||
| 		Ok          bool | ||||
| 		FileContent string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			Expecting: map[string]string{"key1": "pair1", "key2": "pair2", "key3": "pair3", "key4": "pair4"}, | ||||
| 			Ok:        true, | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| key2: pair2 | ||||
| key3: pair3 | ||||
| key4: pair4`, | ||||
| 		}, { | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| hash_map: | ||||
|   key2: pair2 | ||||
| `, | ||||
| 		}, { | ||||
| 			Expecting: map[string]string{"key1": "pair1", "key2": "pair2"}, | ||||
| 			Ok:        true, | ||||
| 			FileContent: ` | ||||
|  | ||||
| key1: pair1 | ||||
| key2: pair2 | ||||
| `, | ||||
| 		}, { | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| bad_key_pair | ||||
| `, | ||||
| 		}, { | ||||
| 			Expecting: nil, | ||||
| 			FileContent: `{ | ||||
| 	"key1": "pair1", | ||||
| 	"key2": "pair2", | ||||
| 	"key3": "pair3", | ||||
| 	"key4": { | ||||
| 		"some_key": "some_value" | ||||
| 	} | ||||
| }`, | ||||
| 		}, { | ||||
| 			FileContent: "", | ||||
| 		}, { | ||||
| 			Expecting: map[string]string{"key1": "pair1", "key2": "pair2", "key3": "pair3", "key4": "pair4"}, | ||||
| 			Ok:        true, | ||||
| 			FileContent: `--- | ||||
| key1: pair1 | ||||
| key2: pair2 | ||||
| key3: pair3 | ||||
| key4: pair4 | ||||
| `, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for i, test := range testCases { | ||||
| 		fd := createTestNodeLabelFile(t, test.FileContent) | ||||
| 		defer func(f *os.File) { | ||||
| 			os.Remove(f.Name()) | ||||
| 		}(fd) | ||||
|  | ||||
| 		labels, err := kubelet.retrieveNodeLabelsFile(fd.Name()) | ||||
| 		if test.Ok && err != nil { | ||||
| 			t.Errorf("test case %d should not have returned an error, %s", i, err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if test.Expecting != nil && !reflect.DeepEqual(test.Expecting, labels) { | ||||
| 			t.Errorf("test case %d not as expected, got: %#v, expecting: %#v", i, labels, test.Expecting) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func createTestNodeLabelFile(t *testing.T, content string) *os.File { | ||||
| 	f, err := ioutil.TempFile("", "node_label_file") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("unexpected error creating node_label_file: %v", err) | ||||
| 	} | ||||
| 	f.Close() | ||||
|  | ||||
| 	if err := ioutil.WriteFile(f.Name(), []byte(content), 0700); err != nil { | ||||
| 		t.Fatalf("unexpected error writing node label file: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return f | ||||
| } | ||||
|  | ||||
| func TestMakePortMappings(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		container            *api.Container | ||||
|   | ||||
		Reference in New Issue
	
	Block a user