×

使用Red Hat OpenShift Service Mesh,您可以控制服务之间流量和API调用的流动。服务网格中的一些服务可能需要在网格内通信,而其他服务可能需要隐藏。您可以管理流量以隐藏特定的后端服务,公开服务,创建测试或版本部署,或在一组服务上添加安全层。

使用网关

您可以使用网关来管理网格的入站和出站流量,以指定您希望进入或离开网格的流量。网关配置应用于在网格边缘运行的独立Envoy代理,而不是与您的服务工作负载一起运行的sidecar Envoy代理。

与其他控制进入您系统的流量的机制(例如Kubernetes Ingress API)不同,Red Hat OpenShift Service Mesh网关使用流量路由的全部功能和灵活性。

Red Hat OpenShift Service Mesh网关资源可以使用4-6层负载均衡属性(例如端口)来公开和配置Red Hat OpenShift Service Mesh TLS设置。您可以将常规Red Hat OpenShift Service Mesh虚拟服务绑定到网关,并像管理服务网格中任何其他数据平面流量一样管理网关流量,而不是将应用程序层流量路由(L7)添加到相同的API资源。

网关主要用于管理入口流量,但您也可以配置出口网关。出口网关允许您为离开网格的流量配置一个专用出口节点。这使您可以限制哪些服务可以访问外部网络,从而为您的服务网格增加安全控制。您也可以使用网关来配置纯内部代理。

网关示例

网关资源描述在网格边缘运行的负载均衡器,接收传入或传出的HTTP/TCP连接。规范描述了一组应公开的端口、要使用的协议类型、负载均衡器的SNI配置等。

以下示例显示了外部HTTPS入口流量的示例网关配置

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key

此网关配置允许来自ext-host.example.com的HTTPS流量通过端口443进入网格,但不指定任何流量路由。

要指定路由并使网关按预期工作,您还必须将网关绑定到虚拟服务。您可以使用虚拟服务的gateways字段执行此操作,如下例所示

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-svc
spec:
  hosts:
  - ext-host.example.com
  gateways:
    - ext-host-gwy

然后,您可以为外部流量配置虚拟服务的路由规则。

管理入口流量

在Red Hat OpenShift Service Mesh中,入口网关允许将监控、安全和路由规则应用于进入集群的流量。使用服务网格网关来公开服务网格外部的服务。

确定入口IP和端口

入口配置取决于您的环境是否支持外部负载均衡器。外部负载均衡器在集群的入口IP和端口中设置。要确定集群的IP和端口是否已配置为外部负载均衡器,请运行以下命令。在此示例中,istio-system是服务网格控制平面项目的名称。

$ oc get svc istio-ingressgateway -n istio-system

该命令返回命名空间中每个项目的NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE

如果设置了EXTERNAL-IP值,则您的环境具有可用于入口网关的外部负载均衡器。

如果EXTERNAL-IP值为<none>或永久为<pending>,则您的环境不提供用于入口网关的外部负载均衡器。

使用负载均衡器确定入口端口

如果您的环境具有外部负载均衡器,请按照以下说明操作。

步骤
  1. 运行以下命令以设置入口IP和端口。此命令在您的终端中设置一个变量。

    $ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  2. 运行以下命令以设置入口端口。

    $ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
  3. 运行以下命令以设置安全入口端口。

    $ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
  4. 运行以下命令以设置TCP入口端口。

    $ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')

在某些环境中,负载均衡器可以使用主机名而不是IP地址公开。在这种情况下,入口网关的EXTERNAL-IP值不是IP地址。它是一个主机名,之前的命令无法设置INGRESS_HOST环境变量。

在这种情况下,请使用以下命令来更正INGRESS_HOST

$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
在没有负载均衡器的情况下确定入口端口

如果您的环境没有外部负载均衡器,请确定入口端口并改用节点端口。

步骤
  1. 设置入口端口。

    $ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
  2. 运行以下命令以设置安全入口端口。

    $ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
  3. 运行以下命令以设置TCP入口端口。

    $ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')

配置入口网关

入口网关是在网格边缘运行的负载均衡器,它接收传入的HTTP/TCP连接。它配置公开的端口和协议,但不包括任何流量路由配置。入口流量的流量路由与内部服务请求一样,使用路由规则进行配置。

