Docker Swarm 和 Riemann 的实时集群监控

edm0412-2

深入浅出 Docker Swarm|DaoCloud 现推出 Docker Swarm 系列技术文章,为大家深入浅出地解读 Docker Swarm 的概念、使用方法以及最真实的案例分析。全系列共五篇,本周为大家每日放送一篇精彩内容,敬请期待。

这是 Docker Swarm 系列的第二篇,关于 Docker Swarm 和 Riemann 的实时集群监控。

Riemann 一款由 Clojure 语言编写的高效监控、处理和响应分布式系统健康状况的工具软件,由 Kyle Kingsbury(代号 aphyr )研发。

今天我们将要讨论:

  1. 为什么 Docker 用户需要关心监控?
  2. 为什么要用 Riemann?
  3. 如何把 Riemann 组件 Docker 化?
  4. 如何用 Docker Swarm 部署 Riemann 组件?
  5. 如何使用 Riemann 控制台?

为什么 Docker 用户需要关心监控?

对于一些开发者来说,大谈特谈“监控”是最催眠的事情。的确,健康监控或其他形式的应用监测常常沦为不重要的东西:一山放过一山拦。现代开发者早已习惯了在应用交付用户前排除重重障碍。但恰当的监控可以帮助开发者实现梦寐以求的东西:快速可靠的应用和心满意足的客户。

如果你的基础架构和应用开发环节中,没有把监控作为「一等公民」集成的话,你早晚会陷入泥潭。气急败坏的客户会通过推特或其他方式变成你事实上的监控系统,因为他们会告诉你某某某功能不能用,或者网站崩掉了。这些事故比起其他任何问题,能更快速地毁掉你的生意和声誉,所以你无论如何都必须避免它们。

此外,一旦建立并用上了监控工具,它所能提供的观察力是极有价值的。从手动检查主机和服务,到安装配置好优良的监控软件,那感觉就好像是,以前上网连搜索引擎都没有,现在却到处能用谷歌。

对于处境独特的 Docker 用户而言,监控的价值更加意义重大,原因很简单:在以 Docker 为基础的世界里,需要监控的东西比以前多了一个数量级。你不仅有一大堆VM需要监测,还要面对各个 VM 上运行着的纷繁复杂的容器。此外还有一些移动组件如容器编排工具,key-value store,Docker 自身的 daemon 进程等等需要监控,而移动组件的数量是相当惊人的!在「 Docker 化」的世界里,自觉对应用进行监控和排故,其回报是不言自明的。

为什么要用 Riemann ?

使用 Riemann 有很多理由,以下几点是最显见的。

  • Riemann 基于推送的服务模式,让你可以检测到问题所在,近乎实时地修复故障

传统的监测系统如 Nagios 通常基于查询模式:它们定时启动(例如每 5 分钟启动一次),运行一套健康监测程序,看看系统中的各部分是否处于应有状态(比如你的服务都已启动),然后通过邮件或其他方式向你报告结果。Riemann 则要求各个服务汇报自身的事件,一旦事件流停止流动,就能马上发现系统故障或网络断开。同样地,我们还能收集和处理各种形式的事件,事先监控,未雨绸缪,而不是在发生故障后疲于奔命。

  • Riemann 的流处理能够对输入的数据进行强大的转换

举个例子:即使某个意外错误在 1 小时内有 1000 次日志,Riemann 也能把所有错误打包整理,用少数几封邮件就可以告知用户此错误发生了多少次。这就可以避免系统报警疲劳。另一个例子— Riemann 用的是非常精细的百分位度量,这可以准确反映系统运行的真实状况,而不会被平均值这类笼统数值一叶障目,遗漏掉重要的系统信息。

  • Riemann 可以很轻易地导入或导出数据,可以实现一些有趣的用例,比如为稍后的分析存储事件数据

