利用Kubernetes中的leaderelection实现组件高可用

【实践】 使用k8s的leader-election来实现多副本应用的选举 如何正确使用 leader-election, leader-election的常见概念和坑 阅读详情

在Kubernetes中,通常kube-schduler和kube-controller-manager都是多副本进行部署的来保证高可用,而真正在工作的实例其实只有一个。这里就利用到 leaderelection 的选主机制,保证leader是处于工作状态,并且在leader挂掉之后,从其他节点选取新的leader保证组件正常工作。

不单单只是k8s中的这两个组件用到,在其他服务中也可以看到这个包的使用,比如cluster-autoscaler等都能看得到这个包的,今天就来看看这个包的使用以及它内部是如何实现的。

使用

以下是一个简单使用的例子,编译完成之后同时启动多个进程,但是只有一个进程在工作,当把leader进程kill掉之后,会重新选举出一个leader进行工作,即执行其中的 run 方法:

/*
例子来源于client-go中的example包中
*/

package main

import (
    "context"
    "flag"
    "os"
    "os/signal"
    "syscall"
    "time"

    "github.com/google/uuid"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    clientset "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/tools/leaderelection"
    "k8s.io/client-go/tools/leaderelection/resourcelock"
    "k8s.io/klog"
)

func buildConfig(kubeconfig string) (*rest.Config, error) {
    if kubeconfig != "" {
        cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
        if err != nil {
            return nil, err
        }
        return cfg, nil
    }

    cfg, err := rest.InClusterConfig()
    if err != nil {
        return nil, err
    }
    return cfg, nil
}

func main() {
    klog.InitFlags(nil)

    var kubeconfig string
    var leaseLockName string
    var leaseLockNamespace string
    var id string

    flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
    flag.StringVar(&id, "id", uuid.New().String(), "the holder identity name")
    flag.StringVar(&leaseLockName, "lease-lock-name", "", "the lease lock resource name")
    flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "", "the lease lock resource namespace")
    flag.Parse()

    if leaseLockName == "" {
        klog.Fatal("unable to get lease lock resource name (missing lease-lock-name flag).")
    }
    if leaseLockNamespace == "" {
        klog.Fatal("unable to get lease lock resource namespace (missing lease-lock-namespace flag).")
    }

    // leader election uses the Kubernetes API by writing to a
    // lock object, which can be a LeaseLock object (preferred),
    // a ConfigMap, or an Endpoints (deprecated) object.
    // Conflicting writes are detected and each client handles those actions
    // independently.
    config, err := buildConfig(kubeconfig)
    if err != nil {
        klog.Fatal(err)
    }
    client := clientset.NewForConfigOrDie(config)

    run := func(ctx context.Context) {
        // complete your controller loop here
        klog.Info("Controller loop...")

        select {}
    }

    // use a Go context so we can tell the leaderelection code when we
    // want to step down
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // listen for interrupts or the Linux SIGTERM signal and cancel
    // our context, which the leader election code will observe and
    // step down
    ch := make(chan os.Signal, 1)
    signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-ch
        klog.Info("Received termination, signaling shutdown")
        cancel()
    }()

    // we use the Lease lock type since edits to Leases are less common
    // and fewer objects in the cluster watch "all Leases".
    // 指定锁的资源对象,这里使用了Lease资源,还支持configmap,endpoint,或者multilock(即多种配合使用)
    lock := &resourcelock.LeaseLock{
        LeaseMeta: metav1.ObjectMeta{
            Name:      leaseLockName,
            Namespace: leaseLockNamespace,
        },
        Client: client.CoordinationV1(),
        LockConfig: resourcelock.ResourceLockConfig{
            Identity: id,
        },
    }

    // start the leader election code loop
    leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
        Lock: lock,
        // IMPORTANT: you MUST ensure that any code you have that
        // is protected by the lease must terminate **before**
        // you call cancel. Otherwise, you could have a background
        // loop still running and another process could
        // get elected before your background loop finished, violating
        // the stated goal of the lease.
        ReleaseOnCancel: true,
        LeaseDuration:   60 * time.Second,//租约时间
        RenewDeadline:   15 * time.Second,//更新租约的
        RetryPeriod:     5 * time.Second,//非leader节点重试时间
        Callbacks: leaderelection.LeaderCallbacks{
            OnStartedLeading: func(ctx context.Context) {
                //变为leader执行的业务代码
                // we're notified when we start - this is where you would
                // usually put your code
                run(ctx)
            },
            OnStoppedLeading: func() {
                 // 进程退出
                // we can do cleanup here
                klog.Infof("leader lost: %s", id)
                os.Exit(0)
            },
            OnNewLeader: func(identity string) {
                //当产生新的leader后执行的方法
                // we're notified when new leader elected
                if identity == id {
                    // I just got the lock
                    return
                }
                klog.Infof("new leader elected: %s", identity)
            },
        },
    })
}

