虚拟IP管理系统

前言

VIP是虚拟的IP地址,并不对应于一个实际的物理网络接口。通过为一台机器提供备用故障转移选项,VIP可用于提供连接冗余。

现在常用keepalived来实现VIP,结构图如下

Keepalived问题

脑裂问题

在master和backup无法正常通行时(比如master和backup之间网络出现问题),backup会认为master已经挂掉,从而选举自己成为master,开始履行master的职责,对外广播GARP和VRRP报文。这时旧的master依然在正常工作,那么我们在子网内将有两个主机在同时告诉其他主机:“我是192.168.1.2。”这就是“脑裂问题”。

一般采用两个办法来防止脑裂问题。

  1. 仲裁。当两个节点出现分歧时,由第三方的仲裁者决定听谁的。
  2. fencing。当不能确定某个节点的状态时,通过fencing把对方干掉,确认共享资源被完全释放。

成本问题

VRRP是一种典型的2N冗余,往往需要两个或以上的实例来保证单个VIP的高可用。但是在实际工程中,多个VIP同时出问题可能性是比较低的,在这种情况下,如果能用N+M(M<N)冗余来达到效果无疑能达到节省成本的效果。

利用keepalived其实也可以得到部分N+M的效果,如下图所示。这种方式需要注意配置文件的编写,这无疑也意味着运维成本的增加。

设计

本文会提出一种方法利用zookeeper来解决脑裂和成本问题,同时提供一些工具来帮助管理VIP。下面用ZVIP来指代这种方法。

整体设计比较简单,如下图所示:

演示

现在探讨这些不同的角色以及每个角色需要执行的确切步骤。

假设要创建地址为192.168.1.2和192.168.1.3的VIP,如下图所示。其中192.168.1.4(node1),192.168.1.5(node2)和192.168.1.5(node3)为实际的IP地址,在node1,node2和node3上运行agent。master运行在主机example.com上。

现在有了一个group,这个group里有2个VIP和3个节点。这个group中有两个角色 1. master。master负责管理group 2. agent。agent承担真正VIP的功能。

下面通过zkCli工具来演示工作的流程。

系统初始化

创建/groups, /nodes, /tasks这些znode。

[zk: localhost:2181(CONNECTED) 0] create /groups ""
Created /groups
[zk: localhost:2181(CONNECTED) 1] create /nodes ""
Created /nodes
[zk: localhost:2181(CONNECTED) 4] create /tasks ""
Created /tasks
[zk: localhost:2181(CONNECTED) 5] ls /
[groups, nodes, zookeeper, tasks]

当一个agent服务起来时,会在/nodes下注册一个znode并且watch创建的znode。也会在/tasks下执行同样的操作。

# For node1
[zk: localhost:2181(CONNECTED) 7] create /nodes/node-192-168-1-4 ""
Created /nodes/node-192-168-1-3
[zk: localhost:2181(CONNECTED) 9] ls /nodes/node-192-168-1-4 true
[]

# For node1
[zk: localhost:2181(CONNECTED) 7] create /tasks/node-192-168-1-4 ""
Created /nodes/node-192-168-1-4
[zk: localhost:2181(CONNECTED) 9] ls /tasks/node-192-168-1-4 true
[]

设置一个group

一个group总是被手动创建。创建者一定知道VIP的地址并且会知道真实机器的信息。创建者通过master来设置一个group(通过ui界面或者调用接口)。

master创建一个znode /groups/group1;然后在各个node下创建这个group。

# For master
[zk: localhost:2181(CONNECTED) 10] create /groups/group1 ""
Created /groups/group1
[zk: localhost:2181(CONNECTED) 11] create /groups/group1/vips ""
Created /groups/group1
[zk: localhost:2181(CONNECTED) 12] create /groups/group1/nodes ""
Created /groups/group1/nodes
[zk: localhost:2181(CONNECTED) 13] create /groups/group1/vips/vip-192-168-1-2 some-config
Created /groups/group1/vips/vip-192-168-1-2
[zk: localhost:2181(CONNECTED) 14] create /groups/group1/vips/vip-192-168-1-3 some-config
Created /groups/group1/vips/vip-192-168-1-3
[zk: localhost:2181(CONNECTED) 15] create /nodes/node-192-168-1-4/group1 some-config
Created /nodes/node-192-168-1-4/group1
[zk: localhost:2181(CONNECTED) 16] create /nodes/node-192-168-1-5/group1 some-config
Created /nodes/node-192-168-1-5/group1
[zk: localhost:2181(CONNECTED) 17] create /nodes/node-192-168-1-6/group1 some-config
Created /nodes/node-192-168-1-6/group1

node1因为之前监听了/nodes/node-192-168-1-4这个节点,所以会接受到zookeeper的通知,node1去读取/nodes/node-192-168-1-4下面的znode,更新自己的配置。然后在/groups/group1/nodes下去创建一个临时znode。

