mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	kube-proxy: add '--bind-address-hard-fail' flag to treat failure to bind to a port as fatal
Signed-off-by: SataQiu <1527062125@qq.com>
This commit is contained in:
		@@ -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'. 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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -375,6 +375,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
 | 
			
		||||
 
 | 
			
		||||
@@ -146,6 +146,7 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
 | 
			
		||||
		ProxyMode:           proxyMode,
 | 
			
		||||
		NodeRef:             nodeRef,
 | 
			
		||||
		MetricsBindAddress:  config.MetricsBindAddress,
 | 
			
		||||
		BindAddressHardFail: config.BindAddressHardFail,
 | 
			
		||||
		EnableProfiling:     config.EnableProfiling,
 | 
			
		||||
		OOMScoreAdj:         config.OOMScoreAdj,
 | 
			
		||||
		ConfigSyncPeriod:    config.ConfigSyncPeriod.Duration,
 | 
			
		||||
 
 | 
			
		||||
@@ -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"`
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user