关键启动参数说明:

kubeconfig: 指定kubeconfig文件地址
lease-lock-name:指定lock的名称
lease-lock-namespace:指定lock存储的namespace
id: 例子中提供的区别参数,用于区分实例
logtostderr:klog提供的参数,指定log输出到控制台
v: 指定日志输出级别

同时启动两个进程:
启动进程1:

go run main.go -kubeconfig=/Users/silenceper/.kube/config -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=1 -v=4
I0215 19:56:37.049658   48045 leaderelection.go:242] attempting to acquire leader lease  default/example...
I0215 19:56:37.080368   48045 leaderelection.go:252] successfully acquired lease default/example
I0215 19:56:37.080437   48045 main.go:87] Controller loop...

启动进程2:

➜  leaderelection git:(master) ✗ go run main.go -kubeconfig=/Users/silenceper/.kube/config -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=2 -v=4
I0215 19:57:35.870051   48791 leaderelection.go:242] attempting to acquire leader lease  default/example...
I0215 19:57:35.894735   48791 leaderelection.go:352] lock is held by 1 and has not yet expired
I0215 19:57:35.894769   48791 leaderelection.go:247] failed to acquire lease default/example
I0215 19:57:35.894790   48791 main.go:151] new leader elected: 1
I0215 19:57:44.532991   48791 leaderelection.go:352] lock is held by 1 and has not yet expired
I0215 19:57:44.533028   48791 leaderelection.go:247] failed to acquire lease default/example

这里可以看出来id=1的进程持有锁,并且运行的程序,而id=2的进程表示无法获取到锁,在不断的进程尝试。

现在kill掉id=1进程,在等待lock释放之后(有个LeaseDuration时间),leader变为id=2的进程执行工作

I0215 20:01:41.489300   48791 leaderelection.go:252] successfully acquired lease default/example
I0215 20:01:41.489577   48791 main.go:87] Controller loop...

深入理解

基本原理其实就是利用通过Kubernetes中 configmap , endpoints 或者 lease 资源实现一个分布式锁,抢(acqure)到锁的节点成为leader,并且定期更新(renew)。其他进程也在不断的尝试进行抢占,抢占不到则继续等待下次循环。当leader节点挂掉之后,租约到期,其他节点就成为新的leader。

入口

通过 leaderelection.RunOrDie 启动,

func RunOrDie(ctx context.Context, lec LeaderElectionConfig) {
    le, err := NewLeaderElector(lec)
    if err != nil {
        panic(err)
    }
    if lec.WatchDog != nil {
        lec.WatchDog.SetLeaderElection(le)
    }
    le.Run(ctx)
}

传入参数 LeaderElectionConfig :

type LeaderElectionConfig struct {
    // Lock 的类型
    Lock rl.Interface
    //持有锁的时间
    LeaseDuration time.Duration
    //在更新租约的超时时间
    RenewDeadline time.Duration
    //竞争获取锁的时间
    RetryPeriod time.Duration
    //状态变化时执行的函数,支持三种:
    //1、OnStartedLeading 启动是执行的业务代码
    //2、OnStoppedLeading leader停止执行的方法
    //3、OnNewLeader 当产生新的leader后执行的方法
    Callbacks LeaderCallbacks

    //进行监控检查
    // WatchDog is the associated health checker
    // WatchDog may be null if its not needed/configured.
    WatchDog *HealthzAdaptor
    //leader退出时,是否执行release方法
    ReleaseOnCancel bool
    
    // Name is the name of the resource lock for debugging
    Name string
}