以下步骤演示如何创建一个网关并配置一个VirtualService,以便将Bookinfo示例应用程序中的服务通过路径/productpage/login暴露给外部流量。

步骤
  1. 创建网关以接收流量。

    1. 创建一个YAML文件,并将以下YAML内容复制到其中。

      网关示例 gateway.yaml
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: bookinfo-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
    2. 应用YAML文件。

      $ oc apply -f gateway.yaml
  2. 创建一个VirtualService对象来重写主机头。

    1. 创建一个YAML文件,并将以下YAML内容复制到其中。

      虚拟服务示例
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: bookinfo
      spec:
        hosts:
        - "*"
        gateways:
        - bookinfo-gateway
        http:
        - match:
          - uri:
              exact: /productpage
          - uri:
              prefix: /static
          - uri:
              exact: /login
          - uri:
              exact: /logout
          - uri:
              prefix: /api/v1/products
          route:
          - destination:
              host: productpage
              port:
                number: 9080
    2. 应用YAML文件。

      $ oc apply -f vs.yaml
  3. 测试网关和VirtualService是否已正确设置。

    1. 设置网关URL。

      export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
    2. 设置端口号。在此示例中,istio-system是服务网格控制平面项目的名称。

      export TARGET_PORT=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.port.targetPort}')
    3. 测试已明确公开的页面。

      curl -s -I "$GATEWAY_URL/productpage"

      预期结果为200

理解自动路由

Istio OpenShift路由(IOR)是一个已弃用的功能。已弃用的功能仍然包含在Red Hat OpenShift Service on AWS中,并将继续得到支持;但是,它将在该产品的未来版本中删除,并且不推荐用于新的部署。

有关Red Hat OpenShift Service on AWS中已弃用或删除的主要功能的最新列表,请参阅Red Hat OpenShift Service on AWS发行说明中的“已弃用和已删除的功能”部分。

OpenShift网关路由在服务网格中自动管理。每次在服务网格内创建、更新或删除Istio网关时,都会创建、更新或删除OpenShift路由。

从Service Mesh 2.5开始,对于ServiceMeshControlPlane资源的新实例,默认情况下会禁用自动路由。

带有子域的路由

Red Hat OpenShift Service Mesh创建具有子域的路由,但必须配置Red Hat OpenShift Service on AWS才能启用它。子域(例如*.domain.com)受支持,但并非默认支持。在配置通配符主机网关之前,请配置Red Hat OpenShift Service on AWS通配符策略。

创建子域路由

以下示例在Bookinfo示例应用程序中创建网关,该网关创建子域路由。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway1
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - www.bookinfo.com
    - bookinfo.example.com

Gateway资源创建以下OpenShift路由。您可以使用以下命令检查路由是否已创建。在此示例中,istio-system是服务网格控制平面项目的名称。

$ oc -n istio-system get routes
预期输出
NAME           HOST/PORT             PATH  SERVICES               PORT  TERMINATION   WILDCARD
gateway1-lvlfn bookinfo.example.com        istio-ingressgateway   <all>               None
gateway1-scqhv www.bookinfo.com            istio-ingressgateway   <all>               None

如果删除网关,Red Hat OpenShift Service Mesh将删除路由。但是,手动创建的路由永远不会被Red Hat OpenShift Service Mesh修改。

路由标签和注释

有时OpenShift路由需要特定的标签或注释。

对于这种情况和其他用例,Red Hat OpenShift Service Mesh会将Istio网关资源中存在的所有标签和注释(以kubectl.kubernetes.io开头的注释除外)复制到托管的OpenShift路由资源中。

如果需要服务网格创建的OpenShift路由中的特定标签或注释,请在Istio网关资源中创建它们,它们将被复制到服务网格管理的OpenShift路由资源中。

禁用自动路由创建

默认情况下,ServiceMeshControlPlane资源会自动将Istio网关资源与OpenShift路由同步。禁用自动路由创建允许您更灵活地控制路由,如果您有特殊情况或更喜欢手动控制路由。

为特定情况禁用自动路由创建

如果要为特定的Istio网关禁用OpenShift路由的自动管理,则必须将注释maistra.io/manageRoute: false添加到网关元数据定义中。Red Hat OpenShift Service Mesh将忽略具有此注释的Istio网关,同时保持其他Istio网关的自动管理。

