標籤:架構 必須 移除 學習 zone 物理 enter 應用程式 post
本文介紹了利用Docker和Kubernetes搭建一套具有冗餘備份組合的MongoDB服務,從容器對CI和CD引發的改變入手,討論了容器技術對MongoDB帶來的挑戰和機會,然後實戰如何部署一套穩定的MongoDB服務,非常的乾貨
介紹
想嘗試在膝上型電腦上運行MongoDB嗎?希望通過執行一個簡單的命令,然後就有一個輕量級、自組織的沙箱嗎?並可再通過一條命令就可以移除所有的痕迹嗎?
需要在多個環境中運行相同的應用程式棧?建立自己的容器鏡像,使得開發、測試、操作和支援小組啟動一份完全相同的環境。
容器正在改變整個軟體生命週期;它覆蓋了從最初的技術實驗到通過開發、測試、部署和支援的概念證明。
閱讀微服務:容器和編排白皮書
編排工具管理者多個容器如何建立、升級和高可用。編排同樣管理著容器如何串連,並利用多個微服務容器建立穩定的應用服務。
豐富的功能、簡單的工具、強大的API讓容器和編排得到DevOps團隊的青睞。DevOps工程師將它們整合到持續整合(CI)和持續傳遞(CD)工作流程中。
本篇文章將探索你在嘗試運行和編排MongoDB容器時遇到的問題,並描述如何克服這些問題。
對於MongoDB的思考
採用容器和編排運行MongoDB帶來了一些新的思考:
MongoDB資料庫節點是有狀態的。若一個容器掛了,並且被重新編排,資料丟失是不能接受的(雖然它可以從其他節點中恢複資料,但是很費時)。為解決這個問題,Kubernetes中的卷抽象(Volume abstraction)特性將用於映射MongoDB資料檔案夾到一個持久化地址,避免容器的失敗或重編排。
同一組MongoDBDatabase Backup節點之間需要通訊,即使是在重編排之後。同一冗餘備份組合的節點必須知道全部其他節點的地址,但是當某個容器重編排之後,它的IP地址會變化。例如,所有Kubernetes內的容器共用一個IP地址,當pod被重編排之後這個地址就會改變。在Kubernetes中,這個問題可以通過聯絡Kubernetes服務與MongoDB節點來解決,採用Kubernetes的DNS服務提供主機名稱給重編排之後的服務。
一旦每個獨立的MongoDB節點(每個節點在單獨容器中)啟動起來,備份組合必須初始化,並把每個節點加入進來。這需要編排工具提供額外的邏輯。特別是備份組合中只有一個MongoDB節點時,必須執行rs.initiate和rs.add命令。
如果編排架構提供自動化重編排容器功能(如Kubernetes的特性),那麼這可以提高MongoDB的容災性,節點會在掛掉之後自動重新建立,恢複到完整冗餘水平且不需要人工幹預。
當編排架構掌控所有容器的狀態時,它並不管理容器內的應用或者備份資料。這就意味著採用一個有效管理和備份方案很重要,如MongoDB Cloud Manager,包括MongoDB Enterprise Advanced和MongoDB Professional兩部分。考慮到需要建立鏡像,可採用你傾向的MongoDB版本和MongoDB Automation Agent。
利用Docker和Kubernetes實現MongoDB冗餘備份
如前一節所述,MongoDB這類分散式資料庫在利用編排架構(如Kubernetes)進行部署時需要額外考慮。本節將對這部分細節進行分析,並介紹如何?。
首先,我們在一個單獨的Kubernetes叢集(同一個資料中心內,並不存在物理上的冗餘備份)中建立整個MongoDB冗餘集合。如果跨多個資料中心進行建立,其步驟也差異不大,後續將會介紹。
備份中的每個成員都運行在獨自的pod中,只暴露其ip地址和連接埠。固定的IP地址對於外部應用和其他冗餘備份節點非常重要,它決定了哪些pod將被重新部署。
展示了其中一個pod與關聯的冗餘控制器和服務的關係。
深入這些配置中描述的資源,內容如下:
啟動核心節點mongo-node1。該節點包括了一個叫做的mongo的鏡像,來源於[Docker Hub],其暴露27107連接埠。
Kubernetes的卷特性用於映射/data/db檔案夾到持久化目錄mongo-persistent-storage1;該目錄為Google Cloud上建立的目錄映射mongodb-disk1,用於持久化MongoDB的資料。
容器由pod進行管理,標記為mongo-node,同時對rod提供一個隨機產生的名字。
冗餘控制器命名為mongo-rc1,用於確保mongo-node1的執行個體一直處於運行中。
負載平衡服務命名為mongo-svc-a用27017暴露連接埠。該服務通過pod的標籤匹配正確的服務到對應的pod上,對外暴露的ip和連接埠給應用程式使用,同時用於冗餘備份組合中各節點的通訊。雖然每個容器擁有內部ip,但是當容器被重啟或者移動之後它們會變更,因此不能用於冗餘備份組合之間的通訊。
展示了冗餘備份及中的另一個成員資訊:
90%的配置是相同的,只有幾處不同:
硬碟和卷的名字必須是唯一的,於是採用mongodb-disk2和mongo-persisitent-storage2。
Pod分配到jane執行個體,同時節點命名為mongo-node2,用於區分新服務與圖1中的Pod
冗餘控制命名為mongo-rc2
服務命名為mongo-svc-b,並擷取一個不同的外部IP地址(本例子中,Kubernets分配為104.1.4.5)
第三個冗餘備份成員的配置仿照上述的模式進行,展示了完整的冗餘配置集合:
注意,即使配置3一樣,在一個三個或者多個節點的Kubernetes叢集上,Kubernetes可能會調度兩個或者多個MongoDB冗餘備份成員在同一個宿主機上。這是因為Kubernetes將三個pod視為三個獨立的服務。
為了增加冗餘,需要建立一個額外的headless服務。該服務不具備提供外部服務的能力,甚至沒有外部IP地址,但是它用於通知Kubernetes這三個MongoDB Pod是屬於同一個服務,於是Kubernetes會將它們調度在不同的節點上。
具體的設定檔和相關操作命令可以從啟動微服務:容器&調度說明白皮書中找到。其中包含了三個特殊的步驟確保合并三個MongoDB到一個功能中,即本文中描述的冗餘備份。
多個可用性區域域MongoDB冗餘集合
所有冗餘組件均運行在同一個GCE叢集上時具有很高的風險,在同一個zone的叢集也一樣。如果發生一個重大事件導致可用zone離線,那麼MongoDB冗餘集合也就不可用。如果需要地理上的冗餘備份,那麼三個pod需要運行在不同的zone內。
只需要很少的改動就可以建立這樣一個冗餘備份組合。每一個叢集需要獨自的Kubernetes YAML檔案來定義pod、冗餘控制器和服務。然後,就可以完成一個zone的叢集建立、持久化儲存和MongoDB節點。
展示了運行在不同zone上的冗餘結合:
推薦一個交流學習群:685167672 裡面會分享一些資深架構師錄製的視頻錄影:有Spring,MyBatis,Netty源碼分析,高並發、高效能、分布式、微服務架構的原理,JVM效能最佳化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多:
大神教你輕鬆玩轉Docker和Kubernetes中如何運行MongoDB微服務