首页 > 解决方案 > Ingress 仅将流量路由到一个路由

问题描述

我有两个 pod,每个都有一个 LoadBalancer svc。每个服务的 IP 地址都在工作。

我的第一个服务是:

apiVersion: v1
kind: Service
metadata:
  name: hello-world-1
spec:
  type: LoadBalancer
  selector:
    greeting: hello
    version: one
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50000

我的第二项服务是:

apiVersion: v1
kind: Service
metadata:
  name: hello-world-2
spec:
  type: LoadBalancer
  selector:
    greeting: hello
    version: two
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 5000

我的入口是:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: gce
spec:
  defaultBackend:
    service:
      name: hello-world-1
      port:
        number: 60000
  rules:
  - http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: hello-world-1
            port:
              number: 60000
      - path: /v2
        pathType: ImplementationSpecific
        backend:
          service:
            name: hello-world-2
            port:
              number: 5000

只有第一条路线以这种方式工作,当我放

<MY_IP>/v2

在我得到的网址栏中

Cannot GET /v2
  

如何配置入口,以便在未指定子路径时命中 / 路由,在指定 /v2 时命中 /v2 路由?

如果我将第一条路线更改为

backend:
          service:
            name: hello-world-2
            port:
              number: 5000

并摆脱它的第二个工作。

但是如果我将路由更改为 /v2 它会停止工作吗?

***** 编辑 *****

按照本教程的ingress tut,我尝试更改 yaml,以便不同的路由位于不同的端口上,这会破坏它。有人知道为什么吗?

标签: kubernetesgoogle-kubernetes-engine

解决方案


默认情况下,当您在集群中创建入口时,GKE 会创建一个 HTTP(S) 负载均衡器并将其配置为将流量路由到您的应用程序,如以下文档 [1] 中所述。因此,您不应该将服务配置为 LoadBalancer 类型,而是需要将它们配置为 NodePort。

在这里,您可以按照与您想要完成的类似的完整实现示例进行操作:

  1. 为每个版本创建一个在指定端口中运行应用程序容器映像的清单:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  namespace: default
spec:
  selector:
    matchLabels:
      run: web1
  template:
    metadata:
      labels:
        run: web1
    spec:
      containers:
      - image: gcr.io/google-samples/hello-app:1.0
        imagePullPolicy: IfNotPresent
        name: web1
        ports:
        - containerPort: 8000
          protocol: TCP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web2
  namespace: default
spec:
  selector:
    matchLabels:
      run: web2
  template:
    metadata:
      labels:
        run: web2
    spec:
      containers:
      - image: gcr.io/google-samples/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: web2
        ports:
        - containerPort: 9000
          protocol: TCP
  1. 创建两个服务(每个版本一个)作为类型NodePort。在此步骤中非常重要的一点是,指定的targetPort应该是应用程序正在侦听的目标端口,在我的情况下,两个服务都指向端口 8080,因为我使用的是相同的应用程序但版本不同:
apiVersion: v1
kind: Service
metadata:
  name: web1
  namespace: default
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 8080
  selector:
    run: web1
  type: NodePort

---
apiVersion: v1
kind: Service
metadata:
  name: web2
  namespace: default
spec:
  ports:
  - port: 9000
    protocol: TCP
    targetPort: 8080
  selector:
    run: web2
  type: NodePort
  1. 最后,您需要使用路径规则创建入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: gce
spec:
  defaultBackend:
    service:
      name: web1
      port:
        number: 8000
  rules:
  - http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: web1
            port:
              number: 8000
      - path: /v2
        pathType: ImplementationSpecific
        backend:
          service:
            name: web2
            port:
              number: 9000

如果您正确配置了所有内容,命令kubectl get ingress my-ingress的输出应该是这样的:

NAME         CLASS    HOSTS   ADDRESS          PORTS   AGE
my-ingress   <none>   *       <External IP>    80      149m

而且,如果您的服务指向正确的端口,并且您的应用程序正在侦听这些端口,则对您的外部 ip ( curl External IP ) 进行 curl 应该可以让您进入应用程序的版本一,这是我的示例输出:

Hello, world!
Version: 1.0.0
Hostname: web1-xxxxxxxxxxxxxx

对您的外部 ip /v2 ( curl External IP/v2 ) 进行 curl 应该可以让您进入应用程序的第二版:

Hello, world!
Version: 2.0.0
Hostname: web2-xxxxxxxxxxxxxx

[1] https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer


推荐阅读