Riemann 用户可以用 TCP 或 UDP 上一个很简单的协议缓冲来发送事件。Riemann 可以把事件和指标从简单的索引发送到多种后端,包括 Graphite,InfluxDB,Librato 等等,还能内建功能支持通过 SMS、邮件和 Slack 等途径发送通知。

  • Riemann 的架构模型很简单,可以避免监控软件太难操作或频繁崩溃的尴尬局面

Riemann 的设计就是从底层直达操作和产出层面。尽管这其中会有一些妥协(比如无法安全分配一个单独的 Riemann 实例),但在实际运用中,Riemann 的原则基本是一鸟在手,胜过十鸟在林,此刻的不完美信息好过遥远的完美信息。如果 Riemann 服务器崩溃了,只需要简单的重启就能解决,不需要对混乱状态进行纷繁复杂的调解。

同样的,基于推送的模式也有助于解决“谁来监控监控软件”的问题(换句话说,我们如何检测监控软件本身有没有问题)。我们只需在下游服务器上建几个 Riemann 服务器和前端事件。如果上游服务器出故障了,下游服务器就会感知并提醒用户。尤其是在云端运行 Docker 的时候,这一功能的价值非常明显。

  • 它非常快

摘自 Riemann 登录页:“吞吐量取决于你的流对事件做了什么,不过商用 x86 硬件上一小块 Riemann 每秒就能处理数百万次事件,延迟时间却只有亚毫秒,5 毫秒可以完成 99 次。Riemann 完全并行并利用 Clojure 及 JVM 的并发基元( primitives )”。

如何 Docker 化 Riemann 组件?

今天我们讨论 Docker 化三种组件,这三种组件合并起来,就能有效发挥 Riemann 的性能。

  1. Riemann 服务器进程,由 Clojure 语言编写,是主流处理引擎
  2. Riemann-health 程序,由 Ruby 语言编写,向中央 Riemann 服务器报告健康/使用指标
  3. Riemann-dash 程序,基于 Ruby 语言编写,是一个小型 Sinatra 应用,为 Riemann 提供网页控制台界面

我们将用 Docker Swarm 运行它们,它们借助 libnetwork 的 overlay 驱动来彼此联动。这里有一张组件的样本架构示意图,展示了它们是如何并入我们的 3 节点集群的。每个节点都有一个 riemann-health 实例向服务器报告指标。另外两个容器会被随机调配,至于落到哪台主机上都不要紧。

riemannhealth

在本文章中,假设你已经装好了一个 Swarm 集群,拥有至少 3 个运行的节点。

Docker 镜像

Riemann 服务器的 Dockerfile 是这样子的:

1.pic

如你所见,它只是简单安装了 Java 运行环境,从 Kyle 的网站里抓取了.deb 调试包,然后安装了中央 Riemann 服务器。它还将以下配置文件插入了镜像。

2.pic这是一个用 Clojure 写的很简单的配置文件,仅仅把传来的事件插入了 Riemann 索引并在5秒之后过期。当一个事件过期时,Riemann 会在日志上标记这个事件已经过期。

Riemann 的一个重大优势,就是可以定义事件有关的行为。借助 Riemann 的基元( primitives ),我们可以把缺失的信息当成一条新信息:如果一段时间内某个服务或主机没有传送事件,我们就知道它要么是崩溃了,要么是诸如网络不畅之类的原因阻挡了信息的传输。因为我们可自定义此类情况发生时所采取的动作,所以我们可以设置在主机崩溃时通过 Slack 频道发出报警(或者进行备份)。

从理论上讲,这可以拓展成一个具备自我修复能力的自控系统。例如,当我们检测到某台主机或服务的指标消失时,就可以启动新的服务先顶上,重启主机,以及采取其他措施。

现在我们有了建立 Riemann 服务器镜像(收集指标)的办法,但还需要一个实际发送信息的途经。Riemann-health 程序将向中央处理器发送 CPU ,内存和负载信息,所以我们来把它 Docker 化:

3.pic

我们用这个 entrypoint.sh 脚本来确保我们能配置健康程序应当连接的 Riemann 服务器的位置(默认中,我们把这个容器叫做 Riemann-server,使用 libnetwork 默认 DNS )

entrypoint.sh 看起来是这个样子的:

4.pic当我们最终运行这个容器时,/etc/hostname 会从外部系统挂载到容器上,确保 Riemann-health 程序向中央服务器发送正确的主机名。

最后,我们来瞧瞧 Riemann 控制台的镜像:

5.picconfig.rb:

6.pic

如何用 Docker Swarm 部署 Riemann 组件?

我们用 Docker Compos 文件表示这些容器的运行信息,调度参数(确保 Riemann-health 实例布在每个节点上)以及相应的 overlay 网络(确保它们都能在多主机上访问到对方)。由于我们指定了要创建的网络,就需要用 version 2(笔者写作时最新的方案)配置格式编写 compose 文件。

我们的 Docker Compose 文件是这样的:

11.pic 12.pic

有一些值得一提的方面:

  • Riemannhealth 是在主机的 pid 命名空间里运行的,以便准确收集每个进程的使用参数。
  • Riemannserver 和 Riemannhealth 都在 Riemann 的 overlay 网络上,以确保 daemon 可向中央服务器发送事件。
  • Swarm 调度限制设置用 environment,确保每台主机上只有一个 Riemannhealth 服务实例在运行。
  • Riemannserver 的 container_name 是手动设置的,以防依赖 Compose 通过 libnetwork,为 DNS 发现生成自动命名惯例。

只要文件安放到位,接下来的事情就好办了:

10.pic

我们可以用 docker-compose ps 查看创建好的容器:

9.pic然后,把 Riemannhealth 服务外扩展到我们可用的节点:

14.pic 15.pic请注意,因为我们有调度限制,所以无法扩得很大:

8.pic

好,现在我们见识过 Riemann 服务器和控制台的运行,以及健康 daemon 向每台主机的中央服务器报告参数的过程。现在我们来看看怎么操作 Riemann 控制台。

如何使用 Riemann 控制台?

现在我们可以收集参数,但还需要把收集到的东西可视化,这时就需要 Riemann 控制台了。

基于以上的 Compose 文件,建议是使用 SSH 转发控制台端口(4567)和中央 Riemann 服务器端口(5556)到你的 localhost 上。这能让你安全方便地访问控制台。比如,假设服务器处在 swarmnode-0,仪表板处在 swarmnode-1.

7.pic

你会看到空白的 Riemann 控制台。

9

我们可以用如 Chart、Grid 等格式来展示 Riemann 查询。

8

比如,这些绿色的区域表示正从各种主机和服务汇聚到中央 Riemann 服务器的参数。如果这些参数开始触及“危险区域”,这些长方形就会按程度变成黄色或红色。

另外,你还可以设置 Riemann 向时间序列数据库发送数据(比如跟 Grafana 这样的可视化前端绑定),这样你就可以查看受监控内容的历史,并做出像这样精美的图表:

0
640

配合使用 ELK 这样的中心化日志,你能看到更多更细微的架构内的运作。拥有这样的工具,你可以完全掌控系统的健康,不必担心发生问题。例如,在百分位级别的监控下,Riemann 潜流里大约每小时就出现一次的刺突,你都能看得清清楚楚。掌握了这些信息,我们就能把问题扼杀在摇篮里,防止它积少成多,最终变得一溃千里。

结论

Docker Swarm 和 Riemann都是令人非常着迷的技术,建议大家深入了解和使用它们。市面上已经有很多可用的 Riemann 工具,特别是用于监控 Docker Daemon 和编排系统的工具,都非常棒。你也很有可能成为编写这些工具的开发者之一,所以继续深入,好好写代码吧!

Leave a Reply

Your email address will not be published. Required fields are marked *