无法访问 Spring 通过 AWS 上的 Kubernetes 集群 运行 上的 nginx 入口控制器公开的引导微服务

Unable to access Spring Boot microservice exposed via nginx ingress controller on Kubernetes cluster running on AWS

我在 AWS 上使用 kube-up.sh 脚本在本演练之后启动了一个 3 节点 Kubernetes 集群(版本:1.5.8):

https://ryaneschinger.com/blog/building-a-kubernetes-cluster-on-aws/

我能够成功访问集群并查看 UI。 kubectl cluster-info 命令的输出:

我写了一个简单的Spring启动微服务:

@RestController
public class AddCustomerController {

    private static final String template = "Customer %s is added.";

    @RequestMapping("/addcustomer")
    public Message addcustomer(@RequestParam(value="name") String name) {

        //Retrieve the hostname of the "node"/"container"
        String hostname = null;
        try {
            hostname = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return new Message(ThreadLocalRandom.current().nextLong(),
                            String.format(template, name),
                            hostname);
    }
}

并在 Gradle 构建后将其打包到 Docker 容器中,并且能够在本地成功使用它。我已将图像推送到 DockerHub。

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD build/libs/*.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

现在我正在使用 Helm Charts 将此应用程序部署到 Kubernetes。

部署描述符:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: add-customer-deployment
spec:
  replicas: 3
  template:
    metadata:
      name: add-customer-microservice
      labels:
        app: add-customer
    spec:
      containers:
      - image: {{ .Values.dockerHubUsername }}/add-customer-microservice:latest
        name: add-customer-microservice
        imagePullPolicy: Always
        ports:
        - containerPort: 8080

服务描述符:

apiVersion: v1
kind: Service
metadata:
  name: add-customer-service
spec:
  selector:
    app: add-customer
  ports:
    - port: 1000
      protocol: TCP
      targetPort: 8080
      name: access-port
  type: NodePort

我对其他 3 个类似的 Spring 引导微服务执行了相同的过程。

入口描述符:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: quantiphi-poc-ingress-dns
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: crud.qdatalabs.com
      http:
        paths:
        - path: /service1
          backend:
            serviceName: add-customer-service
            servicePort: 1000
        - path: /service1/*
          backend:
            serviceName: add-customer-service
            servicePort: 1000
        - path: /service2
          backend: 
            serviceName: get-customer-service
            servicePort: 2000
        - path: /service2/*
          backend:
            serviceName: get-customer-service
            servicePort: 2000
        - path: /service3
          backend: 
            serviceName: update-customer-service
            servicePort: 3000
        - path: /service3/*
          backend:
            serviceName: update-customer-service
            servicePort: 3000
        - path: /service4
          backend: 
            serviceName: delete-customer-service
            servicePort: 4000
        - path: /service4/*
          backend:
            serviceName: delete-customer-service
            servicePort: 4000

首先,我使用 Helm Charts 在我的集群上安装了 nginx 控制器:

helm install --name my-release stable/nginx-ingress

然后我使用以下方法安装我的 Chart:

helm install folder-conataining-helm-chart/

然后我将 crud.qdatalabs.com(类型 A)的别名从 Route53 指向 Ingress 资源生成的 ELB。

URL crud.qdatalabs.com/healthz 给出 200 OK 响应

当我尝试使用 URL crud.qdatalabs.com/service1/addcustomer?name=starman

访问微服务时

我收到了 WhiteLabel 错误页面:

我想我犯了一些配置错误,但无法确定。请帮助我任何方向。我很乐意提供更多详细信息。谢谢。

正如我在 中所述,您遇到的最可能的问题是,当您使用此入口时,您附加的 URI 与直接访问(/service1/ vs /)不同,因此您的应用是丢失并且没有该 uri 的内容。

使用 Nginx Ingress Controller,您可以使用 ingress.kubernetes.io/rewrite-target: / 注释来​​缓解这种情况,并确保即使在入口路径中有子文件夹时也可以访问 /。

因此,您要么需要使用正确的重写注释,要么支持您在服务内部入口中使用的路径。