拥抱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服务
相关文章
相关标签/搜索