ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

01 Istio Crd

Istio-CRD

《云原生服务网格Istio:原理、实践、架构与源码解析 - 张超盟 等(2019)》

类比nginx,istio的crd可以理解为envoy的配置文件片段,这些片段有pilot转换生成envoy真正可用的配置,让envoy来加载使用。

nginx.conf   					--->					nginx
virtual-service(crd) 	--->					envoy

VirtualService

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

虚拟服务:定义路由规则。描述满足条件的请求去哪里。描述的主体是一个服务,而不是一组规则。该服务中包含了路由规则。

VirtualService定义了访问地址和路由目标的联系,它将流量如何路由到给定目标地址。(对特定的目标进行定义路由规则)

一个不是很准确的理解:VirtualService可以理解为是k8s中的Service的替代品(替换host指定的k8s的Service),不过这个替代品只要在网格内的请求才会使用(请求的发起端和接收端都在网格内)。如果不是服务网格内的请求,则会使用原生的k8s的Service。之所以说不准确,是指host不仅仅是指k8s中的Service,也可能是ingress-gateway中定义的host,也可能是通配符“*”或通配符“*”前缀。

image-20210701135701451

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService  #本质上是envoy的配置文件片段。定义了访问hosts中指定的目标服务时,如何路由
metadata:
  name: reviews
spec:
  hosts:  #请求的目标服务地址(流量发送的目标),类似于nginx上的虚拟主机的域名:如果在服务网格内的请求这个host时,就会请求这个vs,这个vs中的路由规则会生效(即服务网格中对这个host的请求,VirtualService替代了k8s的Service)。
  - reviews  #host可以是k8s中的svc、istio的ingressgateway中定义的host或通配符“*”(或前缀)。表示访问这个host的请求将被应用下面定义的路由规则。如果是短域名,会补全VirtualService所在的名称空间。
  gateways:  	#表示应用这些路由规则的gateway。
  						#VirtualService 描述的规则可以作用到网格里的Sidecar和入口处的Gateway,表示将路由规则应用于网格内的访问还是网格外经过Gateway的访问。
  							#如果服务只是在网格内访问的,gateways字段可以省略。定义的规则只作用到网格内的Sidecar。(最常用的场景)
  							#如果服务只是在网格外访问的。配置要关联的Gateway,表示对应Gateway进来的流量执行在这个VirtualService上定义的流量规则。
  							#如果在服务网格内和网格外都需要访问。这里要给这个数组字段至少写两个元素,一个是外部访问的Gateway,另一个是保留关键字“mesh”。使用中的常见问题是忘了配置“mesh”这个常量而导致错。
  - ext-host-gwy  #Gateway名称,(也可以写为ext-host-gwy.istio-system.svc.cluster.local?)
  - mesh					#保留关键字“mesh”,表示来自网格内访问
  http:  #定义http路由规则:多个匹配路由规则,从上往下,依次匹配,匹配到就结束,不再匹配后续的匹配规则(匹配到的第1个规则生效)
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:  #请求目标,最终的流量要被送到这个目标上。是由DestinationRule定义,可以是Destination中定义的服务,也可以是Destination中定义的服务子集。
        host: reviews  #host表示在Istio 中注册的服务名,不但包括网格内的服务,也包括通过ServiceEntry方式注册的外部服务。在Kubernetes平台上如果用到短域名,Istio 就会根据规则的命名空间解
        subset: v2  #表示在host上定义的一个子集
  - route:  #缺省match条件,表示都匹配。
    - destination:
        host: reviews
        subset: v3
  #exportTo:     #(6) exportTo用于控制VirtualService 跨命名空间的可见性,这样就可以控制在一个命名空间下定义的VirtualService是否可以被其他命名空间下的Sidecar和Gateway使用了。如果未赋值,则默认全局可见。“.”表示仅应用到当前命名空间,“*”表示应用到所有命名空间。在Istio 1.1中只支持“.”和“*”这两种配置。

HTTPRoute规则的功能是:满足HTTPMatchRequest条件的流量都被路由到HTTPRouteDestination,执行重定向 (HTTPRedirect)、重写 (HTTPRewrite)、重试 (HTTPRetry)、故障注入(HTTPFaultInjection)、跨站 (CorsPolicy) 策略等。HTTP 不仅可以做路由匹配,还可以做一些写操作来修改请求本身,对用户来说非常灵活。

image-20210628113120570

image-20210701140206231

示例:基于权重

spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 75  #表示流量分配的比例,在一个route下多个destination的weight总和要求是100。如果一个route只有一个destination,那么可以不用配置weight,默认就是100。
    - destination:
        host: reviews
        subset: v2
      weight: 25
#在下面的示例中,match包含两个HTTPMatchRequest元素,2个元素直接是或的关系,元素中属性出与关系:其条件的语义是:headers中的source取值为“north”,并且uri以“/advertisement”开头的请求,或者uri以“/forecast”开头的请求。
- match:
	- headers:
      source:
        exact: north
    uri:
      prefix: "/advertisement/"
	- uri:
      prefix: "/forecast/"

DestinationRule

参考文档:https://istio.io/latest/zh/docs/concepts/traffic-management/#destination-rules

目标规则:定义服务子集、策略。描述到达目标的请求怎么处理。

