diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 9eb428d8fa1e..1a12f50decf3 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -54,6 +54,7 @@ import ( "k8s.io/minikube/pkg/minikube/out" "k8s.io/minikube/pkg/minikube/vmpath" "k8s.io/minikube/pkg/util/retry" + "k8s.io/minikube/pkg/version" ) // Bootstrapper is a bootstrapper using kubeadm @@ -230,6 +231,9 @@ func (k *Bootstrapper) StartCluster(cfg config.MachineConfig) error { return errors.Wrap(err, "timed out waiting to elevate kube-system RBAC privileges") } } + if err := k.applyNodeLabels(cfg); err != nil { + glog.Warningf("unable to apply node labels: %v", err) + } if err := bsutil.AdjustResourceLimits(k.c); err != nil { glog.Warningf("unable to adjust resource limits: %v", err) @@ -483,3 +487,25 @@ func (k *Bootstrapper) applyKicOverlay(cfg config.MachineConfig) error { } return nil } + +// applyNodeLabels applies minikube labels to all the nodes +func (k *Bootstrapper) applyNodeLabels(cfg config.MachineConfig) error { + // time cluster was created. time format is based on ISO 8601 (RFC 3339) + // converting - and : to _ because of kubernetes label restriction + createdAtLbl := "minikube.k8s.io/updated_at=" + time.Now().Format("2006_01_02T15_04_05_0700") + verLbl := "minikube.k8s.io/version=" + version.GetVersion() + commitLbl := "minikube.k8s.io/commit=" + version.GetGitCommitID() + nameLbl := "minikube.k8s.io/name=" + cfg.Name + + // example: + // sudo /var/lib/minikube/binaries/v1.17.3/kubectl label nodes minikube.k8s.io/version=v1.7.3 minikube.k8s.io/commit=aa91f39ffbcf27dcbb93c4ff3f457c54e585cf4a-dirty minikube.k8s.io/name=p1 minikube.k8s.io/updated_at=2020_02_20T12_05_35_0700 --all --overwrite --kubeconfig=/var/lib/minikube/kubeconfig + cmd := exec.Command("sudo", + path.Join(vmpath.GuestPersistentDir, "binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl"), + "label", "nodes", verLbl, commitLbl, nameLbl, createdAtLbl, "--all", "--overwrite", + fmt.Sprintf("--kubeconfig=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig"))) + + if _, err := k.c.RunCmd(cmd); err != nil { + return errors.Wrapf(err, "applying node labels") + } + return nil +} diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index 1534abffde52..4469631e2727 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -112,6 +112,7 @@ func TestFunctional(t *testing.T) { {"FileSync", validateFileSync}, {"UpdateContextCmd", validateUpdateContextCmd}, {"DockerEnv", validateDockerEnv}, + {"NodeLabels", validateNodeLabels}, } for _, tc := range tests { tc := tc @@ -123,6 +124,20 @@ func TestFunctional(t *testing.T) { }) } +// validateNodeLabels checks if minikube cluster is created with correct kubernetes's node label +func validateNodeLabels(ctx context.Context, t *testing.T, profile string) { + rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "get", "nodes", "--output=go-template", "--template='{{range $k, $v := (index .items 0).metadata.labels}}{{$k}} {{end}}'")) + if err != nil { + t.Errorf("%s failed: %v", rr.Args, err) + } + expectedLabels := []string{"minikube.k8s.io/commit", "minikube.k8s.io/version", "minikube.k8s.io/updated_at", "minikube.k8s.io/name"} + for _, el := range expectedLabels { + if !strings.Contains(rr.Output(), el) { + t.Errorf("expected to have label %q in node labels: %q", expectedLabels, rr.Output()) + } + } +} + // check functionality of minikube after evaling docker-env func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { mctx, cancel := context.WithTimeout(ctx, 13*time.Second)