在没有 LB 的情况下使用同一主机公开多个微服务

问题描述 投票:0回答:2

我有一个“UI”和一个“API”微服务,我正在启用 Istio 的情况下部署在 k8s 默认命名空间上。我的 k8s 环境是一个开发箱,没有外部负载均衡器。

UI的端口配置为80(service port):80(container port in pod)。 API的端口配置为8000(服务端口):80(pod中的容器端口)

我必须为外部流量公开这两个微服务,因为有些人可能会使用“UI”,而有些人可能会直接调用“API”(通过邮递员)来满足他们的请求。

当这些微服务作为没有 k8s 层的简单 docker 容器运行时,用户直接使用

host.example.com
进行 UI 和
host.example.com:8000/api
进行 API 调用(API 调用是 JSON-RPC)。

我为这两个微服务设置了网关和虚拟服务:

对于用户界面:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ui-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
servers:
- port:
    number: 80
    name: http
    protocol: HTTP
  hosts:
    - host.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ui-vs
spec:
  hosts:
  - host.example.com
  gateways:
  - ui-gateway
  http:
  - route:
    - destination:
      port:
        number: 80
      host: ui --> name of k8s svc

对于API:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: api-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - host.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: api-vs
spec:
  hosts:
  - host.example.com
  gateways:
  - api-gateway
http:
- route:
  - destination:
      host: api -> name of api service
      port:
        number: 8000

现在通过 Istio 文档(在浏览器上访问)在浏览器中访问这个 UI,我需要通过

${INGRESS_HOST}:${INGRES_PORT}
访问它。 就我而言:

INGRESS_HOST=host.example.com
INGRESS_PORT=31165

因此访问 http://host.example.com:31165 会加载 UI,我现在如何通过邮递员等在

host.example.com
上从外部访问 API 微服务?无法从外部访问 8000 API 端口。我想这一切都必须通过 31165,但是我需要使用什么路由来直接访问 API?如果有的话,我需要在我的设置中做哪些改变?我刚刚开始使用 Istio,所以我们将不胜感激。

kubernetes microservices istio istio-gateway
2个回答
0
投票

一个选项是添加主机标头。

本地开发人员更简单的方法是使用

*.nip.io
地址。

如果你的入口有一个IP(在

k get svc -n istio-system istio-ingressgateway
的结果中寻找一个外部IP),那么这就是你在url中使用的。

例如

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: grafana-virtualservice
  namespace: monitoring
spec:
  gateways:
  - grafana-gateway
  hosts:
  - grafana.192.168.87.2.nip.io
  http:
  - route:
    - destination:
        host: kube-prometheus-stack-grafana
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:  
  name: grafana-gateway
  namespace: monitoring
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - grafana.192.168.87.2.nip.io
    port:
      name: http
      number: 80
      protocol: HTTP

如果您创建证书,HTTPS 重定向也可以工作

例如

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: argocd-gateway
  namespace: argocd
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - argocd.192.168.87.2.nip.io
      port:
        name: http
        number: 80
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - argocd.192.168.87.2.nip.io
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        credentialName: argocd.192.168.87.3.nip.io
        mode: SIMPLE

0
投票

最简单的解决方案是将两者组合成一个

VirtualService
并使用类似路径+重写的东西:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-vs
spec:
  hosts:
    - host.example.com
  gateways:
    - my-gateway
  http:
    - match:
      - uri:
          prefix: /api
      rewrite:
        uri: /
      route:
      - destination:
          host: api # -> name of api service
          port:
            number: 8000
    - match:
      - uri:
          prefix: /ui
      rewrite:
        uri: /
      route:
      - destination:
          port:
            number: 80
          host: ui # --> name of k8s svc

如果您查询

host.example.com:<nodePort>/api
,您将最终到达api主机,并使用
host.example.com:<nodePort>/ui
ui.

您还可以使用子域(

ui.example.com:<nodePort>
api.example.com:<nodePort>
)或基于标题的路由。查看docs以获取更多示例。

© www.soinside.com 2019 - 2024. All rights reserved.