从Tuxedo运维走向Kubernetes运维

【编者的话】Tuxedo作为一款成熟的交易中间件,具有强大的交易处理性能、高度的可靠性和无限的伸缩性。Kubernetes作为新兴容器编排调度引擎,基于容器技术,实现资源管理的自动化以及跨多个数据中心的资源利用率最大化。前者以交易事务管理闻名,后者以容器编排著称。无论是Tuxedo还是Kubernetes,其运行离不开网络、设备及存储等基础设施的支撑。

本文重点对运行于基础设施之上两者运行特点进行分析对比,使具有Tuxedo运维经验的运维人员对Kubernetes有进一步的了解,给后续Kubernetes运维提供参考借鉴。

Tuxedo

Tuxedo ATMI体系架构图

大多数Tuxedo应用都是采用ATMI来实现运行环境和编程接口的,其体系架构如上图所示,整个架构划分为外部接口和内部服务层两个部分。外部接口层的基础是ATMI层,之上是Client。Tuxedo服务层包括通讯模型、管理信息库(MIBs)、应用服务器及管理服务器等。通讯模型指的是Tuxedo客户端和服务端、Tuxedo服务端与服务端之间传递消息的模型。管理信息库为其他应用程序管理和配置Tuxedo系统提供接口,通过该接口,使用人员可以对Tuxedo配置信息进行动态调整及对其运行状态进行实时监控(如某些系统通过MIBs获取Tuxedo队列地址、队列深度等实现流量控制)。应用服务为ATMI应用程序提供了数路由、编码、负载均衡和命名服务等。管理服务为ATMI应用程序提供事件、安全等服务。

Kubernetes

Kubernetes作为一个开源的大规模容器集群管理软件,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部属容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新和维护的一种机制。典型Kubernetes架构图如下所示:

典型Kubernetes架构图

如上图所示,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点(Node)。其中,在Master节点上运行着集群管理相关的一组进程:kube-apiserver、kube-controller-manager、kube-scheduler、etcd和kube-ctl。这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy、docker和kube-ctl,这些服务进程负责Pod的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。 如果你想和更多Kubernetes技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

上面对Tuxedo和Kubernetes的基本架构和组成要素进行了简要介绍,下面通过如下几个方面对两者进行对比分析:

运行态

应用程序要正常运行并提供服务,除了依赖的底层基础设施(如网络、服务器、存储等)外,还依赖应用本身的可执行文件及对应配置文件。基于Tuxedo应用在生产部署及运行时主要依赖应用程序包(可执行文件)、配置文件(ubb和bdm),基于Kubernetes应用在生产部署及运行时同样主要依赖应用程序包、配置文件(YAML或ConfigMap)。二者均通过配置文件和执行文件的组合,实现了服务的正常运行、服务(或服务数)控制或弹性伸缩、负载均衡、容错、监控检测等功能。Tuxedo中进程或可执行文件做为服务的载体,其在

Tuxedo配置文件主要参数如下所示(节选):

*RESOURCES  



……



LDBAL Y             负载均衡



SCANUNIT 10        健康检查控制



SANITYSCAN 12  



*MACHINES  



gumby LMID=SITE1  



……



APPDIR=”/usr/apps/bin”   可执行程序目录



……



*SERVERS  



DEFAULT: RESTART=Y MAXGEN=5 GRACE=3600   容错控制



TLR SRVGRP=BANKB1 SRVID=10 MIN=1 MAX=2   副本控制



RQADDR=QNAME REPLYQ=Y -p [L][low_water][,[terminate_time]][:[high_water][,create_time]]  弹性伸缩控制



……



*SERVICES  



SRVGRP=BANKB1  



LOAD=25 PRIO=70                          负载因子及优先级控制

Kubernetes配置文件主要参数如下所示(节选):

……



metadata:



name: nginx



spec:



replicas: 2                      副本数



……



spec:



restartPolicy:Always            重启策略



container:



- name: nginx



  image: nginx                 镜像



  livenessProbe:                健康检查



         httpGet:                    



         ……



         initialDelaySeconds: 15      表明第一次检测在容器启动后多长时间后开始



         timeoutSeconds: 1          检测的超时时间



   ……

弹性伸缩

对于一些和电商促销或外部行情紧密相关系统,其业务量随着促销或行情变化出现交易高峰,待促销结束或行情稳定后,业务量又快速回落。无论是基于Tuxedo的应用还是基于Kubernetes应用,均提供弹性伸缩功能。

基于Tuxedo应用通过在ubb中配置min、max值,以及队列深度基线值,可实现服务数随业务量变化而动态扩缩容(当然也可通过手工方式快速增加或减少服务),也即Tuxedo是基于业务量进行扩缩容。具体配置如下:

*SERVERS



BillServer SRVGRP=GROUP1 SRVID=1 MIN=2 MAX=4



RQADDR=QNAME REPLYQ=Y -p [L][low_water][,[terminate_time]][:[high_water][,create_time]]

