【问题标题】:Kubernetes Ingress gce expose two basic Sping Boot servicesKubernetes Ingress gke 暴露了两个基本的 Spring Boot 服务
【发布时间】:2021-08-18 22:43:13
【问题描述】:

我正在尝试使用一个必须根据路径重定向流量的 Ingress 部署两个非常基本的服务(Spring Boot)。非常基本的 Ingress 使用示例,但经过数小时后我无法理解为什么此配置不起作用。

第一个控制器,暴露在 8095 端口:

@RestController
public class MainController {

    private Logger logger = LoggerFactory.getLogger(MainController.class);

    @GetMapping({"/", ""})
    public String getDefault(HttpServletRequest request) {
        logger.debug("URL: ", makeUrl(request));
        return "Root reached: " + makeUrl(request);
    }

    @GetMapping("/foo")
    public String getSubPath(HttpServletRequest request){
        logger.debug("URL: ", makeUrl(request));
        return "First sub path reached: " + makeUrl(request);
    }

    @GetMapping("/foo/test")
    public String getSubSubPath(HttpServletRequest request){
        logger.debug("URL: ", makeUrl(request));
        return "First sub sub path reached: " + makeUrl(request);
    }

    @GetMapping("/foo/health/check")
    public String getHealthCheck(HttpServletRequest request) {
        return "Health check passed: " + makeUrl(request);
    }

    private String makeUrl(HttpServletRequest request) {
        return request.getRequestURL().toString() + "?" + request.getQueryString();
    }

}

第二个控制器,暴露在 8080 端口:

@RestController
public class MainController {

    private Logger logger = LoggerFactory.getLogger(MainController.class);

    @GetMapping({"/bar/", "/bar"})
    public String getDefault(HttpServletRequest request) {
        logger.debug("URL: ", makeUrl(request));
        return "Root reached: " + makeUrl(request);
    }

    @GetMapping("/bar/test")
    public String getSubPath(HttpServletRequest request){
        logger.debug("URL: ", makeUrl(request));
        return "First sub path reached: " + makeUrl(request);
    }

    @GetMapping("/bar/test/subsubpath")
    public String getSubSubPath(HttpServletRequest request){
        logger.debug("URL: ", makeUrl(request));
        return "First sub sub path reached: " + makeUrl(request);
    }

    @GetMapping("/bar/health/check")
    public String getHealthCheck(HttpServletRequest request) {
        return "Health check 2 passed: " + makeUrl(request);
    }

    private String makeUrl(HttpServletRequest request) {
        return request.getRequestURL().toString() + "?" + request.getQueryString();
    }

}

我们可以看到控制器的端点只是打印一些消息和 URL,只是为了知道它们是从存在 Ingress 的集群外部到达的。

kubernetes 的部署文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prova1-deployment
spec:
  selector:
    matchLabels:
      app: deploy1
  replicas: 1
  template:
    metadata:
      labels:
        app: deploy1
    spec:
      imagePullSecrets:
        - name: gitlab-registry-prova
      containers:
        - name: prova1-deploy
          image: "registry.gitlab.com/giuxg97/reep/test1-deploy"
          ports:
            - containerPort: 8095
---
apiVersion: v1
kind: Service
metadata:
  name: prova1-service
spec:
  selector:
    app: deploy1
  ports:
    - protocol: TCP
      port: 60000
      targetPort: 8095
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prova2-deployment
spec:
  selector:
    matchLabels:
      app: deploy2
  replicas: 1
  template:
    metadata:
      labels:
        app: deploy2
    spec:
      imagePullSecrets:
        - name: gitlab-registry-prova
      containers:
        - name: prova2-deploy
          image: "registry.gitlab.com/giuxg97/reep/test2-deploy"
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: prova2-service
spec:
  selector:
    app: deploy2
  ports:
    - protocol: TCP
      port: 8090
      targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    # If the class annotation is not specified it defaults to "gce".
    kubernetes.io/ingress.class: "gce"
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: prova1-service
                port:
                  number: 60000
          - path: /bar
            pathType: Prefix
            backend:
              service:
                name: prova2-service
                port:
                  number: 8090

这些图像是从我在 gitlab 上的私有容器注册表中获取的,我可以从部署后的 pod 日志中看到它们的工作原理。

现在的情况是这样的:

  • 如果我转到 IP_INGRESS/,它会将我重定向到正确的页面,并显示“已到达根目录:...”,但如果我转到 IP_INGRESS/foo,则会收到错误“响应 404(后端未找到),服务规则对于路径不存在”,这似乎是当 Ingress 找不到路径时抛出的错误消息(即,如果我转到 IP_INGRESS/test1234,我会得到相同的错误)
  • 如果我转到 IP_INGRESS/bar,我会收到另一条错误消息“错误:服务器错误 服务器遇到临时错误,无法完成您的请求。 请在 30 秒后重试。”并且 pod 没有新日志。

所以似乎唯一可以达到的服务是第一个服务,但在这种情况下我也看不到子路径,但我不知道为什么在阅读了更多文档之后..

我希望你能帮助我!提前谢谢你

【问题讨论】:

    标签: spring-boot kubernetes google-kubernetes-engine gke-networking


    【解决方案1】:

    您好,欢迎来到 Stackoverflow。

    第一期 -

    您的入口定义创建了将流量从 {path} 代理到 {backend.serviceName}{path} 的规则。 找不到路径的可能原因之一是 /foo 被代理到 app-service: 60000/foo 但您打算在“/”根目录提供流量。

    尝试将此注释添加到您的入口资源:

    nginx.ingress.kubernetes.io/rewrite-target: /
    

    来源:https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite

    如果这不能解决问题,则问题可能出在您的“/foo”处理程序方法和 Spring 框架中的其他子路径中。

    关于第二期 -

    使用 Curl 命令 (Curl -D- -s -o/dev/null <<url>>) 检查您是否能够在内部使用后端的节点 ip(不通过 Ingress)访问特定的 URL(在那里您会收到错误的响应)。

    如果您无法在内部访问该 URL,则问题再次出在 Spring 框架中的映射配置上。

    如果您能够在内部访问该 URL,请检查您在部署文件中为 kubernetes 创建的服务。 您也可以尝试更改问题部署的部署端口和服务端口。

    有关 GKE 部署文件配置的详细说明,请参阅此处 -

    https://spring-gcp.saturnism.me/deployment/kubernetes/load-balancing/external-load-balancing#ingress-yaml

    【讨论】:

      猜你喜欢
      • 2021-08-13
      • 2021-07-16
      • 2019-02-24
      • 1970-01-01
      • 2016-03-25
      • 2019-06-20
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多