具有多个后端服务的 GKE Ingress returns 404

GKE Ingress with Multiple Backend Services returns 404

我正在尝试创建一个基于路径指向两个不同后端服务的 GKE Ingress。我看过一些帖子解释说这只能通过 nginx Ingress 实现,因为 gke ingress 不支持 rewrite-target。然而,这份 Google 文档 GKE Ingresss - Multiple backend services 似乎暗示并非如此。我已经按照文档中的步骤进行操作,但没有取得任何成功。仅返回 / 路径前缀上可用的服务。任何其他路径前缀,例如 /v2、returns a 404 Not found.

我的设置详情如下。这里是否有一个明显的错误——Google 文档是否不正确,这只能使用 nginx ingress?

-- Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: app-static-ip
    networking.gke.io/managed-certificates: app-managed-cert
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-2-service
            port:
              number: 8080

-- Service 1
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 5000

-- Service 2
apiVersion: v1
kind: Service
metadata:
  name: api-2-service
  labels:
    app: api-2
spec:
  type: NodePort
  selector:
    app: api-2
  ports:
  - port: 8080
    targetPort: 5000

GCP Ingress 支持多路径。这在 Setting up HTTP(S) Load Balancing with Ingress 中也有很好的描述。对于我的测试,我同时使用了 Hello-world v1 和 v2.

有 3 个可能的问题。

  • 问题与打开的容器端口有关。您可以使用 netstat 检查它:
$ kk exec -ti first-55bb869fb8-76nvq -c container -- bin/sh
/ # netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::8080                 :::*                    LISTEN      1/hello-app
  • 问题也可能是由 Firewall 配置引起的。确保您有正确的设置。 (一般来说,在新集群中我不需要添加任何东西,但如果你有更多的东西并且有特定的防火墙配置,它可能会阻止)。

  • portcontainerPorttargetPort 之间的配置错误。

下面我的例子:

第一次部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first
  labels:
    app: api
spec:
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: container
          image: gcr.io/google-samples/hello-app:1.0
          ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 5000
    targetPort: 8080

第二次部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second
  labels:
    app: api-2
spec:
  selector:
    matchLabels:
      app: api-2
  template:
    metadata:
      labels:
        app: api-2
    spec:
      containers:
        - name: container
          image: gcr.io/google-samples/hello-app:2.0
          ports:
          - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: api-2-service
  labels:
    app: api-2
spec:
  type: NodePort
  selector:
    app: api-2
  ports:
  - port: 6000
    targetPort: 8080

入口

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 5000
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-2-service
            port:
              number: 6000

输出:

$ curl 35.190.XX.249
Hello, world!
Version: 1.0.0
Hostname: first-55bb869fb8-76nvq
$ curl 35.190.XX.249/v2
Hello, world!
Version: 2.0.0
Hostname: second-d7d87c6d8-zv9jr

请记住,您也可以通过添加特定注释在 GKE 上使用 Nginx Ingress

kubernetes.io/ingress.class: "nginx" 

人们在 GKE 上使用 nginx ingress 的主要原因是使用 rewrite 注释和使用 ClusterIPNodePort 作为服务类型的可能性,其中 GCP ingress 仅允许 NodePort 服务类型。

您可以在 GKE Ingress for HTTP(S) Load Balancing

中找到更多信息