# For node1
WATCHER::
 
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/nodes/node-192-168-1-4
[zk: localhost:2181(CONNECTED) 18] create -e -s /groups/group1/nodes/node-192-168-1-4 ""
Created /groups/group1/nodes/node-192-168-1-4
[zk: localhost:2181(CONNECTED) 19] ls /groups/group1/vips
[vip-192-168-1-2, vip-192-168-1-3]
[zk: localhost:2181(CONNECTED) 20] ls /groups/group1/vips/vip-192-168-1-2 true
[]
[zk: localhost:2181(CONNECTED) 21] ls /groups/group1/vips/vip-192-168-1-3 true
[]

当master为/groups/group1/vips下面的节点增加子节点时,agent会得到zookeeper的通知,通过获取节点的内容,可以知道自己是不是被master选中,从而选择是否去执行VIP的职责。

agent执行命令

现在master向node1发送命令,需要node1去执行。流程如下。 master在/tasks/node-192-168-1-4下创建znode,并且监听其变化

# For master
[zk: localhost:2181(CONNECTED) 5] create -s /tasks/node-192-168-1-4/task- "job definition"
Created /tasks/node-192-168-1-4/task-0000000000
[zk: localhost:2181(CONNECTED) 6] ls /tasks/node-192-168-1-4/task-0000000000 true
[]

node1之前已经监听过了/tasks/node-192-168-1-4,所以会得到zookeeper的通知,这时node1会去读取/tasks/node-192-168-1-4下面的节点,拿到要执行的任务,在执行完成后,在/tasks//tasks/node-192-168-1-4/task-0000000000中添加一个状态znode

# For agent
[zk: localhost:2181(CONNECTED) 5] create /tasks/node-192-168-1-4/task-0000000000/status "done"
Created /tasks/node-192-168-1-4/task-0000000000/status

master因为监听了/tasks/node-192-168-1-4/task-0000000000节点,所以会接到zookeeper的通知,知道任务已经完成。

VIP选举

VIP由master选择,master会从/groups/group1/nodes中获取nodes列表,并选择一个node,向其发送一个任务,告诉其让来执行VIP的职责;node执行完成后通知上面的方式告知master任务完成,同时在/groups/group1/vips/vip-192-168-1-3下注册一个临时节点。master会监听这个/groups/group1/vips/vip-192-168-1-3这个节点,在node挂掉的时候master就能获取通知。

VIP Failover

master Failover

要处理master挂掉的情况,我们需要有一个备份的master。当主master挂掉的时候,备份master会接管。

因为只有一个进程能成为为master,所以master进程必须通过某种方式不让其他master获取master权限。

每个master启动时,会在/masters/下创建一个临时节点。当节点创建成功,其他尝试创建同名znode的master会报错,就此得知master这个角色已经被占有的。其他的master会监听这个znode。也会和主master一样监听/groups和/tasks下面的节点。

# For master example.shopee.com
[zk: localhost:2181(CONNECTED) 11] create /masters/master-shopee-com:1212 ""
Created /masters/master-shopee-com:1212

master每次执行分配任务时,必须确认自己的master身份。

Agent Failover

当一个agent挂掉时,比如node1挂掉时,/groups/group1/nodes/node-192-168-1-4这个临时节点会被删除,master会得到zookeeper 的通知,从而开始选择新的节点作为VIP。

原文发布于微信公众号 - 派森公园(demon-hsy)

原文发表时间:2018-02-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏挖掘大数据

Apache NiFi 简介及Processor实战应用

Apache NiFi是什么?NiFi官网给出如下解释:“一个易用、强大、可靠的数据处理与分发系统”。通俗的来说,即Apache NiFi 是一个易于使用、功能...

82810
来自专栏沃趣科技

Oracle Real Time SQL Monitoring

术语说明 TableQueue,消息缓冲区,在并行操作中使用,用于PX进程之间的通信,或者PX进程与QC进程之间的通信,是内存中的一些page,每个消息缓冲区的...

4118
来自专栏郭霖

Android Studio新功能解析,你真的了解Instant Run吗?

本篇文章首发于我的微信公众号,由于网上讲解Android Studio中Instant Run功能的文章实在是太少了,为了让更多人可以了解这个技术,我将这篇文...

1928
来自专栏老司机的技术博客

Redis集群方案怎么做?大牛给你介绍五种方案!

Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促使集群的发展,各个公司也在收集适合自己的集群方案,目前行业用的比较...

1132
来自专栏菩提树下的杨过

Spring Security笔记:Remember Me(下次自动登录)

前一节学习了如何限制登录尝试次数,今天在这个基础上再增加一点新功能:Remember Me. 很多网站,比如博客园,在登录页面就有这个选项,勾选“下次自动登录”...

2736
来自专栏腾讯Bugly的专栏

H5 缓存机制浅析 移动端 Web 加载性能优化

1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离...

3052
来自专栏前端布道

Angular开发实践(六):服务端渲染

Angular Universal Angular在服务端渲染方面提供一套前后端同构解决方案,它就是 Angular Universal(统一平台),一项在服务...

53510
来自专栏前端桃园

从0开始发布一个无依赖、高质量的键盘npm包

1394
来自专栏有困难要上,没有困难创造困难也要上!

iOS提交Appstore时报错: iTunes Store operation failed.

34712
来自专栏信安之路

挑战赛第四关应急响应题目通关秘籍

既然前文提到了溯源攻击者,又给了流量包pcapng包,自然是从流量下手;Wireshark 走起。

914

扫码关注云+社区