将一个自定义域映射到多个服务的正确方法是什么?

What is the correct way to map one custom-domain to many services?

mapping-custom-domains with GKE with Cloud 运行 的说明适用于 1:1 domain:service 映射。但是,如果我想要 1:M domain:service 并与 URI 匹配,

怎么办?
myapp.com/login  >> login-service
myapp.com/logout >> logout-service

我试过的

第二个域映射创建语句将出错,因为域在服务中必须是唯一的:

$ gcloud beta run domain-mappings create --service login-service --domain myapp.com     --cluster mycluster     --cluster-location europe-west2-a
Creating......done.                                                                                                                                         
RECORD TYPE  CONTENTS
A            XX.XXX.XXX.XX

$ gcloud beta run domain-mappings create --service login-service --domain myapp.com     --cluster mycluster     --cluster-location europe-west2-a
ERROR: ... "message": domainmappings.domains.cloudrun.com \"myapp.com\" already exists ...

以前,当使用手动创建的 Knative 环境时,我可以使用 Istio VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: entry-route
  namespace: default
spec:
  - knative-ingress-gateway.knative-serving.svc.cluster.local
  # Set host to the domain name that you own.
  hosts:
  - myapp.com
  http:
  - match:
    - uri:
        prefix: "/login"
    rewrite:
      authority: login-service.default.myapp.com
    route:
      - destination:
          host: knative-ingressgateway.istio-system.svc.cluster.local
        weight: 100
  - match:
    - uri:
        prefix: "/logout"
    rewrite:
      authority: logout-service.default.myapp.com
    route:
      - destination:
          host: knative-ingressgateway.istio-system.svc.cluster.local
        weight: 100

但是虽然我可以在 GKE with Cloud 运行 上应用它,但所有内容都被路由到映射到域的服务。

我还尝试删除创建的 gcloud beta run domain-mappings,将 istio-ingressgateway LoadBalancer 设置为保留的静态 IP,并将我的域指向 LoadBalancer。但是,这只会导致 503s.

为什么我不能直接指向 istio-ingressgateway LoadBalancer 并让 VirtualService 路由给我?

云的域映射功能无法实现这种路由 运行。

域映射只允许您将域或子域映射到服务,它们不允许您映射路由。

因此,例如,您可以将 myapp.com 映射到服务 my-service,或将 login.myapp.com 映射到服务 login-service。 但是您不能将 myapp.com/login 映射到服务 login-service.

为此,您需要将 myapp.com 映射到服务 my-service,然后,该服务将查看请求路径并调用另一个服务 login-service.

或者,如果您在 GKE 上使用 Cloud 运行,您可以将 Cloud 运行 服务放在 Google Cloud Load Balancer, which allow you to use urlMaps 之后。

Firebase Hosting integration with Cloud Run 允许您将不同的子路径重写到不同的云 运行 服务。配置看起来像:

{
  "hosting": {
    "rewrites": [
      {"source": "/api/**", "run": {"serviceId": "api"}},
      {"source": "/charts/*.svg", "run": {"serviceId": "chartgen"}},
      {"source": "**", "run": {"serviceId": "ssr"}}
    ]
  }
}

可以使用 VirtualService 将使用相同域及其路径的流量重新路由到多个服务。

istio-ingressgateway 现在是默认的 Knative 服务主机名(我使用的是较旧的 Knative 版本和 knative-ingressgateway has since been removed)。

  1. 使用gcloud beta run domain-mappings create ...。不需要 M:1 service:domain 映射。
  2. 获取您的 istio-ingressgateway LoadBalancer (kubectl get svc istio-ingressgateway -n istio-system) 使用的 EXTERNAL-IP 并将您的域指向它(例如 myapp.com
  3. 使用 kubectl get svc 获取 Knative 服务主机名(在 EXTERNAL-IP 下列出 - 即 istio-ingressgateway.istio-system.svc.cluster.local
  4. 应用 VirtualService 将其路由目的地映射到 istio-ingressgateway.istio-system.svc.cluster.local:
# e.g. routing.yaml (`kubectl apply -f routing.yaml`)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: entry-route
  namespace: default
spec:
  - knative-ingress-gateway.knative-serving.svc.cluster.local
  # Set host to the domain name that you own.
  hosts:
  - myapp.com
  http:
  - match:
    - uri:
        prefix: "/login"
    rewrite:
      authority: login-service.default.myapp.com
    route:
      - destination:
          host: istio-ingressgateway.istio-system.svc.cluster.local
        weight: 100
  - match:
    - uri:
        prefix: "/logout"
    rewrite:
      authority: logout-service.default.myapp.com
    route:
      - destination:
          host: istio-ingressgateway.istio-system.svc.cluster.local
        weight: 100