Kubernetes,旧貌新颜?

438 阅读10分钟
原文链接: mp.weixin.qq.com
作者|张建峰 编辑|小智 从单体到微服务,论企业级应用服务器到微服务基础设施架构设计演进 架构问题

作为一名软件工程师或者系统架构师,当我们在构造大型应用系统时,常常需要画出一个体系架构图,来表现要开发的应用系统的软件架构。

我想很多软件开发人员都有这样的疑问:这几年业界都在谈微服务,容器化,这样的技术变化的原因是什么?新的或者原有的软件系统到底该用什么样的技术架构体系?如果需要改造,应该怎么做?

希望通过阅读本文给您一些启发。

技术背景

应用服务器是近十几年来应用开发的主流部署环境。以 Java 语言社区为例,Java EE 应用服务器是软件中间件开发领域的主要产品,包括以 Weblogic, Websphere 商业产品, JBoss AS(Wildfly), Glassfish 开源产品,还有 Tomcat, Jetty 等 Servlet 容器服务器,Spring Framework 应用框架等,这些共同组成商业业务软件最重要的部分。

容器 Docker,容器编排 Kubernetes 等带来了容器化微服务软件技术浪潮,互联网公司作为先行者,并在国内外引领软件设计的方法变革,Cloud Native 已经成为当前软件设计中必须考虑的要素。

那么,“传统”的应用服务器和 Kubernetes 之间是否有技术关联性?如果有,它们的内在联系是什么?

相似之处

我在专业技术网站找到了两幅图片,分别是完整的 JavaEE 实现 Wildfly 应用服务器域模式和 kubernetes 架构体系图。

图片出处:

https://kb.novaordis.com/index.php/Wildfly_Domain_Mode_Concepts

图片出处:

https://x-team.com/blog/introduction-kubernetes-architecture/

以上两幅图,并不能表现这两个产品所有技术架构细节,但已经能够充分表现它们的架构特点和组件之间的关系。

我们发现,两者的架构有很多一致的地方:

  1. 都有一个主控节点。Kubernetes 称为 Master Node,Wildfly 中含有 domain controller 的 host1,也是作为主控节点。

  2. 通过主控节点管理多个工作节点。Kubernetes 有两个 Worker Node,Wildfly 图中也有两个工作节点 host2 和 host3。

  3. 管理员通过管理接口 (Rest API) 来对整个系统进行管理,Kubernetes 是通过 kubectl 访问 API server,Wildfly 是通过 jboss-cli 工具访问管理接口,服务器处理组件是 domain controller。当然,它们也都提供图形管理工具。

  4. 工作节点上都有控制进程,Kubernetes 是 kubelet 和 kube-proxy,Wildfly 为 host controller 和 process controller,其中 kubelet 和 host controller 作用类似,都是起到工作节点和主控节点通信和管理节点工作进程的作用。

  5. 每个工作节点上都有多个工作进程,只不过 Kubernetes 是由容器管理 Pod,而 Wildfly 是 JVM 进程管理工作线程。

另外在图示中没有表示出来,在逻辑上概念相似的还有:

  1. Kubenetes 中的 controller-manager 包括各类功能的控制器模块。Wildlfy 中有类似的功能模块,也在 domain controller 中,它们都具备可扩展能力。

  2. Rest API 对外接口采用简单易懂的 Json 格式。而各个节点间为了高效率,通信方式为二进制数据流,可以配置加密方式。

  3. 尽管在工作进程中,Pod 和线程是不同的。但它们逻辑上也有相似之处:都是独立的工作主体;都有完整的生命周期;Pod 间共享网络,存储等信息,线程间可以传递上下文。我个人更愿意把 Pod 看作是高一个或者半个维度的,隔离性更好的“工作线程池”。

  4. 不同的节点或者进程中的服务工作单元,可以动态组成服务群组。Wildfly 中有 Server Group 概念,一个应用可以被同时部署到 Server Group 的所有工作单元;Kubernetes 的 Pod 可以通过定义的 Label 来 Selector,即可以筛选出具有某些标记的 Pod,而作为服务群组对外提供服务。

  5. Kubernetes 有 Service 来提供服务,对于服务消费者,后面的 Pod 服务提供者的信息都是透明的,而且还有 Ingress 对外部应用进一步暴露服务能力。Wildfly 提供了 Wildfly-cluster 作为服务组件的反向代理,虽然做不到像 Service 那样直接通过 iptables 底层机制去映射网络访问端口,但同样也有强大的根据负载能力调节转发请求量的特性,更多起到 Ingress 的作用。

  6. Kubernetes 对有状态的组件支持,是通过 StatefulSet,挂接 Persistent Volumes,启动时重新构建相同状态的工作容器。而 Wildfly 中对状态的管理,包含 Stateful SessionBean, Servlet session 等等,都是通过 Infinispan 的分布式机制,复制状态到多个节点。而且还有一种远程 Infinispan 的配置方法,和 Kubernates 对状态的管理在逻辑上完全一致了。

  7. 对于 Master 主控节点的安全性管理,两者都有完备 RBAC 用户管理认证授权机制,以及完备的加密方式,密钥配置管理等功能。

