Use actual lease duration from Kubernetes object in leader election
LeaderElector.TryAcquireOrRenew was using the locally configured lease duration instead of the value from the Kubernetes object, breaking graceful step-downs where leaders signal their departure by setting lease duration to 1 second.
Changes
- Use
oldLeaderElectionRecord.LeaseDurationSecondsfrom the Kubernetes object instead ofconfig.LeaseDurationwhen checking lease expiration
// Before: ignores actual lease duration from K8s
if (!string.IsNullOrEmpty(oldLeaderElectionRecord.HolderIdentity)
&& observedTime + config.LeaseDuration > DateTimeOffset.Now
&& !IsLeader())
// After: respects actual lease duration from K8s object
if (!string.IsNullOrEmpty(oldLeaderElectionRecord.HolderIdentity)
&& observedTime + TimeSpan.FromSeconds(oldLeaderElectionRecord.LeaseDurationSeconds) > DateTimeOffset.Now
&& !IsLeader())
This aligns the C# implementation with the Go client-go behavior.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
crl.comodoca.com
- Triggering command:
/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot e9f9(dns block)ocsp.comodoca.com
- Triggering command:
/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot e9f9(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to the custom allowlist in this repository's Copilot coding agent settings (admins only)
Original prompt
This section details on the original issue you should resolve
<issue_title>Actual lease duration is ignored in LeaderElector.TryAcquireOrRenew</issue_title> <issue_description>Describe the bug LeaderElector.TryAcquireOrRenew uses the lease duration from the local configuration, instead of the Kubernetes object, assuming that the two values are the same.
This might not be true during graceful step downs, as libraries like the one for Golang set the lease duration to 1 second as a way to signal the leader has stepped down. C# clients would ignore this and still wait for the entire pre-configured duration of the lease before trying to acquire the lease.
This behaviour also differs from the Golang library, which uses the lease duration from the actual Kubernetes object.
Kubernetes C# SDK Client Version 14.0.2
Server Kubernetes Version 1.30.13
Dotnet Runtime Version net8
To Reproduce Create a lease and change its duration to 1s
Expected behavior Non-leader C# clients should try to take the lease
Where do you run your app with Kubernetes SDK (please complete the following information):
- OS: Linux
- Environment: Container
- Cloud: AWS and on-prem </issue_description>
<agent_instructions>fix this</agent_instructions>
Comments on the Issue (you are @copilot in this section)
@tg123 agreed, there is some gap between the golang and .net and those should be filled, let me take a look@k8s-ci-robot @k8s-triage-robot: Closing this issue, marking it as "Not Planned".In response to this:
The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.
This bot triages issues according to the following rules:
- After 90d of inactivity,
lifecycle/staleis applied- After 30d of inactivity since
lifecycle/stalewas applied,lifecycle/rottenis applied- After 30d of inactivity since
lifecycle/rottenwas applied, the issue is closedYou can:
- Reopen this issue with
/reopen- Mark this issue as fresh with
/remove-lifecycle rotten- Offer to help out with Issue Triage
Please send feedback to sig-contributor-experience at kubernetes/community.
/close not-planned
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.
- Fixes kubernetes-client/csharp#1640
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
[APPROVALNOTIFIER] This PR is NOT APPROVED
This pull-request has been approved by: Copilot Once this PR has been reviewed and has the lgtm label, please ask for approval from tg123. For more information see the Code Review Process.
The full list of commands accepted by this bot can be found here.
Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment
[APPROVALNOTIFIER] This PR is NOT APPROVED
This pull-request has been approved by: Copilot Once this PR has been reviewed and has the lgtm label, please ask for approval from tg123. For more information see the Code Review Process.
The full list of commands accepted by this bot can be found here.
Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment