pub struct LeaderElection { /* private fields */ }Expand description
Lease-based leader election, allowing multiple replicas of a controller to run while ensuring that only one of them is reconciling at a time.
This uses a coordination.k8s.io/v1 Lease object, following the same
protocol (and using the same default timings) as the Kubernetes client-go
leaderelection package: the leader repeatedly renews the lease, and
other candidates take the lease over if the leader fails to renew it for
lease_duration. Expiry is determined by observing the lease go
unchanged for lease_duration, rather than by comparing timestamps in
the lease against the local clock, so it is robust to clock skew between
candidates. Note that this protocol is cooperative: it guarantees mutual
exclusion only among candidates that respect the lease.
The controller’s service account needs get, create, and update
permissions on leases in the coordination.k8s.io API group for this
to work.
The identity must be non-empty and unique among the candidates for a
given lease; the pod name (available in the HOSTNAME environment
variable, or via the downward API) is a good choice. Beware that
candidates for the same lease which share an identity will each mistake
the other’s renewals for their own and all act as leader simultaneously,
so never create multiple LeaderElections in the same process with the
same lease name and identity. To have one lease guard several
controllers in a process, share a single LeaderElection via
with_lease instead.
Implementations§
Source§impl LeaderElection
impl LeaderElection
Sourcepub fn new(
client: Client,
namespace: &str,
lease_name: &str,
identity: &str,
) -> Self
pub fn new( client: Client, namespace: &str, lease_name: &str, identity: &str, ) -> Self
Creates a leader election configuration for the Lease named
lease_name in the given namespace, identifying this instance of
the controller as identity. The timings default to the client-go
defaults: a lease duration of 15 seconds, a renew deadline of 10
seconds, and a retry period of 2 seconds.
Sourcepub fn with_lease_duration(self, lease_duration: Duration) -> Self
pub fn with_lease_duration(self, lease_duration: Duration) -> Self
Sets how long a non-leader must wait after the last observed change to the lease before forcibly taking it over. Larger values slow down failover; smaller values increase the risk that a leader which is still running (but partitioned from the API server) has not yet stopped reconciling when the new leader starts. Must be greater than the renew deadline.
Sourcepub fn with_renew_deadline(self, renew_deadline: Duration) -> Self
pub fn with_renew_deadline(self, renew_deadline: Duration) -> Self
Sets how long the leader will keep trying to renew the lease before giving up leadership. Must be less than the lease duration (so that a leader which cannot reach the API server gives up before another candidate can take the lease over) and greater than the retry period.
Sourcepub fn with_retry_period(self, retry_period: Duration) -> Self
pub fn with_retry_period(self, retry_period: Duration) -> Self
Sets how often candidates poll the lease while waiting to acquire it, and how often the leader renews it.
Sourcepub async fn with_lease<F: Future>(&self, fut: F) -> Option<F::Output>
pub async fn with_lease<F: Future>(&self, fut: F) -> Option<F::Output>
Wait until this instance holds the lease, then run fut while
renewing the lease in the background.
If leadership is lost (because the lease could not be renewed in
time, or was taken over by another candidate), fut is dropped,
cancelling its work, and this method returns None. The caller
should then promptly either exit the process (letting Kubernetes
restart it) or rejoin the election by calling this method again.
Note that dropping fut cancels it cooperatively: work it has
spawned as separate tasks, or blocking code, is not cancelled. If
fut does such things, prefer exiting the process so that no work
outlives the lease.
If fut completes on its own, the lease is voluntarily released
(handing leadership over immediately rather than making the other
candidates wait for it to expire) and its output is returned.
To run a Controller under a lease, pass its
run future; to have one lease guard
several controllers (rather than electing a separate leader per
controller), pass a future that runs all of them, for instance:
leader_election
.with_lease(futures::future::join(controller_a.run(), controller_b.run()))
.await;During graceful shutdown (for instance, on receiving a termination
signal), drop the future returned by this method to stop its work,
then call release on a clone of this
LeaderElection to hand leadership over immediately rather than
making the other replicas wait for the lease to expire.
Panics if the configured timings are inconsistent or the identity is empty.
Sourcepub async fn release(&self)
pub async fn release(&self)
Voluntarily release the lease if we hold it, allowing another
candidate to take it over immediately rather than waiting for it to
expire. Call this during graceful shutdown, after the controller has
stopped reconciling (for instance, after the future returned by
with_lease has been dropped in
response to a termination signal). This is best-effort: errors
are logged and ignored, since the lease will expire on its own
regardless.
Trait Implementations§
Source§impl Clone for LeaderElection
impl Clone for LeaderElection
Source§fn clone(&self) -> LeaderElection
fn clone(&self) -> LeaderElection
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for LeaderElection
impl !RefUnwindSafe for LeaderElection
impl Send for LeaderElection
impl Sync for LeaderElection
impl Unpin for LeaderElection
impl UnsafeUnpin for LeaderElection
impl !UnwindSafe for LeaderElection
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more