如何与 Dapr 集成打造 Apache APISIX 网关控制器

张善友

更新时间 11/18/2021

本质上,Apache APISIX 控制器将配置相同标准 Dapr annotations 以注入 daprd sidecar。通过公开这个 sidecar,将允许外部应用程序与集群中启用 Dapr 的应用程序进行通信。

下图为实际项目中的架构流程:

总体架构流程

基本项目概览

Apache APISIX Ingress

在 K8s 生态中,Ingress 作为表示 K8s 流量入口的一种资源,想要让其生效,就需要有一个 Ingress Controller 去监听 K8s 中的 Ingress 资源,并对这些资源进行相应规则的解析和实际承载流量。在当下趋势中,像 Kubernetes Ingress Nginx 就是使用最广泛的 Ingress Controller 实现。

而 APISIX Ingress 则是另一种 Ingress Controller 的实现。跟 Kubernetes Ingress Nginx 的区别主要在于 APISIX Ingress 是以 Apache APISIX 作为实际承载业务流量的数据面。如下图所示,当用户请求到具体的某一个服务/API/网页时,通过外部代理将整个业务流量/用户请求传输到 K8s 集群,然后经过 APISIX Ingress 进行后续处理。

APISIX Ingress

从上图可以看到,APISIX Ingress 分成了两部分。一部分是 APISIX Ingress Controller,作为控制面它将完成配置管理与分发。另一部分 APISIX Proxy Pod 负责承载业务流量,它是通过 CRD(Custom Resource Definitions) 的方式实现的。Apache APISIX Ingress 除了支持自定义资源外,还支持原生的 K8s Ingress 资源。

点击查看更多详情

Dapr

Dapr 是一个可移植、事件驱动的运行时。它使开发人员简单地去构建运行在云和 edge 上弹性、无状态和有状态的应用,并且包含多种语言和开发人员框架。

Dapr 生态图

今天,我们正经历一波云应用浪潮。开发人员熟悉 web+ 数据库应用程序架构(例如经典的 3 层设计),但不熟悉本质上是分布式的微服务应用程序架构。开发人员希望专注于业务逻辑,同时依靠平台为他们的应用程序注入伸缩性、弹性、可维护性、弹性和其他本地云架构的属性。

这就是 Dapr 的用武之地。

Dapr 可以将构建微服务应用程序的最佳实践编入开放、独立的构建块中,使用户能够使用自己选择的语言和框架构建可移植的应用程序。每个构建块都是完全独立,并可在应用程序中使用其中的一个或多个。

此外,Dapr 与平台无关,这意味着用户可以在任何 Kubernetes 集群和其他与 Dapr 集成的托管环境本地运行应用程序。

点击查看更多详情

实践开始

环境准备

  • Kubernetes 1.19+ 集群,集群上已经配置了 Dapr
  • 安装了 Helm CLI 3x
  • Kubectl CLI 已安装并配置为访问集群
  • 可选:用于创建自签名证书的 OpenSSL
  • Apache APISIX 的 Helm Chart 版本为 0.7.2+

步骤一:Apache APISIX Helm 配置

通过运行以下命令为 Apache APISIX 控制器添加最新的 helm chart repo:

1helm repo add apisix https://charts.apiseven.com
2helm repo update

步骤二:创建 Apache APISIX Ingerss 命名空间

确保当前 kubectl 上下文指向正确的 Kubernetes 集群,然后运行以下命令:

1kubectl create namespace ingress-apisix

步骤三:安装支持 Dapr 的 APISIX 控制器

使用以下内容创建一个名为 dapr-annotations.yaml 的文件,以在 Apache APISIX Proxy Pod 上设置注释。

1apisix:
2  podAnnotations:
3    dapr.io/enabled: "true"
4    dapr.io/app-id: " apisix-gateway"
5dapr.io/app-port: "9080"
6dapr.io/enable-metrics: "true"
7dapr.io/metrics-port: "9099"
8dapr.io/sidecar-listen-addresses: 0.0.0.0
9dapr.io/config: ingress-apisix-config

注意:上面的 app-port 是告诉 daprd sidecar Proxy 在监听哪个端口。有关受支持的注释完整列表,可参考 Dapr Kubernetes pod 注释规范

下面以我个人在 AKS 上安装的示例 dapr-annotations.yaml 进行展示。

1 apisix:
2  podAnnotations:
3    dapr.io/app-id: apisix-gateway
4    dapr.io/app-port: '9080'
5    dapr.io/enable-metrics: 'true'
6    dapr.io/enabled: 'true'
7    dapr.io/metrics-port: '9099'
8dapr.io/sidecar-listen-addresses: 0.0.0.0
9dapr.io/config: ingress-apisix-config
10
11gateway:
12  type: LoadBalancer
13
14ingress-controller:
15  enabled: true
16
17dashboard:
18  enabled: true

接下来运行以下命令(引用上述文件):

1helm install apisix apisix/apisix -f dapr-annotations.yaml -n ingress-apisix

步骤四:创建 Apache APISIX 的 Dapr Sidecar 资源

首先,配置 Apache APISIX upstream-apisix-dapr。

配置上游业务

在这里主机名填写:apisix-gateway-dapr,端口号填写 3500。

1{
2  "nodes": [
3    {
4      "host": "apisix-gateway-dapr",
5      "port": 3500,
6      "weight": 1
7    }
8  ],
9  "retries": 1,
10  "timeout": {
11    "connect": 6,
12    "read": 6,
13    "send": 6
14  },
15  "type": "roundrobin",
16  "scheme": "http",
17  "pass_host": "pass",
18  "name": "apisix-dapr"
19}

然后配置 Apache APISIX 服务 apisix-gateway-dapr,上游服务选择 apisix-dapr。

配置服务

1{
2  "name": "apisix-gateway-dapr",
3  "upstream_id": "376187148778341098"
4}

步骤五:部署测试示例项目

HTTPBin 是以 Python+Flask 写的一款工具,这款工具涵盖了各类 HTTP 场景,且每个接口都有返回。接下来,我们使用 kennethreitz/httpbin 作为示例项目进行演示。

1kubectl apply -f 01.namespace.yaml
2kubectl apply -f 02.deployment.yaml
3kubectl apply -f 03.svc.yaml

项目配置

上图为假设有一个使用 Dapr app-id kennethreitz-httpbin 运行的微服务。

路径匹配改写

这里补充一下关于路径匹配的相关设置。比如请求网关是 /httpbin/,后端接收路径应该是 /,中间的 httpbin 只充当服务名的标识。

填写释义

在支持命名空间的托管平台上,Dapr 应用 ID 是符合有效的 FQDN 格式,其中包括目标名称空间。例如,以下字符串包含应用 ID (svc-kennethreitz-httpbin) 以及应用运行在命名空间(kind-test)。

最后可以通过访问:http://20.195.90.43/httpbin/get 来查看代理是否成功。

检查是否代理成功

额外补充说明

当然,在进行部署的过程中,也可以在 Kubernetes 中使用 Apache APISIX 官方 Helm 仓库直接部署 Apache APISIX 和 APISIX Ingress Controller。这样可以直接将 Apache APISIX 作为网关,进行 APISIX Ingress Controller 的数据面来承载业务流量。

最后将 Dapr 通过 Sidecar annotations 注入到 Apache APISIX Proxy Pod,通过服务调用模块来调用集群中的微服务,实现完整流程部署。

删除 Apache APISIX 控制器

如项目结束,想要删除 Apache APISIX 控制器,可按下方命令操作(记得不要忘记删除之前创建的命名空间 ingress-apisix)。

1helm delete apisix -n ingress-apisix