Istio service entry
访问网格外部目标
-
Sidecar Egress Listener如何处理访问外部目标的流量?
-
在默认“ALLOW_ANY”外部流量策略下,Sidecar Envoy支持将这些流量直接Passthrough到外部的端点之上
-
但这些外部目标流量无法纳入到治理体系中,实施如retry、timeout和fault injection一类的功能
-
- ServiceEntry CR就用于向Istio内部维护的服务注册表(Registry)上手动添加注册项(即Entry)从而将那些未能自动添加至网格中的服务,以手动形式添加至网格中
- 向Istio的服务注册表添加一个ServiceEntry后,网格中的Envoy可以流量发送给该Service,其行为与访问网格中原有的服务并无本质上的不同;
- 于是,有了ServiceEntry,用户也就能像治理网格内部流量一样来治理那些访问到网格外部的服务的流量
ServiceEntry
- ServiceEntry用于将未能自动添加至网格中的服务,以手动形式添加至网格中,以使得网格内的自动发现机制能够访问或路由到这些服务
-
未能自动添加至网格中的服务的类型
-
网格外部的服务
-
运行于Kubernetes上,但却非为Istio网格管理的名称空间中的Pod上,或者是Kubernetes集群外部的VM或裸服务器上
-
在ServiceEntry中,这类服务称为MESH_EXTERNAL
-
-
位于网格内部但自身并未注册于Istio注册表的服务,也能够手动添加至Istio的内部的服务注册表中
-
运行于Istio网格内部,但未能自动注册到Istio注册表中
-
在ServiceEntry中,这类服务称为MESH_INTERNAL
-
-
-
ServiceEntry的功能
-
重定向和转发访问外部目标的流量,例如那些访问网格外部的传统服务的流量;
-
为外部的目标添加retry、timeout、fault injection和circuit breaker等一类的功能;
-
将VM(Virtual Machine)添加至网格中,从而能够在VM上运行网格的服务;
-
将不同集群中的服务添加至网格中,从而在Kubernetes上配置多集群的Istio网格;
注意事项
- 访问外部服务时,Sidecar Envoy本身就支持将这些流量直接Passthrough到外部的端点之上,因此,定义ServiceEntry并非必须进行的操作;
-
ServiceEntry主要是为更好地治理这些流量而设计;
- 但ServiceEntry只是为更好地治理这些访问到外部的流量提供了接口,具体的治理机制还要靠VirtualService和DestinationRule进行定义;
ServiceEntry CR资源的定义
- ServiceEntry本身用于描述要引入的外部服务的属性,主要包括服务的DNS名称、IP地址、端口、协议和相关的端点等;
- 端点的获取方式有三种:
-
DNS名称解析
-
静态指定:直接指定要使用端点
-
使用workloadSelector:基于标签选择器匹配Kubernetes Pod,或者由WorkloadEntry CR引入到网格中的外部端点
-
ServiceEntry关键配置项
- hosts:用于在VirtualServices和DestinationRules中选择匹配的主机,通常需要指定外部服务对应的主机名或DNS域名;
-
HTTP流量中,对应于HTTP标头中的Host/Authority;
-
HTTPS/TLS流量中,对应于SNI;
-
-
location:服务的位置
-
MESH_EXTERNAL:表示服务在网格外部,需要通过API进行访问接口;
-
MESH_INTERNAL:表示服务是网格的一部分,通常用于在扩展网格时显式进行服务添加;
-
-
ports:服务使用的端口
-
resolution:服务的解析方式,用于指定如何解析与服务关联的各端点(endpoint)的IP地址
-
NONE:假设传入的连接已经被解析到特定的IP地址;
-
STATIC:使用endpoints字段中指定 的静态IP地址作为与服务关系的实例;
-
DNS:通过异步查询DNS来解析IP地址;类似于Envoy Cluster发现Endpoint的STRICT_DNS
- DNS_ROUND_ROBIN:通过异步查询DNS来解析IP地址,但与前者不同的是,仅在需要启动新连接时使用返回的第一个IP地址,而不依赖于DNS解析的完整结果;类似于Envoy Cluster发现Endpoint的LOGICAL_DNS
-
- endpoints:静态指定的各端点,定义端点的关键字段为address和ports;
- workloadSelector:使用标签选择器动态选择ServiceEntry要用到的端点,但不能与endpoints同时使用;支持选择:
-
由WorkloadEntry CR定义的外部端点对象
-
Kubernetes集群上特定Pod对象
-
ServiceEntry CR 资源规范
~# kubectl explain serviceentry
KIND: ServiceEntry
VERSION: networking.istio.io/v1beta1
DESCRIPTION:
<empty>
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Configuration affecting service registry. See more details at:
https://istio.io/docs/reference/config/networking/service-entry.html
status <>
ServiceEntry的逻辑意义
- ServiceEntry之于Istio来说,其功能类似于自动发现并注册的Service对象,主要负责于网格中完成如下功能
- 基于指定的端口创建Listener,若已存在相应的侦听器,则于侦听器上基于hosts的定义,生成VirtualHost
-
基于解析(resolution)得到的端点创建Cluster
- 生成Route Rule,设定侦听器将接收到的发往相应VirtualHost的流量,路由至生成的Cluster
-
自定义流量管理机制
-
可自定义VirtualService修改ServiceEntry默认生成的Routes
-
通过指定的hosts(主机名)适配到要修改的Route的位置
-
路由目标配置等可按需进行定义,包括将流量路由至其它目标
-
-
可自定义DestinationRule修改ServiceEntry默认生成的Cluster
-
通过指定的hosts(主机名)适配到要修改的Cluster
- 常用于集群添加各种高级设定,例如subset、circuit breaker、traffic policy等;
-
-
ServiceEntry 配置示例
示例一
- 运行在网格内但未能注册到Istio上的服务,通常具有Sidecar Envoy,因此也支持网格中的高级特性,例如mTLS等,此时将其location定义为MESH_INTERNAL,意指支持启用这类特性;否则,则应该将location声明为MESH_EXTERNAL;
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- api.dropboxapi.com
- www.googleapis.com
- api.facebook.com
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
示例二
- 用于将一组运行在外部VM上的MongoDB实例添加到Istio的注册表中
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-mongocluster
spec:
hosts:
- mymongodb.somedomain # not used
addresses:
- 192.192.192.192/24 # VIPs
ports:
- number: 27018
name: mongodb
protocol: MONGO
location: MESH_INTERNAL
resolution: STATIC
endpoints:
- address: 2.2.2.2
- address: 3.3.3.3
- 同上面的ServiceEntry相关联的DestinationRule,用于启动与MongoDB实例的tls连接
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mtls-mongocluster
spec:
host: mymongodb.somedomain
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/myclientcert.pem
privateKey: /etc/certs/client_private_key.pem
caCertificates: /etc/certs/rootcacerts.pem
参考文档
https://istio.io/latest/zh/docs/reference/config/networking/service-entry/