#kubernetes #lease #leader #election #resource-manager #kubernetes-cluster #async

kube-lease-manager

使用 Kubernetes Lease API 的舒适且可靠的领导者选举

8 个版本

0.2.0 2024 年 7 月 24 日
0.1.6 2024 年 7 月 24 日

#186异步

Download history 343/week @ 2024-07-05 114/week @ 2024-07-12 200/week @ 2024-07-19 137/week @ 2024-07-26 54/week @ 2024-08-02 10/week @ 2024-08-09

404 每月下载

MIT 许可证

110KB
1.5K SLoC

kube-lease-manager

使用 Kubernetes Lease API 进行舒适且可靠的领导者选举。

CI status Audit status Crates.io publishing status docs.rs status Version at Crates.io License

kube-lease-manager 是一个高级助手,用于简化使用 Lease Kubernetes 资源 进行领导者选举。它确保在任何时刻只有一个实例的租约管理器持有锁。

一些典型用例

  • 自动协调多个 Kubernetes 控制器实例(Pod)之间的领导者选举;
  • 确保现在只有一个并发作业正在运行;
  • 独占获取共享资源。

功能

  • LeaseManager 是库的核心部分。这是一个 Kubernetes Lease 资源的便捷包装,用于管理领导者选举过程的各个方面。
  • 提供两种不同的高级方法来锁定和释放租约:完全自动化或部分手动锁定控制。
  • 使用 Server-Side-Apply 方法更新租约状态,这有助于冲突检测和解决,并使并发锁定成为不可能。
  • 容忍 Kubernetes 集群节点之间的可配置时间偏差。
  • 租约管理器的行为参数可以轻松灵活地配置。
  • 使用知名且高度赞赏的 kubeTokio 库来访问 Kubernetes API 并协调异步任务执行。
  • 您不需要使用低级 Kubernetes API。
  • 使用 Tokio tracing 库提供事件日志。

请访问 crate 的文档 以获取详细信息和其他示例。


如上所述,kube-lease-manager 提供了两种管理租约锁的可能方法

  1. 全自动:您创建 LeaseManager 实例并运行其 watch() 方法。它返回 Tokio 监视通道 以监视状态变化。除此之外,它还运行一个无需管理的后台任务,该任务持续尝试锁定租约(如果可用)并将更改后的状态发布到通道。当通道关闭时,任务完成。
  2. 部分手动:您创建 LeaseManager 实例并使用其 changed()release() 方法来控制锁定。当租约变为可用时,changed() 会立即尝试锁定租约并返回实际锁定状态。您的责任包括:
    • 保持 changed() 运行(它是一个 Future),以确保在租约使用期间刷新锁定状态;
    • 当您不再需要锁定并希望将其释放给其他人时,调用 release()

第一种方式确保在任何时间点租约都处于锁定状态(有持有者)。第二种方式使您能够在需要时获取和释放锁定。

示例

使用第一种锁定方法的简单示例

use kube::Client;
use kube_lease_manager::{LeaseManagerBuilder, Result};
use std::time::Duration;

#[tokio::main]
async fn main() {
   // Use default Kube client
   let client = Client::try_default().await?;
   // Create the simplest LeaseManager with reasonable defaults using convenient builder.
   // It uses Lease resource called `test-watch-lease`.
   let manager = LeaseManagerBuilder::new(client, "test-watch-lease")
           .build()
           .await?;

   let (mut channel, task) = manager.watch().await;
   // Watch on the channel for lock state changes
   tokio::select! {
        _ = channel.changed() => {
            let lock_state = *channel.borrow_and_update();

            if lock_state {
                // Do something useful as a leader
                println!("Got a luck!");
            }
        }
        _ = tokio::time::sleep(Duration::from_secs(10)) => {
            println!("Unable get lock during 10s");
        }
    }

   // Explicitly close the control channel
   drop(channel);
   // Wait for the finish of the manager and get it back
   let _manager = tokio::join!(task).0.unwrap()?;

   Ok(())
}

请访问 crate 的文档 获取更多示例和用法细节。

待办事项

  • 提供一些真实且有用的示例。

致谢

作者受到两个其他提供类似功能的 crate 的启发: kubertkube-leader-election。它们都很棒,感谢作者们。但它们都缺少我项目中的一个东西。因此,这是创建这个的原因。

许可证

本项目根据 MIT 许可证 许可。

依赖关系

~66MB
~1M SLoC