istio-控制 Ingress 流量 (Gateway VirtualService)
Istio Ingress Gateway
Istio 服务网格中的网关
使用网关为网格来管理入站和出站流量,可以让用户指定要进入或离开网格的流量。
使用网关为网格来管理入站和出站流量,可以让用户指定要进入或离开网格的流量。
网关配置被用于运行在网格内独立 Envoy 代理中,而不是服务工作负载的应用 Sidecar 代理。
Gateway
用于为 HTTP / TCP 流量配置负载均衡器,并不管该负载均衡器将在哪里运行。网格中可以存在任意数量的 Gateway
,并且多个不同的 Gateway
实现可以共存。实际上,通过在配置中指定一组工作负载(Pod)标签,可以将 Gateway 配置绑定到特定的工作负载,从而允许用户通过编写简单的 Gateway Controller 来重用现成的网络设备。
Gateway
只用于配置 L4-L6 功能(例如,对外公开的端口,TLS 配置),所有主流的 L7 代理均以统一的方式实现了这些功能。然后,通过在 Gateway
上绑定 VirtualService
的方式,可以使用标准的 Istio 规则来控制进入 Gateway
的 HTTP 和 TCP 流量。
考虑到上述因素,v1alpha3引入了以下这些新的配置资源来控制进入网格,网格内部和离开网格的流量路由。
- Gateway:gateway资源可以将网格内部的服务暴露给网格外部的服务,供网格外部的服务调用,该资源描述了需要公开的端口、端口的协议类型、以及域名等。
- VirtualService:virtualService用来与Gateway绑定,实现服务访问路由控制、服务版本与流量的控制。
- DestinationRule:外部请求经过VirtualService的路由规则后,如果目标服务设置了dr,那么dr配置的目标服务策略会生效。
- ServiceEntry:将网格外的服务加到服务发现中,就像是网格内的服务一样被治理(成为k8s中的一个service),如网格外的mysql、redis等服务,或是部署在物理机上未加入网格内部的服务。将ServiceEntry描述的service加到服务发现中,对这些服务的outbound流量进行拦截,从而进行治理。
当ServiceEntry描述的service有endpoint变化时,我们可以监听其变化,利用k8s基建,创建或者删除k8s该service的endpoint,由于istio的服务发现依赖于k8s,该变化会被istio pilot-discovery感知到,并通过xDs通知envoy。
VirtualService,DestinationRule和ServiceEntry分别替换了原API中的RouteRule,DestinationPolicy和EgressRule。 Gateway是一个独立于平台的抽象,用于对流入专用中间设备的流量进行建模。
下图描述了跨多个配置资源的控制流程。 不同配置资源之间的关系
gateway
Gateway也可以看作网格的负载均衡器, 提供以下功能: 1) L4-L6的负载均衡 2) 对外的mTLS Istio服务网格中, Gateway可以部署任意多个,可以共用一个,也可以每个租户、 namespace单独隔离
Gateway用于为HTTP / TCP流量配置负载均衡器,并不管该负载均衡器将在哪里运行。 网格中可以存在任意数量的Gateway,并且多个不同的Gateway实现可以共存。 实际上,通过在配置中指定一组工作负载(Pod)标签,可以将Gateway配置绑定到特定的工作负载,从而允许用户通过编写简单的Gateway Controller来重用现成的网络设备。
对于入口流量管理,您可能会问: 为什么不直接使用Kubernetes Ingress API ? 原因是Ingress API无法表达Istio的路由需求。 Ingress试图在不同的HTTP代理之间取一个公共的交集,因此只能支持最基本的HTTP路由,最终导致需要将代理的其他高级功能放入到注解(annotation)中,而注解的方式在多个代理之间是不兼容的,无法移植。
Istio Gateway 通过将L4-L6配置与L7配置分离的方式克服了Ingress的这些缺点。 Gateway只用于配置L4-L6功能(例如,对外公开的端口,TLS配置),所有主流的L7代理均以统一的方式实现了这些功能。 然后,通过在Gateway上绑定VirtualService的方式,可以使用标准的Istio规则来控制进入Gateway的HTTP和TCP流量。
例如,下面这个简单的Gateway配置了一个Load Balancer,以允许访问host bookinfo.com的https外部流量入mesh中:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: servers: - port: number: 443 name: https protocol: HTTPS hosts: - bookinfo.com tls: mode: SIMPLE serverCertificate: /tmp/tls.crt privateKey: /tmp/tls.key
要为进入上面的Gateway的流量配置相应的路由,必须为同一个host定义一个VirtualService(在下一节中描述),并使用配置中的gateways字段绑定到前面定义的Gateway
VirtualService
用一种叫做“Virtual services”的东西代替路由规则可能看起来有点奇怪,但对于它配置的内容而言,这事实上是一个更好的名称,特别是在重新设计API以解决先前模型的可扩展性问题之后。
实际上,发生的变化是:在之前的模型中,需要用一组相互独立的配置规则来为特定的目的服务设置路由规则,并通过precedence字段来控制这些规则的顺序;在新的API中,则直接对(虚拟)服务进行配置,该虚拟服务的所有规则以一个有序列表的方式配置在对应的VirtualService 资源中。
在v1alph3,可以在单个VirtualService资源中提供相同的配置:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - match: - headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$" route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v1
VirtualService描述了一个或多个用户可寻址目标到网格内实际工作负载之间的映射。在上面的示例中,这两个地址是相同的,但实际上用户可寻址目标可以是任何用于定位服务的,具有可选通配符前缀或CIDR前缀的DNS名称。 这对于应用从单体架构到微服务架构的迁移过程特别有用,单体应用被拆分为多个独立的微服务后,采用VirtaulService可以继续把多个微服务对外暴露为同一个目标地址,而不需要服务消费者进行修改以适应该变化。
例如,以下规则允许服务消费者访问Bookinfo应用程序的reviews和ratings服务,就好像它们是http://bookinfo.com/(虚拟)服务的一部分:
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 ...
实际上在`VirtualService`中hosts部分设置只是虚拟的目的地,因此不一定是已在网格中注册的服务。这允许用户为在网格内没有可路由条目的虚拟主机的流量进行建模。 通过将VirtualService绑定到同一Host的Gateway配置(如前一节所述 ),可向网格外部暴露这些Host。
除了这个重大的重构之外, VirtualService还包括其他一些重要的改变:
- 可以在VirtualService配置中表示多个匹配条件,从而减少对冗余的规则设置。
- 每个服务版本都有一个名称(称为服务子集)。 属于某个子集的一组Pod/VM在DestinationRule定义,具体定义参见下节。
- 通过使用带通配符前缀的DNS来指定VirtualService的host,可以创建单个规则以作用于所有匹配的服务。 例如,在Kubernetes中,在’VirtualService’中使用*.foo.svc.cluster.local作为host,可以对foo命名空间中的所有服务应用相同的重写规则。
DestinationRule
DestinationRule配置将流量转发到服务时应用的策略集。 这些策略应由由服务提供者撰写,用于描述断路器,负载均衡设置,TLS设置等。 除了下述改变外,DestinationRule与其前身DestinationPolicy大致相同。
DestinationRule的host可以包含通配符前缀,以允许单个规则应用于多个服务。
DestinationRule定义了目的host的子集subsets (例如:命名版本)。
这些subset用于`VirtualService`的路由规则设置中,可以将流量导向服务的某些特定版本。
通过这种方式为版本命名后,可以在不同的virtual
service中明确地引用这些命名版本的ubset,简化Istio代理发出的统计数据,并可以将subsets编码到SNI头中。
为reviews服务配置策略和subsets的DestinationRule可能如下所示:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews 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
注意,与DestinationPolicy不同的是,可在单个DestinationRule中指定多个策略(例如上面实例中的缺省策略和v2版本特定的策略)。
ServiceEntry
ServiceEntry用于将附加条目添加到Istio内部维护的服务注册表中。 它最常用于对访问网格外部依赖的流量进行建模,例如访问Web上的API或遗留基础设施中的服务。
所有以前使用EgressRule进行配置的内容都可以通过ServiceEntry轻松完成。 例如,可以使用类似这样的配置来允许从网格内部访问一个简单的外部服务:
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: foo-ext spec: hosts: - foo.com ports: - number: 80 name: http protocol: HTTP
也就是说,ServiceEntry比它的前身具有更多的功能。首先,ServiceEntry不限于外部服务配置,它可以有两种类型:网格内部或网格外部。网格内部条目只是用于向网格显式添加服务,添加的服务与其他内部服务一样。采用网格内部条目,可以把原本未被网格管理的基础设施也纳入到网格中(例如,把虚机中的服务添加到基于Kubernetes的服务网格中)。网格外部条目则代表了网格外部的服务。对于这些外部服务来说,mTLS身份验证是禁用的,并且策略是在客户端执行的,而不是在像内部服务请求一样在服务器端执行策略。
由于ServiceEntry配置只是将服务添加到网格内部的服务注册表中,因此它可以像注册表中的任何其他服务一样,与VirtualService和/或DestinationRule一起使用。例如,以下DestinationRule可用于启动外部服务的mTLS连接:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: foo-ext spec: name: foo.com trafficPolicy: tls: mode: MUTUAL clientCertificate: /etc/certs/myclientcert.pem privateKey: /etc/certs/client_private_key.pem caCertificates: /etc/certs/rootcacerts.pem
创建和删除v1alpha3路由规则
由于一个特定目的地的所有路由规则现在都存储在单个VirtualService
资源的一个有序列表中,因此为该目的地添加新的规则不需要再创建新的RouteRule
,而是通过更新该目的地的VirtualService
资源来实现。
旧的路由规则:
istioctl create -f my-second-rule-for-destination-abc.yaml
v1alpha3
路由规则:
istioctl replace -f my-updated-rules-for-destination-abc.yaml
删除路由规则也使用istioctl replace完成,当然删除最后一个路由规则除外(删除最后一个路由规则需要删除VirtualService
)。
在添加或删除引用服务版本的路由时,需要在该服务相应的DestinationRule
更新subsets 。 正如你可能猜到的,这也是使用istioctl replace
完成的。
Gateway
配置信息
Field | Type | Description | Required |
---|---|---|---|
servers | Server[] | 开放的服务列表 | 是 |
selector | map | 通过这个Label来找到执行 Gateway 规则的 Envoy | 是 |
Server
配置信息
Field | Type | Description | Required |
---|---|---|---|
port | Port | 服务对外监听的端口 | 是 |
hosts | string[] | Gateway 发布的服务地址,是一个 FQDN 域名,可以支持左侧通配符来进行模糊查询 | 是 |
tls | TLSOptions | TLS安全配置 | 否 |
defaultEndpoint | string | 默认情况下,应将流量转发到的环回IP端点或Unix域套接字 | 否 |
Port
配置信息
Field | Type | Description | Required |
---|---|---|---|
number | uint32 | 一个有效的端口号 | 是 |
protocol | string | 所使用的协议,支持HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS. | 是 |
name | string | 给端口分配一个名称 | 否 |
Server.TLSOptions
配置信息
Field | Type | Description | Required |
---|---|---|---|
httpsRedirect | bool | 是否要做 HTTP 重定向 | 否 |
mode | TLSmode | 在配置的外部端口上使用 TLS 服务时,可以取 PASSTHROUGH、SIMPLE、MUTUAL、AUTO_PASSTHROUGH 这 4 种模式 | 否 |
serverCertificate | string | 服务端证书的路径。当模式是 SIMPLE 和 MUTUAL 时必须指定 | 否 |
privateKey | string | 服务端密钥的路径。当模式是 SIMPLE 和 MUTUAL 时必须指定 | 否 |
caCertificates | string | CA 证书路径。当模式是 MUTUAL 时指定 | 否 |
credentialName | string | 用于唯一标识服务端证书和秘钥。Gateway 使用 credentialName从远端的凭证存储中获取证书和秘钥,而不是使用 Mount 的文件 | 否 |
subjectAltNames | string[] | SAN 列表,SubjectAltName 允许一个证书指定多个域名 | 否 |
verifyCertificateSpki | string[] | 授权客户端证书的SKPI的base64编码的SHA-256哈希值的可选列表 | 否 |
verifyCertificateHash | string[] | 授权客户端证书的十六进制编码SHA-256哈希值的可选列表 | 否 |
minProtocolVersion | TLSProtocol | TLS 协议的最小版本 | 否 |
maxProtocolVersion | TLSProtocol | TLS 协议的最大版本 | 否 |
cipherSuites | string[] | 指定的加密套件,默认使用 Envoy 支持的加密套件 | 否 |
Server.TLSOptions.TLSmode
配置信息
Name | Description |
---|---|
PASSTHROUGH | 客户端提供的SNI字符串将用作VirtualService TLS路由中的匹配条件,以根据服务注册表确定目标服务 |
SIMPLE | 使用标准TLS语义的安全连接 |
MUTUAL | 通过提供服务器证书进行身份验证,使用双边TLS来保护与下游的连接 |
AUTO_PASSTHROUGH | 与直通模式相似,不同之处在于具有此TLS模式的服务器不需要关联的VirtualService即可从SNI值映射到注册表中的服务。目标详细信息(例如服务/子集/端口)被编码在SNI值中。代理将转发到SNI值指定的上游(Envoy)群集(一组端点)。 |
ISTIO_MUTUAL | 通过提供用于身份验证的服务器证书,使用相互TLS使用来自下游的安全连接 |
Server.TLSOptions.TLSProtocol
配置信息
Name | Description |
---|---|
TLS_AUTO | 自动选择DLS版本 |
TLSV1_0 | TLS 1.0 |
TLSV1_1 | TLS 1.1 |
TLSV1_2 | TLS 1.2 |
TLSV1_3 | TLS 1.3 |
参考:
https://preliminary.istio.io/zh/docs/concepts/traffic-management/#gateways
https://preliminary.istio.io/zh//blog/2018/v1alpha3-routing/
https://preliminary.istio.io/zh/docs/reference/config/networking/gateway/#Gateway
https://blog.csdn.net/fly910905/article/details/103969825
https://www.cnblogs.com/haoyunlaile/p/12882622.html
https://blog.csdn.net/liyunlong41/article/details/106097892