Skip to main content

Command Palette

Search for a command to run...

来自骷髅岛的 Ingress Controller:Kong

Published
3 min read

Kong,是一个在 Nginx 反向代理基础上发展而来的 API 网关产品。我之前一直在推动的 Service Mesh,主要关注的是集群(Mesh)内微服务之间的关系,而 API 网关所管理的则是微服务集群边缘,对外服务的管理。(据我观测,Istio 近期的文档已经出现了 Gateway 等说法,似乎也对这方面的问题颇有兴趣的样子)。

传统的 API:

API Gateway:

5 月 8 日,Kong 发布了 Ingress Controller,对 Kubernetes 和对 Kong 自身来说都是个有意思的事情。

首先,Ingress Controller 本来应该负责集群的对外通信,有些 Ingress Controller,例如 haproxy 和 Traefik 已经初步具备了这方面的能力。 其次,Kong 之前使用 API 调用的方式来进行管理,在 Ingress Controller 的上下文中,改用 CRD 方式进行管理,对于我等 YAML 程序员来说,无疑是个大大的利好消息。

Kong 使用插件的方式提供了一些常见功能,这些现在也可以用 CRD 方式进行使用,其中包括日志、限流、认证、鉴权几大类。

Kong 同时提供商业和社区两个版本,目前有部分插件也是商业版独占的。

今天这一篇,就会对 Kong Ingress Controller 从部署到应用的介绍。

安装

官方提供了一个简易的 Kubernetes 环境中的安装文件;另外在 Ingress Controller 出现之前,Kong 也有一个相对更丰富的 Kubernetes 下的安装文档

全部组件都运行在 kong 命名空间。

数据库

安装过程中会创建一个 Postgres 的 StatefulSet,前面提到,这一版本对 Kubernetes 集群的最低版本要求是 1.8,如果是 1.8 版本,需要将这一个 StatefulSet API 版本改为 apps/v1beta2。另外这一部分需要用 PVC 的形式给数据提供存储空间,所以集群中应该设置缺省 StorageClass。完整的 Kubernetes 安装文档中,还介绍了 Cassandra 的存储方式。

CRD

安装过程中创建了如下的自定义资源:

  • 凭据:用于身份认证。

  • 服务消费者:给不同的 API 用户提供不同的消费者身份,以便实施不同的治理方式。

  • 插件:将过去使用 HTTP API 管理的插件系统,以 CRD 的形式在 Kubernetes 环境下统一管理。

  • KongIngress:对反向代理行为本身进行定义。

服务

其中提供了两组服务:

  • kong-ingress-controller:暴露 8001 端口,用于对 Kong 进行管理。这里建议将服务类型改为 ClusterIP,而不是直接暴露于公网。

  • kong-proxy:Ingress 服务,对其承载的接口调用都从此经过,可以根据集群情况酌情使用 NodePort 或者 ClusterIP -> Ingress 的方式对外提供服务。

提供服务

安装结束后,就可以使用网关来对外提供服务了。

官方提供了一个简单的例子应用,我们当然也可以选择别的应用来试用。为他编写一个 Ingress 资源:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dummy
  annotations:
    kubernetes.io/ingress.class: nginx # 这里仍然是 nginx
spec:
  rules:
  - host: dummy.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: http-svc
          servicePort: 89

如果没有公网 Loadbalancer 条件,可以使用 /etc/hosts、dnsmasq、或者 curl host 几种方式来模拟。

ingress 资源创建成功之后,就可以使用域名来访问这一服务了。

TLS 加密

作为 Ingress Controller,添加证书提供 https 服务也是基本要求之一。这方面 Kong Ingress Controller 使用的是 tls secret 的方式:

  1. 首先获取证书,可以自行签名,或者使用已有证书文件。

  2. kubectl create secret tls rocks --key privkey.pem --cert fullchain.pem:创建一个名为 rocks 的 Secret,其中包含我们的证书和私钥。

  3. 在 Ingress 资源定义中加入下列内容,引用刚才创建的 Secret:

tls:
- hosts:
    - dummy.example.com
    secretName: rocks

这样就可以使用 https 进行访问了。

试用限流插件

前面提到,Kong Ingress Controller 使用 CRD 方式来实现插件的应用。下面我们创建一个限流插件的 CRD:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: one-per-second-ten-per-hour
config:
  hour: 10
  limit_by: ip
  second: 1

