Docker mesos在生产环境的应用

咱们是一家作生鲜电商的公司,从系统搭建初期,咱们就采用微服务架构,基于DEVOPS体系来不断提升咱们的交付的质量和效率, 
随着业务和团队规模的发展,服务逐渐进行拆分,服务之间的交互愈来愈复杂,目前整个微服务已经近几十个应用模块, 
总体架构上包括负载均衡、API网关、基于dubbo的微服务模块、缓存、队列、数据库等,目前整个集群的资源利用率也没有一个合理的规划评估,虚拟机上部署多个应用服务隔离性也存在问题,考虑到愈来愈多门店以及第三方流量的接入,须要考虑系统的快速的伸缩能力,而基于统一资源管理的Docker容器技术在这些方面有一些自然的优点,而且和微服务架构、devops体系完美衔接。 
通过调研和对比,最终咱们采用mesos做为底层资源的管理和调度,marathon做为docker执行的框架,配合zookeeper、consul、nginx做为服务注册发现。目前已经有部分的核心业务已经平稳的运行在基于docker容器的mesos资源管理平台上。node

实现的主要功能特性

  • 平滑与虚拟机集群共存,容器独立IP,跨主机和遗留系统互通
  • 实现无缝发布(滚动发布),发布过程不影响在线业务,平滑升级
  • 应用健康检查,快速扩容,升级,回退
  • 服务自动注册和发现,负载均衡

逻辑架构

这里写图片描述

部署架构

这里写图片描述

在发布流程中,在发布上线以前的环节是预发布,预发布环境验证完成后进行打包,生成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

  • 安装好ETCD集群,经过负载均衡VIP方式(LVS+keepalived)来访问ETCD集群 
    ETCD_AUTHORITY=10.10.195.193:2379 
    export ETCD_AUTHORITY
  • 构建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
        }]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里写图片描述

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