Apinto Ingress Controller发布

前言

通过开源网关团队的努力,Apinto Ingress Controller将在3月下旬正式推出。

在此之前,Apinto更新配置只能通过Open API的方式更新,且只支持宿主机部署、容器部署,更新配置也相对比较麻烦。

因此,Apinto Ingress Controller的推出意味着我们可以将Apinto部署在Kubernetes中,并且通过配置文件的形式实时更新。

设计

虽然原生 ingress controller 支持在 yaml 中 annotation 定义脚本片段,但更多是为了支持高级功能而实现的一个临时方案,一方面大量的annotation脚本不好管理,不好维护,另一方面,对特性的支持也不太友好。

而Apinto有路由、服务、负载、鉴权、插件等多种类型的资源,需要有更加灵活的方式去定义资源。因此我们选择了编写Kubernetes CRD文件的方式去定义Apinto的资源。

下面为Apinto Router CRD的简单定义:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: apintorouters.apinto.com
spec:
  group: apinto.com
  scope: Namespaced
  names:
    plural: apintorouters
    singular: apintorouter
    kind: ApintoRouter
    shortNames:
      - ar
      - router
  versions:
    - name: v1beta
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required: ["name", "listen", "driver", "target", "rules"]
              properties:
                name:
                  type: string
                  minLength: 1
                driver:
                  type: string
                  enum: ["http"]
                listen:
                  type: integer
                  minimum: 1
                  maximum: 65535
                target:
                  type: string
                  pattern: '\w+(@service)$'
                method:
                  type: array
                  items:
                    type: string
                    enum: ["*", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"]
                host:
                  type: array
                  items:
                    type: string
                    pattern: '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?'
                protocol:
                  type: string
                  enum: ["http","https"]
                cert:
                  type: array
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                      crt:
                        type: string
                        minLength: 1
                rules:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    properties:
                      location:
                        type: string
                        minLength: 1
                      header:
                        type: object
                        x-kubernetes-preserve-unknown-fields: true
                      query:
                        type: object
                        x-kubernetes-preserve-unknown-fields: true
                plugins:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true

架构设计如下:

用户提交YAML文件时,会触发ValidatingWebhook操作,Kubernetes此时会回调定义好的Admission Server地址,Apinto Client将YAML文件配置转换成Apinto Gateway的可读配置,Apinto Gateway会校验配置信息的完整性和可靠性,校验完成后,将结果依次返回,最后返回操作结果给用户。

开始使用

自定义资源的配置顺序与apinto一致,均有依赖关系。

以配置路由以及服务为例:

服务 service.yml

apiVersion: apinto.com/v1beta
kind: ApintoService
metadata:
  name: demo-anonymous
spec:
  name: demo-anonymous
  driver: http
  desc: "示例服务"
  timeout: 30000
  anonymous:
    type: round-robin
    config: "http://demo-apinto.eolink.com:8280" #该接口返回http调用信息
  retry: 2
  rewrite_url: /

路由 router.yml

apiVersion: apinto.com/v1beta
kind: ApintoRouter
metadata:
  name: apinto.router
spec:
  name: apinto.router# 路由名称
  listen: 8080    # 监听端口
  driver: http # 驱动
  protocol: http
  method:
    - GET
  rules:      # 规则列表
    - location: "/demo"  # 匹配路径
  target: demo-anonymous@service    # 目标服务ID,格式为:{服务名称}@service

创建服务和路由

kubectl create -f service.yml
kubectl create -f router.yml

创建完服务以及路由之后,调用apinto暴露到集群外的服务来查看是否存在该路由

curl -X GET 'http://{node_ip}:{admin_port}/api/router/apinto.router'

返回

{
    "create": "2022-03-23 06:14:48",
    "driver": "http",
    "id": "apinto.router@router",
    "listen": 8080,
    "method": ["GET"],
    "name": "apinto.router",
    "profession": "router",
    "protocol": "http",
    "rules": [{
        "location": "/demo"
    }],
    "target": "demo-anonymous@service",
    "update": "2022-03-23 06:14:48"
}

通过调用apinto暴露到集群外的服务来请求该路由

curl -X GET 'http://{node_ip}:{http_port}/demo'

返回

{
    "body": "",
    "header": {
        "Accept": ["*/*"],
        "User-Agent": ["curl/7.75.0"],
        "X-Forwarded-For": ["10.24.1.1,10.24.1.1"]
    },
    "host": "192.2.9.43:31080",  
    "method": "GET",
    "path": "/demo",
    "remote_addr": "192.4.5.22:19091", 
    "url": "/demo"
}

备注:以上的ip数据非原始数据

使用示例点此进行跳转。

写在最后

Apinto是一个基于 Golang 开发的微服务网关,能够实现高性能 HTTP API 转发、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统可以自行扩展,能够快速帮助企业进行 API 服务治理、提高 API 服务的稳定性和安全性。

目前Apinto及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。

这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

  • 查找bugs,取得性能上的提升
  • 帮助完善文档,提供用户操作体验
  • 提交你们的issue,让我们知道您的奇思妙想
  • 参与自定义插件的开发,丰富apinto的能力

期待各位的参与,一起让这个项目变得更好。

联系我们