Apache Camel K 技术调研报告

Apache Camel K 简介

什么是 Apache Camel

GitHub: https://github.com/apache/camel

Apache Camel 是一款开源集成框架,通过这一框架能够快速的集成各类数据格式不同的生产或消费数据的系统。

  • Camel 对大部分 EIP(Enterprise Integration Pattren,企业集成模式)提供了相关的实现
  • Camel 包含了数百种组件,能够访问各种数据库、消息中间件、API 等,几乎支持任何通信方式
  • Camel 支持大约 50 种数据格式,能够将数据转换成多种不同的格式,涵盖了金融、电信、医疗保险等行业标准格式的支持
  • Camel 能够独立运行,也能嵌入已有的系统中,或者基于微服务架构,甚至以 Serverless 的方式运行

从开发的角度看,Camel DSL 是一套抽象级别非常高的 API,几乎完全屏蔽了各种组件的 API。

示例:当 8080 端口接收到 GET /event/send-message 请求时,发送当前日期到 RocketMQ 的 Topic camel_sample

      restConfiguration().port(8080);
      from("rest:get:event:/send-message")
          .setBody(exchange -> new Date().toString())
          .to("rocketmq:camel_sample?namesrvAddr={{rocketmq.namesrvAddr}}&producerGroup={{rocketmq.producer.group}}")

什么是 Apache Camel K

GitHub: https://github.com/apache/camel-k

Apache Camel K 是基于 Apache Camel 构建,运行在 Kubernetes (或 Knative, OpenShift)上的 Serverless 架构的轻量级集成平台。

用户可以在部署好的 Camel K Platform 上立即运行 Camel DSL 编写的集成代码。

Camel K 在不脱离 Camel 项目的根本 EIP(企业集成模式,Enterprise Integration Patterns)的前提下,将集成提升到了一个新的高度。

示例:
集成代码 SampleRoute.java

import org.apache.camel.builder.RouteBuilder;
import java.util.Date;

public class SampleRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
      restConfiguration().port(8080);
      from("rest:get:event:/send-message")
          .setBody(exchange -> new Date().toString())
          .to("jms:CAMEL.JMS")
    }
}

Camel K 安装到 Kubernetes 集群后,要运行该集成代码,只需执行:

kamel run -d camel:camel-netty-http -d camel:camel-jms SampleRoute.java

Camel K 架构简介

Camel K 部署场景:

  1. 直接部署在 Kubernetes
  2. 直接部署在 OpenShift
  3. 部署在 Knative

Architectural

Camel K 相关概念

Platform

Camel K Platform 本质上是一个 Kubernetes Operator,是管理 Camel K 相关资源的工具。

Camel K Operator 的职责:

  • Kit 管理,包括构建、查询、删除等
  • Integration 管理,包括创建、删除、查询、更新

命名为 “Platform” 可能会让人误以为这是 Camel K 的 Runtime,实际上,Operator 故障后,只是无法管理 Camel K 相关资源,不会影响已在运行的 Integration。

Camel K Runtime

Java 程序,包含了 Camel 核心库、代码动态编译等模块,能够在运行时动态编译 Java 源码文件、运行 Camel 路由。

Kit

Kit 对应 Docker Image,里面包含了一个可以独立运行的 Java 程序 Camel K Runtime,是运行集成代码的镜像。

Camel K Runtime 仅包含了 Camel 的核心文件,只能使用一些基本的组件,所以需要根据集成代码的依赖构建各种 Kit。

例如:
集成代码依赖了 RocketMQ,则可以构建一个名为 kit-rocketmq ,包含 RocketMQ 相关依赖的 Kit,
作为使用了 RocketMQ 相关组件的集成代码的运行镜像。

Integration

Integration 对应 K8S 的 Deployment 或 Cron Schedule 等部署资源,部署所用镜像就是 Kit 对应的镜像。集成代码以 ConfigMap 的方式挂载到 Pod 中,被 Camel K Runtime 动态编译后加入到 CamelContext 中。

Integration 的 Pod 中只是一个普通的 Java 应用程序,实现日志采集、JVM 监控等功能的操作与其他 Java 应用大同小异。
即使 Camel K Operator 出现故障,也不会有影响已在运行的 Integration。

Camel K 在 Kubernetes 上的运行机制

Kubernetes Operators 简介

Operator 是一种在 Kubernetes 集群中打包、部署、管理应用的方法,是一个部署在 Kubernetes 集群中,使用 Kubernetes 的 API 和 kubectl 管理集群中应用的工具。

Operator

Camel K Operator

Camel K 使用基于 Operator 框架开发的 Camel K Operator 在 Kubernetes 集群上管理 Camel 基础镜像、集成等资源。
将 Camel K 安装到 Kubernetes 集群,实际上是在集群中创建了一系列 CRD(自定义资源,Custom Resources Definitions) 并启动一个 Camel K Operator。

集成代码运行机制

集成代码运行机制示意图:
kamel run

集成代码运行流程图:
Integration

通过 Camel K 提供的 CLI 工具 kamel 运行集成代码后,大致执行步骤如下:

  1. 检查现有的 Camel 基础镜像是否满足用户所需依赖(通过 kamel 命令指定的第三方依赖),不满足则通过 Maven 下载;如果满足条件的基础镜像已存在,则直接执行步骤 4。
  2. 用户指定的依赖下载完成后,构建一个新的 Camel 基础镜像。
  3. 将构建好的 Camel 基础镜像推到指定的 Docker Registry 上。
  4. Camel K Operator 分析用户通过 kamel 命令提交的集成代码文件,根据情况决定创建 Deployment、Cron Schedule、Service 等资源,设置环境变量等,并将集成代码文件通过 ConfigMap 挂载到 Pod 中。
  5. 当集成代码所在的 Pod 启动后,即 Camel K Runtime 启动,读取挂载到 Pod 中的集成代码文件(源码已被压缩处理为二进制文件,非明文),并通过 JOOR 库进行动态编译,完成后加载编译后的字节码
  6. 将路由实例添加到 CamelContext 中,启动 Camel。此时路由代码开始工作。

Camel K 实际应用情况

Camel K 已被列入 CNCF Serverless Landscape:s.cncf.io
在这里插入图片描述

由于互联网上资料较少,Camel K 目前在国内外的应用情况不是很明确。

  • 华为融合集成平台 ROMA (实现使用了 Camel)
  • 华为智慧园区解决方案(华为开源能力中心技术专家姜宁在 “2019年中国KubeCon + CloudNativeCon +开源峰会” 中提到,Camel / Camel K 的演示项目基于智慧园区项目)

本次调研目标

部署 Camel K 到 Kubernetes 集群,运行集成代码

在本地 Kubernetes 集群安装 Camel K,运行集成代码 Demo,了解部署难度、集成运行效果。

调研 Camel K 如何实现 Camel 路由可视化监控

普通的 Camel 应用可以通过 Camel JMX, Jolokia, Hawtio 实现 Camel 路由可视化监控,需要了解同样的方式能否在 Camel K 上实现。

调研 Camel K 在运维方面的支持情况

调研部署 Integration 时,资源分配、环境变量设置、Label 设置、Volumn 挂载等运维相关操作的支持情况。

如果用于生产环境,容器需要配置资源、接入日志采集等一系列运维相关操作,需要了解 Camel K 能否支持这些操作或者操作的难易程度。

Camel K Operator 不可用对业务和集群的影响

了解当 Camel K Operator 发生故障时,对正在运行的集成代码会造成什么影响。

Camel K 集成代码开发方式

和普通的 Java 项目不同,由于 Camel K 只需一个代码文件即可运行,需要寻找一种便于开发、测试集成代码的项目结构。

Camel K 优势

Camel K 特性

Serverless ,让用户集中于核心业务逻辑

用户只需专注于集成逻辑的开发,无需再考虑 Gradle 脚本编写、SpringBoot 版本选择等琐碎的事情。

充分利用 Kubernetes 的特性

故障迁移、资源调度、资源隔离……

自动选择合适的资源

Camel K 能够根据运行的集成代码选择合适的 Kubernetes 资源,例如:

  • 当集成代码中的 timer 周期不小于 60s 的时候,Camel K 会部署一个 Cron schedule,而不是一直运行一个 Pod
  • 自动创建所需资源,例如:检测到集成代码包含 HTTP 消费者时,会自动暴露端口并创建对应的 Service
  • ……

与 Camel SpringBoot 对比

Camel KCamel SpringBoot
项目结构主要包含集成代码文件、集成代码单元测试的 Java 工程完整的 SpringBoot Java 工程
部署流程上传集成代码文件 或 指定 URL编译、jar、(构建镜像)部署
部署时间秒级(首次构建 Kit 可能为分钟级)分钟级
启动时间秒级1 分钟左右
资源占用相对较低,可根据集成类型分配资源(普通部署、定时调度等)相对较高,持续占用

使用 Camel K 的必要性

在系统集成逻辑方面,Camel K 能做到的 Camel SpringBoot 也一定能做到。那使用 Camel K 的必要性在哪里?哪些方面更适合使用 Camel K?

Camel SpringBoot 不适合作为路由可视化配置系统的底层实现

当系统对接逻辑、开放 API 网关以可视化配置的方式进行时,路由的底层具体实现必须具备较高的灵活性。

考虑路由可视化配置系统分别使用 Camel SpringBoot 和 Camel K 作为底层实现时,实现思路与优缺点。

以 Camel SpringBoot 作为路由可视化配置系统的底层实现

以 Camel SpringBoot 作为路由可视化配置的底层实现,实现思路如下:
Visual Camel SpringBoot

由于 Camel SpringBoot 的实例是基于建立好的 Java 工程项目部署的,要实现动态增加 Deployment 的可行性不是很高,新增路由只能选择已经部署好的 Camel SpringBoot 实例。

如果现有的 Camel SpringBoot 实例都没能满足路由所需依赖,则需要调整项目,重新构建,部署。

动态调整路由的时候,需要停止正在运行的 CamelContext,即当前上下文中的所有路由都会停止。

如果新增的路由启动时抛出异常,会导致 CamelContext 无法启动,即集成应用处于不可用的状态,影响业务正常运行。

以 Camel K 作为路由可视化配置系统的底层实现

以 Camel K 作为路由可视化配置的底层实现,实现思路如下:

VIsual Camel K

Serverless 架构的 Camel K 具有非常高的灵活性,能够根据需要构建包含各种指定依赖的 Kit,动态创建 Deployment 部署集成代码。

如果 Camel K 中现有的 Kit 不满足集成代码所需依赖,无需像普通的 Java 工程一样手动调整依赖,只需在向 Camel K 提交集成代码时声明所需依赖,Camel K 会自动构建包含所声明的依赖的 Kit,作为集成代码运行的镜像。

如果在已部署的 Integration 中增加或调整路由,基于 K8S 滚动升级的方式,可以在新的 Pod 启动后再停止原有的 Pod,这么做的好处有:

  • 尽量减少集成业务停机时间
  • 如果升级失败,不会影响原有的集成业务运行

在对接的系统较多的场景下,Camel K 优于 Camel SpringBoot

不同业务系统的集成逻辑相互独立,要求互不干扰。

基于 Camel SpringBoot 集成

如果将多个系统的集成逻辑放在同一个 SpringBoot 项目中,当需要对其中一条逻辑进行微调时,重新部署会导致其他集成逻辑也处于不可用的状态。

需要对接的 n 个系统,为满足集成逻辑互不影响等独立性要求,对应需要建立 n 个 Camel SpringBoot 项目。
且随着项目推进,后期需要对接的系统数量会逐步增加,即 Camel SpringBoot 的工程数量也要随之增加。工程项目过多,不易于管理。

基于 Camel K 集成

基于 Camel K 进行集成,可以将每个系统的集成逻辑作为集成项目中的一个模块,每个模块将该模块需要部署的集成文件列在一个文件中,执行 kamel 命令的时候通过读取文件部署某一模块下的集成代码。

Camel K 目前存在的问题

Camel K 目前只提供了 CLI 命令 kamel 管理资源

目前 Camel K 的管理基于 CLI 命令 kamel 进行,而且要求运行 kamel 的用户拥有 Camel K 所需的 K8S 相关权限。
对于普通开发人员,一般情况下接触不到有权管理 Kubernetes 集群的服务器。
因此,需要将 kamel 命令封装(例如 Jenkins),提供 kamel 部署功能给开发人员。

截至调研报告编写时间,Camel K 1.0.0 尚未正式 Release

