Marathon

本指南从Traefik的角度解释了如何集成Marathon并以可靠的方式操作集群.

Host detection

Marathon提供了多种运行(包含Docker的)应用程序的方式,最受欢迎的方式是

  • 带有动态高端口的BRIDGE网络容器
  • 具有主机端口的HOST网络容器
  • 具有专用IP地址的容器( 每个任务IP ).

Traefik尝试检测配置的模式并将流量路由到正确的IP地址. 可以通过forceTaskHostname选项强制使用任务主机.

Port detection

Traefik还尝试确定正确的端口(这在Marathon中不平凡的事情 ). 以下是Traefik尝试识别端口的顺序(将使用第一个产生肯定结果的端口):

  1. 通过traefik.http.services.serviceName.loadbalancer.server.port=8080指定的任意端口
  2. 任务端口(可能通过traefik.http.services.serviceName.loadbalancer.server.port=index:0标签traefik.http.services.serviceName.loadbalancer.server.port=index:0 ,否则通过第一个traefik.http.services.serviceName.loadbalancer.server.port=index:0 ).
  3. 应用程序的portDefinitions字段中的端口(可能通过traefik.http.services.serviceName.loadbalancer.server.port=index:0标签traefik.http.services.serviceName.loadbalancer.server.port=index:0 ,否则为第一个).
  4. 应用程序的ipAddressPerTask字段中的端口(可能通过traefik.http.services.serviceName.loadbalancer.server.port=index:0标签traefik.http.services.serviceName.loadbalancer.server.port=index:0 ,否则为第一个).

Achieving high availability

Scenarios

在以下三种情况下,马拉松应用程序的可用性可能会受到损害,以及丢失或失败请求的风险:

  • 在启动阶段,Traefik已将请求路由到后端,即使尚未完成引导过程.
  • 在关闭阶段,当后端已经终止时Traefik仍将请求路由到后端.
  • 在应用程序失败期间,Traefik尚未将后端识别为错误的.

前两种情况在应用程序的每次滚动升级(即新版本发布或配置更新)中都是常见的.

以下小节描述了如何解决或缓解每种情况.

Startup

可以为每个应用程序定义就绪检查 (自Marathon 1.1版开始可用),并让Marathon在启动阶段将这些考虑在内.

想法是,每个应用程序都提供一个HTTP端点,Marathon在正在进行的部署过程中会定期查询该HTTP端点,以便在且仅当端点返回配置的HTTP代码范围内的响应时,才能将关联的就绪检查结果标记为成功. 只要检查仍然失败,Marathon就不会继续进行部署(在已配置的升级策略范围内).

从1.4版开始,如果设置了Traefik选项并在应用程序上进行了相应的配置检查,则Traefik会考虑准备检查结果.

Note

由于Marathon API当前公开了准备情况检查结果的方式,就绪的任务可能会轮流使用,延迟很小. 它大约为一个就绪检查超时间隔(根据应用程序规范配置),并保证未就绪的任务不会过早接收流量.

如果无法进行就绪检查,则当前的缓解策略是启用重试并确保存在足够数量的正常应用程序任务,以便一次重试可能会执行其中的一项. 除了其概率性质外,解决方法还以增加延迟为代价.

Shutdown

可以为每个应用程序安装终止处理程序 (自Marathon 1.3版开始可用),每个应用程序的责任是将关闭过程延迟足够长的时间,直到后端以合理的信心从负载平衡旋转中退出为止(即Traefik已收到). Marathon事件总线上的更新,重新计算可用的Marathon后端并应用新配置). 具体来说,每个终止处理程序都应安装一个侦听SIGTERM信号的信号处理程序,并在接收信号时执行以下步骤:

  1. 禁用"保持活动" HTTP连接.
  2. 在一段时间内继续接受HTTP请求.
  3. 停止接受新的连接.
  4. 完成处理所有机上请求.
  5. 关掉.

Traefik已经忽略状态与TASK_RUNNING不匹配的Marathon任务; 由于终止任务转换为TASK_KILLING并最终变为TASK_KILLED状态,因此在Traefik的一端无需进行任何其他操作.

第2步中应继续接受HTTP请求的时间取决于Traefik需要接收和处理Marathon配置更新的时间. 在常规操作条件下,它应该在几秒钟的数量级,而10秒可能是一个很好的默认值.

同样,配置Traefik进行重试(如上一节所述)可以作为一种不错的解决方法. 与终止处理程序配对,它们将覆盖终止序列或Traefik无法及时完成其编排过程的那些情况.

Failure

失败的应用程序总是会意外地发生,因此,很难或什至不可能完全排除不利影响.

故障原因千差万别,可能源于令人无法接受的缓慢,任务崩溃或网络分裂.

有两种减轻疲劳的方法:

  1. 在每个应用程序上配置Marathon健康检查 .
  2. 配置Traefik运行状况检查(可能通过traefik.http.services.yourServiceName.loadbalancer.healthcheck.*标签),并确保以适当的频率进行探测.

马拉松运行状况检查可确保将曾经被认为不正常的应用程序重新安排到其他从站. 但是,可能要花一些时间才能触发并完成后续过程.

因此,Treafik运行状况检查提供了额外的检查,可以更快地响应并且不需要重新加载配置. 此外,它还可以保护Marathon运行状况检查可能无法覆盖的情况,例如网络分裂.

(Non-)Alternatives

经常有几种不同质量的替代方法.

其余部分将探讨它们以及收益/成本权衡.

Reusing Marathon health checks

重用Marathon运行状况检查作为向Traefik发出信号的一种似乎很明显,即是否应将应用程序置于负载平衡循环中.

除了失败的健康检查可能会增加等待时间外,主要的问题是Marathon不会保留健康检查结果. 因此,如果在Marathon群集中发生主换选,则所有运行状况检查结果都将恢复为未知状态,从而有效地导致群集中的所有应用程序不可用,并导致整个群集故障. 重选不仅发生在常规维护工作期间(通常需要对Marathon节点进行滚动升级),而且还发生在Marathon领导者自发失败的时候. 因此,无法确定性地处理这种情况.

Finally, Marathon health checks are not mandatory (the default is to use the task state as reported by Mesos), so requiring them for Traefik would raise the entry barrier for Marathon users.

Traefik过去一直将健康检查结果用作严格的要求,但由于用户报告了严重的后果而不再使用它.

Draining

另一种常见方法是让代理耗尽应该关闭的后端. 也就是说,一旦后端被关闭,Traefik将停止转发请求.

从好的方面来说,这将不需要对相关应用程序进行任何修改. 但是,在Traefik内完全实施这一目标似乎是一项艰巨的任务.

另外,与自定义终止处理程序相比,该方法的灵活性较差,因为只有后者允许实现自定义终止序列的实现,而该终止序列不仅仅包括简单的请求消耗(例如,在终止前将快照状态持久保存到磁盘).

该功能目前尚未实现; 有关排水的要求,一般在第41期 .