Docker容器平台选型调研
编排选型
Swarm
Swarm可以从一个Dockerfile来构建镜像,但是构建的镜像只能在单一节点上运行,而不能够被分布到集群上的其他节点上。因此,应用被认为是一个容器,这种方式不是细粒度的。
Swarm需要使用 docker -compose scale来扩展其中一个容器,这个新的容器将会根据调度器规则进行调度。如果容器负载过重,Docker Swarm并不会自动扩展容器
正常情况下,必须去检查容器是否达到瓶颈, 能够及时的扩容
Swarm cluster ,在docker1.12版本中已经支持失败节点自动检测并拉取
目前 Swarm 可以通过overlay networks 来支持多主机容器网络的访问, 旧版不支持.
Mesos & Marathon(最新版1.4.1)
Mesos 提供资源管理和调度框架抽象的功能,第三方应用需要实现 Mesos 框架提供的 API 才能接入 Mesos 所管理的资源.
mesos在底层添加一个轻量的共享层,提供一个统一的api接口,供其他框架集群访问.
Mesos并不负责调度而是负责委派授权,有很多相应框架已经实现了复杂的调度,如Marathon
相比于Swarm,Mesos的容错性更强,因为Mesos能够在JSON文件中对某个应用使用监测检查
Marathon 有用户UI界面,可以将其视为一个应用程序,它可以看作一个框架来管理容器, 容器可以通过REST API 与Marathon 一起工作, 方便运维。
新版Marathon很好的支持了应用的更新和回滚,除去了容器启动对静态配置文件的依赖,使应用容器更新发布、回滚更加方便.
Mesos在弹性扩缩容后会导致宿主机上产生大量的 Exit 状态的 Docker 容器,清除时较消耗资源,影响系统稳定性。
默认 Mesos 只有基于时长的清除策略,比如几小时,几天后清除,没有基于指定时间的清除策略,比如在系统闲时清除,也无法针对每个服务定制清除策略。
可以修改 Marathon 的源码程序,添加 Docker 容器垃圾清理接口,可以对不同服务按指定策略将Exit状态的Docker容器进行清理。
Mesos不支持抢占,无法设置任务优先级
目前 Apache Aurora 这个插件已经支持优先级和资源抢占, 但是它是和marathon同级别的.
对于 mysql / Kafka这类有状态的存储类应用,目前 mesos+ Marathon还支持得不是很好
本地持久化卷后,下次再启动该容器的时候marathon与mesos会将这个容器再次部署到原先的宿主机上,而不是其他机器.
在有失败发生或者一个简单的服务重启的场景下,Marathon会随机的在任何符合服务定义约束的资源上重启服务,这样对于有状态服务是不适合的,因为这样的话需要很高的操作代价来将本地状态迁移到新的服务上
但是可以通过Marathon本地持久化卷来达到能够部署有状态服务的目的
可以自研所需的framwork.插件化处理. 不过Marathon本身是Scala编写的,UI是React编写,不利于二次开发
其他组件如: mesos-dns 和 marathon-lb.
mesos-dns 是一个服务发现工具
marathon-lb 不仅是服务发现工具,还是负载均衡工具, 要使用marathonn-lb,每组app必须设置HAPROXY_GROUP标签, 采用haproxy进行负载均衡
接入mesos的公司:
kubernetes (最新版1.6)
Kubernetes使用ReplicationController来保证应用至少有一个实例在运行。当在Kubernetes集群中创建了一个pod时,需要创建一个叫做负载均衡的Kubernetes服务,它负责转发流量到各个容器。
如果只有一个实例,也可以使用这种服务,因为它决定了能否将流量准确的转发到拥有动态IP的pod上。
Kubernetes添加了pod和replica的逻辑。这个为调度器和编排工具提供了更加丰富的功能,比如说负载均衡,扩展或者收缩应用的能力。并且还能够更新正在运行中的容器实例。Kubernetes 拥有自我修复,自动化推出和回滚和存储编排. 主要优点:
AutoScale:根据收集的业务 metric 来决定是否需要自动扩缩容
Rolling Deployents:滚动部署新版本并不中断服务,在新版本部署完成后老版本退出
Work Queue:将 Service 从 1:1 的关系扩展到 1:N,为被访问的 Service 前置一层代理 Agent,用来转发请求
Kubernetes 擅长自动修复问题, 并且可以快速地对容器进行重启. 这会导致使用方不会注意容器是否崩溃
为了解决这个问题,可以添加一个集中式日志系统 或其他方式 进行监控
有状态服务集: StatefulSets (1.4版本叫PetSets )
对于PetSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂在上原来Pod的存储继续以它的状态提供服务。( 保证ip/hostname不变 )
适合于PetSet的业务包括数据库服务MySQL/PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务。
使用PetSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,PetSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性
golang语言编写, 有助于二次开发, 社区活跃度高, 可以加入社区提高公司影响力
大致统计下使用kubernetes的公司: eBay、Yahoo、 微软 、 IBM 、英特尔、华为、 VMware 、HPE、Mirantis、 网易 、普元、亚信, 乐视 , 腾讯, 京东
容器技术栈
业界使用架构
京东
Openstack Icehouse + docker1.3 + OVS2.1.3/2.3.2+Centos6.6 ==> K8s + Docker + Flannel +Neutron + OVS + DPDK +JFS
某个容器失效,自动触发RC(保持IP丌变“迁移”)
OVS-VLAN
知乎
突发响应 & 资源高效利用
根据cpu指标调整容器数量
快伸慢缩
Max & Min Hard Limit
支持自定义指标
DNS Client
Bridge
NAT is not bad
iptables 有些坑
通过group做故障隔离
镜像仓库通过hdfs和水平扩展做高可用
Mesos 集群的横向扩展
Git+Jenkins(CI/CD) + mesos + 自研framework + group(隔离) + Consul + haproxy + DNS + Graphite + cAdvisor
docker网络
服务发现
自动Scale
携程
mesos stdout、stderr
Openstack + Mesos + Docker + Chronos + ELK
监控:telegraf -> Influxdb -> Grafana
日志:elk
去哪儿
OpenStack + nova-docker + VLAN =>Mesos + Marathon + Docker(–net=host) + 随机端口 => Mesos + Marathon + Docker + Calico
阿里电商云
利用docker volume plugin支持不同的存储类型
块存储,云盘
对象存储,OSSFS
网络文件系统 NFS
每次代码提交重新构建镜像
禁止修改运行中的镜像
利用volume保存持久化数据
cAdvisor + InfuxDB + prometheus
etcd + consul + zk + docker overlay
使用RDS,OSS,OCS等服务化存储
自研EWS, 基于compose, 参考Kubernetes的设计. 支持多region.
docker容器的正确姿势
存储管理
同程
在私有云的网络可控性本身比较高
多租户的隔离在私有云的意义不多
稳定可控可扩展才是急需求
整体带宽的高保证
对docker容器的网络考虑
本机网络模式:如web
OVS模式: 如数据分析
本机网络模式和OVS模式
基础镜像池的建设
基础镜像之上再构建应用镜像
应用镜像每次发布时重新构建
应用镜像多版本存储
一次构建镜像,各处可用
各应用的回滚、扩容全部基于应用的镜像来完成
dockfile 优化,缩小层数从20层到5层,构建速度快1倍
存储驱动从devicemapper改到overlayfs,构建速度快1倍
发布一个较大应用,耗时只需40s
自动测试系统直接调用容器系统部署环境,测试完成就可回收,供其他测试使用
实测 物理机 和 Container 之间的性能几乎没有损耗
redis性能对比: redis-benchmark -h 127.0.01 -p6379 -q -d 100
物理机利用率提升,合理的编排应用
各应用间资源隔离,避免环境和资源的冲突,提示安全性
爆发式流量进入: 快速扩容和迁移
应用迁移: 减少买服务器的花费
运维工作: 更多的自动化,更精细化的监控和报警
容器5000个,高峰扩容到8000
Docker应用600个, 塞入容器的还有:Mongodb, Redis,Mysql
cpu利用率由20%提升为80%
swarm + swarm agent + etcd + zabbix + Jenkins + (Nginx+Lua) + 配置中心
使用现状
资源隔离层面
优化
镜像管理
网络的思考
网易蜂巢
openstack + K8S + etcd + OpenFlow + iscsi + ceph + billing + 多机房
腾讯
集群内 pod 与 pod 的之间的通信,由于不需要内网 IP(可以用虚拟 IP)所以采用 overlay 网络,由 flannel 组件实现。
公司内网到集群内 pod 通信,例如 HAProxy,游戏某些模块,采用 SR-IOV 网络,由自己定制的 sriov-cni 组件实现。这类 pod 具备双重网络, eth0 对应 overlay 网络, eth1 对应 SR-IOV 网络。
pod 到公司内网之间的通信。在微服务场景下,游戏的数据存储,周边系统等,部署在物理机或者虚拟机上,因此 pod 到这些模块、系统的访问,走的是 NAT 网络。
(Internet) 接入,采用公司的 TGW 方案。
Kubernetes + 网络(Bridge + VLAN / SR-IOV / overlay) + lxcfs + Ceph + configmap\secret + 蓝鲸管控平台
目前,大概有15000多常驻的Docker容器, Docker平台上已经跑了数十款端游、页游和手游
集群都是同时兼容Docker应用和非Docker类型的应用的
Gaia将网络和CPU、内存一样,作为一种资源维度纳入统一管理。业务在提交应用时指定自己的网络IO需求,我们使用TC(Traffic Control)+ cgroups实现网络出带宽控制,通过修改内核,增加网络入带宽的控制
具体网络选型
滴滴
Kubernetes
目前了解的资料,滴滴使用docker化的时间不长,没有太多参考架构设计
uber
待补充
蘑菇街
Kubernetes + VLAN
七牛云
Marathon有些方面不支持我们期望的使用姿势,比如不太好无缝对接服务发现
Marathon采用 scala 开发,出了问题不好排查,也不方便我们做二次开发
如果选用 Marathon的话,我们上面还是要再做一层对 Marathon的包装才能作为Dora的调度服务,这样模块就会变多,部署运维会复杂
Mesos + 自研容器调度框架(DoraFramework) + Bridge+ NAT + Open vSwitch + Consul + Prometheus + Ansible
七牛目前已经达到近千台物理机的规模, mesos支持大规模调度更合适
不选择Mesos的核心框架Marathon 而选择自研
魅族云
调度请求落到集群相应节点
根据IDC、资源与区、Container类型筛选宿主机
根据宿主机资源状态、请求的CPU/内存/磁盘大小动态调度
机柜感知,将同一业务Container调度到不同机柜
镜像存储
异地镜像同步
LVS前端负载均衡,保证高可用
distribution管理镜像
后端ceph保证镜像存储可靠性
webhook notification机制
强一致同步机制
Devicemapper: 成熟稳定, 裸设备, snapshot
IOPS: Native 基本等于 Devicemapper
数据盘存储-LVM
按Container进行配额, 支持在线更改配额
Iperf test: Bridge < OVS veth pair < OVS internal port
Iperf test: Native > SR-IOV > OVS > Bridge
Docker with DPDK
Idea
轮询处理数据包,避免中断开销
用户态驱动,避免内存拷贝、系统调用 – CPU亲和、大页技术
virtio作后端接口
用户态socket挂载到Container
Container内跑DPDK applications
容器化的虚拟机,创建的Container需要长时间运行
每个Container拥有独立、唯一的IP
主机间Container通过大二层网络通讯,通过vlan隔离
Container开启ssh服务,可通过堡垒机登陆
Container开启其他常用服务,如crond
OVS & VLAN + SR-IOV +ceph(保证镜像存储可靠性) + 自己现有的监控系
主机间Container通过大二层网络通讯,通过vlan隔离
异地镜像同步
容器设计理念
网络
Container存储
镜像存储与同步
容器集群调度系统
ucloud
模块配置
一致性和依赖
部署
解决方案
一些经验
模块上下游关系, 后端服务
运行环境,机房的差异性配置等
开发、测试、运行环境的不一致性
依赖于不同的基础库
大量容器实例的管理、扩容、缩容成本高
程序构建、打包、运行和运维统一管理
监控、日志分析
部署效率低下,步骤多,耗时长
部署状态缺少检查机制
应用管理
V2版本
支持UFile驱动
定时pull最新镜像
开发、测试、线上运行环境均采用docker生成的镜像,保证一致
基础系统、基本工具、框架,分层构建
基础镜像在开发、测试、线上环境统一预部署
分离环境、IDC、资源类等差异化的配置项信息
配置模板,提交到cedebase进行版本化管理
对不同的deploys派生不同配置值,填充模板,启动脚本
运行在不同的deploys汇总,只需通过环境变量传递给container即可
模块配置
一致性和依赖
私有镜像仓库
编写dockfile规范、减少镜像层数,基础部分放前面
分地域部署镜像registry
NAT模式下会启用nf_conntrack,造成性能下降,调节内核参数
退出kill container, 升级docker daemon, kill可选
日志打印耗费性能
最好关闭logdriver,将日志打印在后台
docker日志
docker daemon
docker网络
docker镜像
-v 挂载到主机, Flume/Logstash/rsyslog + elasticserach (日志)
vswitch overlay的”大二层”网络SDN组网方案 + ipvlan
kubernetes + Jenkins
主要问题类型和解决思路
主要问题
单实例性能调优 + 万兆卡的性能发挥出来。需要对OVS(Open vSwitch)做一些改进
多机房:多机房及可用域支持
容器网络需求
Iptables 有些坑
跨主机容器间网络访问
容器网络是否需要具备IP地址漂移能力
容器网络面临的问题
Docker Host 模式,混布存在端口冲突。
Docker NAT 模式,Ip地址敏感服务改造大,无法支持服务发现
Overlay网络,涉及IP地址规划,MAC地址分配,网络设备收敛比等问题
Overlay网络安全性,可维护性, 容量规划
版本升级(docker/mesos/k8s)本身的升级
docker 对有状态的服务进行容器化的问题
kafka / mysql
网络选型(k8s和mesos)
思考 && 痛点
可否跨机器访问? 跨域访问?
flannel可以跨容器通信
跨主机的容器互联
容器与外部互联
是否支持静态ip , 固定ip ? 域名访问?
固定ip的话,那么就需要每次部署或者更新或重启的时候,ip保持不变
overlay network, Docker 1.6 可以实现跨主机通信
是否支持dns?
4层/7层访问
容器库容后的网络
ip端口,最好不要自行手动规划
网络策略,防御 ,隔离 ?
容器集群不同应用之间的网络隔离和流量限制
docker 网络
容器的IP在容器重启的时候会改变
不同主机间容器通信需要依赖第三方方案如:pipework
host模式: 容器都是直接共享主机网络空间的,容器需要使用-p来进行端口映射, 无法启动两个都监听在 80 端口的容器, 并且没有做到隔离
container模式: 一个容器直接使用另外一个已经存在容器的网络配置:ip 信息和网络端口等所有网络相关的信息都共享
Bridge模式: 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关
方案
方案类别
Calico,基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。
Macvlan,从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。
性能好,没有NAT,效率比较高, 但是受限于路由表,另外每个容器都有一个ip,那么业务ip可能会被用光.
Weave,UDP广播,本机建立新的BR,通过PCAP互通。
Open vSwitch(OVS),基于VxLAN和GRE协议,但是性能方面损失比较严重。
Flannel,UDP广播,VxLan。
隧道方案, 通过隧道,或者说Overlay Networking的方式:
路由方案
网络的两大阵营
Kubernetes
Weave
Macvlan
Flannel
Calico
Contiv
Mesos CNI
Docker Swarm overlay
Macvlan & IP network drivers
Calico
Contiv(from Cisco)
Docker Libnetwork Container Network Model(CNM)阵营(Docker Libnetwork的优势就是原生,而且和Docker容器生命周期结合紧密)
Container Network Interface(CNI)阵营 (CNI的优势是兼容其他容器技术(e.g. rkt)及上层编排系统(Kuberneres & Mesos))
常见的解决方案有:
思科主导,sdn解决方案,可以用纯软的ovs,也可以用ovs+cisco硬件sdn controller
基于 OpenvSwitch,以插件化的形式支持容器访问网络,支持 VLAN,Vxlan,多租户,主机访问控制策略等
SDN能力,能够对容器的网络访问做更精细的控制
京东基于相同的技术栈(OVS + VLAN)已支持10w+ 容器的运行
能够创建一个虚拟网络来连接部署在多台主机上的Docker容器, 外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上
容器间网络三层隔离,无需要担心arp风暴
基于iptable/linux kernel包转发效率高,损耗低
Calico没有多租户的概念,所有容器节点都要求可被路由,IP地址不能重复
flannel vxlan,overlay方式
calico
ipvlan macvlan,物理二层/三层隔离,目前需要pipework工具在单个节点上配置,仅做了vlan隔离,不解决arp广播
swarm native vxlan,跟flannel vxlan类似
neutron sdn,选择就多种了,ml2+ovsplugin,midonet,vlan or vxlan
Weave
contiv
linux bridge+三层交换机:host上 linux bridge 设置为三层交换机的子网网段,容器之间通信走二层交换,容器与外部走三层交换机的网关。
业界常用网络选型
Mesos支持CNI标准规范
一容器一ip, 网络隔离, DNS服务发现, ip分配, L3的虚拟网络
去哪儿 Mesos + Caclio
七牛 Bridge+ NAT + Open vSwitch
Kubernetes采用扁平化的网络模型,要求每个Pod拥有一个全局唯一IP,Pod直接可以跨主机通信。目前比较成熟的方案是利用Flannel
Flannel已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发模式。
kubernetes 下有 flannel、openvswitch和weave可以实现Overlay Network
唯品会 contiv netplugin方案(固定外网ip) + flannel
京东 Flannel + Neutron + OVS
Flannel性能: 官方:带宽没有下降,延迟明显变大
kubernetes + flannel
Mesos + Caclio
魅族云 OVS & VLAN + SR-IOV
ucloud: vswitch overlay的”大二层”网络SDN组网方案 + ipvlan
日志监控选型(包括监控,统计)
docker由于分层设计模式,容器里面无法固化数据, 容器销毁里面的数据就会丢失, 因此建议将日志挂载到宿主机上, 或者使用分布式存储如ceph
stdout/stderr类型的日志,可通过logspout转发到syslog中心来收集
Docker 的LogDriver 能输出日志到特定的端点,例如Fluentd,Syslog,或者Journald。 Logspout能将容器日志路由到Syslog或者第三方的诸如Redis,Kafka或者Logstash的模块中。
方案介绍
采用容器外收集。将主机磁盘挂在为容器中的日志目录和文件。
将容器中应用的控制到日志也重定向到日志目录。
在主机上对应用日志目录和docker日志目录做日志收集和轮换。
监控可选方案
cAdvisor + InfluxDB + Grafana
cAdvisor + Prometheus + Grafana
Graphite
Zabbix
Datadog
日志可选方案
logstash
ELK
Graylog
flume
heka
fluentd
业界方案
阿里云 : cAdvisor + InfuxDB + prometheus
协程: ELK
知乎: Graphite + cAdvisor
镜像管理
镜像总是从Dockerfile生成
镜像之间应该避免依赖过深,建议为三层,这三层分别是基础的操作系统镜像、中间件镜像和应用镜像
所有镜像都应该有对应的Git仓库,以方便后续的更新
Registry
单点问题,对应的解决方案可以考虑DRBD、分布式存储以及云存储
Regitry的性能问题,目前可用的解决方案是通过HTTP反向代理缓存来加速Layer的下载, 或者提供镜像mirror
Registry用户权限,Nginx LUA可以提供一个简单快速的实现方案
个人理解
选型不能只看编排, 还要看存储/网络等方面的支持
swarm以前有些缺陷,如不能检测失败节点并重启,最新版的也实现
k8s 只是用来调度docker
mesos是用来管理机器集群. 通过Marathon才能间接管理docker
对应网络的支持
是否能够跨主机/跨域
是否能够固定ip/ dns解析?
CNI 标准的支持?
对于存储的支持
是否能够固化?
是否支持分布式存储?
对于编排/调度/升级
是否支持回滚? 在线升级? 滚动升级?
是否能够细粒度分配cpu/内存等
是否支持有状态服务的容器化 和 调度
自动扩缩容能力?
服务注册/发现机制 / 负载均衡
是否有合适的服务注册机制?
负载均衡是否能够满足各种业务场景需求?
其他
隔离, 除了cgroup和namespace, 还有其他的隔离,比如网络隔离
作者:吴德宝AllenWu