停机可能导致严重后果。
与大多数其他行业相比,这句话对医疗技术领域的公司而言更为贴切,因为这里的“严重后果”确实可能包括死亡。最近,我们有机会深入剖析一家公司的技术栈。该公司致力于将医疗记录从纸笔记录转变为安全的数字化数据,让人们可以随时随地访问。这些数据涵盖患者信息、护理指示、生物标志物、医疗分析、历史记录,以及医疗团队之间共享的其他所有信息。
从一开始,该公司就致力于解决一个看似简单的问题:“如何帮助医护人员轻松实时记录数据?”然而,随着公司不断发展,扩展规模和确保数据持续可用的需求,使这一挑战变得日益复杂。本文将介绍该公司的技术发展历程如何促使其采用Kubernetes和NGINX Ingress Controller。
技术栈概览
- 操作系统:Linux
- 容器编排:Microsoft Azure Kubernetes Service
- 网络:Kubernetes、NGINX Ingress Controller,基于NGINX Plus
- 软件开发语言和框架:.Net
- 监控、可观测性和告警:Prometheus
- 监控仪表板:Grafana
- 日志记录:Grafana Loki
- 数据库:Azure SQL Service
- 应用服务器:Azure App Service、.Net
- 消息传递和流式处理:Azure Event Hubs
- 缓存:Redis
- 安全:NGINX App Protect
- 位置和基础设施:2个可用区、2个Kubernetes集群、15–20个节点、60–100个Pod
- DevOps:Azure DevOps Services
下面来看看NGINX在其架构中的位置:

