服务里没有visualsvn server_Consul架构服务注册与发现(干货)

K8s烧起来了,很多概念和工具也烧起来,像service mesh,CNCF,FAAS,serverless等等,太火了,但是除了k8s,其他工具在企业中并没有完全铺开。

就拿serverless而言,概念是很具有前瞻性的,之前我们维护服务器,现在我们维护集群,将来我们应该只维护服务代码,任何IAAS和PAAS我们都不用care,乍一听,牛逼啊,那k8s这种PAAS级别的最终boss是不是也马上要被淘汰了,理论上来说是的,但实际情况呢。

serverless强调我们只维护function,这本身就和面向对象群体有冲突了,人家对你呵,就像对python连续蝉联最热门的编程语言一样的呵。及时你能说服所有人,在用起来的时候你还要考虑上下文复用,比如数据库连接和数据复用,要复用就意味着持久化,要么放在内存里,要么放在数据库里,那对于faas来说,只能放在内存里,那问题来了如果某个function分配的内存只有1G因为他平时调用量很少,如果某个瞬间有很多请求进来,那不就炸了。即使不炸,那这么多连接我都需要放在内存里,后面的客户端怎么连接呢,如果释放了,每次冷启动都需要好几秒,那用户体验是有多差可想而知。这是本身技术的短板,还有就是企业的需求,现在云服务这么便宜,我可以多起一些机器,架构矬一点,但是至少稳定我也不用考虑像faas的日志问题。企业需求导致了有些火过了,企业需求也导致了为啥k8s能烧的这么旺。有点扯远了,我们今天的主题是consul,那consul和k8s有啥关系呢,为啥k8s这么火,consul好像变成了计算时代的CPU如此重要呢,因为k8s是一个为亿万级别设计的平台,对于如此量级的调用,你无法再通过人为去管理那么多服务,所以大家开始探究如果让服务自动注册与发现,而consul就是这么设计。

其实在早k8s时代(docker swarm,Apache mesos, kubernetes三足鼎立的时候),consul就已经比较成熟了,他有kvstore,有dns服务,有服务注册发现。而且还可以是集群模式,甚至多数据中心模式,都是基于raft的一致性算法,raft如果不熟悉,etcd你肯定听过,etcd也是基于raft的一致性算法。那时候还流行两个consul的套件,一个是vault一个是consul-template。vault是一个加密插件,consul-template是基于模板动态生成文件的工具,其语法和现在的helm template很像,因为都是go template语法。consul 很早就尝试把变量维护到一个分布式存储里,如etcd。把服务地址用dns解析的形式,事实证明确实这才是大方向,consul之所有有今天的地位也不是靠运气的。

Consul给我们提供了KV, dns服务, 服务注册,服务发现。微服务时代,我们更需要consul的是服务的注册与发现,所以以下都是基于生产实践中对consul服务注册与发现的讨论。

要使用consul,必须要有一个服务端提供服务,然后客户端可以通过api cli等方式与服务端通信。

对于服务端有两种模式:单主,集群。

对于客户端使用也有两种通信方式:

  1. 同consul 服务端直接通信

  2. 通过client代理到服务端的通信

服务端和客户端使用方式的不同,一共有四种连接方式,单主直连模式,单主client模式,集群直连模式,集群client模式。而在实际使用中,我们都会有集群server以保证集群的HA。

consul服务端不管是何种方式都是一个二进制文件通过指定data目录和配置启动的,生产中一般都是以docker的方式启动,方便监控和维护状态。

对于单主模式下的直连和client模式:

这种服务端模式部署简单,一般只需要考虑数据持久化就可以,再加上一些ACL策略就能用了。但问题也很明显,单主没有HA,所以此种模式一般只考虑用kv功能,不使用服务注册发现功能。仅在应用程序启动的时候获取对应的kv就可以了,程序启动后不依赖consul server。仅使用kv模式的consul可以说是太屈才,不如直接使用Apollo,专业的配置管理工具来的实在。

集群直连模式:

这里只讨论同一dc的结构,顾名思义需要维护一个consul 集群,保证server的HA。consul的集群是一主多从,即一个leader,多个followers。官方建议同个dc中,集群数量控制在3或者5,太多会有开销问题。

该模式下集群中所有server都可以提供服务发现和注册的功能,向任意一个server注册,信息都会同步到集群中的各个节点上。乍一听,没啥问题,对于静态信息,KV,服务注册后的名字和endpoint关系都会同步。但是对于注册服务本身而言,我们是需要对其做健康检查来确保服务是活着的。在集群直连模式下,就会有一个严重的问题

当集群中某台server宕机了,通过该server注册的所有服务都会宕机。

这是为什么?主要和consul 集群的工作机制有关,我们对集群发起一次服务注册,如果客户端是通过endpoint或者反向代理到达consul server的话,那每一次注册必定会随机分配到后面某一台服务器上,收到请求的server会把服务注册到集群中,并且会带有一个自己server的地址,然后通过raft算法在集群内部同步。那为什么要在注册的时候带上自己地址呢,因为后续这个注册服务的server需要对服务进行健康检查,就像是师傅领了个徒弟,可以把徒弟介绍给其他师傅,但是对徒弟负责的只有自己。那么问题来了,当这个注册服务的server宕机后,没有人在对服务做健康检查,那么此时服务就变成unhealthy。就像师傅领了徒弟进来,师傅的师兄弟都知道有这个徒弟的存在,但如果师傅圆寂了,那此时徒弟就没人接管,徒弟很伤心以后没人带他了,整个状态就不健康了。

这是集群模式在客户端直连通信中面临的最大问题,或者说,这是一个伪集群模式。那么如果你目前正在使用的是集群模式,那有什么办法解决这伪HA问题呢。

答案就是集群client模式。

client工作方式:当有服务往client注册时,client会通知集群中的leader,然后信息同步到其他的follower。此时client接管服务的健康检查,即使集群中有server宕机(follower)也不会影响client和服务,因为静态信息在集群中每个节点上都有。

集群client模式在k8s场景中,还有两种变形。

  1. client SideCar模式

  2. client DaemonSet模式

client SideCar模式架构

6ec77070cba5f393b43dfc2be40c3e4a.png

SideCar模式中新增emptyDir卷,存放pod中consul的service和nodeid等信息,防止pod中Consul Client重启导致丢失service数据。
测试场景
  1. 停掉pod里的consul client

    服务不可用可以被发现。consul client会立马重启,启动完成后,服务恢复,此过程一般在3s之内恢复。

  2.  停掉pod里的服务服务不可用可以被发现,在服务重启后,服务恢复(此服务仍为旧服务,nodeid,node都没有变化,因为信息持久化到emptyDir中),此过程依赖服务本身的启动时间。

  3. 停掉pod
    3.1 如果停掉pod之前consul client处于failed状态      服务不可用可以被发现,pod重新启动完成,新服务注册到consul,旧服务不注销,此过程依赖服务本身的启动时间。
    3.2 如果停掉pod之前consul client处于active状态服务不可用可以被发现,pod重新启动完成,新服务注册到consul,旧服务注销,此过程依赖服务本身的启动时间。

  4. 停掉一个consul server follower
    服务不受影响。

  5. 停掉consul server leader服务不可用不可被发现,等重新选主完成后,服务恢复。

  6. 所有consul server 都停掉(模拟网络出现问题)服务不可用不可被发现,等server恢复后,服务恢复,此过程主要依赖网络恢复时间。

client DaemonSet模式架构

ec22cfbcd6d5d102ad21eddc9d9b4629.png

测试场景
  1. 停掉consul client

    服务不可用不可被发现从consul上直接注销,consul client会立马重启,启动完成后,服务出现并恢复,此过程一般在5s之内恢复。

  2. 停掉pod服务不可用可以被发现,pod重新启动完成,新服务注册到consul,旧服务未注销,此过程依赖服务本身的启动时间。

  3. 停掉一个consul server follower
    服务不受影响。

  4. 停掉consul server leader服务不可用不可被发现,等重新选主完成后,服务恢复。

  5. 所有consul server 都停掉(模拟网络出现问题)服务不可用不可被发现,等server恢复后,服务恢复,此过程主要依赖网络恢复时间。

几种状态说明

  1. consul server中没有服务信息,即既不显示health也不显示unhealthy。
    a. 在SideCar模式下,如果服务和consul client状态都是healthy的情况下,直接delete/update pod
    b. 在DaemonSet模式下,consul client down。

  2. consul server中有服务信息,状态为unhealthy,且一直保留。
    a. 在SideCar模式下,pod中consul client 或者 service down的前提下,直接delete/update pod。
    b. 在DaemonSet模式下,delete/update pod。

  3. consul server中有服务信息为unhealthy,然后自动注销a. 在SideCar模式下,服务和consul client都healthy的模式下,更新pod。旧服务会出现短暂的unhealthy(也可能不出现),然后新pod启动,注册新服务,老服务注销。

两种变形的优劣

  1. Sidecar模式最大程度上隔离consul对服务的影响,一个consul client只会影响一个服务的一个POD。

  2. Sidecar模式会额外增大服务器开销。

  3. DaemonSet模式折中了服务器开销和consul影响面。让一个node为一个单位,单个consul client影响单个node上的服务。

  4. DaemonSet需要在服务启动脚本中注入代码,修改服务连接consul client的地址为当前node IP(这会影响所有服务的部署方式,有些用裸java跑的服务影响较大)。

  5. DaemonSet需要持久化consul client的data目录,防止重启后会丢失相关service信息。

在实际生产中,一个consul sidecar容器100m cpu和128m 内存足以支撑,这里仅供参考,还是需要先做性能测试调整到一个合适的数值。

总结

场景SideCarDaemonSet
注册发现被发现恢复注册发现被发现恢复
consul client down✔(不可用)
pod service down✔(不可用)✔(不可用)
pod down✔(不可用)✔(不可用)
consul server follower downN/AN/A
consul server leader down
consul server cluster down

本文提及内容如果有技术上的错误麻烦通知更正,同时欢迎各种技术探讨f70c4f5dd13f1d2eae1ac7f2c1fc8980.png

如果喜欢小编写的文章,记得点点关注哦。c508d0fc60de9871d72292f4ea11b52b.pngc508d0fc60de9871d72292f4ea11b52b.pngc508d0fc60de9871d72292f4ea11b52b.png

下一期预告:聊聊k8s证书更新问题

85ff84f1ee4899b1cdbedce406fd617d.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值