github.com/nginxinc/kubernetes-ingress@v1.12.5/internal/k8s/leader.go (about)

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/golang/glog"
     9  
    10  	v1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/client-go/kubernetes"
    13  	"k8s.io/client-go/kubernetes/scheme"
    14  	"k8s.io/client-go/tools/leaderelection"
    15  	"k8s.io/client-go/tools/leaderelection/resourcelock"
    16  	"k8s.io/client-go/tools/record"
    17  )
    18  
    19  // newLeaderElector creates a new LeaderElection and returns the Elector.
    20  func newLeaderElector(client kubernetes.Interface, callbacks leaderelection.LeaderCallbacks, namespace string, lockName string) (*leaderelection.LeaderElector, error) {
    21  	podName := os.Getenv("POD_NAME")
    22  
    23  	broadcaster := record.NewBroadcaster()
    24  	hostname, _ := os.Hostname()
    25  
    26  	source := v1.EventSource{Component: "nginx-ingress-leader-elector", Host: hostname}
    27  	recorder := broadcaster.NewRecorder(scheme.Scheme, source)
    28  
    29  	lock := resourcelock.ConfigMapLock{
    30  		ConfigMapMeta: metav1.ObjectMeta{Namespace: namespace, Name: lockName},
    31  		Client:        client.CoreV1(),
    32  		LockConfig: resourcelock.ResourceLockConfig{
    33  			Identity:      podName,
    34  			EventRecorder: recorder,
    35  		},
    36  	}
    37  
    38  	ttl := 30 * time.Second
    39  	return leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
    40  		Lock:          &lock,
    41  		LeaseDuration: ttl,
    42  		RenewDeadline: ttl / 2,
    43  		RetryPeriod:   ttl / 4,
    44  		Callbacks:     callbacks,
    45  	})
    46  }
    47  
    48  // createLeaderHandler builds the handler funcs for leader handling
    49  func createLeaderHandler(lbc *LoadBalancerController) leaderelection.LeaderCallbacks {
    50  	return leaderelection.LeaderCallbacks{
    51  		OnStartedLeading: func(ctx context.Context) {
    52  			glog.V(3).Info("started leading")
    53  			if lbc.reportIngressStatus {
    54  				ingresses := lbc.configuration.GetResourcesWithFilter(resourceFilter{Ingresses: true})
    55  
    56  				glog.V(3).Infof("Updating status for %v Ingresses", len(ingresses))
    57  
    58  				err := lbc.statusUpdater.UpdateExternalEndpointsForResources(ingresses)
    59  				if err != nil {
    60  					glog.V(3).Infof("error updating status when starting leading: %v", err)
    61  				}
    62  			}
    63  
    64  			if lbc.areCustomResourcesEnabled {
    65  				glog.V(3).Info("updating VirtualServer and VirtualServerRoutes status")
    66  
    67  				err := lbc.updateVirtualServersStatusFromEvents()
    68  				if err != nil {
    69  					glog.V(3).Infof("error updating VirtualServers status when starting leading: %v", err)
    70  				}
    71  
    72  				err = lbc.updateVirtualServerRoutesStatusFromEvents()
    73  				if err != nil {
    74  					glog.V(3).Infof("error updating VirtualServerRoutes status when starting leading: %v", err)
    75  				}
    76  
    77  				err = lbc.updatePoliciesStatus()
    78  				if err != nil {
    79  					glog.V(3).Infof("error updating Policies status when starting leading: %v", err)
    80  				}
    81  
    82  				err = lbc.updateTransportServersStatusFromEvents()
    83  				if err != nil {
    84  					glog.V(3).Infof("error updating TransportServers status when starting leading: %v", err)
    85  				}
    86  			}
    87  		},
    88  		OnStoppedLeading: func() {
    89  			glog.V(3).Info("stopped leading")
    90  		},
    91  	}
    92  }