如果MAX>1,并且使用了MSSQ(RQADDR, RQPERM)的Server可以配置-p来控制进程的动态增加和减少。控制算法如下:如果请求队列中的请求个数大于high_water 后超过create_time 秒,就增加该服务的一个新进程;如果请求队列中的请求个数小于low_water后超过terminate_time秒,就停止该服务的一个进程。low_water缺省是平均每个服务进程有一个请求消息或者workload 50;high_water 缺省是平均每个服务进程有两个请求消息或者workload 100。create_time 缺省最小是50秒, and terminate_time 缺省最小是60秒。

基于Kubernetes应用,通过Kubernetes的HPA(Horizontal Pod Autoscaler)实现Pod横向自动扩容(Kubernetes管理最小单位为Pod)。属于一种Kubernetes资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。HPA可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(也即Kubernetes基于系统资源进行扩缩容)。

HPA自动扩缩容示意图

工作流程:

  1. 创建HPA资源(通过编写YAML文件进行创建),设定目标CPU使用率限额,以及最大、最小实例数;
  2. 控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况;
  3. 然后与创建时设定的值和指标做对比(平均值之和/限额),求出目标调整的实例个数;
  4. 目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数;

重复2-4步。

基于Tuxedo的应用和Kubernetes应用,在弹性伸缩方面有相同处,也有不同处。相同点为两者通过弹性伸缩可以控制运行服务数量,有效应对业务的突变,不同之处为Tuxedo弹性伸缩(以及负载、服务发现、容错等)均在原服务器(原Node、原IP)上进行,而Kubernetes的扩缩容与服务器(原Node、原IP)没有绑定关系,可以跨Node伸缩、容错,IP也会发生改变。

在Kubernetes中,Node节点可以在运行期间动态增加到Kubernetes集群中,在默认情况下kubelet会向Master节点注册自己。一旦Node被纳入集群管理范围,Master可以根据负载情况将部分流量负载到新加入Node节点。而在Tuxedo中,SHM模式中不具备类似Kubernetes中Node节点的扩容,在MP模式下动态增加节点也相对比较复杂。

容错和故障隔离

对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。无论Tuxedo还是Kubernetes都提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。Tuxedo和Kubernetes依据配置文件(ubb或yaml)配置策略,按照约定间隔对应用服务进行探测,在约定时间段内探测失败则进行重启或隔离。Tuxedo的容错和故障隔离既可基于服务级别,也可基于节点级别(仅针对集群部署模式,目前集群部署模式较少)。Tuxedo具体配置如下:

……



*RESOURCES



MASTER          SITE1,SITE2//site2为备用Master,site1宕机了site2顶替



MODEL           MP  //模式是multiple machine



OPTIONS         LAN //置为lan,这和MP配对使用



SCANUNIT        10  // 健康检查控制



SANITYSCAN      12 



*MACHINES



"node1"//master主机名



            LMID=SITE1



"node2"//从主机主机名



            LMID=SITE2



*GROUPS



APPGRP1



            LMID=SITE1                GRPNO=1



APPGRP2



            LMID=SITE2                GRPNO=2



*NETWORK//配置集群不可少的网络配置



SITE1



            NADDR="//IP1:port1-1"//bridge进程使用的网络地址及端口



            NLSADDR="//IP1:port1-2"//tlisten进程使用的网络地址及端口



SITE2



            NADDR="//IP2:port2-1"



            NLSADDR="//IP2:port2-2"



*SERVERS



DEFAULT: RESTART=Y MAXGEN=5 GRACE=3600   //容错控制



server          SRVID=10                SRVGRP=APPGRP1



server          SRVID=20                SRVGRP=APPGRP2

Tuxedo按照探测间隔,定期对相关服务或节点进行健康检查,发现某个服务异常(coredump)后会自动拉起该服务,如果发现某个节点异常后会自动将该节点从集群中剔除,通过这种方法实现容错和故障隔离功能。

Kubernetes采用Liveness和Readiness探针进行健康检查,其中Liveness探针主要用于判断Container是否处于运行状态,比如当服务crash或者死锁等情况发生时,kubelet会kill掉Container, 然后根据其设置的restart policy进行相应操作,而Readiness探针主要用于判断服务是否已经正常工作,如果服务没有加载完成或工作异常,服务所在的Pod的IP地址会从服务的endpoints中被移除,也就是说,当服务没有ready时,会将其从服务的load balancer中移除,不会再接受或响应任何请求。具体配置如下:

……



spec:



restartPolicy:Always            重启策略



……



  livenessProbe:                健康检查



         httpGet:                    



         path: /health



         port: 8080



         initialDelaySeconds: 15      表明第一次检测在容器启动后多长时间后开始



         timeoutSeconds: 1          检测的超时时间



   ……

Kubernetes具体容错和故障隔离流程如下:

1. 如果服务的健康检查(Readiness)失败,故障的服务实例从service endpoint中下线,外部请求将不会再转发到该服务上,一定程度上保证正在提供的服务的正确性,如果服务自我恢复了(比如网络问题),会自动重新加入service endpoint对外提供服务。

