咱們最近將數百個ZooKeeper實例從單獨的服務器實例遷移到了Kubernetes,而期間沒有停機。咱們使用了強大的Kubernetes功能(例如端點)來簡化流程,本文主要把遷移心得分享給你們,方便有一樣需求的小夥伴們參考。有關一些重要的前提條件,好比網絡,請參見最後。後端
ZooKeeper是許多分佈式系統的基礎,這些分佈式系統主要依靠ZooKeeper來組成集羣,從而發揮分佈式系統的威力。在幕後,它依靠一致性方法來組成集羣:每一個服務器實例都有一個配置文件,其中列出了全部成員主機名和數字ID,而且全部服務器都具備相同的服務器列表,以下所示:服務器
server.1=host1:2888:3888 server.2=host2:2888:3888 server.3=host3:2888:3888
每一個服務器都有一個名爲myid的惟一文件,以告訴它與該列表對應的數字id。網絡
只要不違反關鍵規則,就能夠添加和刪除主機:每臺服務器必須可以達到其配置文件中列出的服務器的法定人數(定義爲簡單多數)。傳統方式將ZooKeeper服務器遷移到新實例的涉及到較多方面:架構
這種方法的缺點是許多配置文件更改和滾動從新啓動,您可能沒有可靠的自動化解決方案。當咱們開始將ZooKeeper遷移到Kubernetes時,咱們開始考慮這種方法,但想出了一種更簡單的方法。由於根據咱們的經驗,每次新領導人選舉都有很小的風險,即花費足夠長的時間來壓倒依賴他們的系統。分佈式
咱們的方法是將現有的ZooKeeper服務器部署在Kubernetes服務中,而後使用相同的ZooKeeper ID進行一對一的服務器到Pod替換,這隻須要一次滾動重啓就能夠從新配置現有的ZK實例,而後逐個關閉服務器。咱們不會在這裏討論爲ZooKeeper配置Kubernetes拓撲的方法,也不會討論簡單的只讀健康檢查,這是很細節的,由於不一樣的方法能夠實現同一個目的,只不過每種方法有優勢和缺點。下面討論的概念也是同樣的。spa
咱們將分五個步驟進行:code
對於下面的每一個步驟,咱們都將包含一個基礎架構拓撲圖,這些圖將僅包含兩個ZooKeeper實例,以便於理解,即便一個不想建立少於三個的集羣也是如此。server
從一個可用的ZooKeeper集羣開始,咱們將要確保主機上的服務可以與咱們的Kubernetes集羣進行通訊。在本文結尾處,咱們提供了幾種方法來實現這一點。blog
爲每一個ZooKeeper服務器建立具備匹配的Endpoint資源的ClusterIP服務,它們應該暴露客戶端端口(2181)和集羣內部端口(2888,3888)。完成後,您應該可以經過如下方式鏈接到ZooKeeper集羣。Kubernetes ClusterIP服務在這裏頗有用,由於它們爲您提供了充當後端Pod的負載平衡器的靜態IP地址,在這種狀況下,咱們將它們與服務到Pod的1:1映射一塊兒使用,所以咱們擁有靜態每一個Pod的IP地址。接口
一旦可以經過Kubernetes ClusterIP服務鏈接到ZooKeeper羣集,則是暫停並從新配置全部客戶端的好時機。若是您在ZooKeeper鏈接字符串中使用CNAME記錄,請更改DNS記錄。最簡單的方法是從新啓動全部客戶端。不然它們將在鏈接失敗時從新解析DNS條目;若是您不使用CNAME記錄,則須要使用新的鏈接字符串並從新啓動全部客戶端進程。在此時,新的鏈接字符串和舊的連接字符串仍然可使用。
接下來,咱們將使ZooKeeper服務器經過這些ClusterIP服務進行對等通訊,爲此,咱們將修改配置文件以合併ClusterIP服務的地址。配置zk_quorum_listen_all_ips也很重要:沒有它,ZK實例將沒法嘗試綁定到主機上任何接口上都不存在的ip地址,由於它是K8S服務IP。
server.1=zk1-kube-svc-0:2888:3888 server.2=zk2-kube-svc-1:2888:3888 server.3=zk3-kube-svc-2:2888:3888 zk_quorum_listen_all_ips: true
滾動重啓這些主機,如今咱們準備開始用pod替換主機。
一次替換一臺服務器,咱們將執行如下步驟:
就是這樣,您的ZooKeeper集羣如今已經在Kubernetes中運行,而且具備全部先前的數據。
爲了使這些步驟正常工做,須要處理一些網絡設置。您須要採起步驟來確保如下各項: