应用运行架构

租户和微服务

在平台中每个 租户 是一个基于 K8S Namespace 进行资源隔离的运行环境,在每个租户中可以部署一个或多个基于 K8S Service 运行的微服务。 每个 微服务 做为 K8S Service,它的背后实际上最终运行的是一个或多个 Pod,K8S Service 只是多个 Pod 负载均衡后的统一服务访问入口。 平台在 K8S Service 之上通过集成 Kong API Gateway 构成了 Service Mesh(服务网格)微服务治理框架。

微服务的应用架构

在平台中,每个微服务由 代理网关 和 多个 服务模块 组成。

  • 代理网关:对应 Service Mesh 中的 Side Car,微服务内的所有服务通过代理网关暴露,并接入到上层的微服务治理框架中;
  • 服务模块:平台的每个微服务可以包含多个服务模块,这些服务模块可以是多种不同技术架构的,例如:Tomcat Web 服务、Java Spring Boot 服务、Python 服务、Node.js 服务、.NET 服务,甚至是基于 Golang 或 C 实现的可执行程序等。

通过前面租户和微服务的介绍,我们知道每个微服务(K8S Service)最终运行的是一个或多个 K8S Pod。Pod 是 K8S 中的最小管理单元,在一个 Pod 中可以包含多个 Container,这个 Container 就对应大家所熟知的 Docker 容器,也就是说每个微服务是可以运行多个 Docker 容器的。

微服务中的多个服务模块与 K8S Pod 中 Container 的对应关系如下图所示:

从上图中我们可以看出:

  • 微服务的 Pod 中提供了多个不同技术架构的运行容器环境 - Runtime Container
  • 多个相同技术架构的服务模块运行在同一个 Runtime Container 中。

我们通过 K8S Dashboard 可以看到如下的容器列表:

在上图中:

  • tomcat、java-runtime、node-runtime、bin-runtime、comp-dotnet-runtime、comp-nginx-runtime、comp-python-runtime:就是 Runtime Container
  • gateway:就是代理网关;
  • migration:数据库初始化服务;
  • app-init:系统初始化服务。

我们去看多个微服务的容器列表会发现一个现象:不同的微服务中这些 Runtime Container 的容器镜像是相同的,接下来我们介绍 Runtime Conatiner 的技术实现原理。

Runtime Container

在讲解 Runtime Container 的技术实现前,我们先来看一下通常基于容器运行一个服务的技术实现,下面以在 tomcat 中运行一个 war 来示例:

从上图我们看到,应用的镜像是在 tomcat 容器镜像的基础上,通过编制 dockerfile 将 war 复制到 wabapps 目录,然后 docker build 出一个新的应用的容器镜像 app image。 在这种方式下,每次当应用更新后,都需要重新构建 app image。因此,很多时候我们会采用另一种技术实现,如下图所示:

上图跟前面一张图的区别是 war 并不直接复制到 app image 中,而是以软链接的方式将 war 文件挂载到 tomcat 中运行。这种方式下,当应用更新时,app image 不需要重新构建,只需要替换挂载存储卷中的 war 文件,重启容器服务即可。

Runtime Container 就是采用了后一种技术实现,Runtime Container 的容器镜像是固定的,应用资源并不包含在 Runtime Container 的容器镜像中。微服务应用运行时,以软链接或复制的方式,动态将服务模块的运行资源加载到对应的 Runtime Container 中运行。这种技术实现带来以下技术优势:

  • 实现了服务运行镜像与服务运行资源分离
    • 应用更新只需要更新服务运行资源,服务运行容器环境重启即可,无需重新构建镜像,重新部署;
    • 当基础镜像需要更新时(例如:tomcat 出现漏洞需要升级版本),只需要重新构建对应的 Runtime Container 的镜像即可。而这个场景在前一种技术实现下,所有依赖 tomcat 的应用镜像都需要全部重新构建才可以。
  • 简化了 K8S 容器应用部署的复杂度
    • 大多数用户无需关心 Pod 运行背后的 Docker Image、Pod Yaml 等底层技术实现,只需要按照模块的定义规范提供相应的应用资源和配置,即可实现应用在容器中运行;
    • 对于需要对 Runtime Container 进行定制的场景,平台支持用户定制自己的 Runtime Container 镜像,定制自己的 Pod Yaml。
  • 共享运行资源池模式
    • 共享运行资源池模式,是平台特有的 Pod 资源调度机制。在池模式下我们通常感受到的是打开一个 IDE 或运行一个服务,资源池中会自动分配一个 Pod,并在几秒钟内启动服务提供运行环境;当服务长时间不使用超过资源池的超时时间后,Pod 资源会自动释放。
    • 而共享运行资源池模式背后的核心技术就是 Runtime Container,在平台的池管理中有开发池和生产池,其中分别又有多个不同的池定义,每个池代表了一种运行环境。每个池中所有的 Pod 的 Yaml 都是相同的,即都包含了相同的 Runtime Container,拥有相同的资源配置(CPU、内存...),用户可以通过池类型管理定义新的池。
    • 由于每个池中所有的 Pod 都是相同的,例如:IDE 池,开发者打开 IDE 时,开发资源绑定到池中的哪一个 Pod 节点都是一样的;
    • 另外注意,池中所有的 Pod 都是已经创建好的,只是在池节点绑定过程中,动态将应用资源以软链接或复制的方式加载到 Runtime Container 中运行,所以平台的共享运行池模式才能实现在几秒钟内恢复一个应用的服务运行环境。

results matching ""

    No results matching ""