LeaderElectionConfig.lock 支持保存在以下三种资源中:
configmap 
endpoint 
lease 
包中还提供了一个 multilock ,即可以进行选择两种,当其中一种保存失败时,选择第二张
可以在interface.go中看到:

    switch lockType {
    case EndpointsResourceLock://保存在endpoints
        return endpointsLock, nil
    case ConfigMapsResourceLock://保存在configmaps
        return configmapLock, nil
    case LeasesResourceLock://保存在leases
        return leaseLock, nil
    case EndpointsLeasesResourceLock://优先尝试保存在endpoint失败时保存在lease
        return &MultiLock{
            Primary:   endpointsLock,
            Secondary: leaseLock,
        }, nil
    case ConfigMapsLeasesResourceLock://优先尝试保存在configmap,失败时保存在lease
        return &MultiLock{
            Primary:   configmapLock,
            Secondary: leaseLock,
        }, nil
    default:
        return nil, fmt.Errorf("Invalid lock-type %s", lockType)
    }

以lease资源对象为例,可以在查看到保存的内容:

➜  ~ kubectl get lease example -n default -o yaml
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
  creationTimestamp: "2020-02-15T11:56:37Z"
  name: example
  namespace: default
  resourceVersion: "210675"
  selfLink: /apis/coordination.k8s.io/v1/namespaces/default/leases/example
  uid: a3470a06-6fc3-42dc-8242-9d6cebdf5315
spec:
  acquireTime: "2020-02-15T12:01:41.476971Z"//获得锁时间
  holderIdentity: "2"//持有锁进程的标识
  leaseDurationSeconds: 60//lease租约
  leaseTransitions: 1//leader更换次数
  renewTime: "2020-02-15T12:05:37.134655Z"//更新租约的时间

关注其spec中的字段,分别进行标注,对应结构体如下:

type LeaderElectionRecord struct {
    HolderIdentity       string      `json:"holderIdentity"`//持有锁进程的标识,一般可以利用主机名
    LeaseDurationSeconds int         `json:"leaseDurationSeconds"`//  lock的租约
    AcquireTime          metav1.Time `json:"acquireTime"`//持有锁的时间
    RenewTime            metav1.Time `json:"renewTime"`//更新时间
    LeaderTransitions    int         `json:"leaderTransitions"`//leader更换的次数
}

获取的锁以及更新锁

Run方法中包含了获取锁以及更新锁的入口

// Run starts the leader election loop
func (le *LeaderElector) Run(ctx context.Context) {
    defer func() {
        //进行退出执行
        runtime.HandleCrash()
        //停止时执行回调方法
        le.config.Callbacks.OnStoppedLeading()
    }()
    //不断的进行获得锁,如果获得锁成功则执行后面的方法,否则不断的进行重试
    if !le.acquire(ctx) {
        return // ctx signalled done
    }
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()
    //获取锁成功,当前进程变为leader,执行回调函数中的业务代码
    go le.config.Callbacks.OnStartedLeading(ctx)
    //不断的循环进行进行租约的更新,保证锁一直被当前进行持有
    le.renew(ctx)
}

le.acquire 和 le.renew 内部都是调用了 le.tryAcquireOrRenew 函数,只是对于返回结果的处理不一样。

le.acquire 对于 le.tryAcquireOrRenew 返回成功则退出,失败则继续。

le.renew 则相反,成功则继续,失败则退出。

我们来看看 tryAcquireOrRenew 方法:

func (le *LeaderElector) tryAcquireOrRenew() bool {
    now := metav1.Now()
    //锁资源对象内容
    leaderElectionRecord := rl.LeaderElectionRecord{
        HolderIdentity:       le.config.Lock.Identity(),//唯一标识
        LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second),
        RenewTime:            now,
        AcquireTime:          now,
    }

    // 1. obtain or create the ElectionRecord
    // 第一步:从k8s资源中获取原有的锁
    oldLeaderElectionRecord, oldLeaderElectionRawRecord, err := le.config.Lock.Get()
    if err != nil {
        if !errors.IsNotFound(err) {
            klog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err)
            return false
        }
        //资源对象不存在,进行锁资源创建
        if err = le.config.Lock.Create(leaderElectionRecord); err != nil {
            klog.Errorf("error initially creating leader election record: %v", err)
            return false
        }
        le.observedRecord = leaderElectionRecord
        le.observedTime = le.clock.Now()
        return true
    }

    // 2. Record obtained, check the Identity & Time
    // 第二步,对比存储在k8s中的锁资源与上一次获取的锁资源是否一致
    if !bytes.Equal(le.observedRawRecord, oldLeaderElectionRawRecord) {
        le.observedRecord = *oldLeaderElectionRecord
        le.observedRawRecord = oldLeaderElectionRawRecord
        le.observedTime = le.clock.Now()
    }
    //判断持有的锁是否到期以及是否被自己持有
    if len(oldLeaderElectionRecord.HolderIdentity) > 0 &&
        le.observedTime.Add(le.config.LeaseDuration).After(now.Time) &&
        !le.IsLeader() {
        klog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity)
        return false
    }

    // 3. We're going to try to update. The leaderElectionRecord is set to it's default
    // here. Let's correct it before updating.
    //第三步:自己现在是leader,但是分两组情况,上一次也是leader和首次变为leader
    if le.IsLeader() {
        //自己本身就是leader则不需要更新AcquireTime和LeaderTransitions
        leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime
        leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions
    } else {
        //首次自己变为leader则更新leader的更换次数
        leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1
    }

    //更新锁资源,这里如果在 Get 和 Update 之间有变化,将会更新失败
    // update the lock itself
    if err = le.config.Lock.Update(leaderElectionRecord); err != nil {
        klog.Errorf("Failed to update lock: %v", err)
        return false
    }

    le.observedRecord = leaderElectionRecord
    le.observedTime = le.clock.Now()
    return true
}

在这一步如果发生并发操作怎么样?

这里很重要一点就是利用到了k8s api操作的原子性:

在 le.config.Lock.Get() 中会获取到锁的对象,其中有一个 resourceVersion 字段用于标识一个资源对象的内部版本,每次更新操作都会更新其值。如果一个更新操作附加上了 resourceVersion 字段,那么 apiserver 就会通过验证当前 resourceVersion 的值与指定的值是否相匹配来确保在此次更新操作周期内没有其他的更新操作,从而保证了更新操作的原子性。

总结

leaderelection 主要是利用了k8s API操作的原子性实现了一个分布式锁,在不断的竞争中进行选举。选中为leader的进行才会执行具体的业务代码,这在k8s中非常的常见,而且我们很方便的利用这个包完成组件的编写,从而实现组件的高可用,比如部署为一个多副本的Deployment,当leader的pod退出后会重新启动,可能锁就被其他pod获取继续执行。

完整代码:https://github.com/go-demo/leaderelection

关注"学点程序"公众号,了解更多干货内容 ! 学点程序

Solidworks曲面建模学习(二)——3D草图 本文主要是演示有一些零件在solidworks中通过3D草来绘制会更加方便。 阅读详情

相关推荐

记录汇川:自由口通信-梯形图

最常见的就是MODBUS通信协议,指令主要通过RS232和RS485端口进行报文发送,所以通信报文格式可以选择MODBUS RTU通信格式或MODBUS ASCII通信格式。255---Y10-Y17:ON(1111 1111)指令进行报文的发送与接收,但是报文内部的数据格式不是由主站PLC决定, 而是由。修改从站一个保持寄存器数据。修改从站多个保持寄存器数据。读取从站的输出信号状态。读取从站的输入信号状态。读取从站保持寄存器数据。读取从站输入寄存器数据。

m0_61837027的博客 4913

Golang项目引入leaderelection实现leader选举

leaderelection基本工作原理其实就是利用通过Kubernetes中 `configmap` , `endpoints` 或者 `lease` 资源实现一个分布式锁,抢(acqure)到锁的节点成为leader,并且定期更新(renew)。其他进程也在不断的尝试进行抢占,抢占不到则继续等待下次循环。当leader节点挂掉之后,租约到期,其他节点就成为新的leader。

追求幸福,探索未知的博客 1034

5个实战必备的多模态情感分析数据集(附下载链接与避坑指南)

本文精选了5个实战必备的多模态情感分析数据集,包括CMU-MOSEI、CH-SIMS、UR-FUNNY、MUStARD和IEMOCAP,并提供了详细的下载链接与避坑指南。文章重点介绍了如何高效获取、预处理这些数据集,并自然整合了多模态情感分析的核心热词,旨在帮助研究者和开发者快速启动项目,规避常见陷阱,聚焦模型创新。

yolo5detector的博客 280

k8s leaderelection

