高速公路ETC车道软件可持续部署技术研究与实践
2021-07-15李从凡梁燕飞广东利通科技投资有限公司智能交通研究院
李从凡 梁燕飞 广东利通科技投资有限公司智能交通研究院
ETC车道系统是高速公路深化收费公路制度改革、取消省界站后车辆通行高速公路费用收取的主要手段,而整个收费过程,是由ETC车道软件自动完成。由于高速公路收费站在地理位置上分布较为分散,且ETC车道数量庞大,传统的ETC车道软件为单体程序,每当版本升级时,往往需要运维人员到达现场关闭车道后进行部署,费时费力;而且为了减少对车辆通行的干扰,只能选择车流量小时逐条更新,效率较低;遇到版本升级频繁时,给运维工作造成巨大的压力。ETC车道软件版本升级工作成本高且周期长,是日常运维的一大痛点。
在理想的情况下,用户希望ETC车道软件时时刻刻都是可用的,为了满足不断变化的新业务,需要不断升级更新应用程序,有时可能需要频繁的发布版本。为达到此目的,本文通过使用微服务技术对ETC车道软件进行重构,并采用K8S特有的滚动更新技术,实现“零停机”、用户“零感知”的可持续部署ETC车道软件。
一、可持续部署技术概述
(一)K8S介绍
K8S是Kubernetes 的简称,它是用来管理容器集群的平台。既然是管理集群,那么就存在被管理节点,针对每个 K8S集群都由一个 Master负责管理和控制集群节点。
我们通过 Master 对每个节点 Node 发送命令。简单来说,Master 就是管理者,Node就是被管理者。Node 可以是一台机器或者一台虚拟机。在 Node 上面可以运行多个Pod,Pod 是 K8S管理的最小单位,同时每个 Pod 可以包含多个容器(Docker)。
通过下面的 K8S架构简图可以看到Master 和 Node 之间的关系:(见图1)
图1 K8S架构简图
(二)滚动更新技术介绍
k8s通过部署(Deployment)来创建副本应用程序,部署自动创建副本集(ReplicaSet),副本集可以精确地控制每次替换的Pod数量。具体来说,k8s每次使用一个新的副本控制器(replication controller)来替换已存在的副本控制器,从而始终使用一个新的Pod模板来替换旧的pod模板。在整个滚动过程期间,保证始终有可用的副本在运行,从而平滑的发布新版本。
二、ETC车道软件架构设计
为了配合k8s实现滚动更新,ETC车道软件采用微服务技术进行设计,使其适应具备容器化部署的能力,具体的架构图如图2所示。
由图2可以看出,ETC车道系统可分为4个部分,其中ETC业务模块实现了收费业务,是整个系统里面的变化部分,也是每次版本升级的关键,它以Pod的形式存在于车道节点中,采用k8s的滚动更新机制进行升级,其他模块为辅助作用,设计理念如下:
图2 ETC车道软件架构图
(一)硬件隔离
由于ETC车道系统外设众多,使用串口通信协议或者PCI卡进行通信,而容器环境作为一台虚拟主机,难以访问宿主机的硬件资源,一般通过网络协议与外部进行通信,因此需要构建一个“硬件控制模块”的单体程序完成串口协议等到网络协议的转换,起到外设与ETC业务模块的桥梁作用。
(二)状态管理
要实现滚动更新机制,实现无缝升级,微服务必须是无状态的。
ETC业务模块负责ETC车辆的整个交易流程,在某通行车辆的交易过程中,必须临时保存交易信息,这和微服务的无状态要求是相矛盾的。
我们引入Redis内存数据库作为交易状态的临时存储手段,因而ETC业务模块可以满足无状态的要求,在新旧Pod的切换过程中,交易仍能持续进行,而且Redis提供持久化机制,就算重启计算机也不会丢失状态,交易仍能继续进行。
三、集群设计
如图3所示,高速公路的收费站为局域网,可以访问部中心和省中心服务器,为了保证集群的可靠性,K8S集群应以收费站为单位建立,而在省中心用Harbor搭建镜像仓库,供全省所有收费站拉取镜像使用。
图3 集群设计图
具体的升级过程为:
1)先将“ETC业务模块”镜像上传到镜像仓库
2)然后在K8S Master节点执行升级命令
3)最后K8S集群自动完成各个ETC Node节点的自动升级。
四、实现持续部署
K8s的目标是在滚动更新的过程中最大程度地减少服务的中断,其工作过程如下:
1)k8s创建新的Pod,让其处于活动状态并准备就绪
2)k8s将会停止旧的 Pod,从而将 Pod的状态更新为“Terminating”
3)k8s将旧的Pod从 Endpoints 对象中移除
4)k8s发送一个 SIGTERM 信号给旧Pod 的主进程。
5)SIGTERM 信号就会让旧Pod容器以正常的方式关闭,并且不接受任何新的连接。
6)旧Pod 从 Endpoints 对象中被移除后,负载均衡器就会将流量路由到其他(新的)Pod 中去。
但由于负载均衡器检测Endpoints对象的变化,并更新其配置是个异步的过程,可能在这个间隔里旧的Pod已经被关闭了,所以就可能导致很少的请求会被路由到终止的Pod 上去。
为了解决这个问题,实现“零停机”,我们在编写Deployment脚本时可以加入:
preStop:
exec:
command:["/bin/bash","-c","sleep 20"]
这样,旧的Pod从Endpoints 对象中被移除后,还能继续提供20秒的服务,保证了无缝切换。
五、实施过程与效果
从2020年3月开始,我们先后在广东省多个路段进行现场试运行和优化,经省中心校验,系统流水正确,流水上传和参数下发正常稳定,路段后台管理系统流水和图片查询统计正常,交易时间<300ms,已具备ETC标准车道(出入口)连续24小时不间断过车交易能力。经过总结,我们认为具备以下实施效果:
(1)应用部署效率提高
利用K8S集群的滚动更新技术,每当ETC车道软件进行版本升级时,只需远程操作站级Master节点,即可完成更新,更新过程不影响ETC车道正常过车,在实际使用过程中,更新一个站的30条ETC车道,耗时不到1分钟。
(2)车道故障率下降
当K8S集群内的Pod出现故障时,集群会将Pod自动重启,而redis中仍保存着交易状态,车道系统从故障中自动恢复,整体稳定性得到显著提升。
(3)系统监控能力提升
得益于K8S集群的多级监控机制,运维人员可以实现对系统、平台、应用的全方位监控,监控可以细化至每一个节点和应用实例。监控指标更加丰富,同时借助消息推送渠道,使软硬件故障通知更为及时,响应更加迅速。
(4)人员成本下降
运维人员直接在K8S的Master节点发出更新指令,K8S自动完成整个更新过程,运维人员在非硬件故障情况下无须到达现场,有效减少了运维人员的工作量。
六、结语
基于Kubernetes 的可持续部署技术将研发与运维人员从烦琐的手工操作中解放出来,同时,系统后台具备了高可靠性、失败冗余和容灾恢复等特点,在高速公路ETC车道的改造实践中具有较大的发展空间。由于当前系统每个ETC Node部署在车道工控机内,当车道工控机出现硬件故障时,ETC车道交易也将中断,如何能利用K8S集群的高可用技术,达到车道工控机出现硬件故障时,ETC车道系统仍能正常交易,是我们下一步的研究方向。