我正在玩 SCDF 几天检查不同的场景,因为我们可能想在我们的一个项目中使用它。
我用
- 掌舵图https://hub.helm.sh/charts/stable/spring-cloud-data-flow/2.7.1
- k8s 版本 - 1.16 (AWS EKS eks.1)
- 使用外部 rabbit 和 postgres - 配置的其余部分是 vanilla SCDF 入门文章的默认配置。
我检查的场景之一是 SCDF 如何处理应用程序故障。
其中一个应用程序版本故意未能通过健康检查,不断返回 503 和状态 DOWN。应用程序是春季启动应用程序。当更新流并使用应用程序的损坏版本时,以前的版本在更新后立即被杀死。在 UI 中,它还将新版本显示为"deploying"。如果经过一段时间并且探测次数失败 - pod 会重新启动。如果您等待几次重新启动,您会看到应用程序的最终状态更改为“失败”。但是,每次重新启动时,它都会重置为"deployed"然后移动到"failed"。
观察到的行为与文档中关于船长的“红\黑”部署策略的内容不一致。
船长有一个简单的“红/黑”升级策略。它部署新版本的应用程序,使用与当前运行版本一样多的实例,并检查应用程序的 /health 端点。如果新应用程序的运行状况良好,则取消部署之前的应用程序。如果新应用程序的健康状况不佳,则取消部署所有新应用程序,并认为升级不成功。
怎么了
我的期望是,Skipper 应该保留应用程序的现有版本,直到确定新版本是健康的。现在看起来它会杀死健康版本并部署损坏的版本,使其在崩溃循环中旋转。
重现问题的步骤
- 部署了名为my-pipeline的流 (v48)
- 一个名为my-app 的应用程序使用 v48 部署
- 更新流并将my-app的版本更改为损坏的 v49
- my-app-v48被杀死
- my-app-v49已启动,但在崩溃循环中运行,不断未能通过健康检查并尝试重新启动
我检查了船长的日志,可以看到以下几行:
2020-07-23 12:32:27.785 INFO 1 --- [eTaskExecutor-4] o.s.c.s.server.deployer.ReleaseAnalyzer :
Existing Package and Upgrade package both have no top level templates
2020-07-23 12:32:27.786 INFO 1 --- [eTaskExecutor-4] o.s.c.s.server.deployer.ReleaseAnalyzer :
Differences detected between existing and replacing application manifests.Upgrading applications
= [my-app]
2020-07-23 12:32:27.944 INFO 1 --- [eTaskExecutor-4] o.s.c.s.s.d.s.HandleHealthCheckStep :
Release my-pipeline-v49 has been DEPLOYED
2020-07-23 12:32:27.944 INFO 1 --- [eTaskExecutor-4] o.s.c.s.s.d.s.HandleHealthCheckStep :
Apps in release my-pipeline-v49 are healthy.
2020-07-23 12:32:27.954 INFO 1 --- [eTaskExecutor-4] o.s.c.s.s.d.s.HandleHealthCheckStep :
Deleting changed applications from existing release my-pipeline-v48
看起来HandleHealthCheckStep#handleHealthCheck是在健康设置为 true 的情况下调用的。我猜这是因为“deploying”或“deployed”(重新启动时应用程序的第一个状态)被视为health。
如果我需要提供更多详细信息,请告诉我。
更新:状态的外观
- 活跃度在 /actuator/health 失败,准备在 /actuator/info 没问题。
k8s状态
pod 的状态是:“0/1 运行”,经过就绪探测延迟后,它会变为“1/1 运行”。在活动探测失败后,Pod 会重新启动并随着重新启动次数的增加返回到“0/1 Running”。
scdf 状态
在 3 第一次重新启动之前。应用程序的状态是“部署”相同的流。在延迟准备就绪后,它会进入“已部署”状态,对于流也是如此。
3 次第一次重新启动后。应用程序的状态是“失败”的流,它是“部分”。在延迟准备就绪后,它会进入“已部署”状态,对于流也是如此。
- 也只是尝试将 liveness 和 rediness 都设置为失败的执行器/健康。
k8s状态
pod 的状态为:“0/1 Running”,重启次数增加
scdf 状态
在 3 第一次重新启动之前。应用程序的状态是“部署”相同的流。
3 次第一次重新启动后。应用程序的状态是“失败”的流,它是“部分”。
然而,在这两种情况下,现有版本的应用程序都会在流升级后立即被终止。