国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【kubernetes】k8s中的選主機(jī)制

這篇具有很好參考價(jià)值的文章主要介紹了【kubernetes】k8s中的選主機(jī)制。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

leader-election選主機(jī)制

1 為什么需要leader-election?

在集群中存在某種業(yè)務(wù)場(chǎng)景,一批相同功能的進(jìn)程同時(shí)運(yùn)行,但是同一時(shí)刻,只能有一個(gè)工作,只有當(dāng)正在工作的進(jìn)程異常時(shí),才會(huì)由另一個(gè)進(jìn)程進(jìn)行接管。這種業(yè)務(wù)邏輯通常用于實(shí)現(xiàn)一主多從。

如果有人認(rèn)為,傳統(tǒng)應(yīng)用需要部署多個(gè)通常是為了容災(zāi),而在k8s上運(yùn)行的Pod受控制器管理,如果Pod異?;蛘逷od所在宿主機(jī)宕機(jī),Pod是可以漂移到其他節(jié)點(diǎn)的,所以,不需要部署多個(gè)Pod,只需要部署一個(gè)Pod就行。k8s上的Pod確實(shí)可以漂移,但是,如果宿主機(jī)宕機(jī),k8s認(rèn)為Pod異常,并在其他節(jié)點(diǎn)重建Pod是有周期的,不能在查詢不到Pod狀態(tài)時(shí)立刻就將Pod驅(qū)逐掉,也許節(jié)點(diǎn)只是臨時(shí)不可用呢?例如,負(fù)載很高,因此,判斷宿主機(jī)宕機(jī)需要有個(gè)時(shí)間短。

k8s節(jié)點(diǎn)故障時(shí),工作負(fù)載的調(diào)度周期

因此,在k8s中運(yùn)行一主多從是為了能夠?qū)崿F(xiàn)主的快速切換。

2 kubernetes中的leader-election

k8s中也有這種業(yè)務(wù)場(chǎng)景,在多master場(chǎng)景下,只能有一個(gè)master上的進(jìn)程工作,例如,scheduler和controller-manager。以scheduler來(lái)說(shuō),它的工作是給Pod分配合適的宿主機(jī),如果有多個(gè)scheduler同時(shí)運(yùn)行,就會(huì)出現(xiàn)競(jìng)爭(zhēng),因此,如果允許這種場(chǎng)景存在的話,就又需要實(shí)現(xiàn)一種調(diào)度邏輯:某個(gè)Pod由哪個(gè)scheduler進(jìn)行調(diào)度,這相當(dāng)于又要實(shí)現(xiàn)一層調(diào)度。但是,實(shí)際上調(diào)度工作是相對(duì)比較簡(jiǎn)單的,不需要多個(gè)scheduler進(jìn)行負(fù)載,只需要一個(gè)scheduler進(jìn)行調(diào)度就行。因此,k8s提供了leader-election的能力。

leader-election的具體工作方式是:各候選者將自身的信息寫入某一個(gè)資源,如果寫成功,某個(gè)后選擇就稱為了主,其他就是備,同時(shí),在之后主會(huì)定期更新資源的時(shí)間,如果超過(guò)一段時(shí)間未更新時(shí)間,其他候選者發(fā)現(xiàn)資源的最后更新時(shí)間超過(guò)一定值,就會(huì)認(rèn)為主掛掉,然后會(huì)向資源寫入自身信息,從而成為新的主。

基于該原理,有一個(gè)現(xiàn)成的鏡像可以使用:instana/leader-elector。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: leader
  name: leader
