Kubernetes:模拟网络分区

本文介绍了如何在 Kubernetes 集群中模拟网络分区,特别是针对 Neo4j 数据库。通过利用 BusyBox 提供的 route 命令,作者展示了如何使一个 Neo4j Pod 与其它 Pod 断开连接,进而触发领导者选举。实验结果显示,neo4j-0 成为了新的领导者,而在网络分区期间,neo4j-2 无法与其他节点通信,直到网络分区被修复。
摘要由CSDN通过智能技术生成

几周前,我写了一篇文章,解释了如何使用Kubernetes创建Neo4j因果集群,并且…我想弄清楚如何模拟网络分区,该分区将使领导者处于少数席位并迫使选举。

我们已经使用iptables命令在AWS的内部工具上完成了此操作,但是不幸的是,在我的容器中没有该容器,该容器仅具有BusyBox提供的实用程序。

幸运的是,其中之一是route命令,它将使我们能够实现相同的目的。

回顾一下,我有3个Neo4j Pod已启动并正在运行:

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
neo4j-0   1/1       Running   0          6h
neo4j-1   1/1       Running   0          6h
neo4j-2   1/1       Running   0          6h

我们可以检查route命令是否可用:

$ kubectl exec neo4j-0 -- ls -alh /sbin/route 
lrwxrwxrwx    1 root     root          12 Oct 18 18:58 /sbin/route -> /bin/busybox

让我们看一下每个服务器当前扮演的角色:

$ kubectl exec neo4j-0 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"FOLLOWER"
 
Bye!
$ kubectl exec neo4j-1 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"FOLLOWER"
 
Bye!
$ kubectl exec neo4j-2 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"LEADER"
 
Bye!

稍微说一下:我可以在没有用户名和密码的情况下调用cypher-shell ,因为我通过将以下内容放入conf / neo4j.conf来禁用授权:

dbms.connector.bolt.enabled=true

回到网络分区……我们需要通过运行以下命令从其他两台服务器中划分neo4j-2

$ kubectl exec neo4j-2 -- route add -host neo4j-0.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-2 -- route add -host neo4j-1.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-0 -- route add -host neo4j-2.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-1 -- route add -host neo4j-2.neo4j.default.svc.cluster.local reject

如果我们查看neo4j-2的日志,可以看到它与其他两台服务器断开连接后已退出:

$ kubectl exec neo4j-2 -- cat logs/debug.log
...
2016-12-04 11:30:10.186+0000 INFO  [o.n.c.c.c.RaftMachine] Moving to FOLLOWER state after not receiving heartbeat responses in this election timeout period. Heartbeats received: []
...

谁被接任领导?

$ kubectl exec neo4j-0 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"LEADER"
 
Bye!
$ kubectl exec neo4j-1 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"FOLLOWER"
 
Bye!
$ kubectl exec neo4j-2 -- bin/cypher-shell "CALL dbms.cluster.role()"
role
"FOLLOWER"
 
Bye!

看起来像neo4j-0! 让我们将一些数据放入数据库中:

$ kubectl exec neo4j-0 -- bin/cypher-shell "CREATE (:Person {name: 'Mark'})"
Added 1 nodes, Set 1 properties, Added 1 labels
 
Bye!

让我们检查该节点是否到达其他两个服务器。 我们希望它在neo4j-1上,而不在neo4j-2上:

$ kubectl exec neo4j-1 -- bin/cypher-shell "MATCH (p:Person) RETURN p"
p
(:Person {name: "Mark"})
 
Bye!
$ kubectl exec neo4j-2 -- bin/cypher-shell "MATCH (p:Person) RETURN p"
 
 
Bye!

在neo4j-2上,随着选举超时触发器的出现,我们会在日志中反复看到这些类型的条目,但无法获得对其发出的投票请求的任何响应:

$ kubectl exec neo4j-2 -- cat logs/debug.log
...
2016-12-04 11:32:56.735+0000 INFO  [o.n.c.c.c.RaftMachine] Election timeout triggered
2016-12-04 11:32:56.736+0000 INFO  [o.n.c.c.c.RaftMachine] Election started with vote request: Vote.Request from MemberId{ca9b954c} {term=11521, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467} and members: [MemberId{484178c4}, MemberId{0acdb8dd}, MemberId{ca9b954c}]
...

我们通过查看raft-messages.log可以看到那些投票请求,可以通过在conf / neo4j.conf中设置以下属性来启用:

causal_clustering.raft_messages_log_enable=true
$ kubectl exec neo4j-2 -- cat logs/raft-messages.log
...
11:33:42.101 -->MemberId{484178c4}: Request: Vote.Request from MemberId{ca9b954c} {term=11537, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
11:33:42.102 -->MemberId{0acdb8dd}: Request: Vote.Request from MemberId{ca9b954c} {term=11537, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
 
11:33:45.432 -->MemberId{484178c4}: Request: Vote.Request from MemberId{ca9b954c} {term=11538, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
11:33:45.433 -->MemberId{0acdb8dd}: Request: Vote.Request from MemberId{ca9b954c} {term=11538, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
 
11:33:48.362 -->MemberId{484178c4}: Request: Vote.Request from MemberId{ca9b954c} {term=11539, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
11:33:48.362 -->MemberId{0acdb8dd}: Request: Vote.Request from MemberId{ca9b954c} {term=11539, candidate=MemberId{ca9b954c}, lastAppended=68, lastLogTerm=11467}
...

要“修复”网络分区,我们只需要删除我们之前运行的所有命令:

$ kubectl exec neo4j-2 -- route delete neo4j-0.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-2 -- route delete neo4j-1.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-0 -- route delete neo4j-2.neo4j.default.svc.cluster.local reject && \
  kubectl exec neo4j-1 -- route delete neo4j-2.neo4j.default.svc.cluster.local reject

现在,让我们检查一下neo4j-2现在是否具有我们之前创建的节点:

$ kubectl exec neo4j-2 -- bin/cypher-shell "MATCH (p:Person) RETURN p"
p
(:Person {name: "Mark"})
 
Bye!

目前为止就这样了!

翻译自: https://www.javacodegeeks.com/2016/12/kubernetes-simulating-network-partition.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模拟实现动态可变分区存储管理系统,内存资源的分配情况用一个单链表来表示,每一个节点表示一个可变分区,记录有内存首地址、大小、使用情况等,模拟内存分配动态输入构造空闲区表,键盘接收内存申请尺寸大小,根据申请,实施内存分配,并返回分配所得内存首址。分配完后,调整空闲区表,并显示调整后的空闲区表和已占用的区表。如果分配失败,返回分配失败信息。模拟内存回收。根据空闲区表,从键盘接收回收区域的内存作业代号。回收区域,调整空闲区表,并显示调整后的空闲区表。对于内存区间的分配,移出,合并就是相应的对链表节点信息进行修改,删除和创建相应的节点。 在模拟实现动态可变分区存储管理系统中用到的是“最佳适应算法”与“最坏适应算法”。所谓“最佳”是指每次为作业分配内存时,总是把满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。因此保证每次找到的总是空闲分区中最小适应的,但这样会在储存器中留下许多难以利用的小的空闲区。最坏适应分配算法是要扫描整个空闲分区表或链表,总是挑选最大的一个空闲分区割给作业使用。进入系统时我们需要内存首地址和大小这些初始化数据。成功后我们可以自由的使用首次适应算法与最佳适应算法对内存进行分配。内存经过一系列分配与回收后,系统的内存分配情况不再连续。首次适应算法与最佳适应算法的差异也就很容易的体现在分配时。动态可变分区存储管理模拟系统采用最佳适应算法、最坏适应算法内存调度策略,对于采用不同调度算法,作业被分配到不同的内存区间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值