为所有情况禁用自动路由创建

您可以为网格中的所有网关禁用OpenShift路由的自动管理。

通过将ServiceMeshControlPlane字段gateways.openshiftRoute.enabled设置为false来禁用Istio网关和OpenShift路由之间的集成。例如,请参见以下资源片段。

apiVersion: maistra.io/v1alpha1
kind: ServiceMeshControlPlane
metadata:
  namespace: istio-system
spec:
  gateways:
    openshiftRoute:
      enabled: false

理解服务条目

服务条目在Red Hat OpenShift Service Mesh内部维护的服务注册表中添加一个条目。添加服务条目后,Envoy代理将向该服务发送流量,就像它是网格中的服务一样。服务条目允许您执行以下操作:

  • 管理在服务网格外部运行的服务的流量。

  • 重定向和转发外部目标(例如,从Web消耗的API)的流量或向遗留基础架构中的服务的流量。

  • 为外部目标定义重试、超时和故障注入策略。

  • 通过将虚拟机添加到网格中,在虚拟机(VM)中运行网格服务。

将来自不同集群的服务添加到网格中,以便在Kubernetes上配置多集群Red Hat OpenShift Service Mesh网格。

服务条目示例

以下示例是一个网格外部服务条目,它将ext-resource外部依赖项添加到Red Hat OpenShift Service Mesh服务注册表

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS

使用hosts字段指定外部资源。您可以完全限定它或使用通配符前缀域名。

您可以配置虚拟服务和目标规则来控制到服务条目的流量,方法与配置网格中任何其他服务的流量相同。例如,以下目标规则配置流量路由以使用双向TLS来保护与使用服务条目配置的ext-svc.example.com外部服务的连接

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ext-res-dr
spec:
  host: ext-svc.example.com
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/certs/myclientcert.pem
      privateKey: /etc/certs/client_private_key.pem
      caCertificates: /etc/certs/rootcacerts.pem

使用VirtualServices

您可以通过Red Hat OpenShift Service Mesh使用虚拟服务将请求动态路由到微服务的多个版本。使用虚拟服务,您可以:

  • 通过单个虚拟服务处理多个应用程序服务。例如,如果您的网格使用Kubernetes,您可以配置虚拟服务来处理特定命名空间中的所有服务。虚拟服务使您可以将单体应用程序转换为由具有无缝用户体验的不同微服务组成的服务。

  • 将流量规则与网关结合使用以控制入口和出口流量。

配置VirtualServices

使用虚拟服务将请求路由到服务网格内的服务。每个虚拟服务都包含一组按顺序评估的路由规则。Red Hat OpenShift Service Mesh将每个给定的请求与虚拟服务匹配到网格内的特定实际目标。

没有虚拟服务,Red Hat OpenShift Service Mesh将使用最少请求负载平衡在所有服务实例之间分配流量。使用虚拟服务,您可以指定一个或多个主机名的流量行为。虚拟服务中的路由规则告诉Red Hat OpenShift Service Mesh如何将虚拟服务的流量发送到适当的目标。路由目标可以是同一服务的不同版本,也可以是完全不同的服务。

步骤
  1. 使用以下示例创建一个 YAML 文件,根据连接应用程序的用户路由请求到 Bookinfo 示例应用程序服务的不同版本。

    VirtualService.yaml 示例
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        route:
        - destination:
            host: reviews
            subset: v2
      - route:
        - destination:
            host: reviews
            subset: v3
  2. 运行以下命令应用VirtualService.yaml,其中VirtualService.yaml是文件的路径。

    $ oc apply -f <VirtualService.yaml>

VirtualService 配置参考

参数 描述
spec:
  hosts:

hosts 字段列出了虚拟服务的目标地址,路由规则适用于该地址。这是用于将请求发送到服务的地址。虚拟服务主机名可以是 IP 地址、DNS 名称或解析为完全限定域名 (FQDN) 的短名称。

spec:
  http:
  - match:

http 部分包含虚拟服务的路由规则,这些规则描述了用于路由发送到 hosts 字段中指定的目的地 HTTP/1.1、HTTP2 和 gRPC 流量的匹配条件和操作。路由规则包括您希望流量到达的目标以及任何指定的匹配条件。示例中的第一个路由规则有一个以 match 字段开头的条件。在此示例中,此路由适用于来自用户jason的所有请求。添加headersend-userexact字段以选择相应的请求。

