譯者 | 康少京
策劃 | 云昭
在眾多NoSQL存儲中,Cassandra 是廣受企業和開發者歡迎的選擇之一。它使用AmazonDynamo引入的架構方面的特性來支持Big Table 數據模型,優勢非常明顯:高度可擴展性和高度可用性、沒有單點故障 NoSQL 列族實現、非常高的寫入吞吐量和良好的讀取吞吐量、二級索引支持搜索可調節的一致性和對復制的支持靈活的模式等。除此之外,它還實現了一個非常棘手的 Kubernetes 集群中運行數據庫(或其他應用程序)的難題,這里供大家參考。 全球應用程序需要一個與它們服務的用戶一樣分布式的數據層,Apache Cassandra已經很好的做到了這一點,目前為蘋果、Netflix和索尼等公司處理數據需求。傳統上,分布式應用程序的數據層管理,由專門的團隊來管理數千個節點的部署和操作(包括本地節點和云中的節點)。
(資料圖片)
為了減輕DevOps團隊的大部分負擔,我們利用Kubernetes(K8s)提供的公共控制區域,在K8ssandra中開發了許多這樣的實踐和模式。不過,有一個問題是,如果沒有適當的注意和預先規劃,跨多個區域或K8s集群運行數據庫(或任何應用程序)是很棘手的。
在這里向您展示下是如何做到這一點的,我們先看看在一個單獨的K8s集群上運行的單個區域K8ssandra部署。它是由六個Cassandra節點組成,分布在該區域內的三個可用性區域中,每個可用性區域中有兩個Cassandra節點。在本例中,我們將使用谷歌云平臺(GCP)區域名稱。然而,這里的例子同樣適用于其他云,甚至是在線云。
這就是我們現在的處境:
云數據庫的現有部署
目標是建立兩個區域,每個區域都有一個 Cassandra 數據中心。 在我們這里的云管理 K8s 部署中,這就轉化為兩個K8s集群——每個集群都有一個單獨的控制平面,但使用一個公共的虛擬私有云 (VPC) 網絡。 通過 Cassandra 集群擴展到多個數據中心,我們可以在區域中斷的情況下獲得冗余,并且在本地訪問數據的情況下改善客戶端應用程序的響應時間和延遲。
這就是我們的目標:擁有兩個區域,每個區域都有自己的 Cassandra 數據中心。
表面上看,我們似乎可以通過簡單地啟動另一個部署相同 K8s YAML 的 K8s 集群來實現這一點。然后對可用區名稱添加一些調整,我們就可以完成了,對吧?最終,這些資源的形狀非常相似,都是 K8s 對象。那么,這不應該有效嗎?也許。根據您的環境,這種方法可能會起作用。
如果沒有使用完全分布式數據庫部署,會避免很多問題。但不幸的是,事情很少那么簡單。即使其中一些障礙很容易清除,還有許多其他無害的事情可能會出錯并導致降級狀態。您選擇的云提供商、K8s 發行版、命令行標志,是的,甚至是 DNS——這些都可能導致您進入一條黑暗深淵。所以,我們來探討一些可能遇到的最常見問題來避免這種情況。
常見障礙即使您的某些部署一開始起來運行得很好,但當您發展到多云環境、升級到另一個 K8s 版本或開始使用不同的發行版和免費工具時,您可能會遇到一兩個障礙。當涉及到分布式數據庫時,它有更多的底層功能。了解 K8s是如何在一系列硬件中運行容器的,將有助于開發高級解決方案--最終它將滿足您的確切需求。
Cassandra 節點需要唯一 IP 地址
您可能遇到的第一個障礙涉及基本網絡?;氐轿覀兊牡谝粋€集群,讓我們看一下所涉及的網絡層。
在下面顯示的 VPC 中,我們有一個無分類域間路由 (CIDR) 范圍,代表 K8s工作實例的地址。在 K8s 集群范圍內,有一個單獨的地址空間,用于操作 pods 和容器運行。Pod 是共享了某些資源的容器集合,例如存儲、網絡和進程空間。 在某些云環境中,這些子網被綁定到特定的可用區域。因此,K8s工作器所啟動的每個子網可能都有一個CIDR范圍。 VPC 中可能還有其他虛擬機,但在本例中,我們將堅持使用 K8s 作為唯一租戶。
具有K8s層的VPC使用的CIDR范圍
在我們的例子中,有 10.100.x.x 用于節點,10.200.x.x 用于 K8s 級別。 每個K8s工作者都會獲得10.200.x.x 的一部分,在該單個實例上運行Pod 的CIDR范圍。
回想一下我們的目標結構,如果兩個集群使用相同或重疊的CIDR地址范圍會發生什么? 當你第一次接觸網絡時,您可能還記得這些錯誤信息:
嘗試連接兩個網絡時的常見錯誤消息
K8s 的錯誤看起來不像這樣。不會彈出集群無法有效溝通的警告。
如果您有一個具有 IP 空間的集群,而另一個集群有相同的IP空間或重疊的位置,那么每個集群如何知道特定數據包何時需要離開自己的地址空間,并且通過 VPC 網絡路由到另一個集群,然后進入該集群的網絡?
正常情況下,這里沒有任何提示。有一些方法可以解決這個問題;但從更高的層面來看,如果你有重疊,那就是自找麻煩。這里的重點是,您需要了解每個集群的地址空間,然后仔細規劃這些 IP 的分配和使用。這允許 Linux 內核(K8s 路由發生的地方)和 VPC 網絡層根據需要轉發和路由數據包。
但是,如果您沒有足夠的 IP怎么辦?在某些情況下,您不能給每 pod提供自己的 IP 地址。因此,在這種情況下,您需要退后一步,確定哪些服務絕對必須具有唯一地址,以及哪些服務可以在同一地址空間中一起運行。例如,如果您的數據庫需要能夠與每個其他pod通信,那么它可能需要自己的唯一地址。但是,如果在東海岸和西海岸的應用程序層只是與他們的本地數據層通信,它們可以擁有自己的專用 K8s 集群,地址范圍相同,避免沖突。
扁平化網絡
在我們的參考部署中,我們將 K8s 集群中的非重疊范圍專用于基礎設施層,這些基礎設施必須是唯一的,并且服務不會通信的重疊 CIDR 范圍。最終,我們在這里所做的是扁平化網絡。
有了不重疊的 IP 范圍,現在可以繼續將數據包路由到每個集群中的 pod。在上圖中,您可以看到西海岸為 10.100,東海岸為 10.150,K8s pod 接收來自這些范圍的 IP。K8s 集群有自己的 IP 空間,200 對 250,并且 pod 像以前一樣被分割。
如何處理 Cassandra 數據中心之間的路由我們有一堆 IP 地址,并且我們對這些地址具有唯一性?,F在,我們如何處理這些數據的路由以及所有這些的通信和發現?發往集群 A 的數據包無法知道它們需要如何路由到集群 B。當我們嘗試跨集群邊界發送數據包時,本地Linux網絡堆棧會發現這不是該主機或本地K8s群集內的任何主機的本地數據包,然后將數據包轉發到 VPC 網絡。從這里開始,我們的云提供商必須有一個路由表條目來了解這個數據包需要去哪里。
在某些情況下,這是開箱即用。 VPC 路由表使用 pod 和服務 CIDR 范圍進行更新,告知應路由哪些主機數據包。在其他環境中,包括混合環境和本地環境,這可能采取通過 BGP向網絡層通告路由的形式。雅虎!日本有一篇很棒的文章介紹了這種確切的部署方法。
但是,這些選項可能并不總是最好的答案,這取決于您的多集群架構在單個云提供商中的樣子。它是混合云還是多云,結合了本地和兩個不同的云提供商?雖然您當然可以在所有這些不同的環境中檢測這些,但您可以指望它需要大量的時間和維護。
要考慮的一些解決方案覆蓋網絡一個更簡單的答案是使用覆蓋網絡,在其中為您的應用程序構建一個單獨的 IP 地址空間——在這種情況下,它是一個 Cassandra 數據庫。然后,您可以利用代理、 sidecars和網關在現有的Kube網絡上運行它。在這篇文章中,我們不會深入探討這一點,但我們有一些關于如何跨 K8s 集群連接有狀態工作負載的很棒的內容,這些內容將向您展示如何從高層次上做到這一點。
所以,接下來是什么?數據包在流動,但現在有一些新的 K8s詭計要處理。假設您已經準備好了網絡并擁有了所有適當的路由,那么這些集群之間至少在 IP層存在一些連接。您擁有 IP 連接 Pod,并且Cluster 1 可以與 Pods 和Cluster 2 通信,但您現在還需要考慮一些新的事情。
服務發現在K8s 網絡中,身份是暫時的。由于集群事件,Pod可能被重新安排并接收新的網絡地址。在某些應用中,這不是問題。在其他情況下,比如數據庫,網絡地址就是身份——這可能導致意外行為。盡管 IP 地址可能會發生變化,但隨著時間的推移,我們的存儲以及每個 pod 所代表的數據都會保持不變。我們必須有一種方法來維護地址到應用程序的映射。這就是服務發現的切入點。
在大多數情況下,服務發現是在 K8s內通過DNS 實現的。即使 pod 的 IP 地址可能發生變化,它也可以具有基于 DNS 的持久身份,該身份會在集群時間發生時被更新。這聽起來很不錯,但是當我們進入多集群的世界時,我們必須確保我們的服務可以跨集群邊界被發現。作為Cluster 1 中的 pod,我應該能夠獲取Cluster 2 中的 pod 的地址。
DNS 存根
解決這個難題的一種方法是 DNS 存根。在這個配置中,我們配置 K8s DNS 服務,將特定域后綴的請求路由到遠程集群。有了完全限定的域名,我們就可以將 DNS 查找請求轉發到適當的集群進行解析并最終路由。
這里的問題是,每個集群都需要通過 kubelet 標志設置單獨的 DNS 后綴,這在所有 K8s 中都不是一個選項。一些用戶通過使用命名空間名稱作為 FQDN 的一部分來配置存根解決此問題。這是可行的,但有點像黑客,不是正確設置集群后綴。
托管 DNS
另一種類似于 DNS 存根的解決方案是使用托管 DNS 產品。 在 GCP 的情況下,有 Cloud DNS 產品,可以將本地 DNS 表項復制到 VPC 級別,供外部集群甚至同一 VPC 內的虛擬機進行解析。 此選項提供了很多好處,包括:
消除管理集群托管 DNS 服務器的開銷——云 DNS 不需要擴展、監控或管理 DNS 實例,因為它是托管的 Google 服務。
每個Google K8s引擎(GKE)節點上DNS查詢的本地解析——與NodeLocal DNSCache類似,云DNS將DNS響應存到本地,提供低延遲和高可擴展性DNS解析。
與 Google Cloud 的操作套件集成——提供了 DNS 監控和日志記錄。
VPC 范圍DNS——提供多集群、多環境和 VPC 范圍的 K8s 業務解析。
用于多集群服務發現的復制托管 DNS
Cloud DNS 抽象了許多傳統的開銷。 云提供商將管理伸縮性、監控和安全補丁,以及您期望從托管產品中獲得的所有其他方面。 對于一些提供商來說,GKE還提供了一個節點本地 DNS 緩存,它通過在較低級別運行 DNS 緩存來減少延遲,這樣您就不用等待 DNS 響應。
從長遠來看,如果您只在單個云中,專門用于DNS的托管服務將可以正常工作。 但是,如果您跨越多個云提供商和本地環境的集群,托管產品可能只是解決方案的一部分。
云本地計算基金會https://www.cncf.io/(CNCF) 提供了多種選擇,并且有大量開源項目缺思在幫助緩解這些痛點方面取得了很大的發展,尤其是在跨云、多云、 或混合云類型的場景。
譯者介紹康少京,51CTO社區編輯,目前從事通訊類行業,底層驅動開發崗位,研究過數據結構,Python,現對操作系統和數據庫等相關領域感興趣。
原文標題:Taking Your Database Beyond a Single Kubernetes Cluster,作者:Christopher Bradford
鏈接:https://dzone.com/articles/taking-your-database-beyond-a-single-kubernetes-cl
X 關閉
X 關閉