k8s lease使用案例

下面给你一个 完整可运行的 Go 示例 ,演示如何使用 Kubernetes 的 Lease 实现 leader 选举机制

这个示例使用官方 client-go 提供的 leaderelection 库,能在多个副本间自动选主、续约、切换。


🧩 示例结构

复制代码
lease-demo/
├── main.go
├── go.mod
└── go.sum

📦 1. go.mod

go 复制代码
module lease-demo

go 1.20

require (
	k8s.io/client-go v0.30.0
	k8s.io/apimachinery v0.30.0
)

🧠 2. main.go

go 复制代码
package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"time"

	v1 "k8s.io/api/coordination/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/leaderelection"
	"k8s.io/client-go/tools/leaderelection/resourcelock"
)

func main() {
	var leaseName, leaseNamespace string
	flag.StringVar(&leaseName, "lease-name", "demo-lease", "Name of the lease resource")
	flag.StringVar(&leaseNamespace, "lease-namespace", "default", "Namespace of the lease resource")
	flag.Parse()

	// 1️⃣ 连接集群(使用 InCluster 或本地 kubeconfig)
	cfg, err := rest.InClusterConfig()
	if err != nil {
		fmt.Println("Not in cluster, try kubeconfig")
		cfg, err = rest.InClusterConfig()
		if err != nil {
			panic(err)
		}
	}
	clientset, err := kubernetes.NewForConfig(cfg)
	if err != nil {
		panic(err)
	}

	// 2️⃣ 设置租约对象(LeaseLock)
	id, _ := os.Hostname()
	lock := &resourcelock.LeaseLock{
		LeaseMeta: metav1.ObjectMeta{
			Name:      leaseName,
			Namespace: leaseNamespace,
		},
		Client: clientset.CoordinationV1(),
		LockConfig: resourcelock.ResourceLockConfig{
			Identity: id,
		},
	}

	// 3️⃣ 创建上下文
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 4️⃣ Leader 选举配置
	leaderelectionCfg := leaderelection.LeaderElectionConfig{
		Lock:            lock,
		LeaseDuration:   15 * time.Second, // 租约有效期
		RenewDeadline:   10 * time.Second, // 续约截止时间
		RetryPeriod:     2 * time.Second,  // 重试间隔
		ReleaseOnCancel: true,
		Name:            "lease-demo-election",
		Callbacks: leaderelection.LeaderCallbacks{
			OnStartedLeading: func(ctx context.Context) {
				fmt.Printf("[%s] ✅ 成为 leader,开始执行任务...\n", id)
				for {
					select {
					case <-ctx.Done():
						return
					default:
						fmt.Printf("[%s] 正在执行任务中...\n", id)
						time.Sleep(5 * time.Second)
					}
				}
			},
			OnStoppedLeading: func() {
				fmt.Printf("[%s] ❌ 失去 leader 身份\n", id)
			},
			OnNewLeader: func(identity string) {
				if identity == id {
					fmt.Printf("[%s] 🏆 我是当前 leader\n", id)
				} else {
					fmt.Printf("[%s] 当前 leader 是 %s\n", id, identity)
				}
			},
		},
	}

	// 5️⃣ 启动 leader 选举
	leaderelection.RunOrDie(ctx, leaderelectionCfg)
}

🚀 3. 构建镜像 & 部署

Dockerfile

dockerfile 复制代码
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
RUN go mod tidy && go build -o lease-demo .

FROM alpine:3.18
COPY --from=builder /app/lease-demo /lease-demo
ENTRYPOINT ["/lease-demo"]

Kubernetes Deployment 示例

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lease-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: lease-demo
  template:
    metadata:
      labels:
        app: lease-demo
    spec:
      serviceAccountName: lease-demo-sa
      containers:
      - name: lease-demo
        image: yourrepo/lease-demo:latest
        args: ["--lease-name=demo-lease", "--lease-namespace=default"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: lease-demo-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: lease-demo-role
  namespace: default
rules:
- apiGroups: ["coordination.k8s.io"]
  resources: ["leases"]
  verbs: ["get", "watch", "list", "update", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: lease-demo-rb
  namespace: default
subjects:
- kind: ServiceAccount
  name: lease-demo-sa
roleRef:
  kind: Role
  name: lease-demo-role
  apiGroup: rbac.authorization.k8s.io

🧾 4. 运行效果

部署后:

bash 复制代码
kubectl logs -l app=lease-demo -f

输出类似:

复制代码
[node1] 🏆 我是当前 leader
[node1] ✅ 成为 leader,开始执行任务...
[node2] 当前 leader 是 node1
[node3] 当前 leader 是 node1
...
(node1 被删除后)
[node2] 🏆 我是当前 leader
[node2] ✅ 成为 leader,开始执行任务...

✅ 5. 小结

功能 描述
LeaseLock 使用 coordination.k8s.io/v1 的 Lease 实现选举
LeaseDuration leader 失效超时时间
RenewDeadline leader 续租截止时间
RetryPeriod 非 leader 的重试时间
OnStartedLeading 成为 leader 后执行的逻辑
OnStoppedLeading 失去 leader 时触发
OnNewLeader 每次 leader 切换都会回调

是否希望我再帮你生成一个对应的 可直接运行的 YAML + Go 代码打包 zip 文件 ?(可以直接 kubectl apply -f 运行)

相关推荐
Dobby_05几秒前
【Docker】容器网络探索(二):实战理解 host 网络
网络·docker·云原生
橙色云-智橙协同研发4 小时前
从 CAD 图纸到 Excel 数据:橙色云智橙 PLM 打造制造企业数字化协同新模式
大数据·功能测试·云原生·cad·plm·云plm·bom提取
Wang's Blog8 小时前
Nestjs框架: 微服务事件驱动通信与超时处理机制优化基于Event-Based 通信及异常捕获实践
微服务·云原生·架构·nestjs
YXWik69 小时前
新版若依微服务增强swagger增强集成knife4j
微服务·云原生·架构
马达加斯加D9 小时前
k8s --- Intro
云原生·容器·kubernetes
梁正雄12 小时前
16、Docker swarm-3
运维·docker·容器
爱吃糖的小秦同学13 小时前
Docker爆红且安装非C盘处理方案
运维·docker·容器
!chen13 小时前
k8s-应用部署和组件及常用命令
云原生·容器·kubernetes
Solar202514 小时前
微服务调用超时:从问题分析到全链路优化实践
微服务·云原生·架构
亿牛云爬虫专家15 小时前
用 Playwright + 容器化做分布式浏览器栈:调度、会话管理与资源回收
分布式·docker·容器·浏览器·爬虫代理·新闻网站·playwright