使用 Docker 和 Kubernetes 將 MongoDB 作為微服務執行
介紹
想在膝上型電腦上嘗試 MongoDB?只需執行一個命令,你就會有一個輕量級的、獨立的沙箱。完成後可以刪除你所做的所有痕跡。
想在多個環境中使用相同的程式棧副本?構建你自己的容器映象,讓你的開發、測試、運維和支援團隊使用相同的環境克隆。
容器正在徹底改變整個軟體生命週期:從最早的技術性實驗和概念證明,貫穿了開發、測試、部署和支援。
編排工具用來管理如何建立、升級多個容器,並使之高可用。編排還控制容器如何連線,以從多個微服務容器構建複雜的應用程式。
豐富的功能、簡單的工具和強大的 API 使容器和編排功能成為 DevOps 團隊的首選,將其整合到連續整合(CI) 和連續交付 (CD) 的工作流程中。
這篇文章探討了在容器中執行和編排 MongoDB 時遇到的額外挑戰,並說明了如何克服這些挑戰。
MongoDB 的注意事項
使用容器和編排執行 MongoDB 有一些額外的注意事項:
- MongoDB 資料庫節點是有狀態的。如果容器發生故障並被重新編排,資料則會丟失(能夠從副本集的其他節點恢復,但這需要時間),這是不合需要的。為了解決這個問題,可以使用諸如 Kubernetes 中的資料卷 抽象等功能來將容器中臨時的 MongoDB 資料目錄對映到持久位置,以便資料在容器故障和重新編排過程中存留。
- 一個副本集中的 MongoDB 資料庫節點必須能夠相互通訊 - 包括重新編排後。副本集中的所有節點必須知道其所有對等節點的地址,但是當重新編排容器時,可能會使用不同的 IP 地址重新啟動。例如,Kubernetes Pod 中的所有容器共享一個 IP 地址,當重新編排 pod 時,IP 地址會發生變化。使用 Kubernetes,可以通過將 Kubernetes 服務與每個 MongoDB 節點相關聯來處理,該節點使用 Kubernetes DNS 服務提供“主機名”,以保持服務在重新編排中保持不變。
- 一旦每個單獨的 MongoDB 節點執行起來(每個都在自己的容器中),則必須初始化副本集,並新增每個節點到其中。這可能需要在編排工具之外提供一些額外的處理。具體來說,必須使用目標副本集中的一個 MongoDB 節點來執行
rs.initiate
和rs.add
命令。 - 如果編排框架提供了容器的自動化重新編排(如 Kubernetes),那麼這將增加 MongoDB 的彈性,因為這可以自動重新建立失敗的副本整合員,從而在沒有人為干預的情況下恢復完全的冗餘級別。
- 應該注意的是,雖然編排框架可能監控容器的狀態,但是不太可能監視容器內執行的應用程式或備份其資料。這意味著使用 MongoDB Enterprise Advanced 和 MongoDB Professional 中包含的 MongoDB Cloud Manager 等強大的監控和備份解決方案非常重要。可以考慮建立自己的映象,其中包含你首選的 MongoDB 版本和 MongoDB Automation Agent。
使用 Docker 和 Kubernetes 實現 MongoDB 副本集
如上節所述,分散式資料庫(如 MongoDB)在使用編排框架(如 Kubernetes)進行部署時,需要稍加註意。本節將介紹詳細介紹如何實現。
我們首先在單個 Kubernetes 叢集中建立整個 MongoDB 副本集(通常在一個資料中心內,這顯然不能提供地理冗餘)。實際上,很少有必要改變成跨多個叢集執行,這些步驟將在後面描述。
副本集的每個成員將作為自己的 pod 執行,並提供一個公開 IP 地址和埠的服務。這個“固定”的 IP 地址非常重要,因為外部應用程式和其他副本整合員都可以依賴於它在重新編排 pod 的情況下保持不變。
下圖說明了其中一個 pod 以及相關的複製控制器和服務。
圖 1:MongoDB 副本整合員被配置為 Kubernetes Pod 並作為服務公開
逐步介紹該配置中描述的資源:
- 從核心開始,有一個名為
mongo-node1
的容器。mongo-node1
包含一個名為mongo
的映象,這是一個在 Docker Hub 上託管的一個公開可用的 MongoDB 容器映象。容器在叢集中暴露埠27107
。 - Kubernetes 的資料卷功能用於將聯結器中的
/data/db
目錄對映到名為mongo-persistent-storage1
的永久儲存上,這又被對映到在 Google Cloud 中建立的名為mongodb-disk1
的磁碟中。這是 MongoDB 儲存其資料的地方,這樣它可以在容器重新編排後保留。 - 容器儲存在一個 pod 中,該 pod 中有標籤命名為
mongo-node
,並提供一個名為rod
的(任意)示例。 - 配置
mongo-node1
複製控制器以確保mongo-node1
pod 的單個例項始終執行。 - 名為
mongo-svc-a
的負載均衡
服務給外部開放了一個 IP 地址以及27017
埠,它被對映到容器相同的埠號上。該服務使用選擇器來匹配 pod 標籤來確定正確的 pod。外部 IP 地址和埠將用於應用程式以及副本整合員之間的通訊。每個容器也有本地 IP 地址,但是當容器移動或重新啟動時,這些 IP 地址會變化,因此不會用於副本集。
下一個圖顯示了副本集的第二個成員的配置。
圖 2:第二個 MongoDB 副本整合員配置為 Kubernetes Pod
90% 的配置是一樣的,只有這些變化:
- 磁碟和卷名必須是唯一的,因此使用的是
mongodb-disk2
和mongo-persistent-storage2
- Pod 被分配了一個
instance: jane
和name: mongo-node2
的標籤,以便新的服務可以使用選擇器與圖 1 所示的rod
Pod 相區分。 - 複製控制器命名為
mongo-rc2
- 該服務名為
mongo-svc-b
,並獲得了一個唯一的外部 IP 地址(在這種情況下,Kubernetes 分配了104.1.4.5
)
第三個副本成員的配置遵循相同的模式,下圖展示了完整的副本集:
圖 3:配置為 Kubernetes 服務的完整副本整合員
請注意,即使在三個或更多節點的 Kubernetes 群集上執行圖 3 所示的配置,Kubernetes 可能(並且經常會)在同一主機上編排兩個或多個 MongoDB 副本整合員。這是因為 Kubernetes 將三個 pod 視為屬於三個獨立的服務。
為了在區域內增加冗餘,可以建立一個附加的 headless 服務。新服務不向外界提供任何功能(甚至不會有 IP 地址),但是它可以讓 Kubernetes 通知三個 MongoDB pod 形成一個服務,所以 Kubernetes 會嘗試在不同的節點上編排它們。
圖 4:避免同一 MongoDB 副本整合員的 Headless 服務
配置和啟動 MongoDB 副本集所需的實際配置檔案和命令可以在白皮書《啟用微服務:闡述容器和編排》中找到。特別的是,需要一些本文中描述的特殊步驟來將三個 MongoDB 例項組合成具備功能的、健壯的副本集。
多個可用區 MongoDB 副本集
上面建立的副本集存在風險,因為所有內容都在相同的 GCE 叢集中執行,因此都在相同的可用區中。如果有一個重大事件使可用區離線,那麼 MongoDB 副本集將不可用。如果需要地理冗餘,則三個 pod 應該在三個不同的可用區或地區中執行。
令人驚奇的是,為了建立在三個區域之間分割的類似的副本集(需要三個叢集),幾乎不需要改變。每個叢集都需要自己的 Kubernetes YAML 檔案,該檔案僅為該副本集中的一個成員定義了 pod、複製控制器和服務。那麼為每個區域建立一個叢集,永久儲存和 MongoDB 節點是一件很簡單的事情。
圖 5:在多個可用區域上執行的副本集
下一步
要了解有關容器和編排的更多資訊 - 所涉及的技術和所提供的業務優勢 - 請閱讀白皮書《啟用微服務:闡述容器和編排》。該檔案提供了獲取本文中描述的副本集,並在 Google Container Engine 中的 Docker 和 Kubernetes 上執行的完整的說明。
作者簡介:
Andrew 是 MongoDB 的產品營銷總經理。他在去年夏天離開 Oracle 加入 MongoDB,在 Oracle 他花了 6 年多的時間在產品管理上,專注於高可用性。他可以通過 @andrewmorgan 或者在他的部落格(clusterdb.com)評論聯絡他。
via: https://www.mongodb.com/blog/post/running-mongodb-as-a-microservice-with-docker-and-kubernetes
作者:Andrew Morgan 譯者:geekpi 校對:wxy
相關文章
- 將手機作為伺服器執行docker服務伺服器Docker
- 配置cri-docker使kubernetes1.24以docker作為執行時Docker
- Java微服務開發指南–使用Docker和Kubernetes構建可伸縮的微服務Java微服務Docker
- 將程式製作為服務執行的方法
- 使用Golang和MongoDB構建微服務GolangMongoDB微服務
- 使用 caddy 作為微服務的 API gateway微服務APIGateway
- [譯] 將 React 作為 UI 執行時ReactUI
- 【微服務】docker使用記錄微服務Docker
- [雲原生微服務架構](十二) Kubernetes和docker都做了啥微服務架構Docker
- MongoDB和資料流:使用MongoDB作為Kafka消費者MongoDBKafka
- 使用Spring Cloud Kubernetes基於Kubernetes、Spring Boot和Docker構建微服務架構 - MoriohCloudSpring BootDocker微服務架構
- Docker簡易版:使用更少擊鍵執行Redis,MongoDBDockerRedisMongoDB
- 使用harbor和nexus作為docker registryDocker
- 微服務執行指南——For Cattle微服務
- 使用 Consul 作為 Python 微服務的配置中心Python微服務
- 結合Docker執行Spring Cloud微服務的多種方式DockerSpringCloud微服務
- 將微服務部署到 Azure Kubernetes 服務 (AKS) 實踐微服務
- 使用docker-compose執行微服務專案#eureka+config+auth+gateway+moduleDocker微服務Gateway
- 為什麼Kubernetes天然適合微服務?微服務
- 為什麼 kubernetes 天然適合微服務微服務
- jenkins+docker進行微服務部署JenkinsDocker微服務
- Docker與微服務Docker微服務
- Docker 微服務教程Docker微服務
- Quarkus和MongoDB微服務簡單案例原始碼MongoDB微服務原始碼
- Kubernetes+Docker微服務實踐之路--彈性擴容Docker微服務
- 微服務為什麼一定要用docker微服務Docker
- 微服務為什麼一定要上Docker?微服務Docker
- 把 React 作為 UI 執行時來使用ReactUI
- 多執行緒在微服務API統計和健康檢查中的使用執行緒微服務API
- docker-執行mysql服務DockerMySql
- Docker+Kubernetes(k8s)微服務容器化實踐DockerK8S微服務
- 為什麼要使用微服務微服務
- 微服務中的事件、流程和長時間執行業務微服務事件行業
- 使用OAuth2和JWT為微服務提供安全保障OAuthJWT微服務
- 使用Systemd執行Docker容器Docker
- 使用docker執行CentOS容器DockerCentOS
- java程式在windows系統作為服務程式執行JavaWindows
- docker-執行jenkins服務DockerJenkins