截至本报告编写时间,最新的 Release 版本为 1.0.0-RC2,该版本在 Docker Registry 的鉴权方面存在小问题,master 分支已修复,但尚未 Release。

Camel K 调研实践

以下实践过程中,如无特殊说明,均使用以下集成代码文件
SampleMQHttp.java

import org.apache.camel.builder.RouteBuilder;

public class SampleMQHttp extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("rocketmq:camel_k_from?namesrvAddr=rpi3.lo:9876&consumerGroup=camel_k_route_consumer")
                .removeHeaders("*")
                .setHeader("User-Agent", () -> "Camel K Sample Netty Http")
                .setHeader("CamelHttpMethod", () -> "GET")
                .to("https://api.github.com/emojis")
                .to("rocketmq:camel_k_to?namesrvAddr=rpi3.lo:9876&producerGroup=camel_k_route_producer");
    }
}

监听 RocketMQ 的 Topic camel_k_from,请求接口并将返回数据发送到 RocketMQ 的 Topic camel_k_to

在本地 Kubernetes 集群安装部署 Camel K (Operator),利用 Camel K 提供的 CLI 命令 kamel 运行集成代码

使用 Camel K 提供的 CLI 工具 kamel 安装 Camel K 到 Kubernetes 集群中,安装后 Rancher 中可以看到 Camel K Operator 正在运行:
rancher-camel-k-operator

使用 kamel 运行集成代码:

rancher-sample-mq-http

向 RocketMQ 的 Topic camel_k_from 发送一条消息,查看 Topic camel_k_to 的消息列表:

rocketmq-console

实现 Camel 可视化监控

使用以下命令运行 Integration:

kamel run SampleMQHttp.java --compression \
-d camel:camel-rocketmq \
-d camel:camel-http \
-d camel:camel-management \
-e MY_CAMEL_K_SAMPLE_ENV=hello,camel-k \
-e JOLOKIA_DISCOVERY_URL='${ip}' \
-t jolokia.enabled=true \
-t jolokia.discovery-enabled=true \
-t jolokia.user=jolokia \
-t jolokia.password=jolokia \
-n camel-k

启动一个 Hawtio ,可视化效果如下:
hawtio

Jolokia 支持基于 UDP 广播的自动发现机制,无需手动配置连接。

Camel K 在运维方面的支持

官方文档:https://camel.apache.org/camel-k/latest/traits/traits.html

使用以下命令运行 Integration:

kamel run SampleMQHttp.java --compression \
-d camel:camel-rocketmq \
-d camel:camel-http \
-d camel:camel-management \
-e MY_CAMEL_K_SAMPLE_ENV=hello,camel-k \
--label my.camel-k.sample=camel-k-sample \
-t container.limit-cpu=1000m \
-t container.limit-memory=500Mi \
--configmap=application-config \
-v camel-k-pvc:/var/log/camel \
-n camel-k

以上命令实现:

  • 设置环境变量 MY_CAMEL_K_SAMPLE_ENV 为 hello,camel-k
  • 设置 label my.camel-k.sample 为 camel-k-sample
  • 限制 cpu 1000m
  • 限制内存 500Mi
  • 挂载 PVC camel-k-pvc ,挂载路径为 /var/log/camel

Rancher 中可以看到,设置环境变量、挂载等操作均能实现:
resources

env
pvc

Camel K Operator 不可用对集成的影响

直接删除 Deployment 或通过 kamel uninstall 删除 Camel K Operator,已在运行的集成不会受到影响,只是暂时无法通过 kamel 命令管理 Camel K 相关资源。

Camel K 调研结论

  • Camel K 本质上只是提供了一个在 Kubernetes 集群上管理镜像和部署集成代码的工具,集成代码的运行的方式仍然是一个包含了 Camel 相关依赖的 Java 应用;
  • Camel K 技术较新,互联网上尚未找到明确的应用案例;
  • Camel K 提供了基于 Jolokia 的方式实现 Camel JMX 监控;
  • Camel K 对 Kubernetes 相关操作 (例如:环境变量设置、Label 设置、资源限制、Volumn 挂载、存活/就绪检查等)的支持比较完善;
  • Camel K Operator 不可用不会影响正在运行的集成,只是无法通过管理 kamel 命令管理集群上 Camel K 相关资源。

相关资料

Logo

开源、云原生的融合云平台

更多推荐