纸质流程的问题
定期记录患者状况和护理信息是医护人员的一项核心职责。传统上,医护人员使用纸张记录患者信息,近年来也开始使用笔记本电脑或平板电脑。这些方式存在几个严重弊端:
- 医护人员每天可能要与数十名患者接触,因此通常很难在提供护理的同时记录详细信息。结果,他们往往只能在轮班结束时补写记录。此时,身心疲惫很容易让人只记录一些笼统的内容。
- 医护人员还必须依靠记忆来回想患者行为的细节。如果能够长期准确、一致地记录,这些细节中呈现的规律可能有助于诊断更严重的健康问题;而记录不准确则可能掩盖这些规律。
- 纸质记录难以在同一机构的不同部门之间共享,更不用说与急救医疗技术人员、急诊室工作人员和保险公司等其他实体共享。如果笔记本电脑或平板电脑未连接到中央数据存储或云端,情况也不会有太大改善。
为应对这些挑战,该公司创建了一套简化的数据记录系统,可通过快捷方式访问患者信息,并记录配药等常见事件。借助这种便捷的访问和使用方式,医护人员可以在与患者互动时实时记录相关信息。
所有数据均存储在由该公司维护的云系统中,该应用还与其他电子病历系统集成,以全面呈现住户行为的长期变化。这有助于护理人员提供更具连续性的照护,建立安全的历史记录,并可轻松与其他医疗软件系统共享。
医生和其他专科人员在接诊患者或以其他方式与患者互动时,也会使用该平台。患者的偏好和个人需求会记录在案,并可随患者转至任何医疗机构。这些信息有助于患者适应新环境,从而改善康复时间等结果。
对于公司必须将患者数据存储多长时间,法律有严格要求。该公司的开发人员在构建这款软件时,确保其能够提供极高的可用性,正常运行时间SLA也远优于通用云应用。绝不能因为患者档案无法加载而让救护车等待。
从车库到云端,再到Kubernetes的演进之旅
与许多初创公司一样,该公司最初将首个概念验证应用运行在一位联合创始人家中的服务器上,以节省成本。确认这一构想切实可行后,该公司将基础设施迁移到云端,以免自行管理数据中心的硬件。由于主要采用Microsoft技术,该公司选择了Azure。初始架构使用Azure App Service中的传统虚拟机(VM)运行应用。Azure App Service是一项托管式应用交付服务,运行Microsoft IIS Web服务器。为存储和检索数据,该公司选择将在VM中运行的Microsoft SQL Server用作托管应用。
在云端运行数年后,该公司业务快速增长,也面临扩展难题。公司需要实现近乎无限的扩展能力,并采用横向扩展而非纵向扩展,因为使用虚拟机进行纵向扩展既缓慢又昂贵。这一需求自然促使公司将容器化和Kubernetes视为可行的解决方案。容器化的另一项优势是,公司开发人员需要频繁发布应用和基础设施更新,同时避免服务中断。由于多个时区的用户持续添加患者记录,因此没有合适的停机时段可用于将变更推送到生产环境,任何故障都可能立即影响客户。
对该公司而言,合理的起点是采用Microsoft的托管Kubernetes服务Azure Kubernetes Services (AKS)。团队研究了Kubernetes最佳实践,并意识到需要在Kubernetes集群前端部署一个Ingress控制器,以有效管理流量以及AKS节点和Pod中运行的应用。
流量路由必须灵活且精准
团队测试了AKS的默认Ingress控制器,但发现其流量路由功能无法按要求向公司的客户交付更新。在患者护理中,不允许出现含糊或相互矛盾的信息。例如,对于同一事件,一名护理人员看到橙色标记,而另一名护理人员看到红色标记,这是不可接受的。因此,同一组织内的所有用户都必须使用相同版本的应用。这给升级带来了很大挑战。由于没有合适的固定时机将客户迁移到新版本,公司需要通过服务器和网络层面的规则,将不同客户的流量路由到不同的应用版本。
为此,该公司为同一组织内的所有用户运行相同的后端平台,不提供在组织内部基础设施层进行分段的多租户功能。借助Kubernetes,可以结合虚拟网络路由、浏览器Cookie和精细的流量规则来拆分流量。然而,该公司的技术团队发现,AKS的默认Ingress控制器只能按百分比拆分流量,无法按要求使用客户组织级或单个用户级规则。
在基本配置下,基于NGINX Open Source的NGINX Ingress Controller也存在同样的限制,因此该公司决定改用更先进的、基于NGINX Plus的NGINX Ingress Controller。NGINX Plus是一款支持精细流量控制的企业级产品。Microsoft和Kubernetes社区基于NGINX Ingress Controller出色的灵活性和控制能力而给出的推荐,进一步坚定了该公司的选择。该配置更能满足公司对Pod管理(而非传统流量管理)的需求,确保Pod在适当的区域中运行,并将流量路由到相应服务。有时流量会在内部进行路由,但在大多数用例中,出于可观测性考虑,流量会通过NGINX Ingress Controller重新向外路由。
前路暗藏风险:监控、可观测性与应用性能
借助NGINX Ingress Controller,技术团队可以全面掌控开发者和最终用户体验。用户登录并建立会话后,可立即被路由到新版本,也可回退到旧版本。补丁可以近乎即时地同时推送给组织内的所有用户。该软件不依赖DNS传播,也不依赖整个云平台的网络更新。
NGINX Ingress Controller还满足了该公司对精细化持续监控的要求。应用性能在医疗保健领域至关重要。延迟或停机可能会妨碍临床诊疗顺利开展,在事关生死的情况下尤其如此。迁移到Kubernetes后,客户开始报告该公司此前未察觉的停机问题。该公司很快发现了问题根源:Azure App Service依赖采样数据。采样数据适合用于分析平均值和总体趋势,但会完全遗漏请求被拒绝、资源缺失等情况,也无法显示医护人员每半小时集中签到并记录患者数据时经常出现的使用量激增。因此,该公司只能获得有关延迟、错误来源、错误请求和服务不可用情况的不完整信息。
问题还不止这些。默认情况下,Azure App Service仅将存储的数据保留1个月,远远达不到许多国家/地区法律规定的数十年期限。按长期保留要求扩展数据存储的成本高得令人难以承受。此外,Azure解决方案无法查看Kubernetes网络堆栈内部的情况。NGINX Ingress Controller在处理第4层和第7层流量时,可以同时监控基础设施和应用参数。
为实现性能监控和可观测性,该公司选择了Prometheus时序数据库,并将其连接到Grafana可视化引擎和仪表板。NGINX数据平面和控制平面已内置与Prometheus和Grafana的集成;技术团队只需进行少量配置更改,即可将所有流量导向Prometheus和Grafana服务器。这些信息还会传送到Grafana Loki日志数据库,以便更轻松地分析日志,并让软件团队能够更好地持续掌控数据。
此配置还可满足未来应对相关事件的需求,例如需要以极高频率进行大规模数据采样,以排查问题和修复错误。使用大多数大型云服务商提供的应用监控系统处理此类事件,成本可能较高;但在此用例中,Prometheus、Grafana和Loki的成本与开销都很低。这三款开源产品均较为稳定,完成初始调优后,通常只需安装补丁即可。
坚守方向:聚焦高可用性与安全性
该公司始终关注两个方面:一是通过安全措施保护极为敏感的数据,二是确保应用在需要时始终可用的高可用性。在迁移到Kubernetes的过程中,该公司进行了一些调整,以增强这两方面的能力。
为实现高可用性,技术团队采用主动-主动、多可用区和多地域分布式基础设施设计,实现全面冗余并消除单点故障。团队维护N+2主动-主动基础设施,在两个不同地域分别部署Kubernetes集群。在每个地域内,软件跨多个数据中心运行,以降低停机风险,并在基础设施任一层发生故障时提供保障。亲和性和反亲和性规则可立即将用户和流量重新路由至正常运行的Pod,避免服务中断。
为保障安全,团队部署了Web应用防火墙(WAF),以防范恶意请求和恶意行为者。大多数WAF都具备针对OWASP十大Web应用安全风险的基本防护能力。在开发应用期间,团队研究了多种WAF,包括Azure原生WAF和ModSecurity。最终,团队选择了NGINX App Protect,利用其内联WAF和分布式拒绝服务(DDoS)防护功能。
NGINX App Protect的一大优势是与NGINX Ingress Controller部署在同一位置,既消除了一个冗余点,又降低了延迟。其他WAF必须部署在Kubernetes环境之外,因而会增加延迟和成本。即使是极小的延迟(例如每个请求额外增加1 ms),长期累积起来也会产生显著影响。
意外的额外收获:开发人员无需停机
在完成大部分应用和网络基础设施向AKS的迁移后,该公司的开发者体验(DevEx)也得到显著改善。如今,开发者几乎总能在客户发现问题之前识别出问题。迁移后,与错误相关的支持电话数量减少了约80%!
该公司的安全和应用性能团队现在拥有详细的Grafana仪表板和统一告警,无需再检查多个系统,也无需为不同流程发出的警告短信和电话设置触发器。开发和DevOps团队现在每天都能发布代码和基础设施更新,甚至一天可发布多次,并采用粒度极细的蓝绿发布模式。过去,他们每周只能发布一到两次更新,还必须安排在使用量较低的时段,压力很大。现在,代码准备就绪后即可发布,开发人员可以通过观察应用行为直接监控其影响。
各方面都取得了积极成效:软件开发速度加快,开发人员士气提升,并挽救了更多生命。
关于作者

相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
