Istio从入门到精通——Istio中的概念介绍

Istio中的概念介绍

一、流量管理

https://istio.io/latest/docs/concepts/traffic-management/

  Istio’s traffic routing rules let you easily control the flow of traffic and API calls between services. Istio simplifies configuration of service-level properties like circuit breakers, timeouts, and retries, and makes it easy to set up important tasks like A/B testing, canary rollouts, and staged rollouts with percentage-based traffic splits. It also provides out-of-box reliability features that help make your application more resilient against failures of dependent services or the network.

Istio 的流量路由规则可以让很容易的控制服务之间的流量和 API 调用。 Istio 简化了服务级别属性的配置,比如熔断器、超时和重试,并且能轻松的设置重要的任务, 如 A/B 测试、金丝雀发布、基于流量百分比切分的分阶段发布等。它还提供了开箱即用的故障恢复特性, 有助于增强应用的健壮性,从而更好地应对被依赖的服务或网络发生故障的情况。

  Istio’s traffic management model relies on the Envoy proxies that are deployed along with your services. All traffic that your mesh services send and receive (data plane traffic) is proxied through Envoy, making it easy to direct and control traffic around your mesh without making any changes to your services.

Istio 的流量管理模型源于和服务一起部署的 Envoy(Envoy: Envoy 是在 Istio 里使用的高性能代理,用于为所有服务网格里的服务调度进出的流量。 了解更多关于 https://www.envoyproxy.io )代理。 网格内服务发送和接收的所有 data plane(data plane: 数据平面是网格的一部分,直接控制工作负载实例之间的通信。Istio 的数据平面使用智能 Envoy 代理部署成 Sidecar 去调节和控制服务网格中发送和接受的流量)流量都经由 Envoy 代理, 这让控制网格内的流量变得异常简单,而且不需要对服务做任何的更改。

二、流量管理介绍

https://istio.io/latest/zh/docs/concepts/traffic-management/#introducing-Istio-traffic-management

  In order to direct traffic within your mesh, Istio needs to know where all your endpoints are, and which services they belong to. To populate its own service registry, Istio connects to a service discovery system. For example, if you’ve installed Istio on a Kubernetes cluster, then Istio automatically detects the services and endpoints in that cluster.

为了在网格中导流,Istio 需要知道所有的 endpoint 在哪以及它们属于哪些服务。 为了定位到 service registry (服务注册中心: Istio 维护了一个内部服务注册表 (service registry [ˈrεdʒɪstrɪ]),它包含在服务网格中运行的一组服务及其相应的服务 endpoints。 Istio 使用服务注册表生成 Envoy 配置。 Istio 不提供服务发现, 尽管大多数服务都是通过 Pilot [ˈpaɪlət] adapter [əˈdæptɚ] 自动加入到服务注册表里的, 而且这反映了底层平台(Kubernetes、Consul、plain DNS)的已发现的服务。还有就是,可以使用 ServiceEntry([ˈεntrɪ]) 配置进行手动注册。),Istio 会连接到一个服务发现系统。例如,如果在 Kubernetes 集群上安装了 Istio, 那么它将自动检测该集群中的服务和 endpoint。

  Using this service registry, the Envoy proxies can then direct traffic to the relevant services. Most microservice-based applications have multiple instances of each service workload to handle service traffic, sometimes referred to as a load balancing pool. By default, the Envoy proxies distribute traffic across each service’s load balancing pool using a least requests model, where each request is routed to the host with fewer active requests from a random selection of two hosts from the pool; in this way the most heavily loaded host will not receive requests until it is no more loaded than any other host.

使用此服务注册中心,Envoy 代理可以将流量定向到相关服务。大多数基于微服务的应用程序, 每个服务的工作负载都有多个实例来处理流量,称为负载均衡池。默认情况下, Envoy 代理基于轮询调度模型在服务的负载均衡池内分发流量,按顺序将请求发送给池中每个成员, 一旦所有服务实例均接收过一次请求后,就重新回到第一个池成员。

  While Istio’s basic service discovery and load balancing gives you a working service mesh, it’s far from all that Istio can do. In many cases you might want more fine-grained control over what happens to your mesh traffic. You might want to direct a particular percentage of traffic to a new version of a service as part of A/B testing, or apply a different load balancing policy to traffic for a particular subset of service instances. You might also want to apply special rules to traffic coming into or out of your mesh, or add an external dependency of your mesh to the service registry. You can do all this and more by adding your own traffic configuration to Istio using Istio’s traffic management API.

Istio 基本的服务发现和负载均衡能力为提供了一个可用的服务网格, 但它能做到的远比这多的多。在许多情况下,可能希望对网格的流量情况进行更细粒度的控制。 作为 A/B 测试的一部分,可能想将特定百分比的流量定向到新版本的服务, 或者为特定的服务实例子集应用不同的负载均衡策略。可能还想对进出网格的流量应用特殊的规则, 或者将网格的外部依赖项添加到服务注册中心。通过使用 Istio 的流量管理 API 将流量配置添加到 Istio, 就可以完成所有这些甚至更多的工作。

  Like other Istio configuration, the API is specified using Kubernetes custom resource definitions (CRDs), which you can configure using YAML, as you’ll see in the examples.

和其他 Istio 配置一样,这些 API 也使用 Kubernetes 的自定义资源定义 (CRD)来声明,可以像示例中看到的那样使用 YAML 进行配置。

三、虚拟服务

https://istio.io/latest/zh/docs/concepts/traffic-management/#virtual-services

  Virtual services, along with destination rules, are the key building blocks of Istio’s traffic routing functionality. A virtual service lets you configure how requests are routed to a service within an Istio service mesh, building on the basic connectivity and discovery provided by Istio and your platform. Each virtual service consists of a set of routing rules that are evaluated in order, letting Istio match each given request to the virtual service to a specific real destination within the mesh. Your mesh can require multiple virtual services or none depending on your use case.

  虚拟服务(Virtual Service)和目标规则(Destination Rule)是 Istio 流量路由功能的核心构建模块。 基于 Istio 和的平台提供的基本连通性及服务发现能力,虚拟服务允许配置请求如何路由到特定的服务。每个虚拟服务包含一组按顺序评估的路由规则,通过这些规则,Istio 将每个到虚拟服务的给定请求匹配到特定的、真实的目标地址。根据的使用场景,的服务网格可以有多个虚拟服务或者不需要虚拟服务。

3.1、为什么使用虚拟服务

  Virtual services play a key role in making Istio’s traffic management flexible and powerful. They do this by strongly decoupling where clients send their requests from the destination workloads that actually implement them. Virtual services also provide a rich way of specifying different traffic routing rules for sending traffic to those workloads.

  虚拟服务在增强 Istio 流量管理的灵活性和有效性方面,发挥着至关重要的作用, 实现方式是解耦客户端请求的目标地址与实际响应请求的目标工作负载。 虚拟服务同时提供了丰富的方式,为发送至这些工作负载的流量指定不同的路由规则。

  Why is this so useful? Without virtual services, Envoy distributes traffic using least requests load balancing between all service instances, as described in the introduction. You can improve this behavior with what you know about the workloads. For example, some might represent a different version. This can be useful in A/B testing, where you might want to configure traffic routes based on percentages across different service versions, or to direct traffic from your internal users to a particular set of instances.

  为什么这如此有用?就像在介绍中所说,如果没有虚拟服务,Envoy 会在所有的服务实例中使用轮询的负载均衡策略分发请求。 可以用对工作负载的了解来改善这种行为。例如,有些可能代表不同的版本。 这在 A/B 测试中可能有用,可能希望在其中配置基于不同服务版本的流量百分比路由, 或指引从内部用户到特定实例集的流量。

  With a virtual service, you can specify traffic behavior for one or more hostnames. You use routing rules in the virtual service that tell Envoy how to send the virtual service’s traffic to appropriate destinations. Route destinations can be different versions of the same service or entirely different services.

  使用虚拟服务,可以为一个或多个主机名指定流量行为。在虚拟服务中使用路由规则, 告诉 Envoy 如何发送虚拟服务的流量到适当的目标。路由目标地址可以是同一服务的不同版本, 也可以是完全不同的服务。

  A typical use case is to send traffic to different versions of a service, specified as service subsets. Clients send requests to the virtual service host as if it was a single entity, and Envoy then routes the traffic to the different versions depending on the virtual service rules: for example, “20% of calls go to the new version” or “calls from these users go to version 2”. This allows you to, for instance, create a canary rollout where you gradually increase the percentage of traffic that’s sent to a new service version. The traffic routing is completely separate from the instance deployment, meaning that the number of instances implementing the new service version can scale up and down based on traffic load without referring to traffic routing at all. By contrast, container orchestration platforms like Kubernetes only support traffic distribution based on instance scaling, which quickly becomes complex. You can read more about how virtual services help with canary deployments in Canary Deployments using Istio.

  一个典型的用例是将流量发送到被指定为服务子集的服务的不同版本。 客户端将虚拟服务视为一个单一实体,将请求发送至虚拟服务主机, 然后 Envoy 根据虚拟服务规则把流量路由到不同的版本。例如,“20% 的调用转发到新版本”或“将这些用户的调用转发到版本 2”。 这允许创建一个金丝雀发布,逐步增加发送到新版本服务的流量百分比。 流量路由完全独立于实例部署,这意味着实现新版本服务的实例可以根据流量的负载来伸缩, 完全不影响流量路由。相比之下,像 Kubernetes 这样的容器编排平台只支持基于实例缩放的流量分发, 这会让情况变得复杂。可以在使用 Istio 进行金丝雀部署(https://istio.io/latest/zh/blog/2017/0.1-canary)的文章里阅读到更多用虚拟服务实现金丝雀部署的内容。

    • Address multiple application services through a single virtual service. If your mesh uses Kubernetes, for example, you can configure a virtual service to handle all services in a specific namespace. Mapping a single virtual service to multiple “real” services is particularly useful in facilitating turning a monolithic application into a composite service built out of distinct microservices without requiring the consumers of the service to adapt to the transition. Your routing rules can specify “calls to these URIs of monolith.com go to microservice A”, and so on. You can see how this works in one of our examples below.

通过单个虚拟服务处理多个应用程序服务。如果的网格使用 Kubernetes, 可以配置一个虚拟服务处理特定命名空间中的所有服务。映射单一的虚拟服务到多个“真实”服务特别有用, 可以在不需要客户适应转换的情况下,将单体应用转换为微服务构建的复合应用系统。 的路由规则可以指定为“对 monolith.com 的 URI 调用转发到 microservice A” 等等。

    • Configure traffic rules in combination with gateways to control ingress and egress traffic.

和网关整合并配置流量规则来控制出入流量。

  In some cases you also need to configure destination rules to use these features, as these are where you specify your service subsets. Specifying service subsets and other destination-specific policies in a separate object lets you reuse these cleanly between virtual services. You can find out more about destination rules in the next section.

在某些情况下,还需要配置目标规则来使用这些特性,因为这是指定服务子集的地方。 在一个单独的对象中指定服务子集和其它特定目标策略,有利于在虚拟服务之间更简洁地重用这些规则。

3.2、虚拟服务示例

  The following virtual service routes requests to different versions of a service depending on whether the request comes from a particular user.

下面的虚拟服务根据请求是否来自特定的用户,把它们路由到服务的不同版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts: //使用 hosts 字段列举虚拟服务的主机——即用户指定的目标或是路由规则设定的目标。这是客户端向服务发送请求时使用的一个或多个地址。
  /*
    reviews: 虚拟服务的hostname可以是IP地址、DNS名称,或者,取决于平台,可以是简短名称(例如Kubernetes服务的简短名称),
    它可以隐式或显式解析为一个完全限定的域名(FQDN)。还可以使用通配符("*")前缀,以便为所有匹配的服务创建一个单独的路由规则集。
    虚拟服务的hosts实际上不需要是Istio服务注册表的一部分,它们只是虚拟目标。这使能够为网格内没有可路由条目的虚拟主机建模流量。

    简单来说,这段话描述了在使用Istio服务网格时,可以通过创建虚拟服务来定义和管理虚拟主机(即不是网格内实际存在的服务)的流量。
    虚拟服务的hostname可以是任何可以解析到FQDN的值,包括IP地址、DNS名称或特定平台的简短名称。此外,使用通配符前缀可以使为所有匹配的服务创建单个路由规则集。
  */
  - reviews
  /*
    http 字段包含了虚拟服务的路由规则,用来描述匹配条件和路由行为,它们把 HTTP/1.1、HTTP2 和 gRPC 等流量发送到 hosts 字段指定的
    目标(也可以用 tcp 和 tls 片段为 TCP 和未终止的 TLS 流量设置路由规则。
    一个路由规则包含了指定的请求要流向哪个目标地址,具有 0 或多个匹配条件,取决于的使用场景。
  */
  http:
   /*
     match: 匹配条件,示例中的第一个路由规则有一个条件,因此以 match 字段开始。
     在本例中, 希望此路由应用于来自 ”jason“ 用户的所有请求,所以使用 headers、end-user和exact字段选择适当的请求。
   */
   - match:
    - headers:
        end-user:
          exact: jason
    route:
    /*
      route 部分的 destination 字段指定了符合此条件的流量的实际目标地址。
      注意与虚拟服务的 hosts 不同,destination 的 host 必须是存在于 Istio 服务注册中心的实际目标地址,否则 Envoy 不知道该将请求发送到哪里。
      可以是一个有代理的服务网格,或者是一个通过服务入口(service entry)被添加进来的非网格服务。
    */
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

3.3、路由规则的更多内容

https://istio.io/latest/docs/concepts/traffic-management/#more-about-routing-rules

  As you saw above, routing rules are a powerful tool for routing particular subsets of traffic to particular destinations. You can set match conditions on traffic ports, header fields, URIs, and more. For example, this virtual service lets users send traffic to two separate services, ratings and reviews, as if they were part of a bigger virtual service at http://bookinfo.com/. The virtual service rules match traffic based on request URIs and direct requests to the appropriate service.

正如上面所看到的,路由规则是将特定流量子集路由到指定目标地址的强大工具。 可以在流量端口、header 字段、URI 等内容上设置匹配条件。例如, 这个虚拟服务让用户发送请求到两个独立的服务:ratings 和 reviews,就好像它们是 http://bookinfo.com 这个更大的虚拟服务的一部分。虚拟服务规则根据请求的 URI 和指向适当服务的请求匹配流量。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - bookinfo.com
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        host: reviews
  - match:
    - uri:
        prefix: /ratings
    route:
    - destination:
        host: ratings

  For some match conditions, you can also choose to select them using the exact value, a prefix, or a regex.

有些匹配条件可以使用精确的值,如前缀或正则。

  You can add multiple match conditions to the same match block to AND your conditions, or add multiple match blocks to the same rule to OR your conditions. You can also have multiple routing rules for any given virtual service. This lets you make your routing conditions as complex or simple as you like within a single virtual service. A full list of match condition fields and their possible values can be found in the HTTPMatchRequest reference.

可以使用 AND 向同一个 match 块添加多个匹配条件,或者使用 OR 向同一个规则添加多个 match 块。 对于任何给定的虚拟服务也可以有多个路由规则。这可以在单个虚拟服务中使路由条件变得随所愿的复杂或简单。匹配条件字段和备选值的完整列表可以在 HTTPMatchRequest 参考中找到。

  In addition to using match conditions, you can distribute traffic by percentage “weight”. This is useful for A/B testing and canary rollouts:

另外,使用匹配条件可以按百分比”权重“分发请求。这在 A/B 测试和金丝雀发布中非常有用:

spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 75
    - destination:
        host: reviews
        subset: v2
      weight: 25

  You can also use routing rules to perform some actions on the traffic, for example:

也可以使用路由规则在流量上执行一些操作,例如:

    • Append or remove headers.

添加或删除 header。

    • Rewrite the URL.

重写 URL。

    • Set a retry policy for calls to this destination.

为调用这一目标地址的请求设置重试策略。

四、目标规则

https://istio.io/latest/docs/concepts/traffic-management/#destination-rules

  Along with virtual services, destination rules are a key part of Istio’s traffic routing functionality. You can think of virtual services as how you route your traffic to a given destination, and then you use destination rules to configure what happens to traffic for that destination. Destination rules are applied after virtual service routing rules are evaluated, so they apply to the traffic’s “real” destination.

与虚拟服务一样, 目标规则也是 Istio 流量路由功能的关键部分。可以将虚拟服务视为将流量如何路由到给定目标地址, 然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后, 目标规则将应用于流量的“真实”目标地址。

  In particular, you use destination rules to specify named service subsets, such as grouping all a given service’s instances by version. You can then use these service subsets in the routing rules of virtual services to control the traffic to different instances of your services.

特别是,可以使用目标规则来指定命名的服务子集,例如按版本为所有给定服务的实例分组。 然后可以在虚拟服务的路由规则中使用这些服务子集来控制到服务不同实例的流量。

  Destination rules also let you customize Envoy’s traffic policies when calling the entire destination service or a particular service subset, such as your preferred load balancing model, TLS security mode, or circuit breaker settings. You can see a complete list of destination rule options in the Destination Rule reference.

目标规则还允许在调用整个目的地服务或特定服务子集时定制 Envoy 的流量策略, 比如喜欢的负载均衡模型、TLS 安全模式或熔断器设置。 在目标规则参考(https://istio.io/latest/zh/docs/reference/config/networking/destination-rule/)中可以看到目标规则选项的完整列表。

4.1、负载均衡选项

  By default, Istio uses a least requests load balancing policy, where requests are distributed among the instances with the least number of requests. Istio also supports the following models, which you can specify in destination rules for requests to a particular service or service subset.

默认情况下,Istio 使用轮询的负载均衡策略,实例池中的每个实例依次获取请求。Istio 同时支持如下的负载均衡模型, 可以在 DestinationRule 中为流向某个特定服务或服务子集的流量指定这些模型。

  • Random: Requests are forwarded at random to instances in the pool.
  • 随机:请求以随机的方式转发到池中的实例。
  • Weighted: Requests are forwarded to instances in the pool according to a specific percentage.
  • 权重:请求根据指定的百分比转发到池中的实例。
  • Round robin: Requests are forwarded to each instance in sequence.
  • 最少请求:请求被转发到最少被访问的实例。

  See the Envoy load balancing documentation for more information about each option.

查看 Envoy 负载均衡文档(https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/load_balancing)获取这部分的更多信息。

4.2、目标规则示例

 The following example destination rule configures three different subsets for the my-svc destination service, with different load balancing policies:

在下面的示例中,目标规则为 my-svc 目标服务配置了 3 个具有不同负载均衡策略的子集:

apiVersion: networking.istio.io/v1alpha3 //定义了Istio的网络API版本, 这里是 networking.istio.io/v1alpha3。
kind: DestinationRule // Istio资源的类型, 这里是DestinationRule。
metadata:
  name: my-destination-rule
spec:
  host: my-svc  //定义了目标规则的host,即这个规则应用于哪个服务,这里是my-svc。
  trafficPolicy: //定义了流量策略。
    loadBalancer:  //定义了负载均衡策略。
      simple: RANDOM  //定义了简单的随机负载均衡策略,即在没有其他条件的情况下,流量会被随机分发到后端实例。
  subsets:  //定义了服务的子集,即服务的不同版本。
  - name: v1
    labels:
      version: v1   //定义了 label 的具体value值,表示这个子集对应的服务的 v1 版本。
  - name: v2
    labels:
      version: v2
    trafficPolicy: //定义了流量策略。
      loadBalancer:  //定义了负载均衡策略。
        simple: ROUND_ROBIN //定义了简单的轮询负载均衡策略,即流量会被依次分发到后端实例。
  - name: v3
    labels:
      version: v3

五、网关

https://istio.io/latest/docs/concepts/traffic-management/#gateways

  You use a gateway to manage inbound and outbound traffic for your mesh, letting you specify which traffic you want to enter or leave the mesh. Gateway configurations are applied to standalone Envoy proxies that are running at the edge of the mesh, rather than sidecar Envoy proxies running alongside your service workloads.

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

  Unlike other mechanisms for controlling traffic entering your systems, such as the Kubernetes Ingress APIs, Istio gateways let you use the full power and flexibility of Istio’s traffic routing. You can do this because Istio’s Gateway resource just lets you configure layer 4-6 load balancing properties such as ports to expose, TLS settings, and so on. Then instead of adding application-layer traffic routing (L7) to the same API resource, you bind a regular Istio virtual service to the gateway. This lets you basically manage gateway traffic like any other data plane traffic in an Istio mesh.

与 Kubernetes Ingress API 这种控制进入系统流量的其他机制不同, Istio 网关让充分利用流量路由的强大能力和灵活性。 可以这么做的原因是 Istio 的网关资源可以配置 4-6 层的负载均衡属性, 如对外暴露的端口、TLS 设置等。然后,无需将应用层流量路由 (L7) 添加到同一 API 资源, 而是将常规 Istio 虚拟服务绑定到网关。 这让可以像管理网格中其他数据平面的流量一样去管理网关流量。

  Gateways are primarily used to manage ingress traffic, but you can also configure egress gateways. An egress gateway lets you configure a dedicated exit node for the traffic leaving the mesh, letting you limit which services can or should access external networks, or to enable secure control of egress traffic to add security to your mesh, for example. You can also use a gateway to configure a purely internal proxy.

网关主要用于管理进入的流量,但也可以配置出口网关。出口网关让为离开网格的流量配置一个专用的出口节点, 这可以限制哪些服务可以或应该访问外部网络, 或者启用出口流量安全控制增强网格安全性。 也可以使用网关配置一个纯粹的内部代理。

  Istio provides some preconfigured gateway proxy deployments (istio-ingressgateway and istio-egressgateway) that you can use - both are deployed if you use our demo installation, while just the ingress gateway is deployed with our default profile. You can apply your own gateway configurations to these deployments or deploy and configure your own gateway proxies.

Istio 提供了一些预先配置好的网关代理部署(istio-ingressgateway 和 istio-egressgateway)供使用——如果使用 demo 配置文件安装它们都已经部署好了; 如果使用的是 default 配置文件则只部署了入口网关。 可以将自己的网关配置应用到这些部署或配置自己的网关代理。

5.1 Gateway 示例

  The following example shows a possible gateway configuration for external HTTPS ingress traffic:

下面的示例展示了一个外部 HTTPS 入口流量的网关配置:

apiVersion: networking.istio.io/v1alpha3 //istio Gateway 的 API 版本
kind: Gateway  //指定了要创建的k8s的自定义资源类型,这里是 isto gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    app: my-gateway-controller  //这部分定义了哪些 pod 会被这个 Gateway 控制。这里的选择器选择了标签为 app: my-gateway-controller 的 pod。
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE  //TLS 模式设置为 SIMPLE,意味着将使用简单的证书和私钥进行 TLS 终端。
      credentialName: ext-host-cert //定义了用于 TLS 的证书和私钥的 Kubernetes Secret 的名称,这里是 ext-host-cert。
    

  This gateway configuration lets HTTPS traffic from ext-host.example.com into the mesh on port 443, but does't specify any routing for the traffic.

这个网关配置允许来自 ext-host.example.com 的HTTPS流量进入 mesh,端口为443,但没有为该流量指定任何路由。

  To specify routing and for the gateway to work as intended, you must also bind the gateway to a virtual service. You do this using the virtual service’s gateways field, as shown in the following example:

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

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService    //指定了要创建的 CRD 资源的类型为 Istio VirtualService。
metadata:
  name: virtual-svc
spec:
  hosts:
  //这里定义了 VirtualService 的主机名, 对应之前 Gateway 配置中的虚拟主机名。这意味着发送到 ext-host.example.com 的请求将被这个 VirtualService 处理。
  - ext-host.example.com
  gateways:
  /*
    这里定义了该 VirtualService 绑定到的 Gateway 的名称,即之前创建的 Gateway 资源 ext-host-gwy。
    这意味着这个 VirtualService 将附加到该 Gateway 上,并处理通过该 Gateway 进入的请求。
  */
    - ext-host-gwy

  You can then configure the virtual service with routing rules for the external traffic.

然后就可以为出口流量配置带有路由规则的虚拟服务。

六、服务入口

https://istio.io/latest/docs/concepts/traffic-management/#service-entries

  You use a service entry to add an entry to the service registry that Istio maintains internally. After you add the service entry, the Envoy proxies can send traffic to the service as if it was a service in your mesh. Configuring service entries allows you to manage traffic for services running outside of the mesh, including the following tasks:

使用服务入口(Service Entry[ˈεntrɪ] : https://istio.io/latest/docs/reference/config/networking/service-entry/#ServiceEntry) 来添加一个入口到 Istio 内部维护的服务注册中心。添加了服务入口后,Envoy 代理可以向服务发送流量, 就好像它是网格内部的服务一样。配置服务入口允许管理运行在网格外的服务的流量,它包括以下几种能力:

    • Redirect and forward traffic for external destinations, such as APIs consumed from the web, or traffic to services in legacy infrastructure.

为外部目标重定向和转发请求,例如来自 Web 端的 API 调用,或者流向遗留老系统的服务。

    • Define retry, timeout, and fault injection policies for external destinations.

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

    • Run a mesh service in a Virtual Machine (VM) by adding VMs to your mesh.

添加一个运行在虚拟机的服务来扩展的网格。

  You don’t need to add a service entry for every external service that you want your mesh services to use. By default, Istio configures the Envoy proxies to passthrough requests to unknown services.   However, you can’t use Istio features to control the traffic to destinations that aren’t registered in the mesh.

我理解的意思是:

不需要为网格服务要使用的每个外部服务都添加服务入口。 默认情况下,Istio 配置 Envoy 代理将请求传递给未知服务。 但是,不能使用 Istio 的特性来控制没有在网格中注册的目标流量。

Istio 的服务入口(Service Entry)提供了一种机制,允许你将网格外部的服务注册到 Istio 的内部服务注册中心,使得这些外部服务能够像网格内部的服务一样接收流量。然而,这并不意味着你需要为每一个外部服务都创建一个服务入口。

创建服务入口的需求取决于你如何需要控制和管理对外部服务的流量。例如,如果你需要对流向某个外部服务的流量进行特殊的控制,如重试、超时、故障注入等,那么你可能需要为这个外部服务创建一个服务入口。

另一方面,Istio 默认配置 Envoy 代理将请求传递给未知服务,如果你没有为某个外部服务创建服务入口,那么 Istio 仍然会将流量路由到这个服务,只是你无法使用 Istio 的特性来控制这个流量的行为。

至于 "添加一个运行在虚拟机的服务来扩展的网格" 这句话,是指你可以将运行在虚拟机(非 Kubernetes 集群内)的服务添加到 Istio 的服务网格中。通过创建相应的服务入口,你可以将 Istio 网格内的流量路由到这些运行在虚拟机上的服务。这样,你就可以将这些虚拟机上的服务纳入 Istio 的统一管理之下,利用 Istio 的各种特性(如流量管理、安全性、可观察性等)来提升这些服务的稳定性和可靠性。所以,Istio 也可以将流量转发给 Kubernetes 集群之外的虚拟机上的服务,以此来扩展服务网格的能力。

6.1、服务入口示例

  The following example mesh-external service entry adds the ext-svc.example.com external dependency to Istio’s service registry:

下面示例的 mesh-external 服务入口将 ext-svc.example.com 外部依赖项添加到 Istio 的服务注册中心,通过这个 ServiceEntry 配置,Istio 将能够识别和管理外部服务 ext-svc.example.com 的流量,就像它是网格内部的服务一样。你可以根据需要使用其他 Istio 的特性来控制和管理这个外部服务的流量,例如流量路由、负载均衡、故障注入等:

apiVersion: networking.istio.io/v1alpha3 //定义了 Istio 配置的 API 版本,这里使用的是 networking.istio.io/v1alpha3 版本
kind: ServiceEntry  //指定了要创建的 Istio 资源类型为 ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL //指定了这个服务的位置为网格外部(MESH_EXTERNAL)。这意味着这个服务运行在 Istio 服务网格之外
  resolution: DNS //指定了服务的解析方式为 DNS。Istio 将使用 DNS 查询来解析主机名 ext-svc.example.com 对应的 IP 地址

  You specify the external resource using the hosts field. You can qualify it fully or use a wildcard prefixed domain name.

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

  You can configure virtual services and destination rules to control traffic to a service entry in a more granular way, in the same way you configure traffic for any other service in the mesh. For example, the following destination rule adjusts the TCP connection timeout for requests to the ext-svc.example.com external service that we configured using the service entry:

可以配置虚拟服务和目标规则,以更细粒度的方式控制到服务入口的流量, 这与网格中的任何其他服务配置流量的方式相同。例如, 下面的目标规则调整了使用服务入口配置的 ext-svc.example.com 外部服务的连接超时:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ext-res-dr
spec:
  host: ext-svc.example.com
  trafficPolicy:
    connectionPool:
      tcp:
        connectTimeout: 1s

  See the Service Entry reference for more possible configuration options.

查看服务入口参考( https://istio.io/latest/zh/docs/reference/config/networking/service-entry/ )获取更多可能的配置项。

七、SideCar

https://istio.io/latest/docs/concepts/traffic-management/#sidecars

  By default, Istio configures every Envoy proxy to accept traffic on all the ports of its associated workload, and to reach every workload in the mesh when forwarding traffic. You can use a sidecar configuration to do the following:

默认情况下,Istio 让每个 Envoy 代理都可以访问来自和它关联的工作负载的所有端口的请求,然后转发到对应的工作负载。可以使用 Sidecar 配置去做下面的事情:

    • Fine-tune the set of ports and protocols that an Envoy proxy accepts.

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

    • Limit the set of services that the Envoy proxy can reach.

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

  You might want to limit sidecar reachability like this in larger applications, where having every proxy configured to reach every other service in the mesh can potentially affect mesh performance due to high memory usage.

可能希望在较庞大的应用程序中限制这样的 Sidecar 可达性, 配置每个代理能访问网格中的任意服务可能会因为高内存使用量而影响网格的性能。

  You can specify that you want a sidecar configuration to apply to all workloads in a particular namespace, or choose specific workloads using a workloadSelector. For example, the following sidecar configuration configures all services in the bookinfo namespace to only reach services running in the same namespace and the Istio control plane (needed by Istio’s egress and telemetry features):

可以指定将 Sidecar 配置应用于特定命名空间中的所有工作负载,或者使用 workloadSelector 选择特定的工作负载。例如,下面的 Sidecar 配置将 bookinfo 命名空间中的所有服务配置为仅能访问运行在相同命名空间和 Istio 控制平面中的服务 (需要使用 Istio's egress and telemetry)。这个 Sidecar 配置主要用于定义 bookinfo 命名空间中服务的出站流量规则。它影响着这些服务如何访问 istio-system 命名空间和它们自己命名空间中的其他服务。

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar //定义了配置资源的类型,这里是 Sidecar。Sidecar 是 Istio 中用于定义服务网格中服务间通信的代理配置的一种资源。
metadata:
  name: default
  namespace: bookinfo
spec:
  egress: //定义了出站流量规则,即服务如何访问外部服务。
  - hosts: //这是一个数组,定义了 egress 规则适用的主机。这里有两个主机模式:
    - "./*" //这个模式匹配任何在当前命名空间中的主机。. 表示当前命名空间,* 是一个通配符,所以这个模式匹配当前命名空间中的所有服务。
    - "istio-system/*" //这个模式匹配 istio-system 命名空间中的所有主机。这意味着任何从 bookinfo 命名空间中的服务到 istio-system 命名空间中的服务的流量都会被这个 egress 规则管理。

八、网络弹性和测试

https://istio.io/latest/docs/concepts/traffic-management/#network-resilience-and-testing

 As well as helping you direct traffic around your mesh, Istio provides opt-in failure recovery and fault injection features that you can configure dynamically at runtime. Using these features helps your applications operate reliably, ensuring that the service mesh can tolerate failing nodes and preventing localized failures from cascading to other nodes.

除了帮助引导网格周围的流量外,Istio还提供了可选择性的故障恢复和故障注入功能,可以在运行时动态配置这些功能。使用这些功能可以帮助你的应用程序可靠地运行,确保服务网格能够容忍故障节点,并防止局部故障逐级扩散到其他节点。

8.1、超时

https://istio.io/latest/docs/concepts/traffic-management/#timeouts

  A timeout is the amount of time that an Envoy proxy should wait for replies from a given service, ensuring that services don’t hang around waiting for replies indefinitely and that calls succeed or fail within a predictable timeframe. The Envoy timeout for HTTP requests is disabled in Istio by default.

超时是 Envoy 代理等待来自给定服务的答复的时间量,以确保服务不会因为等待答复而无限期的挂起, 并在可预测的时间范围内调用成功或失败。HTTP 请求的默认超时时间是 15 秒, 这意味着如果服务在 15 秒内没有响应,调用将失败。

  For some applications and services, Istio’s default timeout might not be appropriate. For example, a timeout that is too long could result in excessive latency from waiting for replies from failing services, while a timeout that is too short could result in calls failing unnecessarily while waiting for an operation involving multiple services to return. To find and use your optimal timeout settings, Istio lets you easily adjust timeouts dynamically on a per-service basis using virtual services without having to edit your service code. Here’s a virtual service that specifies a 10 second timeout for calls to the v1 subset of the ratings service:

对于某些应用程序和服务,Istio 的缺省超时可能不合适。例如,超时太长可能会由于等待失败服务的回复而导致过度的延迟; 而超时过短则可能在等待涉及多个服务返回的操作时触发不必要的失败。为了找到并使用最佳超时设置, Istio 允许您使用虚拟服务按服务轻松地动态调整超时,而不必修改您的业务代码。 下面的示例是一个虚拟服务,它对 ratings 服务的 v1 子集的调用指定 10 秒超时:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings //这表示该虚拟服务宿主的名字是"ratings"。
  http: //这部分定义了HTTP路由规则。
  - route: //这部分定义了路由规则。
    - destination: //这部分定义了请求的目标。
        host: ratings //这表示目标服务的主机名是"ratings"。
        subset: v1 //这表示目标服务的子集是"v1"。Istio可以使用标签来划分服务的子集,这个配置将请求路由到"ratings"服务的"v1"子集。
    timeout: 10s //timeout是指整个请求的超时时间,从发送请求开始到接收到响应为止。如果在timeout指定的时间内没有收到响应,那么请求将被视为超时。

8.2、重试

https://istio.io/latest/docs/concepts/traffic-management/#retries

  A retry setting specifies the maximum number of times an Envoy proxy attempts to connect to a service if the initial call fails. Retries can enhance service availability and application performance by making sure that calls don’t fail permanently because of transient problems such as a temporarily overloaded service or network. The interval between retries (25ms+) is variable and determined automatically by Istio, preventing the called service from being overwhelmed with requests. The default retry behavior for HTTP requests is to retry twice before returning the error.

重试设置指定如果初始调用失败,Envoy 代理尝试连接服务的最大次数。 重试可以通过确保调用不会由于暂时性问题(例如临时过载的服务或网络)而永久失败, 从而提高服务可用性和应用程序性能。重试之间的间隔(25ms+)是可变的,由 Istio 自动确定, 防止被调用的服务被请求淹没。HTTP 请求的默认重试行为是在返回错误之前重试两次。

  Like timeouts, Istio’s default retry behavior might not suit your application needs in terms of latency (too many retries to a failed service can slow things down) or availability. Also like timeouts, you can adjust your retry settings on a per-service basis in virtual services without having to touch your service code. You can also further refine your retry behavior by adding per-retry timeouts, specifying the amount of time you want to wait for each retry attempt to successfully connect to the service. The following example configures a maximum of 3 retries to connect to this service subset after an initial call failure, each with a 2 second timeout.

与超时一样,Istio 默认的重试行为在延迟方面可能不适合您的应用程序需求(对失败的服务进行过多的重试会降低速度)或可用性。 您可以在虚拟服务中按服务调整重试设置,而不必修改业务代码。 您还可以通过添加每次重试的超时来进一步细化重试行为,指定您希望等待每次重试成功连接到服务的时间量。 下面的示例配置了在初始调用失败后最多重试 3 次来连接到服务子集,每个重试都有 2 秒的超时。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings //这表示该虚拟服务宿主的名字是"ratings"。
  http: //这部分定义了HTTP路由规则。
  - route: //这部分定义了路由规则。
    - destination: //这部分定义了请求的目标。
        host: ratings //这表示目标服务的主机名是"ratings"。
        subset: v1 //这表示目标服务的子集是"v1"。Istio可以使用标签来划分服务的子集,这个配置将请求路由到"ratings"服务的"v1"子集。
    retries: //这部分定义了重试策略。
      attempts: 3 //这表示如果一个请求失败, 将尝试重新发送请求3次。
      /*
        这表示每次尝试请求的超时时间是2秒。
        1、perTryTimeout 是在重试策略 (retries) 中使用的, 它指定了每次重试的超时时间。
        2、如果在一次尝试 (或重试) 中, 在 perTryTimeout 指定的时间内没有收到响应,那么这一次尝试将被视为超时,并可能触发下一次重试(根据重试策略)。
        3、配置示例中,perTryTimeout: 2s表示每次重试的超时时间是2秒。
        4、如果没有定义重试策略(即没有retries字段),那么perTryTimeout将不起作用。
      */
      perTryTimeout: 2s
    

8.3、熔断器

https://istio.io/latest/docs/concepts/traffic-management/#circuit-breakers

  Circuit breakers are another useful mechanism Istio provides for creating resilient microservice-based applications. In a circuit breaker, you set limits for calls to individual hosts within a service, such as the number of concurrent connections or how many times calls to this host have failed. Once that limit has been reached the circuit breaker “trips” and stops further connections to that host. Using a circuit breaker pattern enables fast failure rather than clients trying to connect to an overloaded or failing host.

熔断器是 Istio 为创建具有弹性的微服务应用提供的另一个有用的机制。在熔断器中, 设置一个对服务中的单个主机调用的限制,例如并发连接的数量或对该主机调用失败的次数。 一旦限制被触发,熔断器就会“跳闸”并停止连接到该主机。 使用熔断模式可以快速失败而不必让客户端尝试连接到过载或有故障的主机。

  As circuit breaking applies to “real” mesh destinations in a load balancing pool, you configure circuit breaker thresholds in destination rules, with the settings applying to each individual host in the service. The following example limits the number of concurrent connections for the reviews service workloads of the v1 subset to 100:

熔断适用于在负载均衡池中的“real”网格目标地址,您可以在目标规则中配置熔断器阈值, 让配置应用于服务中的每个主机。下面的示例将 v1 子集的 reviews 服务工作负载的并发连接数限制为 100:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule //指定了要创建的 Istio 资源对象的类型是 DestinationRule
metadata:
  name: reviews
spec:
  host: reviews //指定了这个 DestinationRule 应用的服务的主机名是 reviews
  subsets:  //定义了一个或多个服务的子集
  - name: v1 //定义了一个子集的名称是 v1
    labels:
      version: v1
    trafficPolicy: //定义了应用于这个子集的流量策略
      connectionPool: //定义了连接池的设置
        tcp:  //义了 TCP 连接池的设置
          maxConnections: 100 //指定了 TCP 连接池的最大连接数是 100
        

8.4、故障注入

https://istio.io/latest/docs/concepts/traffic-management/#circuit-breakers

  After you’ve configured your network, including failure recovery policies, you can use Istio’s fault injection mechanisms to test the failure recovery capacity of your application as a whole. Fault injection is a testing method that introduces errors into a system to ensure that it can withstand and recover from error conditions. Using fault injection can be particularly useful to ensure that your failure recovery policies aren’t incompatible or too restrictive, potentially resulting in critical services being unavailable.

在配置了网络,包括故障恢复策略之后,可以使用 Istio 的故障注入机制来为整个应用程序测试故障恢复能力。 故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。 使用故障注入特别有用,能确保故障恢复策略不至于不兼容或者太严格,这会导致关键服务不可用。

目前,故障注入配置不能与同一个虚拟服务上的重试或超时配置相结合, 请参见流量管理问题 (https://istio.io/latest/docs/ops/common-problems/network-issues/#virtual-service-with-fault-injection-and-retrytimeout-policies-not-working-as-expected)。

  Unlike other mechanisms for introducing errors such as delaying packets or killing pods at the network layer, Istio’ lets you inject faults at the application layer. This lets you inject more relevant failures, such as HTTP error codes, to get more relevant results.

与其他错误注入机制(如延迟数据包或在网络层杀掉 Pod)不同,Istio 允许在应用层注入错误。 这使您可以注入更多相关的故障,例如 HTTP 错误码,以获得更多相关的结果。

  You can inject two types of faults, both configured using a virtual service:

您可以注入两种故障,它们都使用虚拟服务配置:

    • Delays: Delays are timing failures. They mimic increased network latency or an overloaded upstream service.
    • 延迟:延迟是时间故障。它们模拟增加的网络延迟或一个超载的上游服务。

    • Aborts: Aborts are crash failures. They mimic failures in upstream services. Aborts usually manifest in the form of HTTP error codes or TCP connection failures.
    • 终止:终止是崩溃失败。他们模仿上游服务的失败。终止通常以 HTTP 错误码或 TCP 连接失败的形式出现。

  For example, this virtual service introduces a 5 second delay for 1 out of every 1000 requests to the ratings service.

例如,下面的 Virtual service 为千分之一的访问 ratings 服务的请求配置了一个 5 秒的延迟:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings  //表示该规则适用于主机名为 "ratings" 的服务
  http: //定义了 HTTP 流量的路由规则
  - fault: //故障注入的配置
      delay: //延迟故障注入的配置
        percentage:
          value: 0.1 //表示 10% 的请求会受到故障注入的影响
        fixedDelay: 5s //表示注入的延迟时间为 5 秒
    route: //定义了请求的路由规则
    - destination:
        host: ratings //指定目标服务的主机名为 "ratings"
        subset: v1 //指定目标服务的子集为 "v1"
    

8.5、和你的应用程序一起运行

https://istio.io/latest/docs/concepts/traffic-management/#working-with-your-applications

  Istio failure recovery features are completely transparent to the application. Applications don’t know if an Envoy sidecar proxy is handling failures for a called service before returning a response. This means that if you are also setting failure recovery policies in your application code you need to keep in mind that both work independently, and therefore might conflict. For example, suppose you can have two timeouts, one configured in a virtual service and another in the application. The application sets a 2 second timeout for an API call to a service. However, you configured a 3 second timeout with 1 retry in your virtual service. In this case, the application’s timeout kicks in first, so your Envoy timeout and retry attempt has no effect.

Istio 故障恢复功能对应用程序来说是完全透明的。在返回响应之前, 应用程序不知道 Envoy Sidecar 代理是否正在处理被调用服务的故障。这意味着, 如果在应用程序代码中设置了故障恢复策略,那么您需要记住这两个策略都是独立工作的, 否则会发生冲突。例如,假设您设置了两个超时,一个在虚拟服务中配置, 另一个在应用程序中配置。应用程序为服务的 API 调用设置了 2 秒超时。 而您在虚拟服务中配置了一个 3 秒超时和重试。在这种情况下,应用程序的超时会先生效, 因此 Envoy 的超时和重试尝试会失效。

  While Istio failure recovery features improve the reliability and availability of services in the mesh, applications must handle the failure or errors and take appropriate fallback actions. For example, when all instances in a load balancing pool have failed, Envoy returns an HTTP 503 code. The application must implement any fallback logic needed to handle the HTTP 503 error code.

虽然 Istio 故障恢复特性提高了网格中服务的可靠性和可用性, 但应用程序必须处理故障或错误并采取适当的回退操作。 例如, 当负载均衡中的所有实例都失败时, Envoy 返回一个 HTTP 503 代码。 应用程序必须实现回退逻辑来处理 HTTP 503 错误代码。

posted @ 2023-11-17 09:35  左扬  阅读(155)  评论(0编辑  收藏  举报
levels of contents