咱们是一家作生鲜电商的公司,从系统搭建初期,咱们就采用微服务的架构,基于DEVOPS体系来不断提升咱们的交付的质量和效率,
随着业务和团队规模的发展,服务逐渐进行拆分,服务之间的交互愈来愈复杂,目前整个微服务已经近几十个应用模块,
总体架构上包括负载均衡、API网关、基于dubbo的微服务模块、缓存、队列、数据库等,目前整个集群的资源利用率也没有一个合理的规划评估,虚拟机上部署多个应用服务隔离性也存在问题,考虑到愈来愈多门店以及第三方流量的接入,须要考虑系统的快速的伸缩能力,而基于统一资源管理的Docker容器技术在这些方面有一些自然的优点,而且和微服务架构、devops体系完美衔接。
通过调研和对比,最终咱们采用mesos做为底层资源的管理和调度,marathon做为docker执行的框架,配合zookeeper、consul、nginx做为服务注册发现。目前已经有部分的核心业务已经平稳的运行在基于docker容器的mesos资源管理平台上。node
在发布流程中,在发布上线以前的环节是预发布,预发布环境验证完成后进行打包,生成docker 镜像和基于虚拟机部署的应用部署包,push到各自对应的仓库中,并打Tag。
生产环境发布过程当中,同时发布到Mesos 集群和原有的虚拟机集群上,两套集群网络是打通的。python
在网络架构选型时,会考虑一下几个原则
一、一容器一IP
二、多主机容器互联,主机和容器互联
三、网络隔离、细粒度的ACL
四、性能损耗低
docker bridge使用默认的docker0网桥,容器有独立的网络命名空间,跨主机的容器通讯须要作端口NAT映射;Host的方式采用和宿主机同样的网络命名空间,网络没法作隔离,等等这些方式有很是多的端口争用限制,效率也较低。
Docker Overlay的方式,能够解决跨主机的通讯,现有二层或三层网络之上再构建起来一个独立的网络,这个网络一般会有本身独立的IP地址空间、交换或者路由的实现。
Docker在1.9中libnetwork团队提供了multi-host网络功能,能完成overlay网络
主要有隧道和路由两种方式,
隧道原理是对基础的网络协议进行封包,表明是Flannel。
另一种是在宿主机中实现路由配置实现跨宿主机的容器之间的通讯,好比calico
calico是基于大三层的BGP协议路由方案,没有使用封包的隧道,没有NAT,性能的损耗很小,支持安全隔离防御,支持很细致的ACL控制,对混合云亲和度比较高。通过综合对比考虑,咱们采用calico来实现跨宿主机的网络通信。
mysql
构建Calico网络集群,增长当前节点到集群中,Calico 节点启动后会查询 Etcd,和其余 Calico 节点使用 BGP 协议创建链接
./calicoctl node –libnetwork –ip=10.10.3.210
nginx
增长可用的地址池ip pool
./calicoctl pool add 10.4.10.0/24 –nat-outgoing
./calicoctl pool showweb
建立网络
经过calico IPAM插件(Driver(包括IPAM)负责一个Network的管理,包括资源分配和回收),-d指定驱动类型为calico,建立一个online_net的driver为calico的网络
docker network create -d calico –ipam-driver calico –subnet=10.4.10.0/24 online_netsql
启动容器,网络指定刚才建立的online_net,容器启动时,劫持相关 Docker API,进行网络初始化。
查询 Etcd 自动分配一个可用 IP
建立一对 veth 接口用于容器和主机间通信,设置好容器内的 IP 后,打开 IP 转发
在主机路由表添加指向此接口的路由
宿主机10.10.3.210的路由表:
docker
宿主机10.10.50.145的路由表:
数据库
容器包发送包的路由过程如上图,
宿主机10.10.3.210上的容器IP 10.4.10.64经过路由表发送数据包给另一个宿主机10.10.50.145的容器10.4.10.55api
对于有状态的数据库,缓存等仍是用物理机(虚拟机),来的应用集群用的是虚拟机,Docker容器集群须要和它们打通,作服务和数据的访问交互。那么只须要在物理机(虚拟机)上把当前节点加入容器网络集群便可
ETCD_AUTHORITY=10.10.195.193:2379
export ETCD_AUTHORITY
./calicoctl node –ip=10.10.16.201缓存
API网关提供统一的API访问入口,分为两层,第一层提供统一的路由、流控、安全鉴权、WAF、灰度功能发布等功能,第二层是web应用层,经过调用dubbo服务来实现服务的编排,对外提供网关的编排服务功能,屏蔽业务服务接口的变动;为了可以快速无缝的实现web层快速接入和扩容,咱们用consul做为服务注册中心实现web服务的自动注册和发现。
对于web服务注册,咱们本身实现了Register,调用consul的api进行注册,并经过ttl机制,按期进行心跳汇报应用的健康状态。
对于web服务的发现,咱们基于netflix zuul进行了扩展和改造,路由方面整合consul的发现机制,并增长了基于域名进行路由的方式,对路由的配置功能进行了加强,实现配置的动态reload功能。API网关启动定时任务,经过consul API获取web服务实例的健康状态,更新本地的路由缓存,实现动态路由功能。
平台的微服务框架是基于dubbo RPC实现的,而dubbo依赖zookeeper作服务的发现和注册。
Consul在mesos docker集群的部署方案:
不建议把Consul agent都和Container应用打包成一个镜像,所以consul agent部署在每一个mesos slave宿主机上,那么container如何获取宿主机的IP地址来进行服务的注册和注销,容器启动过程当中,默认状况下,会把当前宿主机IP做为环境变量传递到container中,这样容器应用的register模块就能够获取consul代理的Ip,调用consul的API进行服务的注册和卸载。
在平常应用发布中,须要保障发布过程对在线业务没有影响,作到无缝滚动的发布,那么在中止应用时应通知到路由,进行流量切换。
docker stop命令在执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,而后等待容器中的应用程序终止执行,若是等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。这样咱们可让程序在接收到SIGTERM信号后,有必定的时间处理、保存程序执行现场,优雅的退出程序,咱们在应用的启动脚本中实现一段脚原本实现信号的接受和处理, 接收到信号后,找到应用的PID,作应用进程的平滑kill。见上面图中的脚本。
Marathon为运行中的应用提供了灵活的重启策略。当应用只有一个实例在运行,这时候重启的话,默认状况下Marathon会新起一个实例,在新实例重启完成以后,才会停掉原有实例,从而实现平滑的重启,知足应用无缝滚动发布的要求。
固然,能够经过Marathon提供的参数来设置本身想要的重启策略:
“upgradeStrategy”:{ “minimumHealthCapacity”: N1, “maximumOverCapacity”: N2 }
如何判断新的实例是否启动完成能够提供服务,或者当前容器的应用实例是否健康,是否实例已经不可用了须要恢复,marathon提供了healthchecks健康监测模块
"healthChecks": [{
"protocol": "COMMAND",
"command":{
"value":"sh /data/soft/healthcheck.sh app 10.10.195.193"
},
"gracePeriodSeconds": 90,
"intervalSeconds": 60,
"timeoutSeconds": 50,
"maxConsecutiveFailures": 3
}]
healthcheck.sh经过负载均衡调用HealthMonitor来获取应用实例的监控状态,
HealthMonitor是咱们的健康检查中心,能够获取应用实例的整个拓扑信息。
下图是咱们的总体平台监控的体系架构
监控平台涵盖了系统各个层面的指标体系,这块后续单独列章节详细介绍。
对于容器的监控,因为咱们是采用mesos docker的容器资源管理的架构,所以采用mesos-exporter+Prometheus+grafana的监控方案,mesos-exporter的特色是能够采集 task 的监控数据,能够从task的角度来了解资源的使用状况,而不是一个一个没有关联关系的容器。mesos-exporter导出mesos集群的监控数据到prometheus,prometheus是一套监控报警、时序数据库组合,提供了很是强大存储和多维度的查询,数据的展示统一采用grafana。
本文可自由转载、引用,但需署名做者且注明文章出处。如转载至微信公众号,请在文末添加做者公众号二维码。
转自:http://blog.csdn.net/yangbutao/article/details/68951933