Java EE 技术一直是一个完整的开发生态,同样,Kubernetes 也快速形成了更加庞大的生态体系,我们从其中一些对开发很重要的方面进行分析。

  1. JavaEE 有一套标准的打包方式,如构建 jar,组合成应用 war,进而打包成企业完整应用 ear。Kubernetes 是利用容器镜像,即 docker 的打包机制来管理容器。在 docker 之上,Kubernetes 提出 Pod 概念。对于整体的应用部署,目前 Kubernetes 社区提供了 helm 工具和 chart 包格式。当然也类似 yum 工具管理的 rpm 格式。

  2. Kubernetes 动态扩容,即 ReplicaSets 定义的创建特定数目的实例,可以说是 Kubernetes 最重要的特性之一。JavaEE 定义的 Stateless SessionBean,在应用服务器实现中,会创建一个池来实例化多个,虽然实例个数控制粒度没有那么细,但也是可以通过控制台来定义其实例数量的,实例池由容器来保证其可用实例数目。

  3. Kubernetes 用 ConfigMap 来定义配置信息,用 Secrets 来定义安全方面的配置信息。JavaEE 也有类似的定义,比如 Resource 和 Securtiy 方面的 annotation。在应用服务器扩展方面,Wildfly 可以自行定义 xml schema,提供友好可读的 xml 配置信息,以及 Security Domain/Realm 来定义安全方面的配置信息。

  4. 原 Coreos(后被红帽收购)定义的 Operator Framework(运维框架),基于 Kubernetes CRD(Custom Resource Definitions),定义了完整的一套打包,部署,管理应用的方法,有了这样的工具,第三方软件产品,可以用一种相对“标准”的方式提供容器化的产品。Custom Resource Definitions 是 Kubernetes 的扩展机制,可以预见 Kubernetes 三方扩展将会如雨后春笋般出现。对应的,Wildfly 有子系统(subsystem 扩展机制),可以在 Wildfly 服务器内核之上,开发子系统来扩展功能,Wildfly 所有的 Java EE 都是通过子系统方式实现的。它们都是通过扩展 Controller 的功能,把管理命令挂接到 API server 之上,设计思路惊人的一致!

  5. Wildfly 工作节点的管理,可以通过暴露信息发给主控节点,也可以利用 JMX,Java agent,Interceper 等方式来发送数据到分布式数据中心上(比如可以加载 jolokia),再用独立的或者统一的控制台来管理。同样的,Istio 项目,也是利用 sidecar 模式,在 pod 工作进程上,挂接一个 envoy 模块,由其完成流量分配,安全管理,policy 设置等功能,再由控制台统一管理。

  6. Kubernetes 被成为容器编排产品,所谓编排 (orchestration),就是把不同的应用运行组件,按照实现定义好的规则,根据其依赖性能够启动运行,并保证其运行健壮的能力。Java EE 各个规范间也有依赖性,比如 Webservice 依赖于 Servlet,Wildfly 有一个组件成为 DeploymentFramework,也是处理组件之间的依赖关系的,服务器会按照应用定义好的最终状态声明,按照自己的依赖性原则,逐个启动各个服务,保证应用最后可用。

技术差异

毕竟 Kubernetes 是演进后技术,具有大量新的特性:

  1. 存储方面的特性,Kubernetes 可以挂载各种存储,包括普通的文件系统,NFS,云端的 S3,开源存储方案 Ceph 等应有尽有。Wildfly 还是使用标准的操作系统的文件和目录。利用容器,Kubernetes 能更方便的对文件限额,资源使用量等进行定义和限制操作。

  2. 网络方面的特性,Wildfly 定义了网络接口配置属性,可以对网络 IP,端口,偏移值等进行设置。但这些和 Kubernetes 相比就是九牛一毛,Kubernetes 在 Service 层,就利用 iptables 等方法做网络请求的路由映射,而且商业 Kubernetes 产品都会加入 SDN(软件定义网络)的方案,网络管理成为应用体系重要的一部分。

  3. Kubernetes 中非常重要的组件是 scheduler 调度器,这个在 Wildfly 中没有功能完全一致的组件,因为企业应用的集群部署是按组整体部署的。Wildfly 提供了控制台工具来部署到不同的节点上,尽管这个过程可以自动化,甚至可以引入一些智能的成分来“调度”,但还是和 Kubernetes 提供的调度能力相差甚远。

  4. 对工作节点的管理的规模不同。企业应用服务器集群一般在数十台左右,和互联网动则成千上万的服务器差了几个数量级。对事务的一致性要求也是不同的,它们对于状态信息的分布式分发复制方式存在差别。

  5. 企业级应用服务器,应用上下文信息包含了事务,安全等信息,在线程间进行传递。而应用分布化后,微服务之间也要传递安全,事务等信息,就要用 OIDC/Jwt,TCC/Saga 等分布式方案。业务目标是一致的,但实现方法有很大差异,也对软件架构设计提出了非常高的要求。

总结和展望

毫无疑问 Kubernetes 已经赢得了容器之战,甚至取代 docker 成为容器技术中最重要的开源产品。开发工程师和架构师也需要适应微服务化技术的变化,部署应用到云端上,这个趋势已经开始了。同时,Kubernetes 和其生态,对于应用开发和运维也提出更高的要求。企业在开发软件应用时,也要多方位考虑,包括应用复杂度,访问量,事务的要求,运维能力等。再选择技术方案和中间件产品 / 云计算平台。软件设计从来都没有银弹,最适合的才是最好的。