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

Kubernetes租约概念 文章目录1.k8s租约概念2.k8s资源已raw格式输出3.k8s-yaml基础结构4.CentOS7.x升级内核 1.k8s租约概念 k8s节点租约的概念: [root@VM-2-6-tlinux ~]# kubectl get leases -n kube-node-lease NAME HOLDER AGE 10.0.1.11 10.0.1.11 21d 10.0.1.16 10.0.1.16 21d 10.0.1.4 10.0.1.4 21d 1 阅读详情

在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

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

PL端:HDMI 输出实验 开发板没有HDMI编码芯片,是将FPGA的3.3差分IO直接连接到HDMI连接器,FPGA 完成 24 位 RGB 编码输出TMDS 差分信号。1、学会使用第三点IP核,首先是添加,后面的使用和自带IP核操作一致。2、主要还是在梳理vivado使用流程。 阅读详情

相关推荐

便携式水下动态实时视频色彩还原设备,一键快速实现对水下偏色视频和图像的色彩还原处理

便携式水下动态实时视频色彩还原,一键快速对水下图像进行色彩校正,清晰度提升和亮度均衡处理,为水下资源勘探和科学考古,海洋生态环境监测,水下机器作业等应用提供有力的协助

weixin_43518680的博客 633

Golang项目引入leaderelection实现leader选举

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

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

解决linux 2.5G网卡驱动问题

解决linux 2.5G网卡驱动问题 关键词:2.5G网卡驱动,ubuntu,安装,2.5G Ethernet LINUX driver,Realtek网卡驱动 由于2.5G网卡较新,各linux发行版的通用驱动已不适用,新装的系统会出现无法上网问题,由于国内网络环境去Realtek官网很难下载到驱动文件,故本文提供github上的2.5G Ethernet LINUX driver r8125 for kernel up to 5.6的版本驱动文件r8125-9.003.05.tar.bz2各位可以自

poorguy_aos的博客 1万+

kubelet 初识 状态上报 健康上报通过lease对象

kubelet

python基础 712

Innovus中_clock_gen skew group的隐藏陷阱:如何避免自动分组导致的时序问题

本文深入剖析了在Innovus工具进行时钟树综合(CTS)时,`_clock_gen` skew group自动分组机制可能引发的隐蔽时序问题。文章通过实际案例,解释了该机制如何错误地将分频寄存器与配置寄存器归为一组,从而破坏时钟域边界并导致post-CTS时序违例,并提供了关闭自动提取、手动精确定义skew group等有效解决方案。

gpu4optimizer的博客 266

《YOLO系列模型的多模态项目》配置使用教程(必看内容)

在根目录的文件夹中用于存放的是我已经配置好的一些多模态融合模型,可结合专栏中相应的文章介绍,进一步了解测试其中内容。

Limiiiing的博客 4653

kubectl常用命令大全详解

这是我转载的一个博主写的 K8s 常用命令大全,看了我写的入门基础篇linkKubernetes kubectl 命令表【中文网址】 Kubernetes kubectl 命令表要使用和维护Kubernetes集群,最常用且直接的方式,就是使用自带的命令行工具Kubectl。 下面图片是一个总览,熟悉后可以用于勾起记忆。 [root@master ~]# kubectl create -f demo-deployment.yaml [root@master ~]# kubectl create -f dem

养歌的博客 1万+

1、Ka频段双极化低剖面卫通相控阵天线

设计了双馈口叠层十字缝隙耦合天线,采用“双线极化天线 +旋转馈电 + 移相控制”架构,采用双馈口的叠层十字缝隙耦合天线,并以 2 x2 阵列为主体,旋转排布实现二次圆极化,同时极化可切换,通过多层 PCB 工艺实现天线层、控制/电源层功分网终层、芯片层一体化集成,研制出 64 阵元的圆极化可切换发射天线,测试结果表明:天线工作 频段为 27.5 ~31 GHz,可实现60°扫描,法向轴比

qq_43416206的博客 4366

深入解析kubernetes中的选举机制

在 Kubernetes的 , , 以及使用 的底层实现 都支持高可用系统中的leader选举,本文将以理解 (底层的实现是 ) 中的leader选举以在kubernetes controller中是如何实现的。在运行 时,是有一些参数提供给cm进行leader选举使用的,可以参考官方文档提供的 参数 来了解相关参数。 本身以为这些组件的选举动作时通过etcd进行的,但是后面对 学习时,发现并没有配置其相关的etcd相关参数,这就引起了对选举机制的好奇。怀着这种好奇心搜索了下有关于 kubern

期待幸福 1308

在 TASKPROCESSING 上为 ABAP OData 服务添加多个系统别名:从原理到落地的完整实践

本文面向SAP Gateway与ABAP开发者,详细讲解如何在TASKPROCESSING OData服务上添加系统别名。首先介绍了系统别名的概念与设计初衷,阐述了添加别名的业务场景需求,包括多系统接入、用户分流和灰度发布等。随后提供了标准配置步骤,从SPRO路径到具体操作说明,并分享了三个实际案例说明如何实现跨区域统一待办、按用户角色分流和灰度发布。最后给出了验证方法和常见问题解决方案,帮助开发者掌握这项基础但关键的配置技能,实现服务路由的可控管理。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 137

基于C#开发ABB机器人上位机系统:从操作控制到数据交互的全方位实现

ABB工业机器人是世界领先的自动化设备之一,广泛应用于焊接、装配、搬运、喷涂、包装等多个行业。机器人控制器:用于控制机器人运动、路径规划、状态监控等。上位机系统:提供人机交互界面,允许操作员与机器人进行交互,实现实时控制、参数调整和数据分析。上位机系统通过与机器人控制器通信,采集机器人状态数据,发送控制指令,实现远程监控和控制操作。通过高效的操作界面和数据交互,可以大大提高机器人的工作效率和系统的可维护性。基于C#开发ABB机器人上位机系统,能够实现高效的机器人控制与实时数据交互。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1178

k8s_day02_04

k8s_day02_04 node 介绍 查看所有节点 [root@master01 ~]# kubectl get node NAME STATUS ROLES AGE VERSION master01 Ready master 7d v1.19.4 node01 Ready <none> 6d23h v1.19.4 node02 Ready <none> 6d23h v1.19.4

qq_36801585的博客 916

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

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

https://blog.csdn.net/RA681t58CJxsgCkJ31/article/details/104386126/ 利用 Kubernetes 中的 leaderelection 实现组件高可用 在Kubernetes中,通常kube-schduler和kube-controller-manager都是多副本进行部署的来保证高可用,而真正在工作的实例其实只有一个。...

qingdao666666的博客 580

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

汤庆 6981

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

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

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

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

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

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

m0_47495420的博客 820

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

k8s leaderelection

const ( LEASELOCKNAME = "tes" LEASELOCKNAMESPACE = "kube-system" ) func main () { LeaseLockID = uuid.New().String() client.InitClientSet() run := func(ctx context.Context) { // 添加运行逻辑代码 klog.Info("Controller loop...") select{}.

qq_26572567的博客 749

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

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

weixin_45578634的博客 1464

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

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

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值