From 810e9e107f450598b2b17efb239b8af5f6a2bda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Wed, 7 Dec 2016 09:21:28 +0200 Subject: [PATCH] Refactor the whole binary, a lot of changes in one commit I know, but I just hacked on this and modified everything I thought was messy or could be done better. Fix boilerplates, comments in the code and make the output of kubeadm more user-friendly Start using HostPKIPath and KubernetesDir everywhere in the code, so they can be changed for real More robust kubeadm reset code now. Removed old glog-things from app.Run() Renamed /etc/kubernetes/cloud-config.json to /etc/kubernetes/cloud-config since it shouldn't be a json file Simplification of the code Less verbose output from master/pki.go Cleaned up dead code Start a small logging/output framework: - fmt.Println("[the-stage-here] Capital first letter of this message. Tell the user what the current state is") - fmt.Printf("[the-stage-here] Capital first letter. Maybe a [%v] in the end if an error should be displayed. Always ends with \n") - fmt.Errorf("Never starts with []. Includes a short error message plus the underlying error in [%v]. Never ends with \n") --- cmd/kubeadm/app/apis/kubeadm/env.go | 34 +++++++-------- cmd/kubeadm/app/apis/kubeadm/types.go | 15 +++---- cmd/kubeadm/app/cmd/cmd.go | 13 +++--- cmd/kubeadm/app/cmd/init.go | 14 ++++-- cmd/kubeadm/app/cmd/join.go | 11 +++-- cmd/kubeadm/app/cmd/reset_test.go | 20 ++++----- cmd/kubeadm/app/cmd/version.go | 2 +- cmd/kubeadm/app/kubeadm.go | 4 -- cmd/kubeadm/app/master/addons.go | 10 ++--- cmd/kubeadm/app/master/apiclient.go | 36 ++++++++------- cmd/kubeadm/app/master/discovery.go | 8 ++-- cmd/kubeadm/app/master/kubeconfig.go | 3 +- cmd/kubeadm/app/master/manifests.go | 63 ++++++++++++--------------- cmd/kubeadm/app/master/pki.go | 29 +++++------- cmd/kubeadm/app/master/tokens.go | 10 ++--- cmd/kubeadm/app/node/bootstrap.go | 19 ++++---- cmd/kubeadm/app/node/csr.go | 12 ++--- cmd/kubeadm/app/node/discovery.go | 18 ++++---- cmd/kubeadm/app/preflight/checks.go | 37 +++++++++++----- cmd/kubeadm/app/util/error.go | 33 +++----------- cmd/kubeadm/app/util/kubeconfig.go | 9 ++-- cmd/kubeadm/app/util/tokens.go | 4 +- cmd/kubeadm/kubeadm.go | 3 -- 23 files changed, 188 insertions(+), 219 deletions(-) diff --git a/cmd/kubeadm/app/apis/kubeadm/env.go b/cmd/kubeadm/app/apis/kubeadm/env.go index 050483513db..c3c18d4b202 100644 --- a/cmd/kubeadm/app/apis/kubeadm/env.go +++ b/cmd/kubeadm/app/apis/kubeadm/env.go @@ -25,21 +25,18 @@ import ( var GlobalEnvParams = SetEnvParams() -// TODO(phase2) use componentconfig +// TODO(phase1+) Move these paramaters to the API group // we need some params for testing etc, let's keep these hidden for now func SetEnvParams() *EnvParams { envParams := map[string]string{ - // TODO(phase1+): Mode prefix and host_pki_path to another place as constants, and use them everywhere - // Right now they're used here and there, but not consequently - "kubernetes_dir": "/etc/kubernetes", - "host_pki_path": "/etc/kubernetes/pki", - "host_etcd_path": "/var/lib/etcd", - "hyperkube_image": "", - "repo_prefix": "gcr.io/google_containers", - "discovery_image": fmt.Sprintf("gcr.io/google_containers/kube-discovery-%s:%s", runtime.GOARCH, "1.0"), - "etcd_image": "", - "component_loglevel": "--v=2", + "kubernetes_dir": "/etc/kubernetes", + "host_pki_path": "/etc/kubernetes/pki", + "host_etcd_path": "/var/lib/etcd", + "hyperkube_image": "", + "repo_prefix": "gcr.io/google_containers", + "discovery_image": fmt.Sprintf("gcr.io/google_containers/kube-discovery-%s:%s", runtime.GOARCH, "1.0"), + "etcd_image": "", } for k := range envParams { @@ -49,13 +46,12 @@ func SetEnvParams() *EnvParams { } return &EnvParams{ - KubernetesDir: envParams["kubernetes_dir"], - HostPKIPath: envParams["host_pki_path"], - HostEtcdPath: envParams["host_etcd_path"], - HyperkubeImage: envParams["hyperkube_image"], - RepositoryPrefix: envParams["repo_prefix"], - DiscoveryImage: envParams["discovery_image"], - EtcdImage: envParams["etcd_image"], - ComponentLoglevel: envParams["component_loglevel"], + KubernetesDir: envParams["kubernetes_dir"], + HostPKIPath: envParams["host_pki_path"], + HostEtcdPath: envParams["host_etcd_path"], + HyperkubeImage: envParams["hyperkube_image"], + RepositoryPrefix: envParams["repo_prefix"], + DiscoveryImage: envParams["discovery_image"], + EtcdImage: envParams["etcd_image"], } } diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index eeef3a4e625..7d4e95d95a4 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -21,14 +21,13 @@ import ( ) type EnvParams struct { - KubernetesDir string - HostPKIPath string - HostEtcdPath string - HyperkubeImage string - RepositoryPrefix string - DiscoveryImage string - EtcdImage string - ComponentLoglevel string + KubernetesDir string + HostPKIPath string + HostEtcdPath string + HyperkubeImage string + RepositoryPrefix string + DiscoveryImage string + EtcdImage string } type MasterConfiguration struct { diff --git a/cmd/kubeadm/app/cmd/cmd.go b/cmd/kubeadm/app/cmd/cmd.go index 4edfac7f1aa..e4b73de0897 100644 --- a/cmd/kubeadm/app/cmd/cmd.go +++ b/cmd/kubeadm/app/cmd/cmd.go @@ -37,14 +37,14 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob │ KUBEADM IS ALPHA, DO NOT USE IT FOR PRODUCTION CLUSTERS! │ │ │ │ But, please try it out! Give us feedback at: │ - │ https://github.com/kubernetes/kubernetes/issues │ + │ https://github.com/kubernetes/kubeadm/issues │ │ and at-mention @kubernetes/sig-cluster-lifecycle │ └──────────────────────────────────────────────────────────┘ Example usage: Create a two-machine cluster with one master (which controls the cluster), - and one node (where workloads, like pods and replica sets run). + and one node (where your workloads, like Pods and ReplicaSets run). ┌──────────────────────────────────────────────────────────┐ │ On the first machine │ @@ -69,11 +69,10 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob // // TODO(phase2) create an abstraction that defines files and the content that needs to // be written to disc and write it all in one go at the end as we have a lot of - // crapy little files written from different parts of this code; this could also - // be useful for testing - // by having this model we can allow users to create some files before `kubeadm init` runs, e.g. PKI assets, we - // would then be able to look at files users has given an diff or validate if those are sane, we could also warn - // if any of the files had been deprecated + // crappy little files written from different parts of this code; this could also + // be useful for testing by having this model we can allow users to create some files before + // `kubeadm init` runs, e.g. PKI assets, we would then be able to look at files users has + // given an diff or validate if those are sane, we could also warn if any of the files had been deprecated cmds.ResetFlags() cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc) diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index ebfa652645f..d7394bfcb92 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -52,7 +52,11 @@ const ( var ( initDoneMsgf = dedent.Dedent(` - Kubernetes master initialised successfully! + Your Kubernetes master has initialized successfully! + + But you still need to deploy a pod network to the cluster. + You should "kubectl apply -f" some pod network yaml file that's listed at: + http://kubernetes.io/docs/admin/addons/ You can now join any number of machines by running the following on each node: @@ -163,6 +167,9 @@ type Init struct { } func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight bool) (*Init, error) { + + fmt.Println("[kubeadm] Bear in mind that kubeadm is in alpha, do not use it in production clusters.") + if cfgPath != "" { b, err := ioutil.ReadFile(cfgPath) if err != nil { @@ -175,7 +182,6 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight // Auto-detect the IP if len(cfg.API.AdvertiseAddresses) == 0 { - // TODO(phase1+) perhaps we could actually grab eth0 and eth1 ip, err := netutil.ChooseHostInterface() if err != nil { return nil, err @@ -196,7 +202,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight return nil, &preflight.PreFlightError{Msg: err.Error()} } } else { - fmt.Println("Skipping pre-flight checks") + fmt.Println("[preflight] Skipping pre-flight checks...") } // Try to start the kubelet service in case it's inactive @@ -257,7 +263,7 @@ func (i *Init) Run(out io.Writer) error { // write a file that has already been written (the kubelet will be up and // running in that case - they'd need to stop the kubelet, remove the file, and // start it again in that case). - // TODO(phase1+) this is no longer the right place to guard agains foo-shooting, + // TODO(phase1+) this is no longer the right place to guard against foo-shooting, // we need to decide how to handle existing files (it may be handy to support // importing existing files, may be we could even make our command idempotant, // or at least allow for external PKI and stuff) diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index b5e288926eb..8fe1cf7018a 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -95,6 +95,9 @@ type Join struct { } func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool) (*Join, error) { + + fmt.Println("[kubeadm] Bear in mind that kubeadm is in alpha, do not use it in production clusters.") + if cfgPath != "" { b, err := ioutil.ReadFile(cfgPath) if err != nil { @@ -110,7 +113,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s } cfg.MasterAddresses = append(cfg.MasterAddresses, args...) if len(cfg.MasterAddresses) > 1 { - return nil, fmt.Errorf("Must not specify more than one master address (see --help)") + return nil, fmt.Errorf("Must not specify more than one master address (see --help)") } if !skipPreFlight { @@ -126,7 +129,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s return nil, &preflight.PreFlightError{Msg: err.Error()} } } else { - fmt.Println("Skipping pre-flight checks") + fmt.Println("[preflight] Skipping pre-flight checks...") } // Try to start the kubelet service in case it's inactive @@ -137,9 +140,9 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s ok, err := kubeadmutil.UseGivenTokenIfValid(&cfg.Secrets) if !ok { if err != nil { - return nil, fmt.Errorf("%v (see --help)\n", err) + return nil, fmt.Errorf("%v (see --help)", err) } - return nil, fmt.Errorf("Must specify --token (see --help)\n") + return nil, fmt.Errorf("Must specify --token (see --help)") } return &Join{cfg: cfg}, nil diff --git a/cmd/kubeadm/app/cmd/reset_test.go b/cmd/kubeadm/app/cmd/reset_test.go index 37dc4631826..bd339cd9431 100644 --- a/cmd/kubeadm/app/cmd/reset_test.go +++ b/cmd/kubeadm/app/cmd/reset_test.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors. +Copyright 2016 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package cmd import ( "io/ioutil" "os" - "path/filepath" + "path" "testing" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" @@ -147,14 +147,14 @@ func TestConfigDirCleaner(t *testing.T) { defer os.RemoveAll(tmpDir) for _, createDir := range test.setupDirs { - err := os.Mkdir(filepath.Join(tmpDir, createDir), 0700) + err := os.Mkdir(path.Join(tmpDir, createDir), 0700) if err != nil { t.Errorf("Unable to setup test config directory: %s", err) } } for _, createFile := range test.setupFiles { - fullPath := filepath.Join(tmpDir, createFile) + fullPath := path.Join(tmpDir, createFile) f, err := os.Create(fullPath) defer f.Close() if err != nil { @@ -166,17 +166,17 @@ func TestConfigDirCleaner(t *testing.T) { // Verify the files we cleanup implicitly in every test: assertExists(t, tmpDir) - assertNotExists(t, filepath.Join(tmpDir, "admin.conf")) - assertNotExists(t, filepath.Join(tmpDir, "kubelet.conf")) - assertDirEmpty(t, filepath.Join(tmpDir, "manifests")) - assertDirEmpty(t, filepath.Join(tmpDir, "pki")) + assertNotExists(t, path.Join(tmpDir, "admin.conf")) + assertNotExists(t, path.Join(tmpDir, "kubelet.conf")) + assertDirEmpty(t, path.Join(tmpDir, "manifests")) + assertDirEmpty(t, path.Join(tmpDir, "pki")) // Verify the files as requested by the test: for _, path := range test.verifyExists { - assertExists(t, filepath.Join(tmpDir, path)) + assertExists(t, path.Join(tmpDir, path)) } for _, path := range test.verifyNotExists { - assertNotExists(t, filepath.Join(tmpDir, path)) + assertNotExists(t, path.Join(tmpDir, path)) } } } diff --git a/cmd/kubeadm/app/cmd/version.go b/cmd/kubeadm/app/cmd/version.go index a5b264495fc..28f5f0c1a18 100644 --- a/cmd/kubeadm/app/cmd/version.go +++ b/cmd/kubeadm/app/cmd/version.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors. +Copyright 2016 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/kubeadm/app/kubeadm.go b/cmd/kubeadm/app/kubeadm.go index 1f992581447..5a764a2cda5 100644 --- a/cmd/kubeadm/app/kubeadm.go +++ b/cmd/kubeadm/app/kubeadm.go @@ -24,13 +24,9 @@ import ( _ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install" "k8s.io/kubernetes/cmd/kubeadm/app/cmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/util/logs" ) func Run() error { - logs.InitLogs() - defer logs.FlushLogs() - // We do not want these flags to show up in --help pflag.CommandLine.MarkHidden("google-json-key") pflag.CommandLine.MarkHidden("log-flush-frequency") diff --git a/cmd/kubeadm/app/master/addons.go b/cmd/kubeadm/app/master/addons.go index c76a1563bcb..b67c5c44476 100644 --- a/cmd/kubeadm/app/master/addons.go +++ b/cmd/kubeadm/app/master/addons.go @@ -288,17 +288,17 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse SetNodeAffinity(&kubeProxyDaemonSet.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity()) if _, err := client.Extensions().DaemonSets(api.NamespaceSystem).Create(kubeProxyDaemonSet); err != nil { - return fmt.Errorf(" failed creating essential kube-proxy addon [%v]", err) + return fmt.Errorf("failed creating essential kube-proxy addon [%v]", err) } - fmt.Println(" created essential addon: kube-proxy") + fmt.Println("[addons] Created essential addon: kube-proxy") kubeDNSDeployment := NewDeployment("kube-dns", 1, createKubeDNSPodSpec(cfg)) SetMasterTaintTolerations(&kubeDNSDeployment.Spec.Template.ObjectMeta) SetNodeAffinity(&kubeDNSDeployment.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity()) if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kubeDNSDeployment); err != nil { - return fmt.Errorf(" failed creating essential kube-dns addon [%v]", err) + return fmt.Errorf("failed creating essential kube-dns addon [%v]", err) } kubeDNSServiceSpec, err := createKubeDNSServiceSpec(cfg) @@ -309,10 +309,10 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse kubeDNSService := NewService("kube-dns", *kubeDNSServiceSpec) kubeDNSService.ObjectMeta.Labels["kubernetes.io/name"] = "KubeDNS" if _, err := client.Services(api.NamespaceSystem).Create(kubeDNSService); err != nil { - return fmt.Errorf(" failed creating essential kube-dns addon [%v]", err) + return fmt.Errorf("failed creating essential kube-dns addon [%v]", err) } - fmt.Println(" created essential addon: kube-dns") + fmt.Println("[addons] Created essential addon: kube-dns") return nil } diff --git a/cmd/kubeadm/app/master/apiclient.go b/cmd/kubeadm/app/master/apiclient.go index f6b5fbf466e..ba2a77f8408 100644 --- a/cmd/kubeadm/app/master/apiclient.go +++ b/cmd/kubeadm/app/master/apiclient.go @@ -42,17 +42,15 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli &clientcmd.ConfigOverrides{}, ).ClientConfig() if err != nil { - return nil, fmt.Errorf(" failed to create API client configuration [%v]", err) + return nil, fmt.Errorf("failed to create API client configuration [%v]", err) } - fmt.Println(" created API client configuration") - client, err := clientset.NewForConfig(adminClientConfig) if err != nil { - return nil, fmt.Errorf(" failed to create API client [%v]", err) + return nil, fmt.Errorf("failed to create API client [%v]", err) } - fmt.Println(" created API client, waiting for the control plane to become ready") + fmt.Println("[apiclient] Created API client, waiting for the control plane to become ready") start := time.Now() wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { @@ -62,28 +60,28 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli } // TODO(phase2) must revisit this when we implement HA if len(cs.Items) < 3 { - fmt.Println(" not all control plane components are ready yet") + fmt.Println("[apiclient] Not all control plane components are ready yet") return false, nil } for _, item := range cs.Items { for _, condition := range item.Conditions { if condition.Type != v1.ComponentHealthy { - fmt.Printf(" control plane component %q is still unhealthy: %#v\n", item.ObjectMeta.Name, item.Conditions) + fmt.Printf("[apiclient] Control plane component %q is still unhealthy: %#v\n", item.ObjectMeta.Name, item.Conditions) return false, nil } } } - fmt.Printf(" all control plane components are healthy after %f seconds\n", time.Since(start).Seconds()) + fmt.Printf("[apiclient] All control plane components are healthy after %f seconds\n", time.Since(start).Seconds()) return true, nil }) - fmt.Println(" waiting for at least one node to register and become ready") + fmt.Println("[apiclient] Waiting for at least one node to register and become ready") start = time.Now() wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { nodeList, err := client.Nodes().List(v1.ListOptions{}) if err != nil { - fmt.Println(" temporarily unable to list nodes (will retry)") + fmt.Println("[apiclient] Temporarily unable to list nodes (will retry)") return false, nil } if len(nodeList.Items) < 1 { @@ -91,11 +89,11 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli } n := &nodeList.Items[0] if !v1.IsNodeReady(n) { - fmt.Println(" first node has registered, but is not ready yet") + fmt.Println("[apiclient] First node has registered, but is not ready yet") return false, nil } - fmt.Printf(" first node is ready after %f seconds\n", time.Since(start).Seconds()) + fmt.Printf("[apiclient] First node is ready after %f seconds\n", time.Since(start).Seconds()) return true, nil }) @@ -180,7 +178,7 @@ func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, sched if _, err := client.Nodes().Update(n); err != nil { if apierrs.IsConflict(err) { - fmt.Println(" temporarily unable to update master node metadata due to conflict (will retry)") + fmt.Println("[apiclient] Temporarily unable to update master node metadata due to conflict (will retry)") time.Sleep(apiCallRetryInterval) attemptToUpdateMasterRoleLabelsAndTaints(client, schedulable) } else { @@ -195,7 +193,7 @@ func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, schedulable bo // TODO(phase1+) use iterate instead of recursion err := attemptToUpdateMasterRoleLabelsAndTaints(client, schedulable) if err != nil { - return fmt.Errorf(" failed to update master node - %v", err) + return fmt.Errorf("failed to update master node - [%v]", err) } return nil } @@ -240,7 +238,7 @@ func NativeArchitectureNodeAffinity() v1.NodeSelectorRequirement { } func createDummyDeployment(client *clientset.Clientset) { - fmt.Println(" attempting a test deployment") + fmt.Println("[apiclient] Creating a test deployment") dummyDeployment := NewDeployment("dummy", 1, v1.PodSpec{ HostNetwork: true, SecurityContext: &v1.PodSecurityContext{}, @@ -253,7 +251,7 @@ func createDummyDeployment(client *clientset.Clientset) { wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { // TODO: we should check the error, as some cases may be fatal if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(dummyDeployment); err != nil { - fmt.Printf(" failed to create test deployment [%v] (will retry)", err) + fmt.Printf("[apiclient] Failed to create test deployment [%v] (will retry)\n", err) return false, nil } return true, nil @@ -262,7 +260,7 @@ func createDummyDeployment(client *clientset.Clientset) { wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { d, err := client.Extensions().Deployments(api.NamespaceSystem).Get("dummy") if err != nil { - fmt.Printf(" failed to get test deployment [%v] (will retry)", err) + fmt.Printf("[apiclient] Failed to get test deployment [%v] (will retry)\n", err) return false, nil } if d.Status.AvailableReplicas < 1 { @@ -271,9 +269,9 @@ func createDummyDeployment(client *clientset.Clientset) { return true, nil }) - fmt.Println(" test deployment succeeded") + fmt.Println("[apiclient] Test deployment succeeded") if err := client.Extensions().Deployments(api.NamespaceSystem).Delete("dummy", &v1.DeleteOptions{}); err != nil { - fmt.Printf(" failed to delete test deployment [%v] (will ignore)", err) + fmt.Printf("[apiclient] Failed to delete test deployment [%v] (will ignore)\n", err) } } diff --git a/cmd/kubeadm/app/master/discovery.go b/cmd/kubeadm/app/master/discovery.go index 64ce8ec0efb..b4279941831 100644 --- a/cmd/kubeadm/app/master/discovery.go +++ b/cmd/kubeadm/app/master/discovery.go @@ -123,13 +123,13 @@ func CreateDiscoveryDeploymentAndSecret(cfg *kubeadmapi.MasterConfiguration, cli kd := newKubeDiscovery(cfg, caCert) if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kd.Deployment); err != nil { - return fmt.Errorf(" failed to create %q deployment [%v]", kubeDiscoveryName, err) + return fmt.Errorf("failed to create %q deployment [%v]", kubeDiscoveryName, err) } if _, err := client.Secrets(api.NamespaceSystem).Create(kd.Secret); err != nil { - return fmt.Errorf(" failed to create %q secret [%v]", kubeDiscoverySecretName, err) + return fmt.Errorf("failed to create %q secret [%v]", kubeDiscoverySecretName, err) } - fmt.Println(" created essential addon: kube-discovery, waiting for it to become ready") + fmt.Println("[token-discovery] Created the kube-discovery deployment, waiting for it to become ready") start := time.Now() wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { @@ -142,7 +142,7 @@ func CreateDiscoveryDeploymentAndSecret(cfg *kubeadmapi.MasterConfiguration, cli } return true, nil }) - fmt.Printf(" kube-discovery is ready after %f seconds\n", time.Since(start).Seconds()) + fmt.Printf("[token-discovery] kube-discovery is ready after %f seconds\n", time.Since(start).Seconds()) return nil } diff --git a/cmd/kubeadm/app/master/kubeconfig.go b/cmd/kubeadm/app/master/kubeconfig.go index e1dfe400636..e750f6aa12f 100644 --- a/cmd/kubeadm/app/master/kubeconfig.go +++ b/cmd/kubeadm/app/master/kubeconfig.go @@ -21,7 +21,6 @@ import ( "crypto/x509" "fmt" - // TODO: "k8s.io/client-go/client/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" @@ -44,7 +43,7 @@ func CreateCertsAndConfigForClients(cfg kubeadmapi.API, clientNames []string, ca for _, client := range clientNames { key, cert, err := newClientKeyAndCert(caCert, caKey) if err != nil { - return nil, fmt.Errorf(" failure while creating %s client certificate - %v", client, err) + return nil, fmt.Errorf("failure while creating %s client certificate - [%v]", client, err) } config := kubeadmutil.MakeClientConfigWithCerts( basicClientConfig, diff --git a/cmd/kubeadm/app/master/manifests.go b/cmd/kubeadm/app/master/manifests.go index f1e187833d3..7153c6191f3 100644 --- a/cmd/kubeadm/app/master/manifests.go +++ b/cmd/kubeadm/app/master/manifests.go @@ -47,7 +47,6 @@ const ( kubeControllerManager = "kube-controller-manager" kubeScheduler = "kube-scheduler" kubeProxy = "kube-proxy" - pkiDir = "/etc/kubernetes/pki" ) // WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk @@ -124,16 +123,16 @@ func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error { manifestsPath := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests") if err := os.MkdirAll(manifestsPath, 0700); err != nil { - return fmt.Errorf(" failed to create directory %q [%v]", manifestsPath, err) + return fmt.Errorf("failed to create directory %q [%v]", manifestsPath, err) } for name, spec := range staticPodSpecs { filename := path.Join(manifestsPath, name+".json") serialized, err := json.MarshalIndent(spec, "", " ") if err != nil { - return fmt.Errorf(" failed to marshall manifest for %q to JSON [%v]", name, err) + return fmt.Errorf("failed to marshal manifest for %q to JSON [%v]", name, err) } if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), filename); err != nil { - return fmt.Errorf(" failed to create static pod manifest file for %q (%q) [%v]", name, filename, err) + return fmt.Errorf("failed to create static pod manifest file for %q (%q) [%v]", name, filename, err) } } return nil @@ -191,7 +190,7 @@ func isPkiVolumeMountNeeded() bool { func pkiVolume(cfg *kubeadmapi.MasterConfiguration) api.Volume { return api.Volume{ - Name: "pki", + Name: "k8s", VolumeSource: api.VolumeSource{ // TODO(phase1+) make path configurable HostPath: &api.HostPathVolumeSource{Path: "/etc/pki"}, @@ -265,26 +264,24 @@ func componentPod(container api.Container, volumes ...api.Volume) api.Pod { } } -func getComponentBaseCommand(component string) (command []string) { +func getComponentBaseCommand(component string) []string { if kubeadmapi.GlobalEnvParams.HyperkubeImage != "" { - command = []string{"/hyperkube", component} - } else { - command = []string{"kube-" + component} + return []string{"/hyperkube", component} } - command = append(command, kubeadmapi.GlobalEnvParams.ComponentLoglevel) - return + + return []string{"kube-" + component} } -func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) { - command = append(getComponentBaseCommand(apiServer), +func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) []string { + command := append(getComponentBaseCommand(apiServer), "--insecure-bind-address=127.0.0.1", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--service-cluster-ip-range="+cfg.Networking.ServiceSubnet, - "--service-account-key-file="+pkiDir+"/apiserver-key.pem", - "--client-ca-file="+pkiDir+"/ca.pem", - "--tls-cert-file="+pkiDir+"/apiserver.pem", - "--tls-private-key-file="+pkiDir+"/apiserver-key.pem", - "--token-auth-file="+pkiDir+"/tokens.csv", + "--service-account-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", + "--client-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", + "--tls-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver.pem", + "--tls-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", + "--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv", fmt.Sprintf("--secure-port=%d", cfg.API.BindPort), "--allow-privileged", ) @@ -320,19 +317,19 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) } } - return + return command } -func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) { - command = append(getComponentBaseCommand(controllerManager), +func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) []string { + command := append(getComponentBaseCommand(controllerManager), "--address=127.0.0.1", "--leader-elect", "--master=127.0.0.1:8080", "--cluster-name="+DefaultClusterName, - "--root-ca-file="+pkiDir+"/ca.pem", - "--service-account-private-key-file="+pkiDir+"/apiserver-key.pem", - "--cluster-signing-cert-file="+pkiDir+"/ca.pem", - "--cluster-signing-key-file="+pkiDir+"/ca-key.pem", + "--root-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", + "--service-account-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", + "--cluster-signing-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", + "--cluster-signing-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca-key.pem", "--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", ) @@ -340,7 +337,6 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command [ command = append(command, "--cloud-provider="+cfg.CloudProvider) // Only append the --cloud-config option if there's a such file - // TODO(phase1+) this won't work unless it's in one of the few directories we bind-mount if _, err := os.Stat(DefaultCloudConfigPath); err == nil { command = append(command, "--cloud-config="+DefaultCloudConfigPath) } @@ -351,24 +347,19 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command [ if cfg.Networking.PodSubnet != "" { command = append(command, "--allocate-node-cidrs=true", "--cluster-cidr="+cfg.Networking.PodSubnet) } - - return + return command } -func getSchedulerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) { - command = append(getComponentBaseCommand(scheduler), +func getSchedulerCommand(cfg *kubeadmapi.MasterConfiguration) []string { + return append(getComponentBaseCommand(scheduler), "--address=127.0.0.1", "--leader-elect", "--master=127.0.0.1:8080", ) - - return } -func getProxyCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) { - command = getComponentBaseCommand(proxy) - - return +func getProxyCommand(cfg *kubeadmapi.MasterConfiguration) []string { + return getComponentBaseCommand(proxy) } func getProxyEnvVars() []api.EnvVar { diff --git a/cmd/kubeadm/app/master/pki.go b/cmd/kubeadm/app/master/pki.go index 5db41f50f0a..63ab6ff942f 100644 --- a/cmd/kubeadm/app/master/pki.go +++ b/cmd/kubeadm/app/master/pki.go @@ -24,7 +24,7 @@ import ( "path" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" + "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" certutil "k8s.io/kubernetes/pkg/util/cert" ) @@ -162,39 +162,32 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration) (*rsa.PrivateKey, *x50 caKey, caCert, err := newCertificateAuthority() if err != nil { - return nil, nil, fmt.Errorf(" failure while creating CA keys and certificate - %v", err) + return nil, nil, fmt.Errorf("failure while creating CA keys and certificate [%v]", err) } if err := writeKeysAndCert(pkiPath, "ca", caKey, caCert); err != nil { - return nil, nil, fmt.Errorf(" failure while saving CA keys and certificate - %v", err) + return nil, nil, fmt.Errorf("failure while saving CA keys and certificate [%v]", err) } - fmt.Printf(" generated Certificate Authority key and certificate:\n%s\n", certutil.FormatCert(caCert)) - pub, prv, cert := pathsKeysCerts(pkiPath, "ca") - fmt.Printf("Public: %s\nPrivate: %s\nCert: %s\n", pub, prv, cert) + fmt.Println("[certificates] Generated Certificate Authority key and certificate.") apiKey, apiCert, err := newServerKeyAndCert(cfg, caCert, caKey, altNames) if err != nil { - return nil, nil, fmt.Errorf(" failure while creating API server keys and certificate - %v", err) + return nil, nil, fmt.Errorf("failure while creating API server keys and certificate [%v]", err) } if err := writeKeysAndCert(pkiPath, "apiserver", apiKey, apiCert); err != nil { - return nil, nil, fmt.Errorf(" failure while saving API server keys and certificate - %v", err) + return nil, nil, fmt.Errorf("failure while saving API server keys and certificate [%v]", err) } - fmt.Printf(" generated API Server key and certificate:\n%s\n", certutil.FormatCert(apiCert)) - pub, prv, cert = pathsKeysCerts(pkiPath, "apiserver") - fmt.Printf("Public: %s\nPrivate: %s\nCert: %s\n", pub, prv, cert) + fmt.Println("[certificates] Generated API Server key and certificate") saKey, err := newServiceAccountKey() if err != nil { - return nil, nil, fmt.Errorf(" failure while creating service account signing keys [%v]", err) + return nil, nil, fmt.Errorf("failure while creating service account signing keys [%v]", err) } if err := writeKeysAndCert(pkiPath, "sa", saKey, nil); err != nil { - return nil, nil, fmt.Errorf(" failure while saving service account signing keys - %v", err) + return nil, nil, fmt.Errorf("failure while saving service account signing keys [%v]", err) } - fmt.Printf(" generated Service Account Signing keys:\n") - pub, prv, _ = pathsKeysCerts(pkiPath, "sa") - fmt.Printf("Public: %s\nPrivate: %s\n", pub, prv) - - fmt.Printf(" created keys and certificates in %q\n", pkiPath) + fmt.Println("[certificates] Generated Service Account signing keys") + fmt.Printf("[certificates] Created keys and certificates in %q\n", pkiPath) return caKey, caCert, nil } diff --git a/cmd/kubeadm/app/master/tokens.go b/cmd/kubeadm/app/master/tokens.go index 2758456851b..994e081da4f 100644 --- a/cmd/kubeadm/app/master/tokens.go +++ b/cmd/kubeadm/app/master/tokens.go @@ -39,9 +39,9 @@ func generateTokenIfNeeded(s *kubeadmapi.Secrets) error { if err != nil { return err } - fmt.Printf(" generated token: %q\n", s.GivenToken) + fmt.Printf("[tokens] Generated token: %q\n", s.GivenToken) } else { - fmt.Println(" accepted provided token") + fmt.Println("[tokens] Accepted provided token") } return nil @@ -50,15 +50,15 @@ func generateTokenIfNeeded(s *kubeadmapi.Secrets) error { func CreateTokenAuthFile(s *kubeadmapi.Secrets) error { tokenAuthFilePath := path.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, "tokens.csv") if err := generateTokenIfNeeded(s); err != nil { - return fmt.Errorf(" failed to generate token(s) [%v]", err) + return fmt.Errorf("failed to generate token(s) [%v]", err) } if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.HostPKIPath, 0700); err != nil { - return fmt.Errorf(" failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err) + return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err) } serialized := []byte(fmt.Sprintf("%s,kubeadm-node-csr,%s,system:kubelet-bootstrap\n", s.BearerToken, uuid.NewUUID())) // DumpReaderToFile create a file with mode 0600 if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), tokenAuthFilePath); err != nil { - return fmt.Errorf(" failed to save token auth file (%q) [%v]", tokenAuthFilePath, err) + return fmt.Errorf("failed to save token auth file (%q) [%v]", tokenAuthFilePath, err) } return nil } diff --git a/cmd/kubeadm/app/node/bootstrap.go b/cmd/kubeadm/app/node/bootstrap.go index c2a8815a349..18907a3238e 100644 --- a/cmd/kubeadm/app/node/bootstrap.go +++ b/cmd/kubeadm/app/node/bootstrap.go @@ -53,7 +53,7 @@ const retryTimeout = 5 func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kubeadmapi.ClusterInfo) (*ConnectionDetails, error) { hostName, err := os.Hostname() if err != nil { - return nil, fmt.Errorf(" failed to get node hostname [%v]", err) + return nil, fmt.Errorf("failed to get node hostname [%v]", err) } // TODO(phase1+) https://github.com/kubernetes/kubernetes/issues/33641 nodeName := types.NodeName(hostName) @@ -67,20 +67,20 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub for _, endpoint := range endpoints { clientSet, err := createClients(caCert, endpoint, s.Secrets.BearerToken, nodeName) if err != nil { - fmt.Printf(" warning: %s. Skipping endpoint %s\n", err, endpoint) + fmt.Printf("[bootstrap] Warning: %s. Skipping endpoint %s\n", err, endpoint) continue } wg.Add(1) go func(apiEndpoint string) { defer wg.Done() wait.Until(func() { - fmt.Printf(" trying to connect to endpoint %s\n", apiEndpoint) + fmt.Printf("[bootstrap] Trying to connect to endpoint %s\n", apiEndpoint) err := checkAPIEndpoint(clientSet, apiEndpoint) if err != nil { - fmt.Printf(" endpoint check failed [%v]\n", err) + fmt.Printf("[bootstrap] Endpoint check failed [%v]\n", err) return } - fmt.Printf(" successfully established connection with endpoint %s\n", apiEndpoint) + fmt.Printf("[bootstrap] Successfully established connection with endpoint %q\n", apiEndpoint) // connection established, stop all wait threads close(stopChan) result <- &ConnectionDetails{ @@ -102,8 +102,7 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub establishedConnection, ok := <-result if !ok { - return nil, fmt.Errorf(" failed to create bootstrap clients " + - "for any of the provided API endpoints") + return nil, fmt.Errorf("failed to create bootstrap clients for any of the provided API endpoints") } return establishedConnection, nil } @@ -122,7 +121,7 @@ func createClients(caCert []byte, endpoint, token string, nodeName types.NodeNam } clientSet, err := clientset.NewForConfig(bootstrapClientConfig) if err != nil { - return nil, fmt.Errorf("failed to create clients for the API endpoint %s [%v]", endpoint, err) + return nil, fmt.Errorf("failed to create clients for the API endpoint %q: [%v]", endpoint, err) } return clientSet, nil } @@ -150,9 +149,9 @@ func checkAPIEndpoint(clientSet *clientset.Clientset, endpoint string) error { // check general connectivity version, err := clientSet.DiscoveryClient.ServerVersion() if err != nil { - return fmt.Errorf("failed to connect to %s [%v]", endpoint, err) + return fmt.Errorf("failed to connect to %q [%v]", endpoint, err) } - fmt.Printf(" detected server version %s\n", version.String()) + fmt.Printf("[bootstrap] Detected server version: %s\n", version.String()) // check certificates API serverGroups, err := clientSet.DiscoveryClient.ServerGroups() diff --git a/cmd/kubeadm/app/node/csr.go b/cmd/kubeadm/app/node/csr.go index 11748bf29a7..499d213c6b4 100644 --- a/cmd/kubeadm/app/node/csr.go +++ b/cmd/kubeadm/app/node/csr.go @@ -30,22 +30,22 @@ import ( func PerformTLSBootstrap(connection *ConnectionDetails) (*clientcmdapi.Config, error) { csrClient := connection.CertClient.CertificateSigningRequests() - fmt.Println(" created API client to obtain unique certificate for this node, generating keys and certificate signing request") + fmt.Println("[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request") key, err := certutil.MakeEllipticPrivateKeyPEM() if err != nil { - return nil, fmt.Errorf(" failed to generating private key [%v]", err) + return nil, fmt.Errorf("failed to generating private key [%v]", err) } cert, err := csr.RequestNodeCertificate(csrClient, key, connection.NodeName) if err != nil { - return nil, fmt.Errorf(" failed to request signed certificate from the API server [%v]", err) + return nil, fmt.Errorf("failed to request signed certificate from the API server [%v]", err) } fmtCert, err := certutil.FormatBytesCert(cert) if err != nil { - return nil, fmt.Errorf(" failed to format certificate [%v]", err) + return nil, fmt.Errorf("failed to format certificate [%v]", err) } - fmt.Printf(" received signed certificate from the API server:\n%s\n", fmtCert) - fmt.Println(" generating kubelet configuration") + fmt.Printf("[csr] Received signed certificate from the API server:\n%s\n", fmtCert) + fmt.Println("[csr] Generating kubelet configuration...") bareClientConfig := kubeadmutil.CreateBasicClientConfig("kubernetes", connection.Endpoint, connection.CACert) finalConfig := kubeadmutil.MakeClientConfigWithCerts( diff --git a/cmd/kubeadm/app/node/discovery.go b/cmd/kubeadm/app/node/discovery.go index ad9cd5c0f41..aad37f7290b 100644 --- a/cmd/kubeadm/app/node/discovery.go +++ b/cmd/kubeadm/app/node/discovery.go @@ -37,16 +37,16 @@ func RetrieveTrustedClusterInfo(s *kubeadmapi.NodeConfiguration) (*kubeadmapi.Cl requestURL := fmt.Sprintf("http://%s:%d/cluster-info/v1/?token-id=%s", host, port, s.Secrets.TokenID) req, err := http.NewRequest("GET", requestURL, nil) if err != nil { - return nil, fmt.Errorf(" failed to consturct an HTTP request [%v]", err) + return nil, fmt.Errorf("failed to consturct an HTTP request [%v]", err) } - fmt.Printf(" created cluster info discovery client, requesting info from %q\n", requestURL) + fmt.Printf("[discovery] Created cluster info discovery client, requesting info from %q\n", requestURL) var res *http.Response wait.PollInfinite(discoveryRetryTimeout, func() (bool, error) { res, err = http.DefaultClient.Do(req) if err != nil { - fmt.Printf(" failed to request cluster info, will try again: [%s]\n", err) + fmt.Printf("[discovery] Failed to request cluster info, will try again: [%s]\n", err) return false, nil } return true, nil @@ -58,28 +58,28 @@ func RetrieveTrustedClusterInfo(s *kubeadmapi.NodeConfiguration) (*kubeadmapi.Cl object, err := jose.ParseSigned(buf.String()) if err != nil { - return nil, fmt.Errorf(" failed to parse response as JWS object [%v]", err) + return nil, fmt.Errorf("failed to parse response as JWS object [%v]", err) } - fmt.Println(" cluster info object received, verifying signature using given token") + fmt.Println("[discovery] Cluster info object received, verifying signature using given token") output, err := object.Verify(s.Secrets.Token) if err != nil { - return nil, fmt.Errorf(" failed to verify JWS signature of received cluster info object [%v]", err) + return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object [%v]", err) } clusterInfo := kubeadmapi.ClusterInfo{} if err := json.Unmarshal(output, &clusterInfo); err != nil { - return nil, fmt.Errorf(" failed to decode received cluster info object [%v]", err) + return nil, fmt.Errorf("failed to decode received cluster info object [%v]", err) } if len(clusterInfo.CertificateAuthorities) == 0 || len(clusterInfo.Endpoints) == 0 { - return nil, fmt.Errorf(" cluster info object is invalid - no endpoint(s) and/or root CA certificate(s) found") + return nil, fmt.Errorf("cluster info object is invalid - no endpoint(s) and/or root CA certificate(s) found") } // TODO(phase1+) print summary info about the CA certificate, along with the the checksum signature // we also need an ability for the user to configure the client to validate received CA cert against a checksum - fmt.Printf(" cluster info signature and contents are valid, will use API endpoints %v\n", clusterInfo.Endpoints) + fmt.Printf("[discovery] Cluster info signature and contents are valid, will use API endpoints %v\n", clusterInfo.Endpoints) return &clusterInfo, nil } diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index bd309b79704..e34566fa2f8 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -25,9 +25,11 @@ import ( "net/http" "os" "os/exec" + "path" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/pkg/api/validation" + utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/initsystem" "k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/test/e2e_node/system" @@ -243,13 +245,28 @@ type SystemVerificationCheck struct{} func (sysver SystemVerificationCheck) Check() (warnings, errors []error) { // Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit - bufw := bufio.NewWriterSize(os.Stdout, 1*1024*1024) - // Run the system verification check, but write to out buffered writer instead of stdout - err := system.Validate(system.DefaultSysSpec, &system.StreamReporter{WriteStream: bufw}) + bufw := bufio.NewWriterSize(os.Stdout, 1*1024*1024) + reporter := &system.StreamReporter{WriteStream: bufw} + + var errs []error + // All the validators we'd like to run: + var validators = []system.Validator{ + &system.OSValidator{Reporter: reporter}, + &system.KernelValidator{Reporter: reporter}, + &system.CgroupsValidator{Reporter: reporter}, + &system.DockerValidator{Reporter: reporter}, + } + + // Run all validators + for _, v := range validators { + errs = append(errs, v.Validate(system.DefaultSysSpec)) + } + + err := utilerrors.NewAggregate(errs) if err != nil { // Only print the output from the system verification check if the check failed - fmt.Println("System verification failed. Printing the output from the verification...") + fmt.Println("[preflight] The system verification failed. Printing the output from the verification:") bufw.Flush() return nil, []error{err} } @@ -271,11 +288,11 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { PortOpenCheck{port: 10251}, PortOpenCheck{port: 10252}, HTTPProxyCheck{Proto: "https", Host: cfg.API.AdvertiseAddresses[0], Port: int(cfg.API.BindPort)}, - DirAvailableCheck{Path: "/etc/kubernetes/manifests"}, - DirAvailableCheck{Path: "/etc/kubernetes/pki"}, + DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")}, + DirAvailableCheck{Path: kubeadmapi.GlobalEnvParams.HostPKIPath}, DirAvailableCheck{Path: "/var/lib/kubelet"}, - FileAvailableCheck{Path: "/etc/kubernetes/admin.conf"}, - FileAvailableCheck{Path: "/etc/kubernetes/kubelet.conf"}, + FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")}, + FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")}, InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "mount", mandatory: true}, @@ -308,9 +325,9 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error { PortOpenCheck{port: 10250}, HTTPProxyCheck{Proto: "https", Host: cfg.MasterAddresses[0], Port: int(cfg.APIPort)}, HTTPProxyCheck{Proto: "http", Host: cfg.MasterAddresses[0], Port: int(cfg.DiscoveryPort)}, - DirAvailableCheck{Path: "/etc/kubernetes/manifests"}, + DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")}, DirAvailableCheck{Path: "/var/lib/kubelet"}, - FileAvailableCheck{Path: "/etc/kubernetes/kubelet.conf"}, + FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")}, InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "mount", mandatory: true}, diff --git a/cmd/kubeadm/app/util/error.go b/cmd/kubeadm/app/util/error.go index d6a8c17d192..6c3cfc6f68d 100644 --- a/cmd/kubeadm/app/util/error.go +++ b/cmd/kubeadm/app/util/error.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors. +Copyright 2016 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,37 +22,18 @@ import ( "strings" "k8s.io/kubernetes/cmd/kubeadm/app/preflight" - - "github.com/golang/glog" - "github.com/renstrom/dedent" ) const ( DefaultErrorExitCode = 1 - PreFlight = 2 + PreFlightExitCode = 2 ) -var AlphaWarningOnExit = dedent.Dedent(` - kubeadm: I am an alpha version, my authors welcome your feedback and bug reports - kubeadm: please create an issue using https://github.com/kubernetes/kubernetes/issues/new - kubeadm: and make sure to mention @kubernetes/sig-cluster-lifecycle. Thank you! -`) - type debugError interface { DebugError() (msg string, args []interface{}) } -var fatalErrHandler = fatal - -// BehaviorOnFatal allows you to override the default behavior when a fatal -// error occurs, which is to call os.Exit(code). You can pass 'panic' as a function -// here if you prefer the panic() over os.Exit(1). -func BehaviorOnFatal(f func(string, int)) { - fatalErrHandler = f -} - -// fatal prints the message if set and then exits. If V(2) or greater, glog.Fatal -// is invoked for extended information. +// fatal prints the message if set and then exits. func fatal(msg string, code int) { if len(msg) > 0 { // add newline if needed @@ -60,9 +41,6 @@ func fatal(msg string, code int) { msg += "\n" } - if glog.V(2) { - glog.FatalDepth(2, msg) - } fmt.Fprint(os.Stderr, msg) } os.Exit(code) @@ -74,7 +52,7 @@ func fatal(msg string, code int) { // This method is generic to the command in use and may be used by non-Kubectl // commands. func CheckErr(err error) { - checkErr("", err, fatalErrHandler) + checkErr("", err, fatal) } // checkErr formats a given error as a string and calls the passed handleErr @@ -84,9 +62,8 @@ func checkErr(prefix string, err error, handleErr func(string, int)) { case nil: return case *preflight.PreFlightError: - handleErr(err.Error(), PreFlight) + handleErr(err.Error(), PreFlightExitCode) default: - fmt.Printf(AlphaWarningOnExit) handleErr(err.Error(), DefaultErrorExitCode) } } diff --git a/cmd/kubeadm/app/util/kubeconfig.go b/cmd/kubeadm/app/util/kubeconfig.go index e61a60af576..cf5c1b21e76 100644 --- a/cmd/kubeadm/app/util/kubeconfig.go +++ b/cmd/kubeadm/app/util/kubeconfig.go @@ -21,7 +21,6 @@ import ( "os" "path" - // TODO: "k8s.io/client-go/client/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" @@ -77,21 +76,21 @@ func MakeClientConfigWithToken(config *clientcmdapi.Config, clusterName string, func WriteKubeconfigIfNotExists(name string, kubeconfig *clientcmdapi.Config) error { if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.KubernetesDir, 0700); err != nil { - return fmt.Errorf(" failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.KubernetesDir, err) + return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.KubernetesDir, err) } filename := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, fmt.Sprintf("%s.conf", name)) // Create and open the file, only if it does not already exist. f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { - return fmt.Errorf(" failed to create %q, it already exists [%v]", filename, err) + return fmt.Errorf("failed to create %q, it already exists [%v]", filename, err) } f.Close() if err := clientcmd.WriteToFile(*kubeconfig, filename); err != nil { - return fmt.Errorf(" failed to write to %q [%v]", filename, err) + return fmt.Errorf("failed to write to %q [%v]", filename, err) } - fmt.Printf(" created %q\n", filename) + fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", filename) return nil } diff --git a/cmd/kubeadm/app/util/tokens.go b/cmd/kubeadm/app/util/tokens.go index 34b6bbf407b..568fc144a37 100644 --- a/cmd/kubeadm/app/util/tokens.go +++ b/cmd/kubeadm/app/util/tokens.go @@ -64,10 +64,10 @@ func UseGivenTokenIfValid(s *kubeadmapi.Secrets) (bool, error) { if s.GivenToken == "" { return false, nil // not given } - fmt.Println(" validating provided token") + fmt.Println("[tokens] Validating provided token...") givenToken := strings.Split(strings.ToLower(s.GivenToken), ".") // TODO(phase1+) could also print more specific messages in each case - invalidErr := " provided token does not match expected <6 characters>.<16 characters> format - %s" + invalidErr := "[tokens] Provided token does not match expected <6 characters>.<16 characters> format - %s" if len(givenToken) != 2 { return false, fmt.Errorf(invalidErr, "not in 2-part dot-separated format") } diff --git a/cmd/kubeadm/kubeadm.go b/cmd/kubeadm/kubeadm.go index 6c743cd7a21..6aca5a18f3d 100644 --- a/cmd/kubeadm/kubeadm.go +++ b/cmd/kubeadm/kubeadm.go @@ -17,16 +17,13 @@ limitations under the License. package main import ( - "fmt" "os" "k8s.io/kubernetes/cmd/kubeadm/app" - "k8s.io/kubernetes/cmd/kubeadm/app/util" ) func main() { if err := app.Run(); err != nil { - fmt.Printf(util.AlphaWarningOnExit) os.Exit(1) } os.Exit(0)