1. 概述

Kubernetes (K8s) 是自动化软件开发与部署的编排工具,已成为当今API托管的热门选择,无论是本地部署还是云服务(如Google GKS或Amazon EKS)。另一方面,Spring已成为最流行的Java框架之一。

本教程将演示如何使用Kong Ingress Controller (KIC)在Kubernetes上部署Spring Boot应用,并构建安全防护环境。我们还将通过实现简单的限流器展示KIC的高级功能——全程无需修改应用代码。

2. 增强安全性与访问控制

现代应用部署(尤其是API)面临诸多挑战:

  • 隐私法规(如GDPR)
  • 安全威胁(DDoS攻击)
  • 使用追踪(如API配额和速率限制)

应对这些挑战需要多层防护:防火墙、反向代理、限流器等。虽然K8s环境已提供基础防护,但仍需额外措施保障应用安全,其中关键一步就是部署Ingress Controller并配置访问规则。

Ingress是管理K8s集群外部访问的对象,通过暴露HTTP/HTTPS路由并执行访问规则来控制应用访问。要暴露应用,需定义Ingress规则并使用Ingress Controller(专用反向代理和负载均衡器)。主流Ingress Controller由第三方提供,功能各异,本文使用的Kong Ingress Controller就是典型代表。

3. 环境搭建

为演示KIC与Spring Boot的集成,需准备K8s集群环境:

  • 完整K8s集群(本地或云服务)
  • 或使用Minikube开发示例应用

启动K8s环境后,在集群中部署Kong Ingress Controller(参考官方指南)。Kong会暴露外部IP,建议将其保存为环境变量:

export PROXY_IP=$(minikube service -n kong kong-proxy --url | head -1)

验证KIC是否正常运行:

curl -i $PROXY_IP

预期返回404错误(因尚未部署应用),响应应提示无匹配路由。接下来创建示例应用,确保已安装Docker(用于构建容器镜像)。

4. 创建Spring Boot示例应用

生成带HTTP服务的Spring Boot应用:

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project | tar -xzvf -

⚠️ 如需指定Java版本(如Java 11):

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project -d javaVersion=11 | tar -xzvf -

关键依赖说明:

  • webflux:基于Spring WebFlux和Netty的响应式Web框架
  • actuator:Spring监控组件,自带暴露的Web资源(正好用于测试)

构建应用:

./mvnw install

本地测试运行:

java -jar target/*.jar

在新终端验证健康检查接口:

curl -i http://localhost:8080/actuator/health

预期响应:

HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v3+json
Content-Length: 15

{"status":"UP"}

5. 构建容器镜像

部署到K8s需创建容器镜像:

  • 生产环境:推送至DockerHub或私有镜像仓库
  • Minikube环境:直接使用Minikube的Docker守护进程

配置Docker环境:

eval $(minikube docker-env)

构建应用镜像:

./mvnw spring-boot:build-image

6. 部署应用到K8s

需创建三类K8s对象:

  1. 应用部署对象(Deployment)
  2. 集群IP服务(Service)
  3. Ingress路由规则

6.1 创建Deployment

serviceDeployment.yaml内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: demo
  name: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo
    spec:
      containers:
      - image: docker.io/library/demo:0.0.1-SNAPSHOT
        name: demo
        resources: {}
        imagePullPolicy: Never  # 关键:禁用镜像拉取
status: {}

✅ 部署命令:

kubectl apply -f serviceDeployment.yaml

成功提示:

deployment.apps/demo created

6.2 创建Service

clusterIp.yaml内容:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: demo
  name: demo
spec:
  ports:
  - name: 8080-8080
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: demo  # 匹配Deployment标签
  type: ClusterIP
status:
  loadBalancer: {}

部署命令:

kubectl apply -f clusterIp.yaml

6.3 创建Ingress规则

ingress-rule.yaml内容:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: kong
  rules:
  - http:
      paths:
      - path: /actuator/health
        pathType: ImplementationSpecific
        backend:
          service:
            name: demo
            port:
              number: 8080

部署命令:

kubectl apply -f ingress-rule.yaml

6.4 验证外部访问

通过Kong代理IP访问:

curl -i $PROXY_IP/actuator/health

预期响应(含Kong注入的头部):

HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v3+json
Content-Length: 49
Connection: keep-alive
X-Kong-Upstream-Latency: 325
X-Kong-Proxy-Latency: 1
Via: kong/3.0.0

7. 演示限流功能

KIC的强大之处在于其插件系统:认证、负载均衡、监控、限流等。这里实现每分钟5次请求的限流规则。

创建KongClusterPlugin对象(rate-limiter.yaml):

apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
  name: global-rate-limit
  annotations:
    kubernetes.io/ingress.class: kong
  labels:
    global: true
config:
  minute: 5  # 每分钟限制5次
  policy: local
plugin: rate-limiting

应用配置:

kubectl apply -f rate-limiter.yaml

7.1 限流测试

快速连续执行6次请求:

for i in {1..6}; do curl -i $PROXY_IP/actuator/health; done

前5次返回200,第6次触发429:

HTTP/1.1 429 Too Many Requests
Date: Sun, 06 Nov 2022 19:33:36 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
RateLimit-Reset: 24
Retry-After: 24
X-RateLimit-Remaining-Minute: 0
X-RateLimit-Limit-Minute: 5
RateLimit-Remaining: 0
RateLimit-Limit: 5
Content-Length: 41
X-Kong-Response-Latency: 0
Server: kong/3.0.0

{
  "message":"API rate limit exceeded"
}

响应头部清晰展示限流状态,客户端可根据Retry-After调整重试策略。

8. 清理资源

按LIFO顺序删除资源:

kubectl delete -f rate-limiter.yaml
kubectl delete -f ingress-rule.yaml
kubectl delete -f clusterIp.yaml
kubectl delete -f serviceDeployment.yaml

停止Minikube集群:

minikube stop

9. 总结

本文演示了如何使用Kong Ingress Controller管理K8s集群中Spring Boot应用的访问控制。关键收获:

  • ✅ 通过KIC实现外部访问路由
  • ✅ 无代码修改添加限流防护
  • ✅ 利用K8s原生对象声明式配置

完整源码参考GitHub仓库


原始标题:Kong Ingress Controller with Spring Boot