image-20210701140951427

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc  #表示规则的适用对象,取值是在服务注册中心中注册的服务名,可以是网格内的服务,也可以是以ServiceEnrty方式注册的网格外的服务。如果这个服务名在服务注册中心不存在,则这个规则无效。host如果取短域名,则会根据规则所在的命名空间进行解析.
  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

Gateway

文档:https://istio.io/latest/zh/docs/concepts/traffic-management/#virtual-service-example

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

功能:由于外部流量不在网格内部,所以无法对外部流量进行流量治理。采用ingress gateway,可以将外部流量加入到服务网格内,从而实现流量治理。

作用:只定义了envoy的􏱜􏱻􏵓􏵏􏵅􏷝􏱜􏱻􏵓􏵏􏵅􏷝􏱜􏱻􏵓􏵏􏵅􏷝接入点(监听端口和host,类似nginx的listen和server_name命令),只做4层到6层的端口、tls相关配置,7层的相关配置在virtualService上进行。

image-20210701142350353

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector: #必选字段,表示Gateway负载,为入口处的Envoy运行的Pod的标签,通过这个标签来找到执行Gateway规则的Envoy。社区推荐Gateway的规则定义和Gateway的Envoy负载在同一个命名空间下。
    app: my-gateway-controller  #该配置会应用到哪个pod上(位于istio-system名称空间下istio-ingressgateway)
  servers:
  - port: #必选字段,描述服务在哪个端口对外开放,是对外监听的端口。
      number: 443
      name: https
      protocol: HTTPS
    hosts:  #必选字段,为Gateway 发布的服务地址,是一个FQDN 域名,可以支持左侧通配符来进行模糊匹配
    - ext-host.example.com  #绑定到一个Gateway上的VirtualService,其hosts必须匹配这里的hosts条件,支持精确匹配和模糊匹配
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key

egress使用,见《云原生服务网格Istio:原理、实践、架构与源码解析 - 张超盟 等(2019)》3.5章节

ServiceEntry

文档:https://istio.io/latest/zh/docs/concepts/traffic-management/#virtual-service-example

ServiceEntry:将网格外的服务加入网格中,像网格内的服务一样进行管理。

image-20210701184454218

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

(1) hosts:是一个必选字段,表示与 ServiceEntry 相关的主机名,可以是一个 DNS域名,还可以使用前缀模糊匹配。在使用上有以下几点需要说明。

  • HTTP的流量,这个字段匹配HTTP Header的Host或Authority。
  • HTTPS或TLS的流量,这个字段匹配SNI。
  • 其他协议的流量,这个字段不生效,使用下面的addresses和port字段。
  • 当resolution被设置为DNS类型并且没有指定endpoints时,这个字段将用作后端的域名来进行路由。

(2) addresses:表示与服务关联的虚拟IP地址,可以是CIDR这种前缀表达式。对于HTTP的流量,该字段被忽略,而是使用Header中的Host或Authority。如果addresses为空,则只能根据目标端口来识别,在这种情况下这个端口不能被网格里的其他服务使用。即Sidecar只是作为一个TCP代理,把某个特定端口的流量转发到配置的目标后端。

(3) ports:表示与外部服务关联的端口,是一个必选字段。 (4) location:用于设置服务是在网格内部还是在网格外部。可以取以下两种模式。

  • MESH_EXTERNAL:表示在网格外部,通过API访问的外部服务。示例中的“ext-svc.example.com”就是一个外部服务。

  • MESH_INTERNAL:表示在网格内部,一些不能直接注册到网格服务注册中心的服务,例如一些虚机上的服务不能通过Kubernetes机制自动在Istio中进行服务注册,通过这种方式可以扩展网格管理的服务。

    location 字段会影响mTLS双向认证、策略执行等特性。当和网格外部服务通信时,mTLS双向认证将被禁用,并且策略只能在客户端执行,不能在服务端执行。因为对于外部服务,远端不可能注入一个Sidecar来进行双向认证等操作。

(5) resolution 是一个内容较多的必选字段,表示服务发现的模式,用来设置代理解析服务的方式,将一个服务名解析到一个后端IP地址上,可以设置NONE、STATIC、DNS三种模式。另外,这里配置的解析模式不影响应用的服务名解析,应用仍然使用DNS将服务解析到IP上,这样Outbound流量会被Envoy拦截。

  • NONE:用于当连接的目标地址已经是一个明确IP的场景。当访问外部服务且应用要被解析到一个特定的IP上时,要将模式设为NONE。
  • STATIC:用在已经用endpoints设置了服务实例的地址场景中,即不用解析。
  • DNS:表示用查询环境中的DNS进行解析。如果没有设置endpoints,代理就会使用在hosts中指定的DNS地址进行解析,前提是在hosts中未使用通配符;如果设置了endpoints,则使用endpoints中的DNS地址解析出目标IP。在3.5.1节的配置示例中使用hosts的值“ext-svc.example.com”进行解析。

Sidecar

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

用于对Istio数据面的Envoy行为进行更精细的控制,例如控制Envoy转发和接收的端口、协议等,并可以限制Sidecar Outbound流量允许到达的目标服务集合。

如下所示配置了一组基于命名空间描述的 Egress,定义了bookinfo这个命名空间下的Sidecar只可以访问istio-system和bookinfo两个命名空间下的服务:

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - "./*"  #点表示当前名称空间,即bookinfos
    - "istio-system/*"