沪江目前容器技术主要应用场景:DCS课件业务无状态应用;基于Apache Mesos+Marathon实现沪江容器系统调度管理;Consul+Consul Template+Nginx实现服务自动发现和注册;Prometheus+Grafana+Alertmanager报警实现容器监控报警。本次分享将从以下几方面来讲解:
选择容器技术缘由
容器技术选型
容器存储
容器网络
监控报警
镜像管理
调度管理
服务注册发现
自动化部署
自动化扩缩容
选择容器技术缘由
轻量级
快速交付(ms级)
环境标准化
部署迁移管理灵活
资源利用率高
CI、CD天生优势
多云平台支持
开源
容器技术选型
存储:
网络:
容器互联互通(overlay)
容器物理网络互联互通(bridge、host)
监控:
镜像管理:
调度管理平台:
部署发布:
自动化扩缩容:
存储
存储分类:
日志和共享存储,在存储上Docker和Kubernetes有一定的分歧,Docker公司比较推行Volume-driver理念,即所有存储都是驱动,本地存储和网络存储只是对应的驱动不同而已。
存储用途:
存储常见问题:
问题描述,DeviceMapper loop模式,Docker未将容器日志映射到宿主机,容器内部产生大量日志,导致Containers 或者 local volume逻辑使用100%,容器异常down掉。
解决方案,容器日志本地存储、加强容器存储监控(docker version>=1.13.0,docker system df查看)、容器存储方案选择deviceMapper direct并基于逻辑卷监控(Docker监控先行)
网络
网络分类
几种方式可以实现跨主机的容器通信
大二层,大二层是将物理网卡和容器网络桥接到同一个linux bridge,容器网络可以接入linux bridge,也可以将容器网络接入容器网桥docker0,再把docker0桥接到linux bridge;使得容器网络和宿主机网络在同一个二层网络。常见实现方案host、macvlan。
NAT方式,NAT是默认的Docker网络,利用iptables地址转换实现宿主机IP到容器的通信。容器对外IP都是宿主机的IP,NAT的性能损耗比较大;但只要宿主机之间三层IP可达,容器之间就可以通信。
Tunnel(overlay)方式,VPN、IPIP、VXLAN等都是Tunnel技术,就是在容器的数据包间封装一层或多层其他的数据协议头,达到连通的效果。Docker的Libnetwork支持vxlan overlay方式,weave也支持UDP和Vxlan的overlay模式,flannel,calico等都支持overlay模式。一般需要一个全局的KV store(sdn controller、etcd、Consul、ZooKeeper)来保存控制信息。这种方式一般也是只需要三层可达,容器就能互通。overlay模式容器有独立IP,性能上一般会比NAT好,不同overlay方案之间差别很大。
Routing方式,路由(SDN)方案主要是通过路由设置的方式让容器与容器,容器与宿主机之间相通信。例如:calico的BGP路由方案(非IPIP)。这种方式一般适用于单个数据中心,最常见的是同一个vlan中使用,不同vlan需要设置路由规则。路由方案性能损耗少,和主机网络性能比较接近。
主流网络方案特点
默认支持(bridge、none、container、host),默认Docker支持的网络方案,配置管理方便,同时不需要引入第三方工具,减少运维成本;但是bridge模式网络性能损耗过高,host模式很多场景下面不能很好的解决端口问题,需要IP管理工具对IP和端口做分配管理。
Overlay vxlan在性能和可用性之间折中的一种解决方案,需要全局KV存储;对内核要求高(>3.16),虽然也需要封包拆包,但其过程发生在内核中,性能要优于Flannel。
Flannel,Flannel默认采用 UDP 封装报文,在高并发情况下会有丢包问题,封装报文是在用户端进行的,会有一定的性能损失;要求所有主机在同一个网络,可以直接路由;会导致IP漂移;需要在源和目标主机之间频繁封装、解封装,导致消耗大量CPU资源;同时兼具overlay网络的其他特性。
Calico,Calico BGP需要物理网络支持BGP路由协议、同时容器对物理网络设备性能入侵较大,尤其是在和已存在核心业务协同使用过程中需要谨慎评估。
Macvlan,性能方面仅次于host模式,容器网络和物理网络完全打通,但是需要评估已有网络设备配置瓶颈,尤其是容器数量级增加引入的一些在传统网络中不可能出现的问题。
主流网络方案性能对比
引用UCloud云主机一篇性能测试报告: http://cmgs.me/life/docker-network-cloud。
CPU 压力主要看 load,最终排名是host < calico(BGP)< calico(IPIP)= Flannel(vxlan)= Docker(vxlan)< Flannel(udp)< weave(udp)
物理机上测试 macvlan 和裸网卡的对比图
网络选型
基于目前沪江网络现状(物理网络零变更),同时此项目刚刚处于试应用阶段,我们采用 host、overlay网络,Host模式解决slb容器IP地址和端口固定、容器和外部网络通讯,overlay网络实现跨主机容器网络互通。
Marathon网络配置:
overlay网络配置很简单,依赖分布式KV存储ZooKeeper,基于Marathon框架配置,实现容器之间、容器和物理网络互通。
Overlay网络架构:
创建overlay网络docker network create -d overlay --subnet value networkname
。
Docker启动指定网络存储 --cluster-store=zk://zk1.yeshj.com:2181,zk2.yeshj.com:2181,zk3.yeshj.com:2181,zk4.yeshj.com:2181,zk5.yeshj.com:2181/store
Marathon配置:
注意:Docker Network的使用过程中遇到许多的坑,例如内核的版本或Docker版本过低导致网络不稳定,建议使用Linux内核升到4.4,Docker版本升到1.12以上。网络优化这块,后续计划深入研究Calico BGP网络和MacVLAN,希望对网络性能方面有更大提升。
监控报警
Docker常见监控
cAdvisor、Datadog
Prometheus适合于监控基于容器的基础架构。高维度数据模型,时间序列是通过一个度量值名字和一套键值对识别。灵活的查询语言允许查询和绘制数据。采用了先进的度量标准类型像汇总(summaries),从指定时间跨度的总数构建比率或者是在任何异常的时候报警并且没有任何依赖,中断期间使它成为一个可靠的系统进行调试。也正是由于其灵活的查询绘图语句,我们最终选择Prometheus。
各监控系统详细对比参照:http://dockone.io/article/397
Prometheus特点
基于容器的基础监控、所有组件都已经Docker化、维护部署管理方便
分布式架构
数据采集扩展不依赖分布式存储
支持多种服务发现(默认支持Kubernetes、Consul、EC2、Azure)
常见服务监控有现成的采集器exporter(HAProxy、MySQL、PostgreSQL、Memcached、Redis等)
基于时序的KV存储数据库,支持非常灵活的查询绘图
监控方案选型
选择:cAdvisor+Prometheus+Grafana
Docker监控这块我们尝试过传统Zabbix+Python实现基于物理主机的容器监控方案,但是容器ip的动态变更,导致整个监控系统监控误报率特别高,历史数据无法追踪;继而尝试cAdvisor+Prometheus+Grafana方式,今天主要展示这套监控系统。
系统架构:
组件功能特点
cAdvisor:容器数据采集器、基于容器名称或者ID主要采集主机容器的CPU、内存、网络、文件系统、容器状态等基础信息,cAdvisor metrics api接口提供给Prometheus,便于持久化和灵活查询展示。
Prometheus:基于时序的KV存储数据库,具有灵活的类SQL查询语法,基于查询绘图。
Grafana:数据展示平台,支持多种数据源(Prometheus、Zabbix、Elasticsearch、InfluxDB、OpenTSDB、Graphite等)。
NodeExporter:主机数据采集器,目前部署下来开源程序有问题,暂时使用已有Zabbix方案替代物理机监控。
AlterManager:Grafana 4.0以后版本支持报警管理,支持email、slack等报警方式。
监控页面
Cadvisor
Grafana
优化
优化方案:Mesos exporter/metrics+Promatheus+Grafana
可以在容器监控的时候增加业务属性,基于业务逻辑监控,通过集中化Mesos Masters Metrics,对容器名称添加业务标签。
镜像管理
工具选型
VMware Harbor开源工具
系统架构
Docker Hub镜像存储仓库后端存储:Ceph(存储Docker images和MySQL data)
Dockerhub功能
项目管理:增加、删除、更改、查询
项目成员管理:images管理、用户管理
远程镜像仓库同步复制
项目、仓库、镜像查询搜索
系统管理
用户管理
目标管理
远程负责策略管理
Docker客户端push、pull镜像
删除仓库和镜像
Harbor管理平台展示
多机房部署
各DC分别部署一套Harbor,通过Harbor远程复制实现各DC镜像同步:
Office Harbor => DC01 Harbor => DC02 Harbor
通过DNS区域解析实现不同DC拉取当前DC harbor镜像,push操作push到Office Harbor。
调度管理
调度系统选择
Docker Swarm,官网开发默认的Docker容器集群最简单的管理工具,生产应用较少,不过作为很多开发人员默认选择工具,官网社区支持;12.5版本后默认集成进docker engine,简化集群管理;拥有易于理解的策略和过滤器,但是由于它不能处理节点失败问题,所以在实际的生产环境中,不推荐使用。Swarm和Docker环境很好的结合在一起,它使用了Docker引擎一样的API,并且能够和Docker Compose很好的一起工作,因此它非常适合那些对其他调度器不太了解的开发者。
Kubernetes,目前社区最活跃并且发展势头最好,Kubernetes的逻辑和标准的Docker不同,但是它关于pod和service的概念让开发者在使用容器的同时思考这些容器的组合是什么,真是非常有趣的。Google在它的集群解决方案上提供了非常简单的方式来使用Kubernetes,使得Kubernetes对于那些已经使用了Google生态环境的开发者来说,是一个合理的选择。
Mesos,开源工具,Mesos & Marathon一个完美的组合方案。能够像其他Mesos框架一样调度任务,具有很强的兼容性,支持插件式管理集成,灵活性较高,并且具有大量企业用户使用经验,稳定性最高;拥有一个类似于Docker Compose的描述json文件来制定任务配置,这些特性使得它成为在集群上运行容器的极佳方案
综合对比三种调度框架各自特点,我们选择了Mesos+Marathon作为容器集群资源管理和调度方案。
系统架构
调度系统组件
Mesos,Apache开源的统一资源管理与调度平台,被称为是分布式系统的内核;提供失败侦测,任务发布,任务跟踪,任务监控,低层次资源管理和细粒度的资源共享,可以扩展伸缩到数千个节点。
Marathon,注册到Apache Mesos上的管理长时应用(long-running applications)的Framework;实现服务的发现,为部署提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡,当然也有其他第三方工具Consul等。
Chronos,注册到Apache Mesos上的管理短时、定时、一次性任务的framework; 具备容错特性的作业调度器,可处理依赖性和基于 ISO8601 的调度,替代 cron 的开源产品。可以对作业进行编排,支持使用 Mesos 作为作业执行器。
ZooKeeper 分布式、开放源码的分布式应用程序协调服务,是Google Chubby一个开源的实现,是Hadoop和Hbase的重要组件。为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务。
Mesos+Marathon功能特性
高可用,支持多主节点(主备模式)自动切换
支持多种容器环境(Docker、Mesos Docker)
支持有状态服务,如数据库
使用 Web 管理界面用于配置操作和监控系统状态
约束规则(constraints),比如限制任务分布在特定节点、端口分配等
服务发现、负载均衡(mesos dns、marathon-lb)
支持健康检查,实现容错(http、tcp)
支持事件订阅,用于集成到其它系统
运行指标监控接口(metrics集中化监控)
完善易用的 REST API
Mesos资源管理调度原理
Mesos框架是运行分布式应用的应用程序,它有两个组件:
首先由Mesos主服务器查询可用资源给调度器,第二步调度器向主服务器发出加载任务,主服务器再传达给从服务器,从服务器向执行器命令加载任务执行,执行器执行任务以后,将状态反馈上报给从服务器,最终告知调度器 。从服务器下管理多个执行器,每个执行器是一个容器,以前可以使用Linux容器LXC,现在使用Docker容器。
Mesos失败恢复和高可用性
Mesos主服务器使用ZooKeeper进行服务选举和发现。有一个注册器记录了所有运行任何和从服务器信息,使用MultiPaxos进行日志复制实现一致性。
Mesos有一个从服务器恢复机制,无论什么时候一个从服务器死机了,用户的任务还是能够继续运行,从服务器会将一些关键点信息如任务信息 状态更新持久化到本地磁盘上,重新启动时可以从磁盘上恢复运行这些任务(类似Java中的钝化和唤醒)。
调度系统管理平台
Marathon调度平台
Marathon配置json
Marathon配置Web
Mesos
Chronos
nx/Marathon+Consul Agent+Consul Server+Consul Template
系统组件
Consul Agent:获取当前机器上所有容器状况(服务名称、所在物理节点ip、服务端口等),并注册到consul server中
Consul server:维护服务信息的分布式存储系统
consul-template:读取consul server的service并渲染模块生成配置文件,一旦配置发生变更重新加载配置
系统架构
用户访问前端的Application(nginx/marathon-lb/haproxy),Application通过App Configuration File从后端Application上获取提供的服务,再返回给用户。后端Application上均安装consul agent,并将Consul Agent加入到Consul Cluster中。Consul-template与Consul Cluster的Server连接,动态的从Consul的服务信息库拉取后端Application的服务信息,这些服务信息写入到前端Application的配置文件中,在完成一次写入后(即后台服务发生变更时),Consul-template将自动通过命令告知前端应用重新加载,实现前端Application动态发现后端服务以及应用新配置文件的目的。
以Nginx+Consul Template动态服务器发现与注册为例:
Consul template及时读取Consul 集群服务信息(服务名称、IP、服务端口、服务状态),一旦这些信息发生变更,更新Nginx配置文件,并重新加载Nginx。
配置、服务管理
Consul cluster(3节点):
docker run -d --net=host --name=consul dockerhub.domain.com/consul:0.6.4 -server -advertise consul_server01_ip -recursor dnsserver01_ip -recursor dnsserver02_ip -retry-join consul_server02_ip -retry-join consul_server03_ip
Consul Agent:
docker run -d --net=host --name=consul --restart=always dockerhub.domain.com/consul:0.6.4 -advertise consul_agent_ip -recursor dnsserver01_ip -recursor dnsserver02_ip -retry-join consul_server01_ip -retry-join consul_server02_ip -retry-join consul_server03_ip
Consul Template:
consul-template --zk=zk://zk1.yeshj.com:2181,zk2.yeshj.com:2181,zk3.yeshj.com:2181,zk4.yeshj.com:2181,zk5.yeshj.com:2181/mesos"
Consul Server/Agent config:
cat consul_base.json
{
"datacenter": "shanghai",
"data_dir": "/data",
"ui_dir": "/webui",
"client_addr": "0.0.0.0",
"log_level": "INFO",
"ports": {
"dns": 53
},
"rejoin_after_leave" : true
}
Consul template config:
/bin/sh -c echo "upstream app { {{range service \"$SERVICE\"}} server {{.Address}}:$CONTAINER_PORT; {{else}}server 127.0.0.1:65535;{{end}} } server { listen 80 default_server; location / { limit_rate_after $LIMIT_AFTER; limit_rate $LIMIT_RATE; proxy_pass http://app; } }" > $CT_FILE; nginx -c /etc/nginx/nginx.conf & CONSUL_TEMPLATE_LOG=debug consul-template -consul=$HOST:8500 -template "$CT_FILE:$NX_FILE:nginx -s reload"
consul-template -consul=consul_agent_ip:8500 -template /etc/consul-templates/nginx.conf:/etc/nginx/conf.d/app.conf:nginx -s reload
自动化部署
方案
Jenkins+Git+Marathon Deployment plugin+docker image build script
系统组件
Git程序源码、Dockerfile、marathon.json等程序和配置文件版本管理。
Jenkins实现CI、CD工具,提供各种插件,Marathon Deployment plugin打通Jenkins、Marathon发布流程,只需要提供Marathon认证信息和配置,即可完成发布。
实现逻辑
创建GitLab认证账户 => 构建Jenkins Freestyle任务 => 添加GitLab信息 => 创建构建触发器 => 构建过程(docker image、push image) => 添加docker registry credential => post build (构建marathon deploy)
自动化扩缩容
方案
marathon-lb-autoscale
系统架构
实现方式
Docker容器
启动参数
Marathon配置文件
{
"id": "marathon-lb-autoscale",
"args":[
"--marathon", "http://leader.mesos:8080",
"--haproxy", "http://marathon-lb.marathon.mesos:9090",
"--apps", "nginx"
],
"cpus": 0.5,
"mem": 16.0,
"instances": 1,
"container": {
"type": "DOCKER",
"docker": {
"image": "mesosphere/marathon-lb-autoscale",
"network": "HOST",
"forcePullImage": true
}
}
}
Q&A
Q:请问Prometheus 具体怎么玩的呢?比如,冷热存储metrics数据有做什么处理吗?告警只用了grafana 4.0的吗?
A:可以自己私下看看先关文档,这里一时半会也说不清;metrics数据时以时序方式持久化在prometheus中,不做任何处理,基于类sql方式查询;查询语句中可以设置过滤,或者条件查询;grafana4.0及以后才支持报警,同时传统的监控报警也有zabbix。
Q:请问不同应用的QoS怎么实现的?容器的租户管理和粒度是怎样的?
A:流量控制这块可以考虑在haproxy、或者nginx这块来做apigateway;目前我们容器就自己使用,租户管理这块没有细分。
Q:请问marathon部署的流程是怎么样的,新版本是替换老版本是创建新的app,删除老的,还是怎么样的,app命名规范有没有什么建议。容器部署后如何注册到nginx上,容器的ip如何与上游upstream域名进行关联呢?
A:先按照一定比例(2个)发布新的实例,然后删除老的实例,最终实现实例数目一致;命名最好有规范,防止冲突;nginx+consul server+agent+ template可以解决你的所有疑问。
Q:在此网络环境中是否会出现网络问题导致系统异常?
A:我们之前遇到过Docker 1.9.1低版本bug导致网络丢包,后来升级了docker至12.5,问题解决;目前使用内核 4.4.18 docker 1.13.0,没有任何网络问题
Q:问下普罗米修斯的集群这么做的?后端数据库没有没考虑过opentsdb呢?
A:目前单机没有性能瓶颈,如果存在性能问题可以考虑分机房部署,最终的展示和报警统一放在Grafana上面;没有使用opentsdb。
CIO之家 www.ciozj.com 公众号:imciow