想要在你的手提電腦上嘗試MongoDB嗎?執行一個命令,而後擁有一個輕量級,獨立的沙箱;再執行一個命令,刪除你完成以後全部的痕跡。是否是須要一個在多個環境中都跟你的應用程序堆棧同樣的應用程序?建立一你本身的容器鏡像,而後讓你的開發,測試,操做和支持團隊搭建一個跟你環境徹底同樣的克隆版本。node
容器正在完全改革整個軟件生命週期:從最先的技術實驗到貫穿開發,測試,配置到版本支持的概念驗證。mongodb
編排工具是管理多個容器如何被建立、如何升級、如何發揮高可用性的。編排工具也能夠控制多個容器之間的鏈接關係來達到 用多個容器來搭建一個複雜的應用的效果。docker
齊全的功能,簡單的工具和強大的API令容器和編排功能成爲運維團隊的最愛,運維團隊將這些功能整合到持續集成(CI)和持續交付(CD)工做流程之中。數據庫
這篇帖子深刻研究了當大家嘗試在容器中運行和編程MongDB時所面臨的挑戰,而後闡述了這些挑戰如何克服。編程
用容器和編排工具運行MongoDB介紹了一些額外注意事項:網絡
MongoDB數據庫是有狀態的。在容器運行失敗,而且從新調度以後,數據丟失是不合須要的(能夠經過從replica set中的其餘節點恢復數據,可是須要耗費時間)。爲了解決這個問題,Kubernetes中的數據卷這種抽象功能就能夠被用來映射在容器中本來是MongoDB數據目錄,變成了一個持久數據目錄位置,在這個位置,數據的存活比容器運行失敗、從新調度要長。app
在副本集合中的MongoDB數據庫節點必需要互相交流——從新調度以後也要交流。在副本集合之中的全部節點必須知道他們全部的peers,可是當一個容器從新調度以後,它極可能會用不一樣IP地址從新啓動。好比,全部在一個Kubernentes pod裏面的容器共享一個IP地址,pod一旦從新調度,這個IP地址也會改變。有了Kubernetes,這個現象就能夠經過將每一個MongoDB與Kubernetes Service關聯來解決,使用的是Kubernetes DNS Service來爲經過從新調度保持不變的servi ce提供hostname。框架
一旦但個MongoDB節點在運行(每一個都在本身的容器中),副本集合必需要初始化,並且每一個節點都要添加。這大概就須要一些額外的邏輯性來提供現成的編制工具。尤爲,在intended副本集合中,一個MongoDB節點必須被用來執行rs.initiate和rs.add命令。less
若是編制框架提供自動的容器重調度(如同Kubernetes同樣),那麼這就可以增長MongoDB的彈性,由於運行失敗的副本集合構建能夠自動從新建立,所以能夠實現恢復完整的冗餘控制水平無需任何人工干預。運維
值得注意的是,編制工具可能監控容器的狀態的同時,也可能監控在容器內運行的應用程序,或者備份他們的數據。這就意味着使用強大的監控功能,備份像MongoDB Cloud Manager解決方法都是不可能的,包括使用Mongo DB Enterprise Advanced也是不可能的。考慮一些建立本身的鏡像,鏡像能夠包括本身喜歡包括MongoDB和MongoDB自動化代理的版本。
在以前的小節也講過,像MongoDB 這樣的分佈式數據庫,在使用像Kubernetes這樣的編制框架時,須要一些額外的警示。這個小節會講到下個層次的細節,展現如何實施。
咱們從在單個Kubernetes集羣中建立整個MongoDB副本集合開始(這個正常的話,會在單個的數據中心——不會提供地理性備援)事實上,基本上不會有被改變到在多個集羣上面運行的,這些步驟以後會講到。
每一個副本集合的構件都將做爲本身的pod被運行,伴隨着暴露外部IP地址和端口的服務。這個「固定的」(fixed)IP地址十分重要,由於外部應用程序和其餘副本集成構件能夠在pod從新調度的時候保持不變,繼續依賴它。
下圖闡述了這些pods之中的一個,以及相關的Replication Controller和service。
逐步經過描述的資源配置,咱們有:
從核心開始,這裏有叫作mongo-node1的單個容器,mongo-node1包含了一個叫作 mongo的鏡像,它就是在Docker Hub上面集羣的公開的MongoD B容器鏡像。容器在集羣裏面暴露端口27107。
Kubernetes 數據卷功能被用來在映射 /data/db目錄,在鏈接到叫作mongo-persistent-storage1持久性數據元素;這些依次都是映射到一個建立在Google Cloud 的叫作mongodb-disk1的磁盤裏的。這就是MongoDB存儲數據的地方,這樣,它就會被保存到容器中從新調度。
容器被保存在一個pod中,這個pod上有個標籤標着它本身的名字 mongo-node,並且它還提供名字叫作rod的實例。
名字叫作mongo-rc1的Replication Controller被配置用來確保mongo-node1pod的單個實例是一直在運行的。
名字叫mongo-svc-a的 LoadBalancerservice暴露了一個IP地址到外界,還暴露了27017 藉口,這個接口能夠在容器中被mapped到同一個容器的接口數字。Service使用選擇器來識別正確pod匹配pod的標籤。外部IP地址和接口會被用於應用程序,以及用於副本集成之間的交流。每一個容器都有本地IP地址,可是這些IP地址會在容器被移動或者從新啓動的時候改變,而使用副本集合就不會。
下一張圖展現了副本集合的第二個構件。
90%的配置都是同樣的,只有這些改變了:
磁盤和數據卷名字必須是惟一的,這樣mongodb-disk2和mongo-persistent-storage2會被使用。
pod被用來設置instance: jane和 name:mongo-node2的標籤,這樣新的service就能夠從圖1中的rodPod區別它(經過選擇器)。
Replication Controller被命名爲mongo-rc2
Service被命名爲mongo-svc-b ,而且有一個惟一的,外部IP地址(在這個實例中,Kubernetes被賦值104.1.4.5)。
第三個副本集合構件也是相同的模式,下圖就展現了完整的副本集合:
注意,即便在3個或者更多節點的Kubernetes集羣上運行像圖3所示的配置,Kubernetes可能(一般都會)會調度兩個或者更多的MongoDB副本集合構件在同一個主機上。這是由於Kubernetes講這三個節點當作三個獨立的service了。
爲了增長冗餘(在zone裏面),一個額外的headless service被建立。新的service沒有提供新的性能來通知Kubernetes說,那三個MongoDB pods來自同一個service,因此KUbernetes嘗試在不一樣的節點上調度他們。
真實的須要編制和開啓MongoDB的副本集合的配置文件和命令行能夠點擊這裏查看:點我。特別是,有些特殊的步驟要求將三個Mongo DB實例組合到一個運行的,強健的副本集合,這個的話,已經在論文中講了。
全部東西都在同一個GCE集羣裏面運行,因此副本集合建立的上述東西也仍是伴隨着風險的,在同一個可用區域也是同樣的道理。假設有一個重大事故發生,可用區域離線了,那麼MongoDB副本集合就不可用了。若是須要地理性備援,那麼那三個pods就應該在三個不一樣的可用性地帶或者區域運行。
使人吃驚的是,爲了分別在三個區域內建立類似的副本集合,幾乎不須要改變什麼——這就要求三個集羣。每一個集羣都須要各自的KubernetesYAML文件,這個文件只定義了pod,Replication Controller和service做爲副本集合的一個構件。而後爲每一個區域都建立一個集羣,持久性數據和MongoDB。
爲了瞭解更多關於容器和編制——二者涉及的技術,以及他們交付的業務利益——閱讀這篇論文:點我就是跟上文提到的那篇論文,在如何get到副本集合上以及在GCE上運行Docker和Kubernetes上提供指導。
加入咱們的網絡研討會,一塊兒討論如何用Docker,Kubernetes和MongoDB來實施微服務,瞭解更多關於這個話題的東西。