2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/ * 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-03 08:25:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Copyright  2014  The  Kubernetes  Authors . 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* / 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-19 07:01:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-10 11:58:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								package  endpoint 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-08 10:16:47 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 11:16:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"math" 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 17:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									v1  "k8s.io/api/core/v1" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-13 01:01:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									apiequality  "k8s.io/apimachinery/pkg/api/equality" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 01:48:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/apimachinery/pkg/api/errors" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 22:09:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									metav1  "k8s.io/apimachinery/pkg/apis/meta/v1" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/apimachinery/pkg/labels" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									utilruntime  "k8s.io/apimachinery/pkg/util/runtime" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/apimachinery/pkg/util/wait" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-24 04:56:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									coreinformers  "k8s.io/client-go/informers/core/v1" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clientset  "k8s.io/client-go/kubernetes" 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/client-go/kubernetes/scheme" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									v1core  "k8s.io/client-go/kubernetes/typed/core/v1" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-24 04:56:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									corelisters  "k8s.io/client-go/listers/core/v1" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 22:11:51 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/client-go/tools/cache" 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-08 04:59:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/client-go/tools/leaderelection/resourcelock" 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/client-go/tools/record" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-27 23:20:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/client-go/util/workqueue" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-23 01:40:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/component-base/metrics/prometheus/ratelimiter" 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 03:25:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/klog/v2" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api/v1/endpoints" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podutil  "k8s.io/kubernetes/pkg/api/v1/pod" 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-09 06:34:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									api  "k8s.io/kubernetes/pkg/apis/core" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 03:55:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									helper  "k8s.io/kubernetes/pkg/apis/core/v1/helper" 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:49:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/controller" 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									endpointutil  "k8s.io/kubernetes/pkg/controller/util/endpoint" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 04:30:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									utillabels  "k8s.io/kubernetes/pkg/util/labels" 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 04:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									utilnet  "k8s.io/utils/net" 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								const  ( 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// maxRetries is the number of times a service will be retried before it is dropped out of the queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// With the current rate-limiter in use (5ms*2^(maxRetries-1)) the following numbers represent the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// sequence of delays between successive queuings of a service.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									maxRetries  =  15 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// maxCapacity represents the maximum number of addresses that should be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// stored in an Endpoints resource. In a future release, this controller
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// may truncate endpoints exceeding this length.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									maxCapacity  =  1000 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// truncated is a possible value for `endpoints.kubernetes.io/over-capacity` annotation on an
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// endpoint resource and indicates that the number of endpoints have been truncated to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// maxCapacity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									truncated  =  "truncated" 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// NewEndpointController returns a new *Controller.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  NewEndpointController ( podInformer  coreinformers . PodInformer ,  serviceInformer  coreinformers . ServiceInformer , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									endpointsInformer  coreinformers . EndpointsInformer ,  client  clientset . Interface ,  endpointUpdatesBatchPeriod  time . Duration )  * Controller  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									broadcaster  :=  record . NewBroadcaster ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-09 11:01:45 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									broadcaster . StartStructuredLogging ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									broadcaster . StartRecordingToSink ( & v1core . EventSinkImpl { Interface :  client . CoreV1 ( ) . Events ( "" ) } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									recorder  :=  broadcaster . NewRecorder ( scheme . Scheme ,  v1 . EventSource { Component :  "endpoint-controller" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-25 23:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  client  !=  nil  &&  client . CoreV1 ( ) . RESTClient ( ) . GetRateLimiter ( )  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-23 01:40:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ratelimiter . RegisterMetricAndTrackRateLimiterUsage ( "endpoint_controller" ,  client . CoreV1 ( ) . RESTClient ( ) . GetRateLimiter ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-14 02:38:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e  :=  & Controller { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										client :            client , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										queue :             workqueue . NewNamedRateLimitingQueue ( workqueue . DefaultControllerRateLimiter ( ) ,  "endpoint" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										workerLoopPeriod :  time . Second , 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 20:48:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									serviceInformer . Informer ( ) . AddEventHandler ( cache . ResourceEventHandlerFuncs { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AddFunc :  e . onServiceUpdate , 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 20:48:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										UpdateFunc :  func ( old ,  cur  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											e . onServiceUpdate ( cur ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										DeleteFunc :  e . onServiceDelete , 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 20:48:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . serviceLister  =  serviceInformer . Lister ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . servicesSynced  =  serviceInformer . Informer ( ) . HasSynced 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									podInformer . Informer ( ) . AddEventHandler ( cache . ResourceEventHandlerFuncs { 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-15 02:00:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AddFunc :     e . addPod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										UpdateFunc :  e . updatePod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										DeleteFunc :  e . deletePod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . podLister  =  podInformer . Lister ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . podsSynced  =  podInformer . Informer ( ) . HasSynced 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 08:22:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									endpointsInformer . Informer ( ) . AddEventHandler ( cache . ResourceEventHandlerFuncs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										DeleteFunc :  e . onEndpointsDelete , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . endpointsLister  =  endpointsInformer . Lister ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . endpointsSynced  =  endpointsInformer . Informer ( ) . HasSynced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . triggerTimeTracker  =  endpointutil . NewTriggerTimeTracker ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . eventBroadcaster  =  broadcaster 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . eventRecorder  =  recorder 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 17:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . endpointUpdatesBatchPeriod  =  endpointUpdatesBatchPeriod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . serviceSelectorCache  =  endpointutil . NewServiceSelectorCache ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Controller manages selector-based service endpoints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  Controller  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									client            clientset . Interface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									eventBroadcaster  record . EventBroadcaster 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									eventRecorder     record . EventRecorder 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// serviceLister is able to list/get services and is populated by the shared informer passed to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// NewEndpointController.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									serviceLister  corelisters . ServiceLister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// servicesSynced returns true if the service shared informer has been synced at least once.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Added as a member to the struct to allow injection for testing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									servicesSynced  cache . InformerSynced 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// podLister is able to list/get pods and is populated by the shared informer passed to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// NewEndpointController.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podLister  corelisters . PodLister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// podsSynced returns true if the pod shared informer has been synced at least once.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Added as a member to the struct to allow injection for testing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podsSynced  cache . InformerSynced 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-15 02:00:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// endpointsLister is able to list/get endpoints and is populated by the shared informer passed to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// NewEndpointController.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									endpointsLister  corelisters . EndpointsLister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// endpointsSynced returns true if the endpoints shared informer has been synced at least once.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Added as a member to the struct to allow injection for testing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									endpointsSynced  cache . InformerSynced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Services that need to be updated. A channel is inappropriate here,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// because it allows services with lots of pods to be serviced much
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// more often than services with few pods; it also would cause a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// service that's inserted multiple times to be processed more than
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// necessary.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									queue  workqueue . RateLimitingInterface 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// workerLoopPeriod is the time between worker runs. The workers process the queue of service and pod changes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									workerLoopPeriod  time . Duration 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// triggerTimeTracker is an util used to compute and export the EndpointsLastChangeTriggerTime
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// annotation.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									triggerTimeTracker  * endpointutil . TriggerTimeTracker 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 17:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									endpointUpdatesBatchPeriod  time . Duration 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// serviceSelectorCache is a cache of service selectors to avoid high CPU consumption caused by frequent calls
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// to AsSelectorPreValidated (see #73527)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									serviceSelectorCache  * endpointutil . ServiceSelectorCache 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-03 22:40:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Run will not return until stopCh is closed. workers determines how many
 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// endpoints will be handled in parallel.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  Run ( ctx  context . Context ,  workers  int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-15 15:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									defer  utilruntime . HandleCrash ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									defer  e . queue . ShutDown ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									klog . Infof ( "Starting endpoint controller" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  klog . Infof ( "Shutting down endpoint controller" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:49:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ! cache . WaitForNamedCacheSync ( "endpoint" ,  ctx . Done ( ) ,  e . podsSynced ,  e . servicesSynced ,  e . endpointsSynced )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  0 ;  i  <  workers ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										go  wait . UntilWithContext ( ctx ,  e . worker ,  e . workerLoopPeriod ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-12 15:15:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:49:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-15 15:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										defer  utilruntime . HandleCrash ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										e . checkLeftoverEndpoints ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-15 02:00:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									<- ctx . Done ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-12 15:15:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is added, figure out what services it will be a member of and
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// enqueue them. obj must have *v1.Pod type.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  addPod ( obj  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pod  :=  obj . ( * v1 . Pod ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									services ,  err  :=  e . serviceSelectorCache . GetPodServiceMemberships ( e . serviceLister ,  pod ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-03 17:45:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										utilruntime . HandleError ( fmt . Errorf ( "Unable to get pod %s/%s's service memberships: %v" ,  pod . Namespace ,  pod . Name ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  key  :=  range  services  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 17:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										e . queue . AddAfter ( key ,  e . endpointUpdatesBatchPeriod ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 04:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  podToEndpointAddressForService ( svc  * v1 . Service ,  pod  * v1 . Pod )  ( * v1 . EndpointAddress ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  endpointIP  string 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												dual stack services (#91824)
* api: structure change
* api: defaulting, conversion, and validation
* [FIX] validation: auto remove second ip/family when service changes to SingleStack
* [FIX] api: defaulting, conversion, and validation
* api-server: clusterIPs alloc, printers, storage and strategy
* [FIX] clusterIPs default on read
* alloc: auto remove second ip/family when service changes to SingleStack
* api-server: repair loop handling for clusterIPs
* api-server: force kubernetes default service into single stack
* api-server: tie dualstack feature flag with endpoint feature flag
* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service
* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service
* kube-proxy: feature-flag, utils, proxier, and meta proxier
* [FIX] kubeproxy: call both proxier at the same time
* kubenet: remove forced pod IP sorting
* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy
* e2e: fix tests that depends on IPFamily field AND add dual stack tests
* e2e: fix expected error message for ClusterIP immutability
* add integration tests for dualstack
the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:
- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.
The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:
- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4
* [FIX] add integration tests for dualstack
* generated data
* generated files
Co-authored-by: Antonio Ojea <aojea@redhat.com>
											 
										 
										
											2020-10-27 04:15:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ipFamily  :=  v1 . IPv4Protocol 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 04:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 07:30:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  len ( svc . Spec . IPFamilies )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// controller is connected to an api-server that correctly sets IPFamilies
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ipFamily  =  svc . Spec . IPFamilies [ 0 ]  // this works for headful and headless
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 07:30:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// controller is connected to an api server that does not correctly
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// set IPFamilies (e.g. old api-server during an upgrade)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// TODO (khenidak): remove by when the possibility of upgrading
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// from a cluster that does not support dual stack is nil
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  len ( svc . Spec . ClusterIP )  >  0  &&  svc . Spec . ClusterIP  !=  v1 . ClusterIPNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// headful service. detect via service clusterIP
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  utilnet . IsIPv6String ( svc . Spec . ClusterIP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ipFamily  =  v1 . IPv6Protocol 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												dual stack services (#91824)
* api: structure change
* api: defaulting, conversion, and validation
* [FIX] validation: auto remove second ip/family when service changes to SingleStack
* [FIX] api: defaulting, conversion, and validation
* api-server: clusterIPs alloc, printers, storage and strategy
* [FIX] clusterIPs default on read
* alloc: auto remove second ip/family when service changes to SingleStack
* api-server: repair loop handling for clusterIPs
* api-server: force kubernetes default service into single stack
* api-server: tie dualstack feature flag with endpoint feature flag
* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service
* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service
* kube-proxy: feature-flag, utils, proxier, and meta proxier
* [FIX] kubeproxy: call both proxier at the same time
* kubenet: remove forced pod IP sorting
* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy
* e2e: fix tests that depends on IPFamily field AND add dual stack tests
* e2e: fix expected error message for ClusterIP immutability
* add integration tests for dualstack
the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:
- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.
The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:
- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4
* [FIX] add integration tests for dualstack
* generated data
* generated files
Co-authored-by: Antonio Ojea <aojea@redhat.com>
											 
										 
										
											2020-10-27 04:15:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 07:30:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											// Since this is a headless service we use podIP to identify the family.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// This assumes that status.PodIP is assigned correctly (follows pod cidr and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// pod cidr list order is same as service cidr list order). The expectation is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// this is *most probably* the case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// if the family was incorrectly identified then this will be corrected once the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// the upgrade is completed (controller connects to api-server that correctly defaults services)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  utilnet . IsIPv6String ( pod . Status . PodIP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ipFamily  =  v1 . IPv6Protocol 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												dual stack services (#91824)
* api: structure change
* api: defaulting, conversion, and validation
* [FIX] validation: auto remove second ip/family when service changes to SingleStack
* [FIX] api: defaulting, conversion, and validation
* api-server: clusterIPs alloc, printers, storage and strategy
* [FIX] clusterIPs default on read
* alloc: auto remove second ip/family when service changes to SingleStack
* api-server: repair loop handling for clusterIPs
* api-server: force kubernetes default service into single stack
* api-server: tie dualstack feature flag with endpoint feature flag
* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service
* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service
* kube-proxy: feature-flag, utils, proxier, and meta proxier
* [FIX] kubeproxy: call both proxier at the same time
* kubenet: remove forced pod IP sorting
* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy
* e2e: fix tests that depends on IPFamily field AND add dual stack tests
* e2e: fix expected error message for ClusterIP immutability
* add integration tests for dualstack
the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:
- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.
The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:
- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4
* [FIX] add integration tests for dualstack
* generated data
* generated files
Co-authored-by: Antonio Ojea <aojea@redhat.com>
											 
										 
										
											2020-10-27 04:15:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 07:30:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												dual stack services (#91824)
* api: structure change
* api: defaulting, conversion, and validation
* [FIX] validation: auto remove second ip/family when service changes to SingleStack
* [FIX] api: defaulting, conversion, and validation
* api-server: clusterIPs alloc, printers, storage and strategy
* [FIX] clusterIPs default on read
* alloc: auto remove second ip/family when service changes to SingleStack
* api-server: repair loop handling for clusterIPs
* api-server: force kubernetes default service into single stack
* api-server: tie dualstack feature flag with endpoint feature flag
* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service
* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service
* kube-proxy: feature-flag, utils, proxier, and meta proxier
* [FIX] kubeproxy: call both proxier at the same time
* kubenet: remove forced pod IP sorting
* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy
* e2e: fix tests that depends on IPFamily field AND add dual stack tests
* e2e: fix expected error message for ClusterIP immutability
* add integration tests for dualstack
the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:
- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.
The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:
- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4
* [FIX] add integration tests for dualstack
* generated data
* generated files
Co-authored-by: Antonio Ojea <aojea@redhat.com>
											 
										 
										
											2020-10-27 04:15:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 07:30:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// find an ip that matches the family
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  podIP  :=  range  pod . Status . PodIPs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ipFamily  ==  v1 . IPv6Protocol )  ==  utilnet . IsIPv6String ( podIP . IP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											endpointIP  =  podIP . IP 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												dual stack services (#91824)
* api: structure change
* api: defaulting, conversion, and validation
* [FIX] validation: auto remove second ip/family when service changes to SingleStack
* [FIX] api: defaulting, conversion, and validation
* api-server: clusterIPs alloc, printers, storage and strategy
* [FIX] clusterIPs default on read
* alloc: auto remove second ip/family when service changes to SingleStack
* api-server: repair loop handling for clusterIPs
* api-server: force kubernetes default service into single stack
* api-server: tie dualstack feature flag with endpoint feature flag
* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service
* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service
* kube-proxy: feature-flag, utils, proxier, and meta proxier
* [FIX] kubeproxy: call both proxier at the same time
* kubenet: remove forced pod IP sorting
* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy
* e2e: fix tests that depends on IPFamily field AND add dual stack tests
* e2e: fix expected error message for ClusterIP immutability
* add integration tests for dualstack
the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:
- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.
The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:
- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4
* [FIX] add integration tests for dualstack
* generated data
* generated files
Co-authored-by: Antonio Ojea <aojea@redhat.com>
											 
										 
										
											2020-10-27 04:15:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  endpointIP  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "failed to find a matching endpoint for service %v" ,  svc . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 04:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-19 04:09:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  & v1 . EndpointAddress { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										IP :        endpointIP , 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-19 04:09:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										NodeName :  & pod . Spec . NodeName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										TargetRef :  & v1 . ObjectReference { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-17 14:10:49 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											Kind :       "Pod" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Namespace :  pod . ObjectMeta . Namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Name :       pod . ObjectMeta . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											UID :        pod . ObjectMeta . UID , 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-19 04:09:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is updated, figure out what services it used to be a member of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// and what services it will be a member of, and enqueue the union of these.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// old and cur must be *v1.Pod types.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  updatePod ( old ,  cur  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 23:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									services  :=  endpointutil . GetServicesToUpdateOnPodChange ( e . serviceLister ,  e . serviceSelectorCache ,  old ,  cur ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  key  :=  range  services  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-24 17:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										e . queue . AddAfter ( key ,  e . endpointUpdatesBatchPeriod ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-13 23:52:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is deleted, enqueue the services the pod used to be a member of.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// obj could be an *v1.Pod, or a DeletionFinalStateUnknown marker item.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  deletePod ( obj  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pod  :=  endpointutil . GetPodFromDeleteAction ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  pod  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . addPod ( pod ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 20:48:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// onServiceUpdate updates the Service Selector in the cache and queues the Service for processing.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  onServiceUpdate ( obj  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									key ,  err  :=  controller . KeyFunc ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										utilruntime . HandleError ( fmt . Errorf ( "Couldn't get key for object %+v: %v" ,  obj ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									_  =  e . serviceSelectorCache . Update ( key ,  obj . ( * v1 . Service ) . Spec . Selector ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// onServiceDelete removes the Service Selector from the cache and queues the Service for processing.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  onServiceDelete ( obj  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-03 16:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									key ,  err  :=  controller . KeyFunc ( obj ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										utilruntime . HandleError ( fmt . Errorf ( "Couldn't get key for object %+v: %v" ,  obj ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-29 20:44:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-03 02:51:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 19:57:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . serviceSelectorCache . Delete ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  onEndpointsDelete ( obj  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 08:22:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									key ,  err  :=  controller . KeyFunc ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										utilruntime . HandleError ( fmt . Errorf ( "Couldn't get key for object %+v: %v" ,  obj ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// worker runs a worker thread that just dequeues items, processes them, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// marks them done. You may run as many of these in parallel as you wish; the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// workqueue guarantees that they will not end up processing the same service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// at the same time.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  worker ( ctx  context . Context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  e . processNextWorkItem ( ctx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-21 05:24:43 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  processNextWorkItem ( ctx  context . Context )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									eKey ,  quit  :=  e . queue . Get ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  quit  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  e . queue . Done ( eKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									err  :=  e . syncService ( ctx ,  eKey . ( string ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . handleErr ( err ,  eKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  handleErr ( err  error ,  key  interface { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										e . queue . Forget ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-29 20:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ns ,  name ,  keyErr  :=  cache . SplitMetaNamespaceKey ( key . ( string ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  keyErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										klog . ErrorS ( err ,  "Failed to split meta namespace cache key" ,  "key" ,  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  e . queue . NumRequeues ( key )  <  maxRetries  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-29 20:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										klog . V ( 2 ) . InfoS ( "Error syncing endpoints, retrying" ,  "service" ,  klog . KRef ( ns ,  name ) ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										e . queue . AddRateLimited ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									klog . Warningf ( "Dropping service %q out of the queue: %v" ,  key ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 23:50:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									e . queue . Forget ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									utilruntime . HandleError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  syncService ( ctx  context . Context ,  key  string )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									startTime  :=  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										klog . V ( 4 ) . Infof ( "Finished syncing service %q endpoints. (%v)" ,  key ,  time . Since ( startTime ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-16 16:47:30 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									namespace ,  name ,  err  :=  cache . SplitMetaNamespaceKey ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									service ,  err  :=  e . serviceLister . Services ( namespace ) . Get ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-18 05:40:36 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ! errors . IsNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 09:30:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// Delete the corresponding endpoint, as the service has been deleted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// TODO: Please note that this will delete an endpoint when a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// service is deleted. However, if we're down at the time when
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// the service is deleted, we will miss that deletion, so this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// doesn't completely solve the problem. See #6877.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										err  =  e . client . CoreV1 ( ) . Endpoints ( namespace ) . Delete ( ctx ,  name ,  metav1 . DeleteOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 09:30:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  err  !=  nil  &&  ! errors . IsNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										e . triggerTimeTracker . DeleteService ( namespace ,  name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  service . Spec . Selector  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// services without a selector receive no endpoints from this controller;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// these services will receive the endpoints that are created out-of-band via the REST API.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									klog . V ( 5 ) . Infof ( "About to update endpoints for service %q" ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 09:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pods ,  err  :=  e . podLister . Pods ( service . Namespace ) . List ( labels . Set ( service . Spec . Selector ) . AsSelectorPreValidated ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Since we're getting stuff from a local cache, it is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// basically impossible to get this error.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// We call ComputeEndpointLastChangeTriggerTime here to make sure that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// state of the trigger time tracker gets updated even if the sync turns out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// to be no-op and we don't update the endpoints object.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									endpointsLastChangeTriggerTime  :=  e . triggerTimeTracker . 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 06:42:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ComputeEndpointLastChangeTriggerTime ( namespace ,  service ,  pods ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									subsets  :=  [ ] v1 . EndpointSubset { } 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 18:55:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  totalReadyEps  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  totalNotReadyEps  int 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  pods  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 05:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ! endpointutil . ShouldPodBeInEndpoints ( pod ,  service . Spec . PublishNotReadyAddresses )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-22 18:21:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											klog . V ( 5 ) . Infof ( "Pod %s/%s is not included on endpoints for Service %s/%s" ,  pod . Namespace ,  pod . Name ,  service . Namespace ,  service . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 04:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ep ,  err  :=  podToEndpointAddressForService ( service ,  pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// this will happen, if the cluster runs with some nodes configured as dual stack and some as not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// such as the case of an upgrade..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											klog . V ( 2 ) . Infof ( "failed to find endpoint for service:%v with ClusterIP:%v on pod:%v with error:%v" ,  service . Name ,  service . Spec . ClusterIP ,  pod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 06:39:49 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										epa  :=  * ep 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  endpointutil . ShouldSetHostname ( pod ,  service )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											epa . Hostname  =  pod . Spec . Hostname 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// Allow headless service not to have ports.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  len ( service . Spec . Ports )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  service . Spec . ClusterIP  ==  api . ClusterIPNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-22 18:21:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												subsets ,  totalReadyEps ,  totalNotReadyEps  =  addEndpointSubset ( subsets ,  pod ,  epa ,  nil ,  service . Spec . PublishNotReadyAddresses ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-13 06:42:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												// No need to repack subsets for headless service without ports.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-15 01:45:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  i  :=  range  service . Spec . Ports  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												servicePort  :=  & service . Spec . Ports [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												portNum ,  err  :=  podutil . FindPort ( pod ,  servicePort ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													klog . V ( 4 ) . Infof ( "Failed to find port for service %s/%s: %v" ,  service . Namespace ,  service . Name ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 09:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												epp  :=  endpointPortFromServicePort ( servicePort ,  portNum ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												var  readyEps ,  notReadyEps  int 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-22 18:21:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												subsets ,  readyEps ,  notReadyEps  =  addEndpointSubset ( subsets ,  pod ,  epa ,  epp ,  service . Spec . PublishNotReadyAddresses ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												totalReadyEps  =  totalReadyEps  +  readyEps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												totalNotReadyEps  =  totalNotReadyEps  +  notReadyEps 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-10 09:28:53 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-21 06:32:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									subsets  =  endpoints . RepackSubsets ( subsets ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// See if there's actually an update here.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									currentEndpoints ,  err  :=  e . endpointsLister . Endpoints ( service . Namespace ) . Get ( service . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  errors . IsNotFound ( err )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											currentEndpoints  =  & v1 . Endpoints { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 11:38:19 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ObjectMeta :  metav1 . ObjectMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													Name :    service . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Labels :  service . Labels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-03 02:59:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-13 01:01:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									createEndpoints  :=  len ( currentEndpoints . ResourceVersion )  ==  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 01:16:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Compare the sorted subsets and labels
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Remove the HeadlessService label from the endpoints if it exists,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// as this won't be set on the service itself
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// and will cause a false negative in this diff check.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// But first check if it has that label to avoid expensive copies.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									compareLabels  :=  currentEndpoints . Labels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  _ ,  ok  :=  currentEndpoints . Labels [ v1 . IsHeadlessService ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										compareLabels  =  utillabels . CloneAndRemoveLabel ( currentEndpoints . Labels ,  v1 . IsHeadlessService ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 23:43:36 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// When comparing the subsets, we ignore the difference in ResourceVersion of Pod to avoid unnecessary Endpoints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// updates caused by Pod updates that we don't care, e.g. annotation update.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-13 01:01:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ! createEndpoints  && 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 23:43:36 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										endpointutil . EndpointSubsetsEqualIgnoreResourceVersion ( currentEndpoints . Subsets ,  subsets )  && 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										apiequality . Semantic . DeepEqual ( compareLabels ,  service . Labels )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										capacityAnnotationSetCorrectly ( currentEndpoints . Annotations ,  currentEndpoints . Subsets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										klog . V ( 5 ) . Infof ( "endpoints are equal for %s/%s, skipping update" ,  service . Namespace ,  service . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-15 20:14:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									newEndpoints  :=  currentEndpoints . DeepCopy ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									newEndpoints . Subsets  =  subsets 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									newEndpoints . Labels  =  service . Labels 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-03 02:59:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  newEndpoints . Annotations  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										newEndpoints . Annotations  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 23:39:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ! endpointsLastChangeTriggerTime . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										newEndpoints . Annotations [ v1 . EndpointsLastChangeTriggerTime ]  = 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 13:43:11 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											endpointsLastChangeTriggerTime . UTC ( ) . Format ( time . RFC3339Nano ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-20 18:48:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  {  // No new trigger time, clear the annotation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										delete ( newEndpoints . Annotations ,  v1 . EndpointsLastChangeTriggerTime ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-24 23:37:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  truncateEndpoints ( newEndpoints )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										newEndpoints . Annotations [ v1 . EndpointsOverCapacity ]  =  truncated 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										delete ( newEndpoints . Annotations ,  v1 . EndpointsOverCapacity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 03:55:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  newEndpoints . Labels  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										newEndpoints . Labels  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! helper . IsServiceIPSet ( service )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 04:30:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										newEndpoints . Labels  =  utillabels . CloneAndAddLabel ( newEndpoints . Labels ,  v1 . IsHeadlessService ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 03:55:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 04:30:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										newEndpoints . Labels  =  utillabels . CloneAndRemoveLabel ( newEndpoints . Labels ,  v1 . IsHeadlessService ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 03:55:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									klog . V ( 4 ) . Infof ( "Update endpoints for %v/%v, ready: %d not ready: %d" ,  service . Namespace ,  service . Name ,  totalReadyEps ,  totalNotReadyEps ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 23:39:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  createEndpoints  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										// No previous endpoints, create them
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										_ ,  err  =  e . client . CoreV1 ( ) . Endpoints ( service . Namespace ) . Create ( ctx ,  newEndpoints ,  metav1 . CreateOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Pre-existing
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-23 02:27:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										_ ,  err  =  e . client . CoreV1 ( ) . Endpoints ( service . Namespace ) . Update ( ctx ,  newEndpoints ,  metav1 . UpdateOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 23:39:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  createEndpoints  &&  errors . IsForbidden ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// A request is forbidden primarily for two reasons:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// 1. namespace is terminating, endpoint creation is not allowed by default.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// 2. policy is misconfigured, in which case no service would function anywhere.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Given the frequency of 1, we log at a lower level.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											klog . V ( 5 ) . Infof ( "Forbidden from creating endpoints: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-21 04:04:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// If the namespace is terminating, creates will continue to fail. Simply drop the item.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  errors . HasStatusCause ( err ,  v1 . NamespaceTerminatingCause )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 23:39:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 03:31:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  createEndpoints  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											e . eventRecorder . Eventf ( newEndpoints ,  v1 . EventTypeWarning ,  "FailedToCreateEndpoint" ,  "Failed to create endpoint for service %v/%v: %v" ,  service . Namespace ,  service . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											e . eventRecorder . Eventf ( newEndpoints ,  v1 . EventTypeWarning ,  "FailedToUpdateEndpoint" ,  "Failed to update endpoint %v/%v: %v" ,  service . Namespace ,  service . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-11 15:34:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// checkLeftoverEndpoints lists all currently existing endpoints and adds their
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// service to the queue. This will detect endpoints that exist with no
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// corresponding service; these endpoints need to be deleted. We only need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// do this once on startup, because in steady-state these are detected (but
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// some stragglers could have been left behind if the endpoint controller
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// reboots).
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-01 15:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * Controller )  checkLeftoverEndpoints ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									list ,  err  :=  e . endpointsLister . List ( labels . Everything ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										utilruntime . HandleError ( fmt . Errorf ( "Unable to list endpoints (%v); orphaned endpoints will not be cleaned up. (They're pretty harmless, but you can restart this component if you want another attempt made.)" ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-19 23:47:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  ep  :=  range  list  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-08 17:16:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  _ ,  ok  :=  ep . Annotations [ resourcelock . LeaderElectionRecordAnnotationKey ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// when there are multiple controller-manager instances,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// we observe that it will delete leader-election endpoints after 5min
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// and cause re-election
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// so skip the delete here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// as leader-election only have endpoints without service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-03 16:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										key ,  err  :=  controller . KeyFunc ( ep ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 18:30:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											utilruntime . HandleError ( fmt . Errorf ( "Unable to get key for endpoint %#v" ,  ep ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-22 18:21:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// addEndpointSubset add the endpoints addresses and ports to the EndpointSubset.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// The addresses are added to the corresponding field, ready or not ready, depending
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// on the pod status and the Service PublishNotReadyAddresses field value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-28 05:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// The pod passed to this function must have already been filtered through ShouldPodBeInEndpoints.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  addEndpointSubset ( subsets  [ ] v1 . EndpointSubset ,  pod  * v1 . Pod ,  epa  v1 . EndpointAddress , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-13 06:42:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									epp  * v1 . EndpointPort ,  tolerateUnreadyEndpoints  bool )  ( [ ] v1 . EndpointSubset ,  int ,  int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 18:55:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  readyEps  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  notReadyEps  int 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-13 06:42:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ports  :=  [ ] v1 . EndpointPort { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  epp  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ports  =  append ( ports ,  * epp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  tolerateUnreadyEndpoints  ||  podutil . IsPodReady ( pod )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										subsets  =  append ( subsets ,  v1 . EndpointSubset { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Addresses :  [ ] v1 . EndpointAddress { epa } , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-13 06:42:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											Ports :      ports , 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										readyEps ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-22 18:21:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  {  // if it is not a ready address it has to be not ready
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-10 02:49:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										klog . V ( 5 ) . Infof ( "Pod is out of service: %s/%s" ,  pod . Namespace ,  pod . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										subsets  =  append ( subsets ,  v1 . EndpointSubset { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											NotReadyAddresses :  [ ] v1 . EndpointAddress { epa } , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-13 06:42:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											Ports :              ports , 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-09 23:22:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										notReadyEps ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  subsets ,  readyEps ,  notReadyEps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-14 15:54:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 09:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  endpointPortFromServicePort ( servicePort  * v1 . ServicePort ,  portNum  int )  * v1 . EndpointPort  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									epp  :=  & v1 . EndpointPort { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-07 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Name :         servicePort . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Port :         int32 ( portNum ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Protocol :     servicePort . Protocol , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AppProtocol :  servicePort . AppProtocol , 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 09:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  epp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// capacityAnnotationSetCorrectly returns false if number of endpoints is greater than maxCapacity or
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// returns true if underCapacity and the annotation is not set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  capacityAnnotationSetCorrectly ( annotations  map [ string ] string ,  subsets  [ ] v1 . EndpointSubset )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									numEndpoints  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  subset  :=  range  subsets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										numEndpoints  +=  len ( subset . Addresses )  +  len ( subset . NotReadyAddresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  numEndpoints  >  maxCapacity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If subsets are over capacity, they must be truncated so consider
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// the annotation as not set correctly
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									_ ,  ok  :=  annotations [ v1 . EndpointsOverCapacity ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ! ok 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// truncateEndpoints by best effort will distribute the endpoints over the subsets based on the proportion
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// of endpoints per subset and will prioritize Ready Endpoints over NotReady Endpoints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  truncateEndpoints ( endpoints  * v1 . Endpoints )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									totalReady  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									totalNotReady  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  subset  :=  range  endpoints . Subsets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										totalReady  +=  len ( subset . Addresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										totalNotReady  +=  len ( subset . NotReadyAddresses ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 02:26:46 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  totalReady + totalNotReady  <=  maxCapacity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									truncateReady  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									max  :=  maxCapacity  -  totalReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									numTotal  :=  totalNotReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  totalReady  >  maxCapacity  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										truncateReady  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										max  =  maxCapacity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										numTotal  =  totalReady 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									canBeAdded  :=  max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  endpoints . Subsets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										subset  :=  endpoints . Subsets [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										numInSubset  :=  len ( subset . Addresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! truncateReady  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											numInSubset  =  len ( subset . NotReadyAddresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// The number of endpoints per subset will be based on the propotion of endpoints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// in this subset versus the total number of endpoints. The proportion of endpoints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// will be rounded up which most likely will lead to the last subset having less
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// endpoints than the expected proportion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										toBeAdded  :=  int ( math . Ceil ( ( float64 ( numInSubset )  /  float64 ( numTotal ) )  *  float64 ( max ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If there is not enough endpoints for the last subset, ensure only the number up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// to the capacity are added
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  toBeAdded  >  canBeAdded  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											toBeAdded  =  canBeAdded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  truncateReady  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Truncate ready Addresses to allocated proportion and truncate all not ready
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// addresses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											subset . Addresses  =  addressSubset ( subset . Addresses ,  toBeAdded ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											subset . NotReadyAddresses  =  [ ] v1 . EndpointAddress { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											canBeAdded  -=  len ( subset . Addresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Only truncate the not ready addresses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											subset . NotReadyAddresses  =  addressSubset ( subset . NotReadyAddresses ,  toBeAdded ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											canBeAdded  -=  len ( subset . NotReadyAddresses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										endpoints . Subsets [ i ]  =  subset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// addressSubset takes a list of addresses and returns a subset if the length is greater
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// than the maxNum. If less than the maxNum, the entire list is returned.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  addressSubset ( addresses  [ ] v1 . EndpointAddress ,  maxNum  int )  [ ] v1 . EndpointAddress  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( addresses )  <=  maxNum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  addresses 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  addresses [ 0 : maxNum ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 09:54:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								}