spec:
  replicas: 3
  selector:
    matchLabels:
      app: leader
  template:
    metadata:
      labels:
        app: leader
    spec:
      containers:
      - image: instana/leader-elector:0.5.13
        name: leader
        command: ["/app/server","--id=$(POD_NAME)","--election=leader-election","--http=0.0.0.0:4040"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

上面的yaml有兩個(gè)需要注意的地方:

  • /app/server是二進(jìn)制程序,id參數(shù)是候選者的唯一標(biāo)識(shí),election是資源名稱,http是應(yīng)用監(jiān)聽(tīng)的IP和端口號(hào)
  • 將pod的名稱作為id參數(shù),也就是候選者的唯一標(biāo)識(shí)

創(chuàng)建deploy后,會(huì)啟動(dòng)三個(gè)Pod,通過(guò)kubectl logs可以看到只有一個(gè)Pod成為主,也就是向資源名稱為leader-election的Endpoint寫入了自身的Pod名稱。然后通過(guò)代理(kubectl proxy)訪問(wèn):http://localhost:8001/api/v1/namespaces/default/pods/:4040/proxy/,就會(huì)看到主的Pod名稱。

知道了leader-election的大概原理,也知道了上面的鏡像可以直接實(shí)現(xiàn)主的選舉,那么如何使用呢?

2.1 Sidecar

直接將上面的leader-elector鏡像作為Sidecar,將Pod名稱作為候選者的唯一標(biāo)識(shí),然后將Pod名稱也注入到環(huán)境變量,在業(yè)務(wù)進(jìn)程起來(lái)后,定時(shí)調(diào)用http://localhost:4040就可以獲取主,如果發(fā)現(xiàn)主的名稱與自身的Pod的名稱一致,就執(zhí)行業(yè)務(wù)邏輯,否則一直等待。

2.2 SDK

使用Sidecar的好處是比較方便,開(kāi)發(fā)成本低,不便的地方就是,適用場(chǎng)景有限,只能寫入Endpoint資源。因此,在某些場(chǎng)景下,可以使用SDK,直接基于leader-election庫(kù)開(kāi)發(fā)。

k8s-leader-election

創(chuàng)建一個(gè)Lease類型的鎖(當(dāng)然,也可以是其他類型,但是lease更加輕量),創(chuàng)建資源時(shí)需要指定資源的命名空間、名稱、標(biāo)識(shí)(這一批Pod都會(huì)該命名空間的資源寫入自身的唯一標(biāo)識(shí))。然后調(diào)用leaderelection庫(kù)中的RunOrDie()函數(shù),此時(shí)會(huì)指定:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-725511.html

  • Lock:資源鎖,將前面創(chuàng)建的Lease類型鎖填入
  • ReleaseOnCancel:
  • LeaseDuration:租約時(shí)間
  • RenewDeadline:leader刷新超時(shí)
  • RetryPeriod:刷新租約的時(shí)間間隔
  • Callbacks:指定成為leader時(shí)要執(zhí)行的業(yè)務(wù)邏輯(OnStartedLeading),從leader變成非leader時(shí)要執(zhí)行的邏輯(OnStoppedLeading),leader變更時(shí)要執(zhí)行的邏輯(OnNewLeader)。

3 具體實(shí)現(xiàn)機(jī)制

// leaderelection/leaderelection.go
func (le *LeaderElector) Run(ctx context.Context) {
	defer runtime.HandleCrash()
	defer func() {
		le.config.Callbacks.OnStoppedLeading()
	}()

	// 申請(qǐng)資源鎖,有三種情形:
	// 1 出錯(cuò),則返回false,Run()直接退出
	// 2 獲取到鎖了,則返回true,執(zhí)行回調(diào)函數(shù)
	// 3 未獲取到鎖,acquire()函數(shù)不會(huì)返回
	if !le.acquire(ctx) {
		return // ctx signalled done
	}
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	// 申請(qǐng)成功后,執(zhí)行回調(diào)函數(shù)
	go le.config.Callbacks.OnStartedLeading(ctx)

	// 定時(shí)刷新租約
	le.renew(ctx)
}

// 申請(qǐng)資源鎖
func (le *LeaderElector) acquire(ctx context.Context) bool {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()
	succeeded := false
	desc := le.config.Lock.Describe()
	klog.Infof("attempting to acquire leader lease %v...", desc)

	// 每隔RetryPeriod去申請(qǐng)資源鎖,或者更新
	wait.JitterUntil(func() {
		succeeded = le.tryAcquireOrRenew(ctx)
		le.maybeReportTransition()
		if !succeeded {
			// 沒(méi)有獲取到鎖,下一次再嘗試
			klog.V(4).Infof("failed to acquire lease %v", desc)
			return
		}

		// 成功獲取到鎖,則退出
		le.config.Lock.RecordEvent("became leader")
		le.metrics.leaderOn(le.config.Name)
		klog.Infof("successfully acquired lease %v", desc)
		cancel()
	}, le.config.RetryPeriod, JitterFactor, true, ctx.Done())
	return succeeded
}

func (le *LeaderElector) renew(ctx context.Context) {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	// 每隔RetryPeriod嘗試更新租約
	wait.Until(func() {
		timeoutCtx, timeoutCancel := context.WithTimeout(ctx, le.config.RenewDeadline)
		defer timeoutCancel()
		err := wait.PollImmediateUntil(le.config.RetryPeriod, func() (bool, error) {
			return le.tryAcquireOrRenew(timeoutCtx), nil
		}, timeoutCtx.Done())

		le.maybeReportTransition()
		desc := le.config.Lock.Describe()
		if err == nil {
			klog.V(5).Infof("successfully renewed lease %v", desc)
			return
		}
		le.config.Lock.RecordEvent("stopped leading")
		le.metrics.leaderOff(le.config.Name)
		klog.Infof("failed to renew lease %v: %v", desc, err)
		cancel()
	}, le.config.RetryPeriod, ctx.Done())

	// if we hold the lease, give it up
	if le.config.ReleaseOnCancel {
		le.release()
	}
}

// 嘗試獲取或者更新資源鎖
func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool {
	now := metav1.Now()
	leaderElectionRecord := rl.LeaderElectionRecord{
		HolderIdentity:       le.config.Lock.Identity(),
		LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second),
		RenewTime:            now,
		AcquireTime:          now,
	}

	// 1 獲取資源鎖記錄
	oldLeaderElectionRecord, oldLeaderElectionRawRecord, err := le.config.Lock.Get(ctx)
	if err != nil {
		if !errors.IsNotFound(err) {
			klog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err)
			return false
		}

		// 創(chuàng)建資源鎖
		if err = le.config.Lock.Create(ctx, leaderElectionRecord); err != nil {
			klog.Errorf("error initially creating leader election record: %v", err)
			return false
		}

		le.setObservedRecord(&leaderElectionRecord)

		return true
	}

	// 2 將資源鎖記錄與緩存的上一次的值進(jìn)行對(duì)比
	// 如果當(dāng)前不是leader,并且資源鎖沒(méi)有過(guò)期,則退出
	if !bytes.Equal(le.observedRawRecord, oldLeaderElectionRawRecord) {
		le.setObservedRecord(oldLeaderElectionRecord)

		le.observedRawRecord = oldLeaderElectionRawRecord
	}
	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.
	if le.IsLeader() {
		// 當(dāng)前是leader,鎖資源未過(guò)期,將之前的資源鎖的數(shù)據(jù)填充到新的資源鎖中(申請(qǐng)鎖時(shí)間,切換次數(shù))
		leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime
		leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions
	} else {
		// 當(dāng)前不是leader
		leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1
	}

	// 更新資源鎖
	if err = le.config.Lock.Update(ctx, leaderElectionRecord); err != nil {
		klog.Errorf("Failed to update lock: %v", err)
		return false
	}

	le.setObservedRecord(&leaderElectionRecord)
	return true
}

