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对象:
- 应用部署对象(Deployment)
- 集群IP服务(Service)
- 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仓库。