原创

带弹簧靴的Kong Ingress控制器

温馨提示:
本文最后更新于 2022年11月16日,已超过 20 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

1.概述

Kubernetes(K8s) 是一个自动化软件开发和部署的协调器,是当今流行的API托管选择,在本地或云服务上运行,如Google cloud Kubernetes Service(GKS)或Amazon Elastic Kubernets Service(EKS)。另一方面 Spring 已经成为最流行的Java框架之一。

在本教程中,我们将演示如何使用Kong Ingress Controller(KIC)在Kubernetes上设置受保护的环境来部署Spring Boot应用程序。我们还将通过为我们的应用程序实现一个简单的速率限制器来演示KIC的高级使用,而不需要任何编码。

2.改进的安全性和访问控制

现代应用程序部署,尤其是API,面临许多挑战,例如:隐私法(例如GPDR)、安全问题(DDOS)和使用跟踪(例如API配额和速率限制)。在这种情况下,现代应用程序和API需要额外的保护级别来应对所有这些挑战,如防火墙、反向代理、速率限制器和相关服务。尽管K8s环境保护我们的应用程序免受这些威胁,但我们仍需要采取一些措施来保护应用程序的安全。这些措施之一是部署入口控制器并设置其对应用程序的访问规则。

入口是一个对象,通过向部署的应用程序公开HTTP/HTTPS路由并对其强制执行访问规则,来管理对K8s集群和部署在其上的应用程序的外部访问。为了公开应用程序以允许外部访问,我们需要定义入口规则并使用入口控制器,这是一种专用的反向代理和负载平衡器。通常,入口控制器由第三方公司提供,功能各不相同,如 Kong入口控制器本文中使用的。

3.设置环境

为了演示Kong Ingress Controller(KIC)在Spring Boot应用程序中的使用,我们需要能够访问K8s集群,这样我们就可以使用完整的Kubernetes、本地安装或云提供,或者开发我们的示例 使用Minikube的应用程序。启动K8s环境后,我们需要部署Kong Ingress Controller 在我们的集群上.Kong公开了一个外部IP,我们需要使用它来访问我们的应用程序,因此最好使用该地址创建一个环境变量:

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

就是这样!安装了Kong Ingress控制器,我们可以通过访问该控制器来测试它是否正在运行 代理_ IP:

curl -i $PROXY_IP

响应应该是404错误,这是正确的,因为我们还没有部署任何应用程序,所以应该说没有与这些值匹配的路由。现在是创建示例应用程序的时候了,但在此之前,我们可能需要安装 Docker公司如果它不可用。为了将我们的应用程序部署到K8s,我们需要一种方法来创建容器映像,我们可以使用Docker来完成。

4.创建示例Spring Boot应用程序

现在我们需要一个Spring Boot应用程序并将其部署到K8s集群。要使用至少一个公开的web资源生成一个简单的HTTP服务器应用程序,我们可以这样做:

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

一件重要的事情是选择默认的Java版本。如果我们需要使用旧版本 java版本 需要属性:

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

在这个示例应用程序中,我们选择了 web流量, 其生成具有 Spring WebFlux和Netty。但添加了另一个重要的依赖项。致动器, 它是Spring应用程序的监控工具,已经公开了一些web资源,这正是我们需要用Kong测试的。这样,我们的应用程序已经公开了一些我们可以使用的web资源。让我们构建它:

./mvnw install

生成的jar是可执行的,因此我们可以通过运行它来测试应用程序:

java-jar目标/*.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.从应用程序生成容器图像

将应用程序部署到Kubernetes集群的过程包括创建容器映像并将其部署到集群可访问的存储库。在现实生活中,我们会将图像推送到DockerHub或我们自己的私有容器图像注册中心。但是,当我们使用Minikube时,让我们将Docker客户端环境变量指向Minikub的Docker:

$(minikube docker-env)

我们可以构建应用程序映像:

./mvnw spring-boot:build-image

6.部署应用程序

现在是在我们的K8s集群上部署应用程序的时候了。我们需要创建一些K8s对象来部署和测试我们的应用程序,所有需要的文件都可以在演示的存储库中找到:

  • 具有容器规范的应用程序的部署对象
  • 为Pod分配集群IP地址的服务定义
  • 在我们的路由中使用Kong的代理IP地址的入口规则

部署对象只需创建运行我们图像的必要pod,这是创建它的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: {}

我们指的是Minikube内部创建的图像,得到了它的全名。请注意,有必要指定 图像提取策略属性为 从不因为我们没有使用图像注册服务器,所以我们不希望K8s尝试下载图像,而是使用已经在其内部Docker存档中的图像。我们可以使用 库贝特尔:

kubectl apply -f serviceDeployment.yaml

如果部署成功,我们可以看到消息:

deployment.apps/demo created

要为我们的应用程序创建统一的IP地址,我们需要创建一个服务,该服务为其分配内部集群范围的IP地址。这是创建它的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
  type: ClusterIP
status:
  loadBalancer: {}

现在我们还可以使用 库贝特尔:

kubectl apply -f clusterIp.yaml

请注意,我们正在选择标签 演示 这指向我们部署的应用程序。为了能够从外部访问(在K8s集群之外),我们需要创建一个入口规则,在本例中,我们将其指向路径 /致动器/健康 和端口8080:

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

现在我们可以使用Kong的代理IP地址进行外部访问:

$ curl -i $PROXY_IP/actuator/health
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.演示速率限制器

我们设法在Kubernetes上部署了一个Spring Boot应用程序,并使用Kong Ingress Controller提供对它的访问。但KIC做的远不止这些:身份验证、负载平衡、监控、速率限制和其他功能。为了展示Kong的真正威力,我们将在应用程序中实现一个简单的速率限制器,将访问限制为每分钟五个请求。为此,我们需要创建一个名为 KongCluster插件在我们的K8s集群中。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
  policy: local
plugin: rate-limiting

插件配置允许我们为应用程序指定额外的访问规则,我们将访问限制为每分钟五次请求。让我们应用此配置并测试结果:

kubectl apply -f rate-limiter.yaml

为了测试它,我们只需在一分钟内重复我们之前使用的CURL命令五次以上,就会得到一个429错误:

curl -i $PROXY_IP/actuator/health
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"
}

我们可以看到响应HTTP头向客户端通知速率限制。

8.清理资源

为了清理演示,我们需要按后进先出顺序删除所有对象:

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应用程序的访问。

一如既往,可以找到源代码 在GitHub上.

正文到此结束