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