diff --git a/cmd/controller/controller.go b/cmd/controller/controller.go index 7503fd4fdb0f..d703e6a1a063 100644 --- a/cmd/controller/controller.go +++ b/cmd/controller/controller.go @@ -667,7 +667,7 @@ func (c *command) startWorker(ctx context.Context, nodeName apitypes.NodeName, k // opts to start the worker. Needs to be a copy so the original token and // possibly other args won't get messed up. wc := workercmd.Command(*(*config.CLIOptions)(c)) - wc.Labels = append(wc.Labels, fields.OneTermEqualSelector(constant.K0SNodeRoleLabel, "control-plane").String()) + wc.Labels[constant.K0SNodeRoleLabel] = "control-plane" if opts.Mode() == config.ControllerPlusWorkerMode && !opts.NoTaints { key := path.Join(constant.NodeRoleLabelNamespace, "master") taint := fields.OneTermEqualSelector(key, ":NoSchedule") diff --git a/cmd/controller/controller_test.go b/cmd/controller/controller_test.go index f06276648ee7..71a35c0b0ec2 100644 --- a/cmd/controller/controller_test.go +++ b/cmd/controller/controller_test.go @@ -80,7 +80,7 @@ Flags: --kube-controller-manager-extra-args string extra args for kube-controller-manager --kubelet-extra-args string extra args for kubelet --kubelet-root-dir string Kubelet root directory for k0s - --labels strings Node labels, list of key=value pairs + --labels mapStringString Node labels, list of key=value pairs -l, --logging stringToString Logging Levels for the different components (default [containerd=info,etcd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1,kube-scheduler=1,kubelet=1]) --no-taints disable default taints for controller node --profile string worker profile to use on the node (default "default") diff --git a/cmd/install/controller_test.go b/cmd/install/controller_test.go index 5f2f2b19164d..3a6fd24b636c 100644 --- a/cmd/install/controller_test.go +++ b/cmd/install/controller_test.go @@ -73,7 +73,7 @@ Flags: --kube-controller-manager-extra-args string extra args for kube-controller-manager --kubelet-extra-args string extra args for kubelet --kubelet-root-dir string Kubelet root directory for k0s - --labels strings Node labels, list of key=value pairs + --labels mapStringString Node labels, list of key=value pairs -l, --logging stringToString Logging Levels for the different components (default [containerd=info,etcd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1,kube-scheduler=1,kubelet=1]) --no-taints disable default taints for controller node --profile string worker profile to use on the node (default "default") diff --git a/pkg/component/worker/kubelet.go b/pkg/component/worker/kubelet.go index 2287c43d5f6d..fef78d255a4c 100644 --- a/pkg/component/worker/kubelet.go +++ b/pkg/component/worker/kubelet.go @@ -41,6 +41,7 @@ import ( corev1 "k8s.io/api/core/v1" apitypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/validation" + cliflag "k8s.io/component-base/cli/flag" kubeletv1beta1 "k8s.io/kubelet/config/v1beta1" "github.com/sirupsen/logrus" @@ -58,7 +59,7 @@ type Kubelet struct { StaticPods StaticPods LogLevel string ClusterDNS string - Labels []string + Labels map[string]string Taints []string ExtraArgs stringmap.StringMap DualStackEnabled bool @@ -140,7 +141,7 @@ func (k *Kubelet) Start(ctx context.Context) error { } if len(k.Labels) > 0 { - args["--node-labels"] = strings.Join(k.Labels, ",") + args["--node-labels"] = ((*cliflag.ConfigurationMap)(&k.Labels)).String() } if k.DualStackEnabled && k.ExtraArgs["--node-ip"] == "" { diff --git a/pkg/config/cli.go b/pkg/config/cli.go index 3389c8acf30a..5550599a06dd 100644 --- a/pkg/config/cli.go +++ b/pkg/config/cli.go @@ -26,6 +26,8 @@ import ( "github.com/k0sproject/k0s/pkg/constant" "github.com/k0sproject/k0s/pkg/k0scloudprovider" + cliflag "k8s.io/component-base/cli/flag" + "github.com/spf13/pflag" ) @@ -75,7 +77,7 @@ type WorkerOptions struct { LogLevels LogLevels CriSocket string KubeletExtraArgs string - Labels []string + Labels map[string]string Taints []string TokenFile string TokenArg string @@ -243,12 +245,17 @@ func GetWorkerFlags() *pflag.FlagSet { f.Deprecated = "it has no effect and will be removed in a future release" }) + if workerOpts.Labels == nil { + // cliflag.ConfigurationMap expects the map to be non-nil. + workerOpts.Labels = make(map[string]string) + } + flagset.String("kubelet-root-dir", "", "Kubelet root directory for k0s") flagset.StringVar(&workerOpts.WorkerProfile, "profile", "default", "worker profile to use on the node") flagset.BoolVar(&workerOpts.CloudProvider, "enable-cloud-provider", false, "Whether or not to enable cloud provider support in kubelet") flagset.StringVar(&workerOpts.TokenFile, "token-file", "", "Path to the file containing join-token.") flagset.VarP((*logLevelsFlag)(&workerOpts.LogLevels), "logging", "l", "Logging Levels for the different components") - flagset.StringSliceVarP(&workerOpts.Labels, "labels", "", []string{}, "Node labels, list of key=value pairs") + flagset.Var((*cliflag.ConfigurationMap)(&workerOpts.Labels), "labels", "Node labels, list of key=value pairs") flagset.StringSliceVarP(&workerOpts.Taints, "taints", "", []string{}, "Node taints, list of key=value:effect strings") flagset.StringVar(&workerOpts.KubeletExtraArgs, "kubelet-extra-args", "", "extra args for kubelet") flagset.StringVar(&workerOpts.IPTablesMode, "iptables-mode", "", "iptables mode (valid values: nft, legacy, auto). default: auto")