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 运行)

相关推荐
阿里云云原生1 天前
阿里云获评 Agentic AI 开发平台领导者,函数计算 AgentRun 赢下关键分!
云原生
蝎子莱莱爱打怪1 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes
崔小汤呀1 天前
Docker部署Nacos
docker·容器
缓解AI焦虑1 天前
Docker + K8s 部署大模型推理服务:资源划分与多实例调度
docker·容器
阿里云云原生1 天前
MSE Nacos Prompt 管理:让 AI Agent 的核心配置真正可治理
微服务·云原生
阿里云云原生2 天前
当 AI Agent 接管手机:移动端如何进行观测
云原生·agent
阿里云云原生2 天前
AI 原生应用开源开发者沙龙·深圳站精彩回顾 & PPT下载
云原生
阿里云云原生2 天前
灵感启发:日产文章 100 篇,打造“实时热点洞察”引擎
云原生
1candobetter2 天前
Docker Compose Build 与 Up 的区别:什么时候必须重建镜像
docker·容器·eureka
~莫子2 天前
Haproxy七层负载详解+实验详细代码
云原生