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

相关推荐
敲上瘾29 分钟前
Docker镜像构建优化指南:CMD/ENTRYPOINT、多阶段构建与缓存优化
运维·缓存·docker·容器·架构
❀͜͡傀儡师4 小时前
docker安装mac系统
macos·docker·容器
0***146 小时前
PHP在微服务中的架构设计
微服务·云原生·架构
RUNNING123!8 小时前
RedHat 7.9 docker 安装 zabbix
docker·容器·zabbix
weixin_449290019 小时前
docker_ollama
docker·容器·eureka
weixin_537765809 小时前
【容器技术】虚拟化原理与Docker详解
运维·docker·容器
虚伪的空想家10 小时前
arm架构服务器使用kvm创建虚机报错,romfile “efi-virtio.rom“ is empty
linux·运维·服务器·javascript·arm开发·云原生·kvm
u***u68510 小时前
云原生架构2025年趋势:Serverless与边缘计算
云原生·架构·serverless
火车头-11011 小时前
【docker 部署nacos1.4.7】
运维·docker·容器
j2001032211 小时前
Docker 部署与管理
docker·容器·eureka