mirror of https://github.com/k3s-io/k3s
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")pull/6/head
parent
e46d8fef60
commit
810e9e107f
|
@ -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"],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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("<master/addons> failed creating essential kube-proxy addon [%v]", err)
|
||||
return fmt.Errorf("failed creating essential kube-proxy addon [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("<master/addons> 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("<master/addons> 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("<master/addons> failed creating essential kube-dns addon [%v]", err)
|
||||
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("<master/addons> created essential addon: kube-dns")
|
||||
fmt.Println("[addons] Created essential addon: kube-dns")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -42,17 +42,15 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
|
|||
&clientcmd.ConfigOverrides{},
|
||||
).ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("<master/apiclient> failed to create API client configuration [%v]", err)
|
||||
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("<master/apiclient> created API client configuration")
|
||||
|
||||
client, err := clientset.NewForConfig(adminClientConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("<master/apiclient> failed to create API client [%v]", err)
|
||||
return nil, fmt.Errorf("failed to create API client [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> 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("<master/apiclient> test deployment succeeded")
|
||||
fmt.Println("[apiclient] Test deployment succeeded")
|
||||
|
||||
if err := client.Extensions().Deployments(api.NamespaceSystem).Delete("dummy", &v1.DeleteOptions{}); err != nil {
|
||||
fmt.Printf("<master/apiclient> failed to delete test deployment [%v] (will ignore)", err)
|
||||
fmt.Printf("[apiclient] Failed to delete test deployment [%v] (will ignore)\n", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("<master/discovery> 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("<master/discovery> failed to create %q secret [%v]", kubeDiscoverySecretName, err)
|
||||
return fmt.Errorf("failed to create %q secret [%v]", kubeDiscoverySecretName, err)
|
||||
}
|
||||
|
||||
fmt.Println("<master/discovery> 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("<master/discovery> 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
|
||||
}
|
||||
|
|
|
@ -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("<master/kubeconfig> 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,
|
||||
|
|
|
@ -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("<master/manifests> 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("<master/manifests> 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("<master/manifests> 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 {
|
||||
|
|
|
@ -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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> 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("<master/pki> generated Service Account Signing keys:\n")
|
||||
pub, prv, _ = pathsKeysCerts(pkiPath, "sa")
|
||||
fmt.Printf("Public: %s\nPrivate: %s\n", pub, prv)
|
||||
|
||||
fmt.Printf("<master/pki> 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
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ func generateTokenIfNeeded(s *kubeadmapi.Secrets) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("<master/tokens> generated token: %q\n", s.GivenToken)
|
||||
fmt.Printf("[tokens] Generated token: %q\n", s.GivenToken)
|
||||
} else {
|
||||
fmt.Println("<master/tokens> 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("<master/tokens> 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("<master/tokens> 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("<master/tokens> 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
|
||||
}
|
||||
|
|
|
@ -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("<node/bootstrap> 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("<node/bootstrap> 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("<node/bootstrap> 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("<node/bootstrap> endpoint check failed [%v]\n", err)
|
||||
fmt.Printf("[bootstrap] Endpoint check failed [%v]\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("<node/bootstrap> 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("<node/bootstrap> 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("<node/bootstrap> 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()
|
||||
|
|
|
@ -30,22 +30,22 @@ import (
|
|||
func PerformTLSBootstrap(connection *ConnectionDetails) (*clientcmdapi.Config, error) {
|
||||
csrClient := connection.CertClient.CertificateSigningRequests()
|
||||
|
||||
fmt.Println("<node/csr> 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("<node/csr> 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("<node/csr> 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("<node/csr> failed to format certificate [%v]", err)
|
||||
return nil, fmt.Errorf("failed to format certificate [%v]", err)
|
||||
}
|
||||
fmt.Printf("<node/csr> received signed certificate from the API server:\n%s\n", fmtCert)
|
||||
fmt.Println("<node/csr> 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(
|
||||
|
|
|
@ -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("<node/discovery> failed to consturct an HTTP request [%v]", err)
|
||||
return nil, fmt.Errorf("failed to consturct an HTTP request [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Printf("<node/discovery> 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("<node/discovery> 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("<node/discovery> failed to parse response as JWS object [%v]", err)
|
||||
return nil, fmt.Errorf("failed to parse response as JWS object [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("<node/discovery> 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("<node/discovery> 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("<node/discovery> 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("<node/discovery> 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("<node/discovery> 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
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("<util/kubeconfig> 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("<util/kubeconfig> 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("<util/kubeconfig> failed to write to %q [%v]", filename, err)
|
||||
return fmt.Errorf("failed to write to %q [%v]", filename, err)
|
||||
}
|
||||
|
||||
fmt.Printf("<util/kubeconfig> created %q\n", filename)
|
||||
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", filename)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -64,10 +64,10 @@ func UseGivenTokenIfValid(s *kubeadmapi.Secrets) (bool, error) {
|
|||
if s.GivenToken == "" {
|
||||
return false, nil // not given
|
||||
}
|
||||
fmt.Println("<util/tokens> 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 := "<util/tokens> 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")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue