K8s 的最后一片拼圖:dbPaaS
共 9395字,需瀏覽 19分鐘
·
2024-07-17 11:41
來源:infoQ公眾號,作者:曹偉,云猿生數(shù)據(jù)創(chuàng)始人 & CEO
K8s 的發(fā)展使得私有云跟公共云之間的技術(shù)差不斷的縮小,不管是在私有云還是公共云,大家今天都在基于 K8s 去開發(fā) PaaS 系統(tǒng)。而 K8s 作為構(gòu)建 PaaS 的基礎(chǔ),其全景圖里還缺最后一塊“拼圖”——dbPaaS。作為一個云數(shù)據(jù)庫行業(yè)干了十幾年的資深從業(yè)者,以及一個云數(shù)據(jù)庫初創(chuàng)公司的創(chuàng)始人,在本文中,我將結(jié)合近年來數(shù)據(jù)庫和云計算的發(fā)展方向,以及我們在技術(shù)和工程上的實(shí)踐,分享一些看法。
近年來, 數(shù)據(jù)庫整個領(lǐng)域主要在以下三個方向上發(fā)展: 公共云全托管,Serverless 和私有化部署。
公共云全托管,包括各家云廠商的 RDS,以及每家云廠商自研的數(shù)據(jù)庫,如 PolarDB、Aurora 等等,都屬于這個板塊。大部分公共云用戶都是用這個服務(wù),這個板塊比較成熟穩(wěn)定,跟著公共云的規(guī)模一起緩慢增長。公共云的主要的優(yōu)勢是彈性,有更多彈性需求的用戶都在被吸引到公有云的 Serverless 產(chǎn)品上。而海外很多初創(chuàng)的公司,像 CockroachDB、Neon、 PlanetScale,包括中國的初創(chuàng)公司 TiDB 都在往 Serverless,無服務(wù)器數(shù)據(jù)庫這個方向發(fā)展。
另外一個方向就是私有化部署。有報告說中國公共云的服務(wù)器大概只占服務(wù)器總數(shù)的 5% ,線下部署的比例是非常高的。大型的互聯(lián)網(wǎng)公司、央國企、銀行都是用私有云。國內(nèi)的信創(chuàng)數(shù)據(jù)庫基本上都是在做這個方向。本質(zhì)上來講,企業(yè)選擇什么數(shù)據(jù)庫是由企業(yè)的業(yè)務(wù)場景來決定的,很少會因?yàn)檫x擇一個數(shù)據(jù)庫而倒推上面的云和架構(gòu)。
企業(yè)對云的選擇和使用是一直在變化的。選擇私有云有很多原因,內(nèi)因比如說合規(guī)、成本控制、自主可控,外因主要是 K8s。
第一個變化是中國的私有云正在從 OpenStack 全面進(jìn)化到 K8s。過去的私有云,是用 OpenStack 管理物理機(jī)生產(chǎn)虛擬機(jī)。如果客戶要用容器和 K8s 再在虛擬機(jī)上去搭上面的容器。但是最近,大家都開始用 K8s 去管理物理機(jī),業(yè)務(wù)最好是能夠全部容器化、云原生化。如果你要用虛擬機(jī),可以在 K8s 上管理,例如用 kubevirt 這樣的技術(shù)在 Pod 里面跑虛擬機(jī),底層是 K8s,VM 在上層,這是一個挺大的變化。
第二個變化是 K8s 的發(fā)展使得私有云跟公共云之間的技術(shù)差逐步變窄。公共云和私有云上的 K8s 技術(shù)差別并不大。過去云廠商主要的技術(shù)壁壘都在于我怎么把幾百萬臺虛擬機(jī)運(yùn)維好,用規(guī)模優(yōu)勢來降低成本,但是這樣的技術(shù)在 K8s 面前就像馬奇諾防線一樣被繞過了。公共云和私有云今天都得站在怎么把容器做好,怎么把 K8s 生態(tài)做好這同一條起跑線上。
第三個趨勢是,不管運(yùn)行在私有云還是公共云,大家都在基于 K8s 去開發(fā) PaaS 系統(tǒng)。K8s 作為一個多云的,可以一統(tǒng)公共云、私有云的容器操作系統(tǒng),可以屏蔽底層 IaaS 的差異,讓上層通過 Pod、Service、PVC 等抽象來操作 IaaS 資源。調(diào)度器、服務(wù)發(fā)現(xiàn)、配置管理、API Server 等等這些開發(fā)一個 PaaS 所需要依賴的基礎(chǔ)能力,K8s 都提供了,不僅可以節(jié)約很多開發(fā)成本,而且 K8s 在設(shè)計和工程上都做的更好。比如說,K8s 的 API 是聲明式 API,這個就是個挺先進(jìn)的設(shè)計。公共云廠商做的比較早,在設(shè)計 API 的時候還沒有這個理念,所以 API 都是過程式的。但后來的系統(tǒng),比方說 Terraform,就用的聲明式 API,所以開發(fā)者使用起來更簡單,書寫起來更容易理解,也更不容易出錯。在 K8s 上做 PaaS 就可以利用好這些后發(fā)優(yōu)勢。
K8s 作為構(gòu)建 PaaS 的基礎(chǔ),其全景圖里還缺最后一塊“拼圖”——dbPaaS。在 K8s 上構(gòu)建 dbPaaS 是大勢所趨。所有的 PaaS 都在用 K8s 做自己的底座,dbPaaS,就是數(shù)據(jù)庫的 PaaS 也不例外。如果企業(yè)的私有云都用 K8s 來構(gòu)建,再搞一套虛擬機(jī)或者物理機(jī)的管理平臺,然后在這個基礎(chǔ)上發(fā)明一套 K8s 已經(jīng)有了的能力,再做數(shù)據(jù)庫的管理,其實(shí)是一個重復(fù)建設(shè),不是特別合理。
dbPaaS 有哪些挑戰(zhàn)?我過去在阿里云做 RDS,最深有體會的一件事情是數(shù)據(jù)庫的類目太多了,版本也太多了。大家使用的組合里面至少幾十種數(shù)據(jù)庫的不同版本。
每一種數(shù)據(jù)庫的運(yùn)維操作都也很復(fù)雜,因?yàn)閿?shù)據(jù)庫是存儲企業(yè)關(guān)鍵數(shù)據(jù)的基礎(chǔ)設(shè)施,運(yùn)維操作精細(xì)而復(fù)雜。與之對應(yīng)的就是人不夠,與之對應(yīng)的痛苦就是人手不夠,挺多事情都是可以靠堆人去做的,但是作為云廠商,要考慮向做一件事情投入人力的 ROI(投資回報率),也就是人效。
說到人效,這里就要說到煙囪式架構(gòu)這個陷阱。企業(yè)在構(gòu)建 dbPaaS 的時候,方法通常是對于每一種要支持的數(shù)據(jù)庫,就搞一個獨(dú)立的小團(tuán)隊,然后寫一套獨(dú)立的代碼,甚至有的時候連運(yùn)維人員都是獨(dú)立的。這種做法人效低,因?yàn)橹蚊扛鶡焽璧娜肆Χ际且粋€小池子,人員很難在煙囪之間流動,因此用煙囪式架構(gòu)去支持 dbPaaS 這種長尾市場的業(yè)務(wù),是一個錯誤的選擇。拉長時間看,人員變動引起故障的概率在煙囪式架構(gòu)里更高。還有更多的問題,比如資源不能做到跨引擎共享和混部,會增加部署一套 dbPaaS 的起步成本。
用一種新的方法去實(shí)現(xiàn) dbPaaS。今天各種各樣的數(shù)據(jù)庫都會發(fā)布自己的容器,容器本身就是一個標(biāo)準(zhǔn)的東西,那我們能不能像搭積木一樣的,在 K8s 上把它們給組裝起來部署提供服務(wù),然后把它們的運(yùn)維操作,也以一種標(biāo)準(zhǔn)地去組裝?
樂高積木能夠拼搭成各種各樣的藍(lán)圖,其本質(zhì)在于樂高是高度標(biāo)準(zhǔn)化的。它的凸起凹槽、厚度,都是有標(biāo)準(zhǔn)的。如果想讓數(shù)據(jù)庫像樂高積木一樣的能夠搭起來,也要解決一個標(biāo)準(zhǔn)問題,然后把各種各樣的數(shù)據(jù)庫容器適配到這個標(biāo)準(zhǔn)上。
在計算機(jī)科學(xué)當(dāng)中,有幾個比較著名的標(biāo)準(zhǔn),比如說 POSIX,POSIX 是對文件系統(tǒng)操作接口的抽象。K8s 里面有容器運(yùn)行時標(biāo)準(zhǔn) CRI,容器存儲標(biāo)準(zhǔn) CSI,容器網(wǎng)絡(luò)標(biāo)準(zhǔn) CNI,等等。通過這些標(biāo)準(zhǔn),各種各樣的容器網(wǎng)絡(luò)、存儲、分布式存儲的項目都可以對接到 K8s 生態(tài)中去。除了標(biāo)準(zhǔn)和抽象之外,還有一個我們值得借鑒的方法叫分層,比如說 OSI 的 7 層網(wǎng)絡(luò)協(xié)議和 TCP/IP 4 層協(xié)議。通過分層,各家廠商的網(wǎng)絡(luò)產(chǎn)品軟硬件、各種協(xié)議,都能找到合適的一個層次,通過層與層之間的標(biāo)準(zhǔn)接口,適配起來組成一個完整的系統(tǒng)。
我們通過抽象和分層這兩種方法來定義容器化數(shù)據(jù)庫的標(biāo)準(zhǔn),設(shè)計了 API,本質(zhì)上它類似于 POSIX API,是一個標(biāo)準(zhǔn)。我們先看下 POSIX API,有了 POSIX API 之后,上層的應(yīng)用就可以用一個很標(biāo)準(zhǔn)的 API 去操作各種文件,不用管底層的文件系統(tǒng)是什么,是 ext4,xfs 還是 nfs。類似的,我們設(shè)計的 API 是一個描述多個數(shù)據(jù)庫容器之間的關(guān)系和拓?fù)浣Y(jié)構(gòu),以及每個數(shù)據(jù)庫容器的組成、可以提供的服務(wù)以及如何響應(yīng)各種事件的行為的一個描繪,它是抽象的,跟任何一種具體的數(shù)據(jù)庫是無關(guān)的,能夠表達(dá)各種各樣的數(shù)據(jù)庫。此外,在設(shè)計這個 API 的時候我們也做了分層。我們分了五層,最底下一層是 K8s 的 API,它代表的 IaaS 的對象,倒數(shù)第二層是 Instance,描繪怎么把 IaaS 資源組裝起來,構(gòu)成一個單節(jié)點(diǎn)的數(shù)據(jù)庫的副本。InstanceSet 就是把多個 Instance 組裝成了一個多副本的數(shù)據(jù)庫。Component 在多副本的基礎(chǔ)上,加了更多數(shù)據(jù)庫的行為,比如說成員管理,備份恢復(fù)等等。再之上是組裝成 Cluster, Cluster 就是一個完整的數(shù)據(jù)庫集群,包含多個組件。我們把不同數(shù)據(jù)庫的能力、特性都映射到這個 5 層當(dāng)中去,通過抽象和分層提出了一個數(shù)據(jù)庫容器組運(yùn)行在 K8s 上的標(biāo)準(zhǔn)。
dbPaaS Operator 的核心實(shí)現(xiàn)就是通過這個抽象的 API 來管理數(shù)據(jù)庫的生命周期,它不知道操作的數(shù)據(jù)庫是 MySQL 還是 PostgreSQL 還是 Redis,它只知道操作的是一個 Cluster 對象,一個 Component 對象,操作的是抽象的對象。通過這種方法就能做到 DBPaaS 最核心的控制軟件,跟被操作的數(shù)據(jù)庫引擎無關(guān)。它能做到一套代碼適配到多種的數(shù)據(jù)庫引擎上去,這是我們最核心的創(chuàng)新,是吸收了阿里云 RDS 設(shè)計、開發(fā)、維護(hù)經(jīng)驗(yàn)教訓(xùn)后的創(chuàng)新,全世界范圍目前沒有第二個 dbPaaS 采用了這種設(shè)計。用戶去操作數(shù)據(jù)庫也會通過 Cluster,Component 這種標(biāo)準(zhǔn) API,不管對數(shù)據(jù)庫做任何運(yùn)維操作,體驗(yàn)會非常的接近,學(xué)習(xí)成本會比較低。
再比如 Redis 高可用部署。Redis 主從架構(gòu)會包含 Redis Server 和 Sentinel,其中 Redis Server 是一主一從兩個副本,而 Sentinel 是三節(jié)點(diǎn)。Redis 官方原生的集群架構(gòu) Redis Cluster 則是一個水平分片的集群架構(gòu),比如說有 5 個分片,可以用 5 個 Component 來表達(dá),每個 Component 又是一主一從兩個節(jié)點(diǎn)。
接下來一個問題是我們怎么把 30 多種數(shù)據(jù)庫給集成到一套 dbPaaS Operator 代碼里。我們再回顧下 POSIX API,如果一個文件系統(tǒng)想兼容 POSIX 標(biāo)準(zhǔn),讓使用 POSIX API 訪問文件系統(tǒng)的應(yīng)用程序都能操作它,就得先實(shí)現(xiàn) POSIX 接口。類似的,一個數(shù)據(jù)庫要想接入這個 dbPaaS Operator,就得讓這個引擎也實(shí)現(xiàn)一組 dbPaaS Addon API。
給大家舉個例子,Redis 是怎么接入到 dbPaaS 當(dāng)中?Redis 有很多種部署形態(tài),單節(jié)點(diǎn)、主從、Sharding、還有 Redis cluster,形態(tài)有很多種。按照煙囪式的做法,每種部署形態(tài)都會是一個煙囪,一套獨(dú)立的代碼去管理。而在我們的 dbPaaS 里,不同的部署形態(tài)可以像積木一樣去組裝,不同的部署形態(tài)就是幾行 YAML 的區(qū)別。
首先我們要實(shí)現(xiàn)一個個“積木塊”?!胺e木塊”要把 Redis,Sentinel、Redis proxy 這些數(shù)據(jù)庫鏡像進(jìn)行一次包裝。對這些 Docker 鏡像,我們用 dbPaaS 的 API,用 YAML 給它們增加一些擴(kuò)展信息,里面會包含配置文件模板、服務(wù)和網(wǎng)絡(luò)的配置、以及存儲的配置等,還會擴(kuò)展一些被事件觸發(fā)時會執(zhí)行的腳本(Action),以及版本鏡像列表以及不同版本兼容性的描述信息等等。寫完 Redis Server 的定義,我們就可以它看作是一個“積木塊”。Redis Sentinel 和 Redis proxy 也是類似的,我們用 YAML 把它們都定義成 dbPaaS 的“積木塊”。
定義好這些“積木塊”之后,我們在另一個 YAML 當(dāng)中定義它的拓?fù)浣Y(jié)構(gòu),告訴 KubeBlocks 系統(tǒng)剛才那些“積木塊”該怎么組裝,就能組裝成一個集群結(jié)構(gòu)。開發(fā)一個 Addon 的成本就是 寫 YAML 加上一些腳本,配置文件的模板,以及監(jiān)控的模板等等,不需要寫 Go 代碼、Java 代碼,大概就是寫幾千行的非代碼文件就能接進(jìn)來,比從頭寫一個管控?zé)焽璧拈_發(fā)成本要低多了。
關(guān)于數(shù)據(jù)庫的容器化,我常常遇到兩個問題。第一個就是容器化會不會影響數(shù)據(jù)庫的性能?第二個是 K8s 適不適合管理有狀態(tài)服務(wù)?
首先回答第一個問題。容器化不會影響數(shù)據(jù)庫的性能。容器本身其實(shí)就是 Linux 操作系統(tǒng)當(dāng)中的一個普通的進(jìn)程,只是這個進(jìn)程設(shè)置了 namespace,設(shè)置了 group,使得它能夠完成一些叫做“隔離”的障眼法。重要的事情說三遍,容器不是虛擬化,容器不是虛擬化,容器不是虛擬化。
上圖大概畫了 4 種常見的隔離方案,有虛擬化的,有 gVisor、有容器,在這四種虛擬化的方案當(dāng)中,前面三種 VM、 microVM、gVisor 都有一層虛擬化層,這層虛擬化層有的放在 hypervisor 里面,有的放在用戶態(tài),唯獨(dú)容器 runC 是沒有虛擬化這層的,它就是一個普通的進(jìn)程。所以性能上來說,在容器基礎(chǔ)上做優(yōu)化,它的底子其實(shí)是最好的。為什么要隔離呢?因?yàn)楝F(xiàn)在 CPU 的核數(shù)太多了。前兩天有一個新聞?wù)f明年 AMD、英特爾還有 ARM 的核數(shù)都要達(dá)到 200 核了,大家都在往一個服務(wù)器上塞更多的核,這樣密度更高能效更好,但這么多核數(shù)單體應(yīng)用和單體數(shù)據(jù)庫都無法消費(fèi),大家用的最多的數(shù)據(jù)庫一般都是 8C、16C,這時候一定是要用隔離技術(shù),而在隔離技術(shù)里容器的性能是最好的。
基于容器,我們做了一些優(yōu)化,把容器做到跟物理機(jī)上面的性能一樣。最顯著的,我們優(yōu)化容器存儲、容器網(wǎng)絡(luò)、以及數(shù)據(jù)庫的一些參數(shù),可以達(dá)到在物理機(jī)上同樣的甚至更好的性能。比如說 PostgreSQL 的吞吐,我們對 PG 容器做了一些優(yōu)化之后,吞吐的峰值和公共云上 RDS 一個水平,而且在低并發(fā)量下比 RDS 的吞吐更高,在高并發(fā)量下吞吐會更穩(wěn)。用容器跑 Redis 的用戶經(jīng)常擔(dān)心,延遲會不會增長,如果不優(yōu)化肯定有影響,所以我們把容器網(wǎng)絡(luò)換成 eBPF 之后,就跟物理網(wǎng)絡(luò)的延遲一樣低了。
第二個問題是 K8s 適不適合管理有狀態(tài)的服務(wù)?首先 K8s 原生用來管理有狀態(tài)服務(wù)的控制器,叫 StatefulSet。StatefulSet 確實(shí)不太好用,它有挺多限制,比如不支持 PVC 存儲在線擴(kuò)容的,另外變更 Pod 的時候,必須要嚴(yán)格按順序去變更,這使得我沒辦法去指定一個 Pod 下線,它也不支持異構(gòu)的各種各樣的 Pod 配置。所以我們在 KubeBlocks 當(dāng)中把 StatefulSet 換成了我們自己寫的 InstanceSet,解決掉了 StatefulSet 的各種問題。
另一方面,很多人誤以為 在 K8s 里面必須要依賴 Pod 的遷移以及 PVC 跨機(jī)重新掛載這些 K8s 原生的機(jī)制去解決高可用、高可靠的問題,而在線下環(huán)境往往沒有分布式存儲,如果 Node 掛了,PVC 沒辦法遷移,會導(dǎo)致在線下部署的時候數(shù)據(jù)庫的可用性、可靠性受損。所以我們在 KubeBlocks 里面的做法是不依賴于 K8s 的檢測和重調(diào)度,而是使用數(shù)據(jù)庫本身的高可用和多副本技術(shù)去解決一個節(jié)點(diǎn)掛掉之后服務(wù)怎么恢復(fù)的問題,把數(shù)據(jù)庫的穩(wěn)定性和 K8s 的穩(wěn)定性解耦開。
我們接觸到了很多的企業(yè),發(fā)現(xiàn)在 K8s 上去構(gòu)建 dbPaaS 是業(yè)界正在進(jìn)行的趨勢。公共云廠商,如阿里云的 RDS 全線產(chǎn)品都是跑在 K8s 上的,騰訊云的 TDSQL 是跑在 K8s 上的,移動云電子云的 RDS 跑在 K8s 上…… 海外的數(shù)據(jù)庫的初創(chuàng)公司,像 TiDB,Cockroach、Neon、PlanteScale 也都是把自己的數(shù)據(jù)庫的 dBPaaS 架在 K8s 上。
總之,在 K8s 上建數(shù)據(jù)庫已經(jīng)成為趨勢。越來越多的企業(yè)選擇將自己的數(shù)據(jù)庫部署在 K8s 之上, 這種方式可以充分發(fā)揮容器技術(shù)的優(yōu)勢, 提高數(shù)據(jù)庫的敏捷性、可靠性和可運(yùn)維性。這種趨勢在未來幾年內(nèi)有望進(jìn)一步擴(kuò)大和深化。
往期推薦
點(diǎn)亮,服務(wù)器三年不宕機(jī)
