摘要:宋體是面向內(nèi)部基于打造的容器服務(wù)平臺(tái),旨在提升內(nèi)部研發(fā)效率,幫助改善規(guī)范研發(fā)流程。宋體作為容器編排框架,可以減輕配置部署管理和監(jiān)控大規(guī)模容器應(yīng)用的負(fù)擔(dān)。宋體核心原理宋體解釋不得不提中兩個(gè)最具價(jià)值的理念聲明式和控制器模式。
KUN(Keep UCloud Nimble)是面向 UCloud 內(nèi)部、基于 Kubernetes 打造的容器服務(wù)平臺(tái),旨在提升內(nèi)部研發(fā)效率,幫助改善、規(guī)范研發(fā)流程。在 KUN 平臺(tái)的建設(shè)過(guò)程中,內(nèi)部用戶對(duì)于一些基礎(chǔ)通用的分布式軟件如 Redis、Kafka 有強(qiáng)需求,但又不想操心其部署及運(yùn)維。KUN 團(tuán)隊(duì)在分析這些痛點(diǎn)后,決定利用 Kubernetes Operator 的能力,并彌補(bǔ)了開源 Operator 的一些不足,將 Operator 產(chǎn)品化來(lái)幫助用戶部署和管理這些分布式、帶狀態(tài)的應(yīng)用。通過(guò) Operator 服務(wù)化,KUN 平臺(tái)擴(kuò)充了 Kubernetes 交付 Pod、PVC、SVC 的能力,能夠快速交付 Redis 等分布式、帶狀態(tài)的系統(tǒng),提供了一個(gè)平臺(tái)之上的平臺(tái)。
在這篇文章里,我們主要來(lái)聊一下 Operator 對(duì)于 Kubernetes 的價(jià)值以及我們團(tuán)隊(duì)基于 Operator 所做的相關(guān)工作。
Operator 是什么,解決了什么問(wèn)題
為什么需要 Operator
無(wú)狀態(tài)和有狀態(tài)
2014-2015 年容器和微服務(wù)的出現(xiàn),為軟件開發(fā)和基礎(chǔ)架構(gòu)帶來(lái)了巨大的創(chuàng)新和挑戰(zhàn)。容器提供了隔離和限制,同時(shí)容器的狀態(tài)是易失的,它對(duì)自己外部的狀態(tài)和數(shù)據(jù)不關(guān)心,專注于單一的服務(wù),比如 Web 應(yīng)用、日志服務(wù)、業(yè)務(wù)程序、緩存等。這些服務(wù)都能作為容器交付和運(yùn)行,而一旦容器數(shù)量形成規(guī)模,管理的難度也越來(lái)越大。
Kubernetes 作為容器編排框架,可以減輕配置、部署、管理和監(jiān)控大規(guī)模容器應(yīng)用的負(fù)擔(dān)。事實(shí)上早期的 Kubernetes 非常善于管理無(wú)狀態(tài)的應(yīng)用程序,比如 Kubernetes 提供的 Deployment 控制器。它認(rèn)為所有的 Pod 都是完全一樣的,Pod 間沒(méi)有順序和依賴,擴(kuò)容的時(shí)候就根據(jù)模板創(chuàng)建一個(gè)一樣的新的應(yīng)用,也可以任意刪除 Pod。但對(duì)于像數(shù)據(jù)庫(kù)這樣的有狀態(tài)的應(yīng)用程序,添加刪除實(shí)例可能需要不同的節(jié)點(diǎn)做不同的配置,與已有的集群進(jìn)行通信協(xié)商等,這些操作通常需要我們?nèi)斯?lái)干預(yù),這就會(huì)增加運(yùn)維的負(fù)擔(dān),并且增加出錯(cuò)的可能性,最重要的是它消除了 Kubernetes 的一個(gè)主要賣點(diǎn):自動(dòng)化。
這是一個(gè)大問(wèn)題,那么如何在 Kubernetes 中管理有狀態(tài)的應(yīng)用程序呢?
StatefulSet 的價(jià)值和不足 ?
Kubernetes 的 1.5 版本開始出現(xiàn)了 StatefulSet,StatefulSet 提供了一系列資源來(lái)處理有狀態(tài)的容器,比如:volume,穩(wěn)定的網(wǎng)絡(luò)標(biāo)識(shí),從 0 到 N 的順序索引等。通過(guò)為 Pod 編號(hào),再使用 Kubernetes 里的兩個(gè)標(biāo)準(zhǔn)功能:Headless Service 和 PV/PVC,實(shí)現(xiàn)了對(duì) Pod 的拓?fù)錉顟B(tài)和存儲(chǔ)狀態(tài)的維護(hù),從而讓用戶可以在 Kubernetes 上運(yùn)行有狀態(tài)的應(yīng)用。
然而 Statefullset 只能提供受限的管理,通過(guò) StatefulSet 我們還是需要編寫復(fù)雜的腳本通過(guò)判斷節(jié)點(diǎn)編號(hào)來(lái)區(qū)別節(jié)點(diǎn)的關(guān)系和拓?fù)洌枰P(guān)心具體的部署工作,并且一旦你的應(yīng)用沒(méi)辦法通過(guò)上述方式進(jìn)行狀態(tài)的管理,那就代表了 StatefulSet 已經(jīng)不能解決它的部署問(wèn)題了。
既然 StatefulSet 不能完美的勝任管理有狀態(tài)應(yīng)用的工作,那還有什么優(yōu)雅的解決方案呢?答案是 Operator。Operator 在 2016 年由 CoreOS 提出,用來(lái)擴(kuò)充 Kubernetes 管理有狀態(tài)應(yīng)用的能力。
Operator 核心原理
解釋 Operator 不得不提 Kubernetes 中兩個(gè)最具價(jià)值的理念:“聲明式 API” 和 “控制器模式”。“聲明式 API” 的核心原理就是當(dāng)用戶向 Kubernetes 提交了一個(gè) API 對(duì)象的描述之后,Kubernetes 會(huì)負(fù)責(zé)為你保證整個(gè)集群里各項(xiàng)資源的狀態(tài),都與你的 API 對(duì)象描述的需求相一致。Kubernetes 通過(guò)啟動(dòng)一種叫做 “控制器模式” 的無(wú)限循環(huán),WATCH 這些 API 對(duì)象的變化,不斷檢查,然后調(diào)諧,最后確保整個(gè)集群的狀態(tài)與這個(gè) API 對(duì)象的描述一致。
比如 Kubernetes 自帶的控制器:Deployment,如果我們想在 Kubernetes 中部署雙副本的 Nginx 服務(wù),那么我們就定義一個(gè) repicas 為 2 的 Deployment 對(duì)象,Deployment 控制器 WATCH 到我們的對(duì)象后,通過(guò)控制循環(huán),最終會(huì)幫我們?cè)?Kubernetes 啟動(dòng)兩個(gè) Pod。
Operator 是同樣的道理,以我們的 Redis Operator 為例,為了實(shí)現(xiàn) Operator,我們首先需要將自定義對(duì)象的說(shuō)明注冊(cè)到 Kubernetes 中,這個(gè)對(duì)象的說(shuō)明就叫 CustomResourceDefinition(CRD),它用于描述我們 Operator 控制的應(yīng)用:redis 集群,這一步是為了讓 Kubernetes 能夠認(rèn)識(shí)我們應(yīng)用。然后需要實(shí)現(xiàn)自定義控制器去 WATCH 用戶提交的 redis 集群實(shí)例,這樣當(dāng)用戶告訴 Kubernetes 我想要一個(gè) redis 集群實(shí)例后,Redis Operator 就能夠通過(guò)控制循環(huán)執(zhí)行調(diào)諧邏輯達(dá)到用戶定義狀態(tài)。
所以 Operator 本質(zhì)上是一個(gè)個(gè)特殊應(yīng)用的控制器,其提供了一種在 Kubernetes API 之上構(gòu)建應(yīng)用程序并在 Kubernetes 上部署程序的方法,它允許開發(fā)者擴(kuò)展 Kubernetes API,增加新功能,像管理 Kubernetes 原生組件一樣管理自定義的資源。如果你想運(yùn)行一個(gè) Redis 哨兵模式的主從集群或者 TiDB 集群,那么你只需要提交一個(gè)聲明就可以了,而不需要關(guān)心部署這些分布式的應(yīng)用需要的相關(guān)領(lǐng)域的知識(shí),Operator 本身可以做到創(chuàng)建應(yīng)用、監(jiān)控應(yīng)用狀態(tài)、擴(kuò)縮容、升級(jí)、故障恢復(fù),以及資源清理等,從而將分布式應(yīng)用的使用門檻降到最低。
Operator 核心價(jià)值
在這里我們總結(jié)一下 Operator 的價(jià)值:
? Operator 擴(kuò)展了 Kubernetes 的能力;
? Operator 將人類的運(yùn)維知識(shí)系統(tǒng)化為代碼;
? Operator 以可擴(kuò)展、可重復(fù)、標(biāo)準(zhǔn)化的方式實(shí)現(xiàn)目標(biāo);
? Operator 減輕開發(fā)人員的負(fù)擔(dān)。
Operator 服務(wù)化目標(biāo)
聊完 Operator 的能力和價(jià)值我們把目光轉(zhuǎn)向 KUN 上的 Operator 平臺(tái)。前面說(shuō)過(guò),用戶想在 Kubernetes 中快速的運(yùn)行一些分布式帶狀態(tài)的應(yīng)用,但是他們本身不想關(guān)心部署、運(yùn)維,既然 Operator 可以靈活和優(yōu)雅的管理有狀態(tài)應(yīng)用,我們的解決方案就是基于 Operator 將 Kubernetes 管理有狀態(tài)應(yīng)用的能力方便地暴露給用戶。
核心的的目標(biāo)主要有兩方面:
1、針對(duì) Operator 平臺(tái)
? 提供一個(gè)簡(jiǎn)單易用的控制臺(tái)供用戶使用,用戶只需要點(diǎn)點(diǎn)鼠標(biāo)就能快速拉起有狀態(tài)應(yīng)用。并且能在控制臺(tái)上實(shí)時(shí)看到應(yīng)用部署的進(jìn)度和事件,查看資源,更新資源等。
? 通過(guò)模板提交聲明,參數(shù)可配置化,創(chuàng)建應(yīng)用的參數(shù)通用化,將應(yīng)用名稱等通用配置和應(yīng)用參數(shù)(如:redis 的 maxclients、timeout 等參數(shù))解耦。這樣帶來(lái)的好處就是不同的 Operator 可以共用創(chuàng)建頁(yè)面,而不需要為每種 Operator 定制創(chuàng)建頁(yè)面,同時(shí) Operator 暴露出更多的應(yīng)用配置參數(shù)時(shí),前端開發(fā)也不需關(guān)心,由后端通過(guò) API 返回給前端參數(shù),前端渲染參數(shù),用戶修改參數(shù)后,通過(guò) API 傳遞到后端,后端將參數(shù)與模板渲染成最終的實(shí)例聲明提交到 Kubernetes 中,節(jié)省了前端開發(fā)時(shí)間。
? 可以管理通過(guò)公共的 Operator 和 Namespace 私有的 Operator 創(chuàng)建的實(shí)例。用戶可以用我們提供的公用 Operator,也可以把 Operator 部署到自己的 NameSpaces,給自己的項(xiàng)目提供服務(wù),但這兩種 Operator 創(chuàng)建的應(yīng)用實(shí)例都可以通過(guò) Operator 控制臺(tái)管理。
? 可以無(wú)限添加 Operator。
2、針對(duì) Operator 控制器
? 拉起分布式集群,自動(dòng)運(yùn)配置、運(yùn)維;? 可以動(dòng)態(tài)更改所控制應(yīng)用參數(shù);
? 控制器本身需要無(wú)狀態(tài),不能依賴外部數(shù)據(jù)庫(kù)等;
? 實(shí)時(shí)更新狀態(tài),維護(hù)狀態(tài),推送事件;
? 可以運(yùn)行在集群范圍,也能運(yùn)行在單 NameSpace,并且可以共存,不能沖突;
針對(duì)這些設(shè)計(jì)目標(biāo)最終我們的 Operator 控制臺(tái)如下:
同時(shí)我們?yōu)?Operator 控制臺(tái)定制了第一個(gè) Operator:Redis Operator,未來(lái)會(huì)推出更多的 Operator,接下來(lái)我們就來(lái)看下 Redis Operator 的實(shí)現(xiàn)。
Redis Operator
Redis 集群模式選型
我們知道 Redis 集群模式主要有主從模式、哨兵模式、Redis 官方 Cluster 模式及社區(qū)的代理分區(qū)模式。
分析以上幾種模式,主從模式的 Redis 集群不具備自動(dòng)容錯(cuò)和恢復(fù)功能,主節(jié)點(diǎn)和從節(jié)點(diǎn)的宕機(jī)都會(huì)導(dǎo)致讀寫請(qǐng)求失敗,需要等待節(jié)點(diǎn)修復(fù)才能恢復(fù)正常;而 Redis 官方 Cluster 模式及社區(qū)的代理分區(qū)模式只有在數(shù)據(jù)量及并發(fā)數(shù)大的業(yè)務(wù)中才有使用需求。哨兵模式基于主從模式,但是因?yàn)樵黾恿松诒?jié)點(diǎn),使得 Redis 集群擁有了主從切換,故障轉(zhuǎn)移的能力,系統(tǒng)可用性更好,而且客戶端也只需要通過(guò)哨兵節(jié)點(diǎn)拿到 Master 和 Slave 地址就能直接使用。因此我們決定為 Kun Operator 平臺(tái)提供一個(gè)快速創(chuàng)建哨兵模式的 Redis 集群的 Redis Operator。
開源 Operator 的不足
目前已經(jīng)有一些開源的 Redis Operator,通過(guò)對(duì)這些 Operator 分析下來(lái),我們發(fā)現(xiàn)都不能滿足我們的需求,這些開源的 Operator:
? 不能設(shè)置 Redis 密碼。
? 不能動(dòng)態(tài)響應(yīng)更改參數(shù)。
? 沒(méi)有維護(hù)狀態(tài),推送事件。
? 不能在開啟了 istio 自動(dòng)注入的 Namespace 中啟動(dòng)實(shí)例。
? 只能運(yùn)行在集群或者單 Namespace 模式。
改進(jìn)工作
當(dāng)前我們定制開發(fā)的 Redis Operator 已經(jīng)在 Github 上開源
https://github.com/ucloud/redis-operator
。提供:
1. 動(dòng)態(tài)響應(yīng)更改 Redis 配置參數(shù)。
2. 實(shí)時(shí)監(jiān)控集群狀態(tài),并且推送事件,更新狀態(tài)。
3. 誤刪除節(jié)點(diǎn)故障恢復(fù)。
4. 設(shè)置密碼。
5. 打開關(guān)閉持久化快捷配置。
6. 暴露 Prometheus Metrics。
使用 Redis Operator 我們可以很方便的起一個(gè)哨兵模式的集群,集群只有一個(gè) Master 節(jié)點(diǎn),多個(gè) Slave 節(jié)點(diǎn),假如指定 Redis 集群的 size 為 3,那么 Redis Operator 就會(huì)幫我們啟動(dòng)一個(gè) Master 節(jié)點(diǎn),兩個(gè) Salve 節(jié)點(diǎn),同時(shí)啟動(dòng)三個(gè) Sentinel 節(jié)點(diǎn)來(lái)管理 Redis 集群:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/117608.html