擁抱K8S:將ZooKeeper遷移到Kubernetes

咱們最近將數百個ZooKeeper實例從單獨的服務器實例遷移到了Kubernetes,而期間沒有停機。咱們使用了強大的Kubernetes功能(例如端點)來簡化流程,本文主要把遷移心得分享給你們,方便有一樣需求的小夥伴們參考。有關一些重要的前提條件,好比網絡,請參見最後。後端

zk01.jpg

傳統ZooKeeper遷移

ZooKeeper是許多分佈式系統的基礎,這些分佈式系統主要依靠ZooKeeper來組成集羣,從而發揮分佈式系統的威力。在幕後,它依靠一致性方法來組成集羣:每一個服務器實例都有一個配置文件,其中列出了全部成員主機名和數字ID,而且全部服務器都具備相同的服務器列表,以下所示:服務器

server.1=host1:2888:3888

server.2=host2:2888:3888

server.3=host3:2888:3888

每一個服務器都有一個名爲myid的惟一文件,以告訴它與該列表對應的數字id。網絡

只要不違反關鍵規則,就能夠添加和刪除主機:每臺服務器必須可以達到其配置文件中列出的服務器的法定人數(定義爲簡單多數)。傳統方式將ZooKeeper服務器遷移到新實例的涉及到較多方面:架構

  • 在服務器列表中使用「server.4 = host:4…」配置並啓動新主機
  • 更新現有主機上的配置文件以添加新服務器條目,並從其服務器列表中刪除已淘汰的主機
  • 滾動重啓舊主機(3.4x分支中沒有動態服務器配置)
  • 更新客戶端中的鏈接字符串(若是客戶端在錯誤時從新解析DNS,則可能只是更改CNAME記錄)

這種方法的缺點是許多配置文件更改和滾動從新啓動,您可能沒有可靠的自動化解決方案。當咱們開始將ZooKeeper遷移到Kubernetes時,咱們開始考慮這種方法,但想出了一種更簡單的方法。由於根據咱們的經驗,每次新領導人選舉都有很小的風險,即花費足夠長的時間來壓倒依賴他們的系統。分佈式

新方法

咱們的方法是將現有的ZooKeeper服務器部署在Kubernetes服務中,而後使用相同的ZooKeeper ID進行一對一的服務器到Pod替換,這隻須要一次滾動重啓就能夠從新配置現有的ZK實例,而後逐個關閉服務器。咱們不會在這裏討論爲ZooKeeper配置Kubernetes拓撲的方法,也不會討論簡單的只讀健康檢查,這是很細節的,由於不一樣的方法能夠實現同一個目的,只不過每種方法有優勢和缺點。下面討論的概念也是同樣的。spa

咱們將分五個步驟進行:code

  • 完成前提條件,以確保咱們的ZooKeeper集羣已準備好遷移
  • 在部署ZooKeeper服務的Kubernetes中建立ClusterIP服務
  • 配置ZooKeeper客戶端以鏈接到ClusterIP服務
  • 配置ZooKeeper服務器實例以經過ClusterIP服務地址執行對等事務
  • 用KubernetesPod中的ZooKeeper實例替換服務器上運行的每一個ZooKeeper實例

對於下面的每一個步驟,咱們都將包含一個基礎架構拓撲圖,這些圖將僅包含兩個ZooKeeper實例,以便於理解,即便一個不想建立少於三個的集羣也是如此。server

完成先決條件

從一個可用的ZooKeeper集羣開始,咱們將要確保主機上的服務可以與咱們的Kubernetes集羣進行通訊。在本文結尾處,咱們提供了幾種方法來實現這一點。blog

zk02.jpg

建立 ClusterIP 服務

爲每一個ZooKeeper服務器建立具備匹配的Endpoint資源的ClusterIP服務,它們應該暴露客戶端端口(2181)和集羣內部端口(2888,3888)。完成後,您應該可以經過如下方式鏈接到ZooKeeper集羣。Kubernetes ClusterIP服務在這裏頗有用,由於它們爲您提供了充當後端Pod的負載平衡器的靜態IP地址,在這種狀況下,咱們將它們與服務到Pod的1:1映射一塊兒使用,所以咱們擁有靜態每一個Pod的IP地址。接口

zk02.jpg

從新配置ZooKeeper client

一旦可以經過Kubernetes ClusterIP服務鏈接到ZooKeeper羣集,則是暫停並從新配置全部客戶端的好時機。若是您在ZooKeeper鏈接字符串中使用CNAME記錄,請更改DNS記錄。最簡單的方法是從新啓動全部客戶端。不然它們將在鏈接失敗時從新解析DNS條目;若是您不使用CNAME記錄,則須要使用新的鏈接字符串並從新啓動全部客戶端進程。在此時,新的鏈接字符串和舊的連接字符串仍然可使用。

zk03.jpg

從新配置ZooKeeper實例

接下來,咱們將使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替換主機。

zk04.jpg

用Pod 替換 ZooKeeper 主機

一次替換一臺服務器,咱們將執行如下步驟:

  • 選擇一個ZK服務器及其對應的ClusterIP服務
  • 關閉服務器上的ZK進程
  • 啓動一個配置爲與關閉的ZK服務器相同的服務器列表和myid文件的Pod
  • 等待Pod中的ZK啓動並同步來自其餘ZK節點的數據

就是這樣,您的ZooKeeper集羣如今已經在Kubernetes中運行,而且具備全部先前的數據。

zk06.jpg

網絡先決條件

爲了使這些步驟正常工做,須要處理一些網絡設置。您須要採起步驟來確保如下各項:

  • 須要從全部須要鏈接到ZooKeeper的服務器上路由Kubernetes Pod IP地址
  • 全部鏈接到ZooKeeper的服務器都必須可以解析Kubernetes服務主機名
  • Kube-proxy必須在全部須要鏈接到ZooKeeper的服務器上運行,以便它們能夠訪問ClusterIp服務
相關文章
相關標籤/搜索