选主操作就是通过client去etcd获取锁信息,和本地一样,证明是主,开始启动各种controller,然后就更新主的锁的时间戳存入etcd,每过一段时间就更新时间戳等信息存入etcd. 如果发现有新主了,打个log,然后发送event到apiserver.停止master上的各种controller工作。 如果不一样就证明是有人是主了,就一直的过一段时间重试,不停的获取。 代码如下: ...

wasd12121212的博客 1344

DDR为什么需要DQS信号?

本文根据相关书籍和个人经验,谈了一下对DDR中DQS信号作用的理解

weixin_41155581的博客 2万+

LLC谐振变换器中的软开关艺术:ZVS与ZCS的协同设计

本文深入解析了LLC谐振变换器如何通过巧妙的电路设计,协同实现零电压开关(ZVS)与零电流开关(ZCS),从而大幅降低开关损耗与电磁干扰,提升电源效率。文章结合设计实战,详细阐述了谐振参数计算、器件选型及调试避坑指南,为高效、高功率密度电源设计提供了核心思路与解决方案。

weixin_29216957的博客 349

k8s - leader election 实现

leader election lock type 锁类型 leases endpointsleases configmapsleases leases类型实现 对应的struct,leaderelection/resourcelock/leaselock/LeaseLock endpointsleases 实现endpoints和leases两种方式 MultiLock: 用作迁移,里面有两种场景,Primary、Secondary endpointsLock 通过在endpoints里

u014763610的博客 1672

Geoserver新手必看:5分钟搞定世界地图发布(附中国省市数据)

本文为Geoserver新手提供了快速发布世界地图的实战指南。从环境搭建、数据准备入手,详细讲解了如何创建工作区、添加数据存储、发布图层及配置关键参数,并最终通过创建图层组实现地图服务的整合与预览。文章旨在帮助用户快速掌握Geoserver发布地图服务的核心流程与实用技巧。

cola5的博客 223

【k8s】——leaderelection选举策略实现组件高可用

一、前言 分布式服务绕不开一个词:选主。今天主要来聊一下k8s中是如何通过leaderelection来实现组件的高可用的。在k8s本身的组件中,kube-scheduler和kube-manager-controller两个组件是有leader选举的,这个选举机制是k8s对于这两个组件的高可用保障。即正常情况下kube-scheduler或kube-manager-controller组件的多个副本只有一个是处于业务逻辑运行状态,其它副本则不断的尝试去获取锁,去竞争leader,直到自己成为le..

汤庆 6981

StarUML最新版汉化与破解二合一教程:5分钟搞定永久使用

本文提供StarUML最新版的高效使用指南,涵盖从安装到深度定制的全流程优化方案。包括软件获取最佳实践、界面个性化设置、核心建模技巧、团队协作策略及性能优化建议,帮助架构师和开发团队提升UML建模效率。特别推荐版本控制集成和文档自动化输出方案,适用于各类规模的项目开发。

weixin_42530732的博客 450

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

LuciferLiu_DBA 2190

【kubernetes】k8s中的选主机制

如果有人认为,传统应用需要部署多个通常是为了容灾,而在k8s上运行的Pod受控制器管理,如果Pod异常或者Pod所在宿主机宕机,Pod是可以漂移到其他节点的,所以,不需要部署多个Pod,只需要部署一个Pod就行。leader-election的具体工作方式是:各候选者将自身的信息写入某一个资源,如果写成功,某个后选择就称为了主,其他就是备,同时,在之后主会定期更新资源的时间,如果超过一段时间未更新时间,其他候选者发现资源的最后更新时间超过一定值,就会认为主挂掉,然后会向资源写入自身信息,从而成为新的主。

追寻梦想的青春 9370

CloudCompare二次开发(1)——获取指定高程的所有点

使用CloudCompare插件实现获取点云数据中指定高程的所有点。

点云侠的博客 4732

利用 Kubernetes 中的 leaderelection 实现组件高可用

在Kubernetes中,通常kube-schduler和kube-controller-manager都是多副本进行部署的来保证高可用,而真正在工作的实例其实只有一个。这里就利用到 l...

Go中国 1287

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Kubernetes 架构基础 核心控制平面组件

Kubernetes 核心架构 与传统的高性能计算及虚拟化云平台类似,Kubernetes 也遵循主从结构。通常将固定规模的计算节点组成一个集群,在集群中挑选数台计算节点作为管理节点(Master),其余的计算节点作为工作节点(Minion)。针对较大规模的集群,建议将独占节点作为管理节点,而针对较小规模的集群,可以将管理节点和工作节点混用。 如图所示,管理节点和非管理节点的区别是,管理节点上运行的是控制平面组件 ,而工作节点运行的是用户业务。Kubernetes 还拥有各种功能插件,例如监

小楼一夜听春雨,深巷明朝卖杏花 3098

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

关于K8S库中高可用的锁机制详解

简介对于无状态的组件来说,天然具备高可用特性,无非就是多开几个副本而已;而对于有状态组件来说,实现高可用则要麻烦很多,一般来说通过选主来达到同一时刻只能有一个组件在处理业务逻辑。在Kubernetes中,为了实现组件高可用,同一个组件需要部署多个副本,例如多个apiserver、scheduler、controller-manager等,其中apiserver是无状态的,每个组件都可以工作,而sc...

m0_47495420的博客 820

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

6.2 kube-scheduler中的leaderelection选主机制解读

makeLeaderElectionConfig 创建选主抢锁的配置。如果上面的update等操作并发执行会怎么样。resourcelock资源锁的初始化。

福大大架构师每日一题 1048

kubernetes组件 Controller manager深刻认知

statefuleset的rollingupdate每次只升级一个partition,也就是有状态副本集的一个实例,例如mysql实例升级版本, 待确认0没问题之后。当设置一个ReplicaSet的副本数为10的时候,如果实际的容器数小于10,则会执行调用Apiserver创建Pod。以ReplicaSet为例,它会周期地检测理想的“目标容器数”和真实的“当前容器数”是否相同。这是因为deploy这个对象出现的早,后面的对象设计演进更加先进了。同样删除的时候,会通过这个父子关系图进行级联删除。

MyySophia的博客 1636

关于 Kubernetes Master 高可用的一些策略

Kubernetes 高可用也许是完成了初步的技术评估,打算将生产环境迁移进 Kubernetes 集群之前普遍面临的问题。 为了减少因为服务器当机引起的业务中断,生产环境中的业务系统往往已经做好了高可用,而当引入 Kubernetes 这一套新的集群管理系统之后,服务器不再是单一的个体,位于中央位置的 Kubernetes Master 一旦中断服务,将导致所有 Node 节点均不可控,有可能造...

shuningzhang的专栏 809

k8s中基于资源锁的选主分析

简介 k8s中为了实现高可用,需要部署多个副本,例如多个apiserver、scheduler、controller-manager等,其中apiserver是无状态的每个组件都可以工作,而scheduler与controller-manager是有状态的,同一时刻只能存在一个活跃的,需要进行选主。 k8s使用了资源锁(endpoints/configmap/lease)的方式来实现选主,多个副本...

Qinng的博客 4705

线上 leaderelection lost 导致 Kubernetes 组件异常退出的问题排查

记录了一次线上 controller-manager、kube-scheduler 频繁异常重启,报错 leaderelection lost 的问题排查

weixin_45578634的博客 1464

宕机处理:Kubernetes集群高可用实战总结

导语 |在企业生产环境,Kubernetes高可用是一个必不可少的特性,其中最通用的场景就是如何在Kubernetes集群宕机一个节点的情况下保障服务依旧可用。本文对在该场景下实现集群...

QcloudCommunity的博客 2068

[bug]:记一个k8s client-go leaderelection的bug

环境:k8s 1.17.2 申请租约后,进程异常结束没有正常释放租约 leaderelection.go:308] Failed to release lock: Lease.coordination.k8s.io "go-demo" is invalid: spec.leaseDurationSeconds: Invalid value: 0: must be greater than 0 源码: client-go/leaderelection.go at v0.17.2 · kuberne

qq_26572567的博客 570

【client-go v0.36.1】LeaderElection 深度分析(上篇)— 模块定位、结构、LeaderElector 核心逻辑

LeaderElection 深度分析(上篇)— 模块定位、结构、LeaderElector 核心逻辑

zhonglinzhang 364
上一篇: Go的http包中默认路由匹配规则
下一篇: 利用Kubernetes中的leaderelection实现组件高可用
学点程序
博客等级 码龄12年 64粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值