Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →
Avatar for CMGS CMGS
May 09, 2015

 Docker

在芒果TV,我们怎样用的 Docker

Avatar for CMGS

CMGS

May 09, 2015

More Decks by CMGS

Other Decks in Programming

Transcript

  1. Why • 环境差异化问题 • DAE Python • 现在,Python/Java/PHP • 快

    • VM 在 Scale 的时候需要预估时间 • VM 的额外开销⽐比较⼤大 • 轻量 • Image 层叠式 • 性能损失⽐比较⼩小 • 丰富的 API
  2. Mission • 整合 dev 的⽣生态 • 提⾼高集群利⽤用率 • ⽅方⾯面的⽅方式控制集群⾏行为 •

    统⼀一的数据收集统计⽅方式 • 资源隔离和资源复⽤用 • 提⾼高⽣生产效率
  3. 第⼀一代 NBE 结构 • 两级 Nginx 结构 • 服务发现基于 Skydns

    • 配置存储在 etcd • Levi 是运⾏行容器机器的 Agent • 引⼊入 Pod 概念隔离不同⽤用途的 容器池 • ⼀一个 Pod ⼀一个 Dot 进⾏行调度 • 基础设施可复⽤用也可隔离 • Containers share CPU/MEM
  4. 实现细节 • ⼀一个容器有且只允许有⼀一个进程但PHP例外 • Container 可以 Oversell,Milestone 3 之后我们引⼊入了 CPU

    Binding ⽤用于保证服务需求性能 • Docker 的 CpuSet ⽤用于核为单位的调度 • ⺴⽹网络模型使⽤用 Bridge,会有⺴⽹网络闪断的问题,但是⼤大多数情 况下对系统影响可以承受,Host 模型⽆无法进⾏行精确的流量监 控。 • ⽇日志统⼀一外部收集,定时清理 Docker ⼀一定会在本机⽣生成的⽇日 志⽂文件 • 控制镜像层级,定期清理不⽤用镜像,最⼤大化复⽤用
  5. 实现细节 • Dot 与 Levi 之间保持 websocket 通讯 • NBE

    整体是旁路控制 • ⽇日志流输出是我们⾃自⼰己基于 logspout 实现的 Lenz 模块 • 部署和更新只关⼼心 App/Service 的版本 • 监控采集主要是 CPU/MEM/NET 3个指标,我们参考了 cAdvisor 的实现,然后基于 libcontainer 实现了 Metrics 模块并把数据发送到 InfluxDB • 资源分配可以预先也可以第⼀一部署时申请,配置均存在 ETCD 中
  6. 实现细节 • ⽀支持 Daemon Process • 端⼝口是在部署时进⾏行分配和绑定 • Container 实时状态通过

    Levi 上报 • 我们⾃自⼰己实现了⼀一个改造的 Sentry • 同时还实现了⼀一个邮件/微信/短信发送平台,⽤用于通知到开发 者 • 可以通过 MooseFS 共享同类 Container 间的临时⽂文件 • 静态⽂文件在 Build 的时候拷⻉贝到⺫⽬目标磁盘,也可以接前端打 包 API
  7. SOA • SOA 部分必须引⼊入对应语⾔言 SDK • 调⽤用链 tracing • 统⼀一⽇日志格式

    • 统⼀一开发框架 • 更简单的服务发现 • 现有⽅方案基于 dns 和⼀一级 nginx 太绕 • 基于 SDK 可以做到调⽤用列表的动态更新 • 业务级的性能统计 • 反馈和控制接⼝口的⾏行为,⽐比如降级
  8. SOA细节 • SOA 调⽤用链 tracing 基于 zipkin 实现 • 服务发现

    • ⼀一开始我们考虑⽤用 dns+nginx 在保证后端服务可⽤用性的 情况下⾃自动发现 • 这个⽅方案会导致同机服务互调的时候 overhead 太⾼高, 有⼀一定 SLA 的情况下⽆无法实现 • 改进⽅方案是通过 Dot ⽣生成服务列表,SOA 的 SDK 从 etcd 中读取这个列表来找到对应服务减少链路损耗 • 绕开 Nginx 之后的⽅方案允许⼆二进制协议
  9. SCALING • 没引⼊入 CpuSet 前策略是以 QPS 为主 • ⽆无法在部署前预先预估单 Container

    指标 • 简单的 Scale 策略可靠性不⾼高,对 Host 的使⽤用率 没法预估,50%冗余就⽆无从谈起了 • 资源争夺严重,Java 多线程,Python 只吃⼀一个核 • 实际效果还不如盯着 InfluxDB 数据⼿手动上下线
  10. SCALING • 引⼊入 Pod 概念,隔离业务 • Pod 间不能互相部署对⽅方的 Container •

    Pod 内如果只有⼀一种业务就可预估所需资源 • Pod 可以按照⺴⽹网络/机房隔离 • ⼀一个 Pod 完整的 NBE 结构,通过 DNS 来进⾏行 Pod 间服务发现 • Pod 与公司开发账号系统挂钩,做到权限控制
  11. SCALING • 在拥有多种业务的 Pod 中引⼊入私有 Host • 私有 Host 严格遵循

    Cpu bound • 私有 Host 的 Container 只有在其他私有 Host 有 ⾜足够多 Core 的情况下扩展 • 私有 Host 的 Container 性能指标是可预估的,同 理 Host 冗余也可预估
  12. SCALING • Pod 中公有 Host • 公有 Host ⾥里⾯面的 Container

    不允许扩展到私有 Host • 公有 Host 的 Container 上限以 Host 系统冗余为决 定性指标 • 私有 Host 的 Container 可以扩展到公有 Host,但不 保证其性能 • 公有 Host 是⼀一种服务降级的⼿手段 • ⼀一般来说 Pod ⾥里⾯面的 Host ⼤大多数时间都是私有的
  13. RESOURCE • ⺫⽬目前⽀支持 MySQL/Redis/InfulxDB/Sentry 4类资源分配 • MySQL/InfluxDB • 单个 App/Service

    ⼀一个独⽴立的库和对应的账号 • Redis 是使⽤用我们⾃自⼰己的 Redis Cluster • 我们⾃自⼰己改造 Sentry 会⾃自动创建对应的 DSN • Memcache/Rabbitmq 这类资源⺫⽬目前还是⼿手⼯工分配⽅方式 • 服务发现的域名分配基于 {appname}.{podname}.hunantv.com 这个规则写⼊入 skydns, 对外域名则需要通过⼈人⼯工⽅方式申请
  14. ⾃自⾝身部署 • 在考虑MFS部署的情况下,⼀一个NBE集群最⼩小需要的 基础设施有 • InfluxDB • Etcd+Skydns+dnscache • Dot

    • Levi • 可选 MySQL/Redis/Sentry,另外可以选择使⽤用 Moosefs 来提供⽂文件共享和 logstash 收集⽇日志
  15. ⾃自⾝身部署 • 我们⾃自⼰己实现了⼀一套⾃自动部署系统,Project Armin • 基于 Ansible • ⺫⽬目标 •

    ⾃自动优化⺫⽬目标服务器基础配置(tcp什么的) • 针对不同的服务器⾓角⾊色部署对应服务和其配置 • 能检查集群机器健康状态 • 不考虑 Host 是否是物理机还是云,因此⽀支持混合后端 • ⺫⽬目前只完成了 CentOS 6.5 和部分 Ubuntu 14.04 的对应⽅方案
  16. 监控 • Bridge ⺴⽹网络模型下可以监控到单 Container 流量详细 数据 • CPU/MEM 可以通过

    libcontainer 中的某个结构体可以 拿到 • Docker 1.5 metric 的⽀支持也是基于 libcontainer 的这 个结构体,因此强制要求后端使⽤用 libcontainer • 同类 Container 数据先合并,再求 Derivative 就可以 得到趋势图了 • 这是为啥我们⽤用 InfluxDB
  17. ⺴⽹网络 • ⺴⽹网络是个⼤大问题 • 完全没问题的是 Host 模式 • 流量区分没法做 •

    端⼝口⽆无法分配 • 独占的情况下⽤用 Host 最好 • NAT 基于 Iptables 那⼀一坨东⻄西 • Netfilter 有默认链接上限,某些情景下会出现⼤大量 connection refuse • IPtables 本⾝身策略同样会作⽤用于 Container
  18. ⺴⽹网络 • Bridge 基于 Linux 桥接 • ⺴⽹网络瞬断 • ⼤大多数情况下可以忍受

    • 三层 NAT 肯定有性能损失的 • 隔离性上不是那么的好
  19. ⺴⽹网络 • 趋势是⽤用 SDN 技术来实现⺴⽹网络隔离,Docker 已经 收购了 SocketPlane • 我们⺫⽬目前使⽤用

    Bridge,⾃自定义配置⺫⽬目前来看是可⾏行 的,默认配置没想象中问题那么⼤大
  20. 遇到的坑 • 只要有 Stdout/Stderr,Docker 就会把其写⼊入到某个⽂文 件,在线上环境中这是⼀一定要清理的 • Mem limit 会导致

    Container 瞬挂,合理使⽤用会避免单个 Container memory leak • Docker daemon 是 root/root 权限 • 某些时候 docker 会导致⺴⽹网络设备没有删除引发 Host OS 各种错误 • docker daemon 有时候起不起来等等 • 新技术是有⻛风险的
  21. 解决⽅方案 • 谨慎的选择 docker 版本,从我们经验来说新版⼀一般 会⽐比旧版要靠谱,但不推荐直接使⽤用源码编译版本 • 谨慎选择宿主机内核版本,我们⺫⽬目前选⽤用 UEK 的

    3.8 内核,另外选择这个内核是因为我们 redis proxy 需要 reuseport ⽀支持 • 使⽤用 Bridge 模式最好⾃自定义配置 • Docker Registry 的 Bug 请相信⾃自⼰己的眼睛 • 公司内部 Base Image 请⾃自⾏行构建
  22. 物理环境选择 • CentOS 6.5 + UEK 3.8 Kernel • CentOS

    7 的稳定性和兼容性⺫⽬目前都不尽⼈人意 • Ubuntu 最⼤大的问题是没有运维经验 • EPEL ⺫⽬目前含有 Docker 的更新,可以直接使⽤用 • CoreOS ⺫⽬目前不推荐⼤大规模使⽤用,主要是运维⼒力量 跟不上,另外 etcd 的稳定性还差了点⽕火候
  23. Project Eru • 在第⼀一代 NBE 完成 Milestone 3 之后我们考虑后续⽆无 论是

    Scaling 还是 Dot-levi 的结构在演进上存在⽐比较 ⼤大的障碍,因此决定写第⼆二版的 NBE,项⺫⽬目代号 Eru • 在躺过很多的坑之后,Eru 的开发速度明显快于之前 速度 • 放弃单 Dot 多 Levi 通讯结构,Levi 简化后变为 Eru- Agent 模块独⽴立的部署在 Host 机器上 • Dot 改写为 Eru-Core 模块,⽆无状态可对等部署很多 个,并只提供 API
  24. Features • Native containers pods support • 更好的私有和公有 Host 模型

    • 引⼊入 Group 概念进⾏行权限管理 • ⽀支持多 entrypoint 和多协议(tcp/udp) • 服务发现交给外部服务实现 • 资源分配剥离 • 版本和应⽤用配置绑定,资源配置独⽴立,部署时选择 • 异步进⾏行 Container 操作,可以通过 API 实时跟踪当前状态
  25. 实现细节 • Eru-Core • Go 转 Python,完全⽤用 Python 实现 Eru-Core

    • 唯⼀一的好处就是其他⼈人可以加⼊入开发了 • Go 版本的 docker client 源码质量实在太差 • 使⽤用 Celery+Redis 实现部署异步化 • 通⽤用化 Entrypoint ,实现⼀一份代码多种运⾏行⾓角⾊色
  26. 实现细节 • Eru-Agent • ⽇日志记录⽂文件清理 • Metrics 收集和发送 • Log

    收集和发送 • Report container status to core • 开销⾜足够⼩小,能 udp 的地⽅方绝不 tcp • 与 Eru-Core 通过 Redis PubSub 机制通讯
  27. 实现细节 • 私有 Host 以 CPU 核⼼心数为 Container 部署上限 •

    公有的 Host 以可⽤用端⼝口数为上限 • 可以选择配置 Port 为 Core 的多少倍,达到可预 估上限的⺫⽬目的 • 多个 Eru-Core 之间通过 Redis 和 MySQL 共享数 据,任意⼀一个 Core 挂了都不会影响到部署和管理 • 通⽤用 Hook 连接起代码库到 App/Service 的流程
  28. 实现细节 • 资源分配通过 eru-res 来进⾏行 • eru-cli 项⺫⽬目提供了⼀一个命令⾏行⼯工具 • Etcd

    现在为可选项 • 通过 Redis 通知第三⽅方接⼊入服务更新⾃自⾝身状态 • 服务发现
  29. Memory limit • 其实这是个成本问题 • ⺴⽹网络>CPU>Memory>Disk • ⼀一般你的代码不 leak 内存就会够⽤用

    • 并发⾼高处理性能上限也是 CPU 决定的 • 加内存的成本远低于加 CPU • 性能计算主要也是靠 CPU 来决定 • 因此我们不太关⼼心内存消耗
  30. Why not Kubernetes • 太复杂 • 我在离开⾖豆瓣的时候开始关注这⼀一块,其实⼤大家的 ⺫⽬目标都是 Google 家的

    Borg 类似的⽅方式来构建⽣生 态系统 • 整合成本⾼高于开发成本 • ⼆二次开发也不容易 • 稳定性和可控性不⾼高
  31. SCALING M1 • 预先设定是否对某应⽤用开启 auto scaling • 只对私有 Host 有效

    • 设定所需核数和平均 CPU 利⽤用率预期值及时间 • 平均 CPU 利⽤用率 = Derivative(Sum(CPU User time)) / Containers • ⾼高于预期值多⻓长时间则激发增加容器的⾏行为 • 从宿主机中选择能整除所需核数的最⼤大可⽤用核数的 机器
  32. SCALING M1 • 平均 CPU 利⽤用率低于预期值多⻓长时间 • Container > 1

    • 找到有这个 Container 最多的 Host • 减少容器 • systemd-socket-proxyd • 更加精细化的启动控制
  33. ⺴⽹网络 • docker 本⾝身的 bridge 等于是三层做的隔离 • 跨机通讯在有端⼝口管理的情况下并不是问题,唯⼀一 的问题没法做到应⽤用间的隔离 •

    macvlan 这类的技术可以以 container 为最⼩小单元 构建弹性 SDN ⺴⽹网络,对⺴⽹网络控制层的要求⽐比较⾼高 • 业内有五种⽅方案
  34. ⺴⽹网络 • pipework • 亲⼉儿⼦子,说不定就 merge 进 docker 了,⽐比较灵 活,同时⽀支持的模式也⽐比较多

    • flannel/kubernets 本⾝身的⺴⽹网络管理互为绑定 • weave ⺫⽬目前来看是⽐比较接地⽓气的⼀一种⽅方案 • socketplane,这个概念性就⽐比较强了没怎么研究
  35. weave • 每台 Host 均会启动⼀一个 Weaver Container,并以 6783 作为 Host

    间通讯端⼝口 • 在机器上会建⽴立⼀一个 weave 的 bridge,⽤用于 Container 的出流量 • ⽤用 weave 启动 container 或者 attach 到某⼀一个已启 动的 container 的时候,会在 container 中增加⼀一个 独⽴立的虚拟⺴⽹网卡,并配置对应的 IP • 这时候宿主机的 bridge 也会⽣生成相应的虚拟⺴⽹网卡 (2块,⼀一块是 docker 的⼀一块是 weave 的)
  36. weave • 这时候 10.2.1.2 这个 IP 只在 weave 组的⺴⽹网络中有效,这个⼦子⺴⽹网 的

    Container 可以互相访问 • 对于宿主⽽而⾔言,因为桥接的 weave ⺴⽹网桥没 IP 因此是没法通过这个 IP 访问到这个⼦子⺴⽹网的 Container • 给 weave ⺴⽹网桥设定同⼀一⼦子⺴⽹网 IP, 宿主则可以访问到这⼀一⼦子⺴⽹网的 Container • 原理其实就是加路由表 • 如果暴露服务给外部的话,需要增 加 NAT 规则
  37. weave • 跨 Host 间的访问依赖于 weave ⺴⽹网桥路由,其更新 依靠 Weaver container

    间的通讯来进⾏行 • 对宿主机暴露端⼝口让上层进⾏行反向代理依然需要端 ⼝口管理 • Container 间隔离主要依靠 weave 设定不同的⼦子⺴⽹网 • 所以理论上来说这还是⼀一种3层数据包路由+2层隔 离的⽅方式
  38. weave • 总之 Weave 的⽅方案可以看成 docker bridge ⽅方案 的增强版 •

    端⼝口暴露是需要上层控制 • 实际上是为了解决应⽤用间(Pod)隔离这么个⺫⽬目标
  39. macvlan • ip link add vethm01 link eth0 type macvlan

    mode bridge • ip link set netns ${docker-pid cid} vethm01 • docker-enter ${docker-pid cid} • ip link set vethm01 up • ip addr add ${IP} dev vethm01 • ip route add default via ${Gateway} dev vethm01
  40. macvlan • 这种⽅方式宿主机没法访问同机 container,需要在宿 主机也增加⼀一块虚拟⺴⽹网卡绑定同⼀一⺴⽹网段 IP 才⾏行 • 设定 macvlan

    设备 IP 的时候需要和物理⺴⽹网卡 IP ⼀一 个⺴⽹网络,不然 container 没法访问外⺴⽹网 • 当然也可以通过复⽤用 docker0 桥接进⾏行外⺴⽹网访问 • ⼦子⺴⽹网的其他物理/Container 均可以访问到⽤用此 macvlan 设备的 Container
  41. macvlan • 这个⽅方式近似的可以把 container 看成独⽴立的机器 • 端⼝口分配变为了 IP 分配 •

    应⽤用/Pod 隔离靠⼦子⺴⽹网隔离,⼆二层 • 不需要做 NAT • Container 的⺴⽹网络栈和物理机完全隔离 • pipework 我实在搞不动了……基本上原理⼤大概如此
  42. 依赖 • Eru-Core • Redis • MySQL • Eru-Agent •

    Redis • InfluxDB • ⽇日志⽀支持通过 syslog 和 udp 两种⽅方式汇总
  43. 对⽐比 • Docker Machine ——> Armin • 混合后端⾃自动化部署⾃自⼰己 • Docker

    Swarm ——> Core • 对多个 Docker 操控 • Docker Compose ——> Core • 集群编排能⼒力
  44. Q&A