2. 如果设置了Container(Liveness)的探针,对故障服务的Container(Liveness)的探针同样会失败,container会被kill掉,并根据原设置的container重启策略,系统倾向于在其原所在的机器上重启该container、或其他机器重新创建一个Pod。

3. 由于上面的机制,整个服务实现了自身可用与自动恢复。

服务发现

Tuxedo使用公告板来提供命名服务。Bulletin Board(公告板)是一块共享内存,Tuxedo把系统的配置保存在一个该共享内存中,主要包括服务进程、服务、消息队列、事件、运行环境的配置和统计信息等,TUXEDO通过BBL对公告板等进行管理。Tuxedo在服务启动时根据配置文件首先会创建一片共享内存作为公告板并将相关参数加载到共享内存中,在服务启动时会将服务相关信息(如服务名、队列名、服务数量、服务状态、请求数等)注册到BB中,在服务调用过程中,调用方通过BB的命名服务获取后台服务信息,实现服务的发现和调用。

Tuxedo服务发现及调用(一)

Tuxedo服务发现及调用(二)

Tuxedo服务发现及调用如上图一所示,客户端连接到Tuxedo公告板,根据服务名查找(Looks up)公告板、获取(Gets)所调用服务相关信息、调用(Invokes)服务。由于tuxedo是基于队列通过ATMI接口进行信息交互,具体ATMI、Message Queue、Bulletin Board交互如图二所示,客户端通过ATMI接口将消息发送到服务端队列(队列信息通过BB获取),服务端处理完后通过ATMI接口将处理结果返回到客户端队列。

Kubernetes提供了Service的概念,可以通过VIP访问Pod提供的服务,但是在使用的时候还有一个问题:怎么知道某个应用的 VIP?比如我们有两个应用,一个App,一个是db,每个应用使用rc进行管理,并通过service暴露出端口提供服务。App需要连接到db应用,我们只知道db应用的名称,但并不知道其VIP地址。起初,kubernetes采用了Docker使用过的方法——环境变量。每个Pod启动时候,会通过环境变量设置所有服务的IP和port信息,这样Pod中的应用可以通过读取环境变量来获取依赖服务的地址信息。这种方式服务和环境变量的匹配关系有一定的规范,使用起来也相对简单,存在的问题是:依赖的服务必须在Pod启动之前就存在,否则不会出现在环境变量中。理想方案是:应用能够直接使用服务的名字,不需要关心它实际IP地址,中间的转换能够自动完成,名字和IP之间的转换就是DNS系统的功能,因此Kubernetes也提供了DNS 方法来解决这个问题。

Kubernetes服务发现

如有两个服务frontend和backend,服务frontend调用服务backend。其调用过程如下:

  • 先通过本Node上运行的DNS Server查找到backend服务的Cluster IP。
  • 再通过本Node上运行的代理Kube-proxy,将请求分发给其中任意一个backend实例。

一次完整的请求

我们从Tuxedo ATMI体系架构图中可以看出,Tuxedo系统服务层包括管理信息库(MIBs),管理信息库为其他应用程序管理和配置Tuxedo系统提供了一套编程接口,通过这套接口可以对Tuxedo系统进行动态调整和监控。如动态增加Tuxedo服务时,用户通过ATMI Client调用管理信息库(MIBs),通过管理信息库完成服务的增加,最后将服务信息注册到公告板(BB)。

类似地,Kubernetes也提供了一套接口供使用者进行服务的管理维护,具体流程如下:

Kubernetes一次完整的服务请求示意图

使用人员通过Kubectl提交一个创建RC的请求,该请求通过API Server被写入etcd中,此时Controller Manager通过API Server的监听资源变化的接口监听到这个RC事件,分析之后,发现当前集群中还没有它所对应的Pod实例,于是根据RC里的Pod模板定义生成一个Pod对象,通过API Server写入etcd中,接下来,此事件被Scheduler发现,它立即执行一个复杂的调度流程,为这个新Pod选定一个落户的Node,然后又通过API Server将这一结果写入到etcd中。随后,目标Node上运行的Kubelet进程通过API Server检测到这个“新生的”Pod并且按照它的定义,启动该Pod并负责他的一生。

综上所述,Tuxedo软件在金融等行业已应用多年,经过多年积累,运维人员对Tuxedo维护积累了丰富的运维经验。Kubernetes作为后起之秀,逐步在互联网、金融等行业开始应用,相关运维积累存在提升空间。本文通过对两者运行态、容错、扩缩容、服务发现以及一次完整的请求等方面进行对比,希望通过对两者的对比,找出两者运行及运维的相通之处,能够给运维人员维护Kubernetes提供一个思路和借鉴,使得具备Tuxedo等传统软件运维经验的运维人员快速具备Kubernetes运维能力。

原文链接: https://mp.weixin.qq.com/s/P77jueYtBiM_bQy4dtvEag