spec:
  http:
  - match:
    - destination:

route 部分中的destination字段指定与该条件匹配的流量的实际目标。与虚拟服务的 host 不同,目的地的 host 必须是 Red Hat OpenShift Service Mesh 服务注册表中存在的真实目的地。这可以是带有代理的网格服务或使用服务条目添加的非网格服务。在此示例中,主机名是 Kubernetes 服务名称。

理解目标规则

目标规则在评估虚拟服务路由规则后应用,因此它们适用于流量的实际目标。虚拟服务将流量路由到目的地。目标规则配置在该目的地发生的情况。

默认情况下,Red Hat OpenShift Service Mesh 使用最少请求负载均衡策略,其中活动连接最少的池中的服务实例接收请求。Red Hat OpenShift Service Mesh 还支持以下模型,您可以在目标规则中为特定服务或服务子集的请求指定这些模型。

  • 随机:请求随机转发到池中的实例。

  • 加权:根据特定百分比将请求转发到池中的实例。

  • 最少请求:请求转发到请求最少的实例。

目标规则示例

以下目标规则示例为my-svc目标服务配置了三个不同的子集,并具有不同的负载均衡策略。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3

理解网络策略

Red Hat OpenShift Service Mesh 会自动在服务网格控制平面和应用程序命名空间中创建和管理多个NetworkPolicies资源。这是为了确保应用程序和控制平面可以相互通信。

例如,如果您已将 Red Hat OpenShift Service on AWS 集群配置为使用 SDN 插件,则 Red Hat OpenShift Service Mesh 会在每个成员项目中创建一个NetworkPolicy资源。这允许来自其他网格成员和控制平面的网格中所有 Pod 的入口流量。这也将入口流量限制为仅限成员项目。如果您需要来自非成员项目的入口流量,则需要创建一个NetworkPolicy以允许该流量通过。如果您从服务网格中删除命名空间,则此NetworkPolicy资源将从项目中删除。

禁用自动 NetworkPolicy 创建

如果您想禁用NetworkPolicy资源的自动创建和管理(例如,为了执行公司安全策略或允许直接访问网格中的 Pod),您可以这样做。您可以编辑ServiceMeshControlPlane并将spec.security.manageNetworkPolicy设置为false

禁用spec.security.manageNetworkPolicy后,Red Hat OpenShift Service Mesh 将不会创建**任何**NetworkPolicy对象。系统管理员负责管理网络并解决由此可能造成的任何问题。

先决条件
  • 已安装 Red Hat OpenShift Service Mesh Operator 版本 2.1.1 或更高版本。

  • ServiceMeshControlPlane资源已更新到 2.1 或更高版本。

步骤
  1. 在 Red Hat OpenShift Service on AWS Web 控制台中,单击**运算符**→**已安装的运算符**。

  2. 从**项目**菜单中选择安装服务网格控制平面的项目,例如istio-system

  3. 单击 Red Hat OpenShift Service Mesh Operator。在**Istio 服务网格控制平面**列中,单击您的ServiceMeshControlPlane的名称,例如basic-install

  4. 在**创建 ServiceMeshControlPlane 详情**页面上,单击YAML以修改您的配置。

  5. ServiceMeshControlPlane字段spec.security.manageNetworkPolicy设置为false,如本例所示。

    apiVersion: maistra.io/v2
    kind: ServiceMeshControlPlane
    spec:
      security:
          manageNetworkPolicy: false
  6. 单击**保存**。

配置用于流量管理的 sidecar

默认情况下,Red Hat OpenShift Service Mesh 将每个 Envoy 代理配置为接受其关联工作负载的所有端口上的流量,并在转发流量时到达网格中的每个工作负载。您可以使用 sidecar 配置执行以下操作:

  • 微调 Envoy 代理接受的端口和协议集。

  • 限制 Envoy 代理可以访问的服务集。

为了优化服务网格的性能,请考虑限制 Envoy 代理配置。

在 Bookinfo 示例应用程序中,配置一个 Sidecar,以便所有服务都可以访问在同一命名空间和控制平面中运行的其他服务。此 Sidecar 配置对于使用 Red Hat OpenShift Service Mesh 策略和遥测功能是必需的。

