diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index e1fe726cf35..46e84cc94a4 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -84,7 +84,7 @@ type KubeletServer struct { NetworkPluginDir string NetworkPluginName string VolumePluginDir string - NodeLabels string + NodeLabels map[string]string NodeStatusUpdateFrequency time.Duration OOMScoreAdj int PodCIDR string @@ -166,7 +166,7 @@ func NewKubeletServer() *KubeletServer { NetworkPluginDir: "/usr/libexec/kubernetes/kubelet-plugins/net/exec/", NetworkPluginName: "", VolumePluginDir: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/", - NodeLabels: "", + NodeLabels: make(map[string]string), NodeStatusUpdateFrequency: 10 * time.Second, OOMScoreAdj: qos.KubeletOOMScoreAdj, PodInfraContainerImage: kubetypes.PodInfraContainerImage, @@ -243,7 +243,8 @@ 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.StringVar(&s.NodeLabels, "node-labels", s.NodeLabels, " Labels to add when registering the node in the cluster. Labels must be specified as a json map of key:value pairs.") + bindableNodeLabels := util.ConfigurationMap(s.NodeLabels) + fs.Var(&bindableNodeLabels, "node-labels", " Labels to add when registering the node in the cluster. Labels must are key=value pairs seperated by ','.") 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%") diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 222708ac1b6..2010fb21e56 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -698,7 +698,7 @@ type KubeletConfig struct { NetworkPluginName string NetworkPlugins []network.NetworkPlugin NodeName string - NodeLabels string + NodeLabels map[string]string NodeStatusUpdateFrequency time.Duration OOMAdjuster *oom.OOMAdjuster OSInterface kubecontainer.OSInterface diff --git a/docs/admin/kubelet.md b/docs/admin/kubelet.md index f7138091ae2..2050a5575b6 100644 --- a/docs/admin/kubelet.md +++ b/docs/admin/kubelet.md @@ -115,7 +115,7 @@ kubelet --network-plugin="": 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/": The full path of the directory in which to search for network plugins --node-ip=: IP address of the node. If set, kubelet will use this IP address for the node - --node-labels="": Labels to add when registering the node in the cluster. Labels must be specified as a json map of key:value pairs. + --node-labels=: Labels to add when registering the node in the cluster. Labels must are key=value pairs seperated by ','. --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 @@ -145,7 +145,7 @@ kubelet --volume-plugin-dir="/usr/libexec/kubernetes/kubelet-plugins/volume/exec/": The full path of the directory in which to search for additional third party volume plugins ``` -###### Auto generated by spf13/cobra on 12-Jan-2016 +###### Auto generated by spf13/cobra on 14-Jan-2016 diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 713748a91ad..865676bc693 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -32,7 +32,6 @@ import ( "sync" "time" - "encoding/json" "github.com/golang/glog" cadvisorapi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/api" @@ -80,7 +79,6 @@ import ( "k8s.io/kubernetes/pkg/util/selinux" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/validation/field" - "k8s.io/kubernetes/pkg/util/yaml" "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/watch" @@ -168,7 +166,7 @@ func NewMainKubelet( imageGCPolicy ImageGCPolicy, diskSpacePolicy DiskSpacePolicy, cloud cloudprovider.Interface, - nodeLabels string, + nodeLabels map[string]string, nodeStatusUpdateFrequency time.Duration, resourceContainer string, osInterface kubecontainer.OSInterface, @@ -512,7 +510,7 @@ type Kubelet struct { nodeInfo predicates.NodeInfo // a list of node labels to register - nodeLabels string + nodeLabels map[string]string // Last timestamp when runtime responded on ping. // Mutex is used to protect this value. @@ -966,12 +964,8 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) { }, } - labels, err := kl.getNodeLabels() - if err != nil { - return nil, err - } // @question: should this be place after the call to the cloud provider? which also applies labels - for k, v := range labels { + for k, v := range kl.nodeLabels { if cv, found := node.ObjectMeta.Labels[k]; found { glog.Warningf("the node label %s=%s will overwrite default setting %s", k, v, cv) } @@ -1026,26 +1020,6 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) { return node, nil } -// getNodeLabels extracts the node labels specified on the command line -func (kl *Kubelet) getNodeLabels() (map[string]string, error) { - labels := make(map[string]string, 0) - if kl.nodeLabels == "" { - return labels, nil - } - rawLabels := make(map[string]json.Number, 0) - - err := yaml.NewYAMLOrJSONDecoder(strings.NewReader(kl.nodeLabels), 12).Decode(&rawLabels) - if err != nil { - return nil, fmt.Errorf("the --node-labels content '%s' is invalid, %s", kl.nodeLabels, err) - } - - // Parse the labels - for k, v := range rawLabels { - labels[k] = v.String() - } - return labels, nil -} - // registerWithApiserver registers the node with the cluster master. It is safe // to call multiple times, but not concurrently (kl.registrationCompleted is // not locked). diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 4698371ebc1..4c355edde03 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -3726,56 +3726,6 @@ func TestRegisterExistingNodeWithApiserver(t *testing.T) { } } -func TestGetNodeLabels(t *testing.T) { - kubelet := newTestKubelet(t).kubelet - - testCases := []struct { - Expecting map[string]string - NodeLabels string - Ok bool - }{ - { - 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 { - 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) - } - if !reflect.DeepEqual(test.Expecting, list) { - t.Errorf("test case %d are not the same, %v ~ %v", i, list, test.Expecting) - } - } -} - func TestMakePortMappings(t *testing.T) { tests := []struct { container *api.Container