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

相关推荐
红尘客栈26 小时前
Kubernetes 集群调度
java·linux·网络·容器·kubernetes
m0_464608266 小时前
Kubernetes 集群调度与PV和PVC
云原生·容器·kubernetes
Syntech_Wuz8 小时前
从 C 到 C++:容器适配器 std::stack 与 std::queue 详解
数据结构·c++·容器··队列
熙客12 小时前
阿里云负载均衡SLB的使用
网络·阿里云·云原生·云计算·负载均衡
yannan201903131 天前
Docker容器
运维·docker·容器
小宁爱Python1 天前
Windows Docker Desktop占用C盘空间过大解决办法集合
运维·docker·容器
JAVA学习通1 天前
发布自己的 jar 包到 Maven 中央仓库 ( mvnrepository.com )
人工智能·docker·自然语言处理·容器·rocketmq
Cloud孙文波1 天前
探索Apache APISIX:动态高性能API网关
云原生·kubernetes·apisix
木亦汐丫1 天前
Docker 镜像版本Alpine、Slim、Bookworm、Bullseye、Stretch、Jessie
运维·docker·容器·debian·alpine·slim·bullseye