到了這里,關(guān)于【kubernetes】k8s中的選主機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架構(gòu)、Master節(jié)點(diǎn) Node節(jié)點(diǎn) K8S架構(gòu)圖

    【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架構(gòu)、Master節(jié)點(diǎn) Node節(jié)點(diǎn) K8S架構(gòu)圖

    一、docker的問(wèn)世 ????????在LXC(Linux container)Linux容器虛擬技術(shù)出現(xiàn)之前,業(yè)界網(wǎng)紅是虛擬機(jī)。虛擬機(jī)技術(shù)的代表,是VMWare和OpenStack。 虛擬機(jī)是什么? ????????虛擬機(jī)其實(shí)就是 在你的操作系統(tǒng)里面,裝一個(gè)軟件,然后通過(guò)這個(gè)軟件,再模擬一臺(tái)甚至多臺(tái)“子電腦”出來(lái)。

    2024年03月26日
    瀏覽(36)
  • 基于Docker的K8s(Kubernetes)集群部署

    基于Docker的K8s(Kubernetes)集群部署

    開(kāi)始搭建k8s集群 三臺(tái)服務(wù)器修改主機(jī)名稱 關(guān)閉對(duì)話窗口,重新連接 三臺(tái)主機(jī)名稱呢就修改成功了。 接下來(lái)修改每臺(tái)節(jié)點(diǎn)的 hosts 文件 所有節(jié)點(diǎn)關(guān)閉 setLinux 查看是否關(guān)閉成功 為每個(gè)節(jié)點(diǎn)添加 k8s 數(shù)據(jù)源 如果安裝docker數(shù)據(jù)源找不到y(tǒng)um-config 所有節(jié)點(diǎn)安裝kubelet kubelet安裝中… k

    2024年02月08日
    瀏覽(25)
  • 容器技術(shù),1. Docker,2. Kubernetes(K8s):

    容器技術(shù),1. Docker,2. Kubernetes(K8s):

    目錄 容器技術(shù) 1. Docker: 2. Kubernetes(K8s): Docker和Kubernetes 容器的主要應(yīng)用場(chǎng)景有哪些? 有效的將單個(gè)操作系統(tǒng)的資源劃分到孤立的組中,以便更好的在孤立的組之間平衡有沖突的資源使用需求,這種技術(shù)就是容器技術(shù)。 容器技術(shù)指通過(guò)在物理主機(jī)操作系統(tǒng)上創(chuàng)建一個(gè)一個(gè)

    2024年02月11日
    瀏覽(30)
  • Docker、Kubernetes(K8s)和KVM辨析

    Docker、Kubernetes(K8s)和KVM都是虛擬化技術(shù),但它們各自的應(yīng)用場(chǎng)景和功能有所不同。 Docker是一種輕量級(jí)的虛擬化技術(shù),它允許開(kāi)發(fā)者將應(yīng)用程序及其依賴項(xiàng)打包到一個(gè)可移植的容器中,然后在任何運(yùn)行Docker的服務(wù)器上部署。與傳統(tǒng)的虛擬機(jī)相比,Docker容器提供了一種輕量級(jí)

    2024年02月21日
    瀏覽(54)
  • 四、Kubernetes(k8s) 工作中的常用命令

    四、Kubernetes(k8s) 工作中的常用命令

    顧名思義, Namespace 是命名空間的意思,在 Kubernetes 中,“命名空間(Namespace)” 提供一種機(jī)制,將同一集群中的資源劃分為相互隔離的組。 同一命名空間內(nèi)的資源名稱要唯一,但跨命名空間時(shí)沒(méi)有這個(gè)要求。 命名空間作用域僅針對(duì)帶有命名空間的對(duì)象,例如 Deployment、Se

    2024年02月08日
    瀏覽(20)
  • Kind | Kubernetes in Docker 把k8s裝進(jìn)docker!

    Kind | Kubernetes in Docker 把k8s裝進(jìn)docker!

    有點(diǎn)像杰克船長(zhǎng)的黑珍珠 目錄 零、說(shuō)明 一、安裝 安裝 Docker 安裝 kubectl 安裝 kind 二、創(chuàng)建/切換/刪除集群 創(chuàng)建 切換 刪除 將鏡像加載到 kind 群集中 官網(wǎng):kind Kind: Kubernetes in Docker 的簡(jiǎn)稱。kind 是一個(gè)使用 Docker 容器“節(jié)點(diǎn)”運(yùn)行本地 Kubernetes 集群的工具。kind 主要設(shè)計(jì)用于

    2024年02月16日
    瀏覽(18)
  • 【一起來(lái)學(xué)kubernetes】7、k8s中的ingress詳解

    【一起來(lái)學(xué)kubernetes】7、k8s中的ingress詳解

    Ingress 是Kubernetes集群中的一種資源類型,用于實(shí)現(xiàn)用域名的方式訪問(wèn)Kubernetes內(nèi)部應(yīng)用。它為Kubernetes集群中的服務(wù)提供了入口,可以提供負(fù)載均衡、SSL終止和基于名稱的虛擬主機(jī)。在生產(chǎn)環(huán)境中常用的Ingress有 Treafik 、 Nginx 、 HAProxy 、 Istio 等?;靖拍钍窃贙ubernetes v 1.1版中添

    2024年02月05日
    瀏覽(26)
  • 【k8s】kubernets和docker之間版本的對(duì)應(yīng)關(guān)系

    如果查看1.18版本k8s對(duì)應(yīng)的docker支持的最新版本 https://github.com/kubernetes/kubernetes/blob/release-1.18/build/dependencies.yaml 查看最新版本k8s對(duì)應(yīng)的docker支持的最新版本 https://github.com/kubernetes/kubernetes/blob/master/build/dependencies.yaml

    2024年02月11日
    瀏覽(55)
  • k8s中的服務(wù)發(fā)現(xiàn)機(jī)制是如何實(shí)現(xiàn)的

    Kubernetes的服務(wù)發(fā)現(xiàn)機(jī)制是Kubernetes集群中一個(gè)非常核心的功能,它允許集群內(nèi)的Pod、Service以及其他網(wǎng)絡(luò)實(shí)體相互發(fā)現(xiàn)和通信。這種機(jī)制對(duì)于構(gòu)建微服務(wù)架構(gòu)的應(yīng)用程序尤為重要,因?yàn)樗梢韵簿幋a的網(wǎng)絡(luò)地址和端口號(hào),提供動(dòng)態(tài)的、可擴(kuò)展的服務(wù)訪問(wèn)方式。 在Kubernetes中

    2024年03月28日
    瀏覽(18)
  • kubernetes(k8s)大白學(xué)習(xí)02:容器和docker基礎(chǔ)、使用、架構(gòu)學(xué)習(xí)

    kubernetes(k8s)大白學(xué)習(xí)02:容器和docker基礎(chǔ)、使用、架構(gòu)學(xué)習(xí)

    簡(jiǎn)單說(shuō):容器(container)就是計(jì)算機(jī)上的一個(gè)沙盒進(jìn)程,它與計(jì)算機(jī)上的所有其它進(jìn)程相隔離。 這種隔離是怎么做到的呢?它利用了內(nèi)核提供的 namespace 和 cgroup 這 2 種技術(shù)。這些技術(shù)能力在 Linux 中已經(jīng)存在了很長(zhǎng)時(shí)間。而 Docker 或容器技術(shù)致力于將這些功能更易于使用和更

    2024年02月07日
    瀏覽(45)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包