目前并没有很完善的插件 CRD 规范的文档,因此其中的具体字段需要去该插件的文档页面去查找,例如这里引用的 Ratelimit。在这一个 YAML 中我们会发现,其中并没有表明具体使用的插件以及对应的服务,通过对 controller 管理端口的 /plugins 进行查询,也会看到其中并没有定义活动的插件。

要把它应用到具体服务上,还需要修改我们要控制的 Ingress 资源,在其中加入注解,来引用这一 CRD:

kubernetes.io/ingress.class: nginx
rate-limiting.plugin.konghq.com: one-per-second-ten-per-hour

提交新的 Ingress 之后,再次访问管理端口的 plugins 路径,会得到以下响应:

{
    "total": 1,
    "data": [
        {
            "created_at": 1525966801000,
            "config": {
                "redis_database": 0,
                "policy": "cluster",
                "redis_timeout": 2000,
                "hide_client_headers": false,
                "hour": 20,
                "limit_by": "ip",
                "redis_port": 6379,
                "second": 10,
                "fault_tolerant": true
            },
            "id": "8539eb6f-5467-11e8-a92e-000d3a07d45d",
            "name": "rate-limiting",
            "enabled": true,
            "route_id": "f2961715-11fd-410a-a934-dbd6822e5fac"
        }
    ]
}

可以使用 siege 或者 curl/wrk 等其他工具来访问 API,会发现超过限度之后,服务器返回 429 的状态码:

HTTP/1.1 200 0.20 secs: 727 bytes ==> GET / HTTP/1.1 200 0.22 secs: 729 bytes ==> GET / HTTP/1.1 429 0.20 secs: 38 bytes ==> GET / HTTP/1.1 429 0.21 secs: 38 bytes ==> GET / HTTP/1.1 429 0.20 secs: 38 bytes ==> GET / HTTP/1.1 200 0.20 secs: 729 bytes ==> GET / HTTP/1.1 200 0.20 secs: 727 bytes ==> GET / HTTP/1.1 429 0.20 secs: 38 bytes ==> GET /

证明限流功能已经生效。

试用消费者

前面提到,可以使用消费者这一概念,对微服务的用户身份加以甄别,从而提供不同的管控方式。在前面的基础上,我们希望为部分用户修改一下响应内容。

首先创建一个 KongConsumer 对象:

apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: rich
username: boss

接下来,为这个用户创建凭据,凭据是需要认证的,所以还要启用一个插件:key-auth,官方文档中并没有提及这一点:

apiVersion: configuration.konghq.com/v1
kind: KongCredential
metadata:
  name: rich-login
consumerRef: rich # 如果删除这一字段,就代表面向所有消费者。
type: key-auth
config:
  key: 62eb165c070a41d5c1b58d9d3d725ca1

然后,为这个用户创建一个插件配置

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rich-response
consumerRef: rich
config:
  hour: 100
  limit_by: ip
  second: 10

最后,在 Ingress 资源中启用两个插件,分别是 key-authresponse-transformer

response-transformer.plugin.konghq.com: boss
key-auth.plugin.konghq.com: auth

重新配置 Ingress 之后,可以使用 curl 进行校验:

curl --header "apikey: aasome_key_data" -s -i https://dummy.example.com HTTP/1.1 403 Forbidden Date: Fri, 11 May 2018 04:17:57 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: kong/0.13.1

{"message":"Invalid authentication credentials"}

可以看到上面的认证没能通过。

curl --header "apikey: some_key_data" -s -i https://dummy.example.com | grep boss boss: true x-consumer-username=boss2

Key Auth 认证插件根据 APIKey 取得了用户名,并且激活了 Response Transformer 插件,在 Header 中加入了我们配置的内容。

Kong 原有的 API 在这里还是可以使用的,例如:

  1. curl http://[api-url]/plugins 查询生效插件

  2. curl http://[api-url] 返回 JSON 中的 /plugins/available_on_server 列出所有可用插件。

  3. curl ttp://[api-url]/consumers 列出所有消费者。

相关链接:

  1. https://konghq.com/

  2. https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/master/deploy/single/all-in-one-postgres.yaml

  3. https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/master/deploy/manifests/dummy-application.yaml

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts