From ce9a13ef13e140ff49fe6df3d69e9e3295884e73 Mon Sep 17 00:00:00 2001 From: Alexander Kanevskiy Date: Tue, 1 Nov 2016 16:23:10 +0200 Subject: [PATCH] Warn user if connections to API or Discovery are going to be over proxy kubeadm during initialization of master and slave nodes need to make several API calls directly to the node where it is running or master. In environments with http/https proxies, user might accidentally have configuration where connections to API would go over proxy instead of directly. User can re-run kubeadm with corrected NO_PROXY variable. Example: $ NO_PROXY=* kubeadm join ... --- cmd/kubeadm/app/cmd/init.go | 20 ++++++++--------- cmd/kubeadm/app/cmd/join.go | 14 ++++++------ cmd/kubeadm/app/preflight/checks.go | 33 ++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index c6dea3bb4eb..6046d3e6683 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -168,16 +168,6 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight } } - if !skipPreFlight { - fmt.Println("Running pre-flight checks") - err := preflight.RunInitMasterChecks(cfg) - if err != nil { - return nil, &preflight.PreFlightError{Msg: err.Error()} - } - } else { - fmt.Println("Skipping pre-flight checks") - } - // Auto-detect the IP if len(cfg.API.AdvertiseAddresses) == 0 { // TODO(phase1+) perhaps we could actually grab eth0 and eth1 @@ -188,6 +178,16 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight cfg.API.AdvertiseAddresses = []string{ip.String()} } + if !skipPreFlight { + fmt.Println("Running pre-flight checks") + err := preflight.RunInitMasterChecks(cfg) + if err != nil { + return nil, &preflight.PreFlightError{Msg: err.Error()} + } + } else { + fmt.Println("Skipping pre-flight checks") + } + // TODO(phase1+) create a custom flag if cfg.CloudProvider != "" { if cloudprovider.IsCloudProvider(cfg.CloudProvider) { diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index fb6c781021d..7587b1e21af 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -98,9 +98,15 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s } } + // TODO(phase1+) this we are missing args from the help text, there should be a way to tell cobra about it + if len(args) == 0 && len(cfg.MasterAddresses) == 0 { + return nil, fmt.Errorf("must specify master IP address (see --help)") + } + cfg.MasterAddresses = append(cfg.MasterAddresses, args...) + if !skipPreFlight { fmt.Println("Running pre-flight checks") - err := preflight.RunJoinNodeChecks() + err := preflight.RunJoinNodeChecks(cfg) if err != nil { return nil, &preflight.PreFlightError{Msg: err.Error()} } @@ -108,12 +114,6 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s fmt.Println("Skipping pre-flight checks") } - // TODO(phase1+) this we are missing args from the help text, there should be a way to tell cobra about it - if len(args) == 0 && len(cfg.MasterAddresses) == 0 { - return nil, fmt.Errorf("must specify master IP address (see --help)") - } - cfg.MasterAddresses = append(cfg.MasterAddresses, args...) - ok, err := kubeadmutil.UseGivenTokenIfValid(&cfg.Secrets) if !ok { if err != nil { diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index 31cb31e7be2..e09f0d8cb5a 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net" + "net/http" "os" "os/exec" @@ -185,6 +186,33 @@ func (hc HostnameCheck) Check() (warnings, errors []error) { return nil, errors } +// HttpProxyCheck checks if https connection to specific host is going +// to be done directly or over proxy. If proxy detected, it will return warning. +type HttpProxyCheck struct { + Proto string + Host string + Port int +} + +func (hst HttpProxyCheck) Check() (warnings, errors []error) { + + url := fmt.Sprintf("%s://%s:%d", hst.Proto, hst.Host, hst.Port) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, []error{err} + } + + proxy, err := http.DefaultTransport.(*http.Transport).Proxy(req) + if err != nil { + return nil, []error{err} + } + if proxy != nil { + return []error{fmt.Errorf("Connection to %q uses proxy %q. If that is not intended, adjust your proxy settings", url, proxy)}, nil + } + return nil, nil +} + func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { // TODO: Some of these ports should come from kubeadm config eventually: checks := []PreFlightCheck{ @@ -199,6 +227,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { PortOpenCheck{port: 10250}, 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: "/var/lib/etcd"}, @@ -219,7 +248,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { return runChecks(checks, os.Stderr) } -func RunJoinNodeChecks() error { +func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error { // TODO: Some of these ports should come from kubeadm config eventually: checks := []PreFlightCheck{ IsRootCheck{root: true}, @@ -227,6 +256,8 @@ func RunJoinNodeChecks() error { ServiceCheck{Service: "docker"}, ServiceCheck{Service: "kubelet"}, 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"}, DirAvailableCheck{Path: "/var/lib/kubelet"}, InPathCheck{executable: "ebtables", mandatory: true},