步骤
  1. 使用以下示例创建一个 YAML 文件,以指定您希望将 sidecar 配置应用于特定命名空间中的所有工作负载。否则,请使用workloadSelector选择特定工作负载。

    sidecar.yaml 示例
    apiVersion: networking.istio.io/v1alpha3
    kind: Sidecar
    metadata:
      name: default
      namespace: bookinfo
    spec:
      egress:
      - hosts:
        - "./*"
        - "istio-system/*"
  2. 运行以下命令应用sidecar.yaml,其中sidecar.yaml是文件的路径。

    $ oc apply -f sidecar.yaml
  3. 运行以下命令以验证 sidecar 是否已成功创建。

    $ oc get sidecar

路由教程

本指南参考 Bookinfo 示例应用程序,以提供示例应用程序中路由的示例。安装Bookinfo 应用程序以了解这些路由示例的工作原理。

Bookinfo 路由教程

服务网格 Bookinfo 示例应用程序由四个单独的微服务组成,每个微服务都有多个版本。安装 Bookinfo 示例应用程序后,reviews微服务的三个不同版本会同时运行。

当您在浏览器中访问 Bookinfo 应用程序/product页面并刷新几次时,有时图书评论输出包含星级评定,有时则不包含。如果没有显式指定要路由到的默认服务版本,服务网格会依次将请求路由到所有可用版本。

本教程将帮助您应用将所有流量路由到微服务的v1(版本 1)的规则。稍后,您可以应用一个规则来根据 HTTP 请求头的值路由流量。

先决条件
  • 部署 Bookinfo 示例应用程序以使用以下示例。

应用虚拟服务

在以下步骤中,我们将通过应用虚拟服务来设置微服务的默认版本,从而将所有流量路由到每个微服务的v1版本。

步骤
  1. 应用虚拟服务。

    $ oc apply -f https://raw.githubusercontent.com/Maistra/istio/maistra-2.6/samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. 要验证您是否已应用虚拟服务,请使用以下命令显示已定义的路由

    $ oc get virtualservices -o yaml

    该命令将返回一个kind: VirtualService类型的YAML格式资源。

您已配置Service Mesh将流量路由到Bookinfo微服务的v1版本,包括reviews服务的版本1。

测试新的路由配置

通过刷新Bookinfo应用程序的/productpage来测试新配置。

步骤
  1. 设置GATEWAY_URL参数的值。您可以使用此变量来查找Bookinfo产品页面的URL。在本例中,istio-system是控制平面项目的名称。

    export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
  2. 运行以下命令以检索产品页面的URL。

    echo "http://$GATEWAY_URL/productpage"
  3. 在您的浏览器中打开Bookinfo站点。

无论您刷新多少次,页面中的评论部分都不会显示评分星级。这是因为您已将Service Mesh配置为将所有流量路由到reviews:v1版本的服务,而此版本的微服务不访问星级评分服务。

您的服务网格现在将流量路由到服务的某个特定版本。

基于用户身份的路由

更改路由配置,以便来自特定用户的全部流量都路由到特定服务版本。在本例中,来自名为jason的用户的所有流量将被路由到reviews:v2服务。

Service Mesh本身并不具备对用户身份的特殊内置理解。本例之所以可行,是因为productpage服务向发送到reviews服务的全部出站HTTP请求添加了自定义的end-user标头。

步骤
  1. 运行以下命令以在Bookinfo示例应用程序中启用基于用户的路由。

    $ oc apply -f https://raw.githubusercontent.com/Maistra/istio/maistra-2.6/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. 运行以下命令以确认规则已创建。此命令将返回所有kind: VirtualService类型的YAML格式资源。

    $ oc get virtualservice reviews -o yaml
  3. 在Bookinfo应用的/productpage页面上,以用户jason身份登录(无需密码)。

  4. 刷新浏览器。每个评论旁边都会显示星级评分。

  5. 以其他用户身份登录(选择任何您想要的名字)。刷新浏览器。现在星级消失了。现在,除了Jason以外,所有用户的流量都被路由到reviews:v1

您已成功配置Bookinfo示例应用程序以基于用户身份进行流量路由。