mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #89350 from SataQiu/fix-kube-proxy-20200323
kube-proxy: treat failure to bind to a port as fatal
This commit is contained in:
commit
cabf5d1cdc
@ -168,6 +168,7 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.Var(utilflag.IPVar{Val: &o.config.BindAddress}, "bind-address", "The IP address for the proxy server to serve on (set to '0.0.0.0' for all IPv4 interfaces and '::' for all IPv6 interfaces)")
|
||||
fs.Var(utilflag.IPPortVar{Val: &o.config.HealthzBindAddress}, "healthz-bind-address", "The IP address with port for the health check server to serve on (set to '0.0.0.0:10256' for all IPv4 interfaces and '[::]:10256' for all IPv6 interfaces). Set empty to disable.")
|
||||
fs.Var(utilflag.IPPortVar{Val: &o.config.MetricsBindAddress}, "metrics-bind-address", "The IP address with port for the metrics server to serve on (set to '0.0.0.0:10249' for all IPv4 interfaces and '[::]:10249' for all IPv6 interfaces). Set empty to disable.")
|
||||
fs.BoolVar(&o.config.BindAddressHardFail, "bind-address-hard-fail", o.config.BindAddressHardFail, "If true kube-proxy will treat failure to bind to a port as fatal and exit")
|
||||
fs.Var(utilflag.PortRangeVar{Val: &o.config.PortRange}, "proxy-port-range", "Range of host ports (beginPort-endPort, single port or beginPort+offset, inclusive) that may be consumed in order to proxy service traffic. If (unspecified, 0, or 0-0) then ports will be randomly chosen.")
|
||||
fs.Var(&o.config.Mode, "proxy-mode", "Which proxy mode to use: 'userspace' (older) or 'iptables' (faster) or 'ipvs' or 'kernelspace' (windows). If blank, use the best-available proxy (currently iptables). If the iptables proxy is selected, regardless of how, but the system's kernel or iptables versions are insufficient, this always falls back to the userspace proxy.")
|
||||
fs.Var(cliflag.NewMapStringBool(&o.config.FeatureGates), "feature-gates", "A set of key=value pairs that describe feature gates for alpha/experimental features. "+
|
||||
@ -531,6 +532,7 @@ type ProxyServer struct {
|
||||
NodeRef *v1.ObjectReference
|
||||
CleanupIPVS bool
|
||||
MetricsBindAddress string
|
||||
BindAddressHardFail bool
|
||||
EnableProfiling bool
|
||||
UseEndpointSlices bool
|
||||
OOMScoreAdj *int32
|
||||
@ -576,7 +578,7 @@ func createClients(config componentbaseconfig.ClientConnectionConfiguration, mas
|
||||
return client, eventClient.CoreV1(), nil
|
||||
}
|
||||
|
||||
func serveHealthz(hz healthcheck.ProxierHealthUpdater) {
|
||||
func serveHealthz(hz healthcheck.ProxierHealthUpdater, errCh chan error) {
|
||||
if hz == nil {
|
||||
return
|
||||
}
|
||||
@ -584,9 +586,13 @@ func serveHealthz(hz healthcheck.ProxierHealthUpdater) {
|
||||
fn := func() {
|
||||
err := hz.Run()
|
||||
if err != nil {
|
||||
// For historical reasons we do not abort on errors here. We may
|
||||
// change that in the future.
|
||||
klog.Errorf("healthz server failed: %v", err)
|
||||
if errCh != nil {
|
||||
errCh <- fmt.Errorf("healthz server failed: %v", err)
|
||||
// if in hardfail mode, never retry again
|
||||
blockCh := make(chan error)
|
||||
<-blockCh
|
||||
}
|
||||
} else {
|
||||
klog.Errorf("healthz server returned without error")
|
||||
}
|
||||
@ -594,7 +600,7 @@ func serveHealthz(hz healthcheck.ProxierHealthUpdater) {
|
||||
go wait.Until(fn, 5*time.Second, wait.NeverStop)
|
||||
}
|
||||
|
||||
func serveMetrics(bindAddress string, proxyMode string, enableProfiling bool) {
|
||||
func serveMetrics(bindAddress, proxyMode string, enableProfiling bool, errCh chan error) {
|
||||
if len(bindAddress) == 0 {
|
||||
return
|
||||
}
|
||||
@ -619,9 +625,14 @@ func serveMetrics(bindAddress string, proxyMode string, enableProfiling bool) {
|
||||
fn := func() {
|
||||
err := http.ListenAndServe(bindAddress, proxyMux)
|
||||
if err != nil {
|
||||
// For historical reasons we do not abort on errors here. We may
|
||||
// change that in the future.
|
||||
utilruntime.HandleError(fmt.Errorf("starting metrics server failed: %v", err))
|
||||
err = fmt.Errorf("starting metrics server failed: %v", err)
|
||||
utilruntime.HandleError(err)
|
||||
if errCh != nil {
|
||||
errCh <- err
|
||||
// if in hardfail mode, never retry again
|
||||
blockCh := make(chan error)
|
||||
<-blockCh
|
||||
}
|
||||
}
|
||||
}
|
||||
go wait.Until(fn, 5*time.Second, wait.NeverStop)
|
||||
@ -648,11 +659,16 @@ func (s *ProxyServer) Run() error {
|
||||
|
||||
// TODO(thockin): make it possible for healthz and metrics to be on the same port.
|
||||
|
||||
var errCh chan error
|
||||
if s.BindAddressHardFail {
|
||||
errCh = make(chan error)
|
||||
}
|
||||
|
||||
// Start up a healthz server if requested
|
||||
serveHealthz(s.HealthzServer)
|
||||
serveHealthz(s.HealthzServer, errCh)
|
||||
|
||||
// Start up a metrics server if requested
|
||||
serveMetrics(s.MetricsBindAddress, s.ProxyMode, s.EnableProfiling)
|
||||
serveMetrics(s.MetricsBindAddress, s.ProxyMode, s.EnableProfiling, errCh)
|
||||
|
||||
// Tune conntrack, if requested
|
||||
// Conntracker is always nil for windows
|
||||
@ -754,9 +770,9 @@ func (s *ProxyServer) Run() error {
|
||||
// Birth Cry after the birth is successful
|
||||
s.birthCry()
|
||||
|
||||
// Just loop forever for now...
|
||||
s.Proxier.SyncLoop()
|
||||
return nil
|
||||
go s.Proxier.SyncLoop()
|
||||
|
||||
return <-errCh
|
||||
}
|
||||
|
||||
func (s *ProxyServer) birthCry() {
|
||||
|
@ -379,6 +379,7 @@ func newProxyServer(
|
||||
ProxyMode: proxyMode,
|
||||
NodeRef: nodeRef,
|
||||
MetricsBindAddress: config.MetricsBindAddress,
|
||||
BindAddressHardFail: config.BindAddressHardFail,
|
||||
EnableProfiling: config.EnableProfiling,
|
||||
OOMScoreAdj: config.OOMScoreAdj,
|
||||
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
|
||||
|
@ -445,6 +445,7 @@ func TestConfigChange(t *testing.T) {
|
||||
|
||||
_, err = file.WriteString(`apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -138,19 +138,20 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
|
||||
}
|
||||
|
||||
return &ProxyServer{
|
||||
Client: client,
|
||||
EventClient: eventClient,
|
||||
Proxier: proxier,
|
||||
Broadcaster: eventBroadcaster,
|
||||
Recorder: recorder,
|
||||
ProxyMode: proxyMode,
|
||||
NodeRef: nodeRef,
|
||||
MetricsBindAddress: config.MetricsBindAddress,
|
||||
EnableProfiling: config.EnableProfiling,
|
||||
OOMScoreAdj: config.OOMScoreAdj,
|
||||
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
|
||||
HealthzServer: healthzServer,
|
||||
UseEndpointSlices: false,
|
||||
Client: client,
|
||||
EventClient: eventClient,
|
||||
Proxier: proxier,
|
||||
Broadcaster: eventBroadcaster,
|
||||
Recorder: recorder,
|
||||
ProxyMode: proxyMode,
|
||||
NodeRef: nodeRef,
|
||||
MetricsBindAddress: config.MetricsBindAddress,
|
||||
BindAddressHardFail: config.BindAddressHardFail,
|
||||
EnableProfiling: config.EnableProfiling,
|
||||
OOMScoreAdj: config.OOMScoreAdj,
|
||||
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
|
||||
HealthzServer: healthzServer,
|
||||
UseEndpointSlices: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ var kubeProxyMarshalCases = []struct {
|
||||
yaml: dedent.Dedent(`
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: ""
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 0
|
||||
@ -106,6 +107,7 @@ var kubeProxyMarshalCases = []struct {
|
||||
yaml: dedent.Dedent(`
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 1.2.3.4
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 0
|
||||
|
@ -30,6 +30,7 @@ ClusterName: kubernetes
|
||||
ComponentConfigs:
|
||||
KubeProxy:
|
||||
BindAddress: 0.0.0.0
|
||||
BindAddressHardFail: false
|
||||
ClientConnection:
|
||||
AcceptContentTypes: ""
|
||||
Burst: 10
|
||||
|
@ -30,6 +30,7 @@ ClusterName: kubernetes
|
||||
ComponentConfigs:
|
||||
KubeProxy:
|
||||
BindAddress: 0.0.0.0
|
||||
BindAddressHardFail: false
|
||||
ClientConnection:
|
||||
AcceptContentTypes: ""
|
||||
Burst: 10
|
||||
|
@ -52,6 +52,7 @@ useHyperKubeImage: true
|
||||
---
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -52,6 +52,7 @@ useHyperKubeImage: true
|
||||
---
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -41,6 +41,7 @@ scheduler: {}
|
||||
---
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -41,6 +41,7 @@ scheduler: {}
|
||||
---
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -1,5 +1,6 @@
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -1,5 +1,6 @@
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
|
@ -120,6 +120,8 @@ type KubeProxyConfiguration struct {
|
||||
// metricsBindAddress is the IP address and port for the metrics server to serve on,
|
||||
// defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces)
|
||||
MetricsBindAddress string
|
||||
// BindAddressHardFail, if true, kube-proxy will treat failure to bind to a port as fatal and exit
|
||||
BindAddressHardFail bool
|
||||
// enableProfiling enables profiling via web interface on /debug/pprof handler.
|
||||
// Profiling handlers will be handled by metrics server.
|
||||
EnableProfiling bool
|
||||
|
@ -96,6 +96,7 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguratio
|
||||
out.BindAddress = in.BindAddress
|
||||
out.HealthzBindAddress = in.HealthzBindAddress
|
||||
out.MetricsBindAddress = in.MetricsBindAddress
|
||||
out.BindAddressHardFail = in.BindAddressHardFail
|
||||
out.EnableProfiling = in.EnableProfiling
|
||||
out.ClusterCIDR = in.ClusterCIDR
|
||||
out.HostnameOverride = in.HostnameOverride
|
||||
@ -135,6 +136,7 @@ func autoConvert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguratio
|
||||
out.BindAddress = in.BindAddress
|
||||
out.HealthzBindAddress = in.HealthzBindAddress
|
||||
out.MetricsBindAddress = in.MetricsBindAddress
|
||||
out.BindAddressHardFail = in.BindAddressHardFail
|
||||
out.EnableProfiling = in.EnableProfiling
|
||||
out.ClusterCIDR = in.ClusterCIDR
|
||||
out.HostnameOverride = in.HostnameOverride
|
||||
|
@ -116,6 +116,8 @@ type KubeProxyConfiguration struct {
|
||||
// metricsBindAddress is the IP address and port for the metrics server to serve on,
|
||||
// defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces)
|
||||
MetricsBindAddress string `json:"metricsBindAddress"`
|
||||
// bindAddressHardFail, if true, kube-proxy will treat failure to bind to a port as fatal and exit
|
||||
BindAddressHardFail bool `json:"bindAddressHardFail"`
|
||||
// enableProfiling enables profiling via web interface on /debug/pprof handler.
|
||||
// Profiling handlers will be handled by metrics server.
|
||||
EnableProfiling bool `json:"enableProfiling"`
|
||||
|
Loading…
Reference in New Issue
Block a user