Merge pull request #35972 from kad/proxy-warning

Automatic merge from submit-queue

kubeadm preflight checks: Warn user if connections to API or Discovery are going to be over proxy

**What this PR does / why we need it**: Continuing discussion from PR #35044, new version will provide warning if kubeadm run in environment where http connections would go over proxy.
Most of the time, it is not expected behaviour and leads to situations like in #34695

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #34695

**Special notes for your reviewer**:

**Release note**:
```release-note
NONE
```

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 ...
pull/6/head
Kubernetes Submit Queue 2016-11-01 15:56:51 -07:00 committed by GitHub
commit 1fe9fb2d69
3 changed files with 49 additions and 18 deletions

View File

@ -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) {

View File

@ -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 {

View File

@ -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},