全方位指南-一篇搞定-Envoy-性能解读-Istio (全方位指南针)
前面咱们创立了一个Gateway和VirtualService对象,用来对外暴露运行,而后咱们就可以经过
ingressgateway
来访问Bookinfo运行了。那么这两个资源对象是如何成功的呢?
资源是用来性能准许外部流量进入Istio服务网格的流量入口,用于接纳传入的HTTP/TCP衔接。它会性能暴露的端口、协定等,但与KubeesIngress资源不同,不会包括任何流量路由性能,真正的路由规定是经过
VirtualService
来性能的。
咱们再检查一下前面创立的Gateway对象的定义:
#samples/bookinfo/networking/bookinfo-gateway.yamlapiVersion:networking.istio.io/v1alpha3kind:Gatewaymetadata:name:bookinfo-gatewayspec:selector:#假设经常使用的是Helm方式装置,则自动应该是istio=ingress标签istio:ingressgateway#婚配ingressgatewaypod的标签(kubectlgetpods-listio=ingressgateway-nistio-system)servers:-port:number:8080name:httpprotocol:HTTPhosts:-"*"
这里定义的Gateway对象中有一个标签选用器,它会婚配
istio=ingressgateway
标签的Pod,其实就是
istio-ingressgateway
这个组件。
其实实质上
istio-ingressgateway
也是一个Envoy代理,用来作为Istio的一致入口网关,它会接纳外部流量,而后依据
VirtualService
中定义的路由规定来启动流量的转发。
咱们可以检查下
istio-ingressgateway
的Envoy性能来验证下:
#进入ingressgateway组件所在的Pod中$kubectlexec-itistio-ingressgateway-9c8b9b586-s6s48-nistio-system--/bin/bashistio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$ll/etc/istio/proxytotal20drwxrwsrwx2rootistio-proxy66Nov302:16./drwxr-xr-x7rootroot103Nov302:16../srw-rw-rw-1istio-proxyistio-proxy0Nov302:16XDS=-rw-r--r--1istio-proxyistio-proxy14130Nov302:16envoy-rev.json-rw-r--r--1istio-proxyistio-proxy2699Nov302:16grpc-bootstrap.jsonistio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$
在
istio-ingressgateway
组件的Pod目录中有一特性能文件
envoy-rev.json
,这个文件就是Envoy的性能文件,该文件经过istio为sidecar注入的参数在启动的时刻修正或生成,由于这里驳回的是xDS灵活性能的方式,所以间接看不到前面咱们减少的Gateway相关信息的,然而咱们可以应用Envoy的Admin提供的
config_dump
来检查下性能文件:
kubectlexecistio-ingressgateway-9c8b9b586-s6s48-cistio-proxy-nistio-system--curl'localhost:15000/config_dump'>ingressgateway_envoy_conf.json
istioenvoy自动性能为json格局,导进去的性能文件十分长(有10000+行),咱们可以先只看下层内容:
咱们可以看到这特性能文件中其实就一个数组,每个元素都是一项性能,每特性能都指定了一个共同的字段,来指定该性能是是干嘛的。接上去咱们就来看下这特性能文件中的每特性能项都是干嘛的。
BootStrapConfigDump
用于在Envoy启动时加载的一些静态性能,包括相似Sidecar的环境变量等信息。咱们也可以经常使用
istioctlproxy-configbootstrap
命令来检查这局部性能:
$istioctlproxy-configbootstrapistio-ingressgateway-9c8b9b586-s6s48-nistio-system-oyamlbootstrap:admin:address:socketAddress:address:127.0.0.1portValue:15000profilePath:/var/lib/istio/data/envoy.profdynamicResources:#灵活性能发现服务信息adsConfig:apiType:GRPCgrpcServices:-envoyGrpc:clusterName:xds-grpcsetNodeOnFirstMessageOnly:truetransportApiVersion:V3cdsConfig:ads:{}initialFetchTimeout:0sresourceApiVersion:V3ldsConfig:ads:{}initialFetchTimeout:0sresourceApiVersion:V3node:#节点信息cluster:istio-ingressgateway.istio-systemid:router~10.244.2.52~istio-ingressgateway-9c8b9b586-s6s48.istio-system~istio-system.svc.cluster.local#......staticResources:clusters:-connectTimeout:0.250s#prometheusclusterloadAssignment:clusterName:prometheus_statsendpoints:-lbEndpoints:-endpoint:address:socketAddress:address:127.0.0.1portValue:15000name:prometheus_statstype:STATIC-connectTimeout:0.250s#agentclusterloadAssignment:clusterName:agentendpoints:-lbEndpoints:-endpoint:address:socketAddress:address:127.0.0.1portValue:15020name:agenttype:STATIC-connectTimeout:1sloadAssignment:clusterName:sds-grpcendpoints:-lbEndpoints:-endpoint:address:pipe:path:./var/run/secrets/workload-spiffe-uds/socketname:sds-grpctype:STATICtypedExtensionProtocolOptions:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:'@type':type.apis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicitHttpConfig:http2ProtocolOptions:{}-circuitBreakers:thresholds:-maxConnections:100000maxPendingRequests:100000maxRequests:100000-maxConnections:100000maxPendingRequests:100000maxRequests:100000priority:HIGHconnectTimeout:1sloadAssignment:#xds-grpcclusterclusterName:xds-grpcendpoints:-lbEndpoints:-endpoint:address:pipe:path:./etc/istio/proxy/XDSmaxRequestsPerConnection:1name:xds-grpctype:STATICtypedExtensionProtocolOptions:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:'@type':type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicitHttpConfig:http2ProtocolOptions:{}upstreamConnectionOptions:tcpKeepalive:keepaliveTime:300-connectTimeout:1sLookupFamily:V4_ONLYdnsRefreshRate:30sloadAssignment:#zipkinclusterclusterName:zipkinendpoints:-lbEndpoints:-endpoint:address:socketAddress:address:zipkin.istio-systemportValue:9411name:zipkinrespectDnsTtl:truetype:STRICT_DNSlisteners:-address:socketAddress:address:0.0.0.0portValue:15090#prometheuslistenerfilterChns:-filters:-name:envoy.filters.network.http_connection_managertypedConfig:'@type':type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerhttpFilters:-name:envoy.filters.http.routertypedConfig:'@type':type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterrouteConfig:virtualHosts:-domains:-'*'name:backendroutes:-match:prefix:/stats/prometheusroute:cluster:prometheus_statsstatPrefix:stats-address:socketAddress:address:0.0.0.0portValue:15021#agentlistener(肥壮审核)filterChains:-filters:-name:envoy.filters.network.http_connection_managertypedConfig:'@type':type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerhttpFilters:-name:envoy.filters.http.routertypedConfig:'@type':type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterrouteConfig:virtualHosts:-domains:-'*'name:backendroutes:-match:prefix:/healthz/readyroute:cluster:agentstatPrefix:agentstatsConfig:#......tracing:#链路追踪http:name:envoy.tracers.zipkintypedConfig:'@type':type.googleapis.com/envoy.config.trace.v3.ZipkinConfigcollectorCluster:zipkincollectorEndpoint:/api/v2/spanscollectorEndpointVersion:HTTP_JSONsharedSpanContext:falsetraceId128bit:true
上方的性能和之前咱们引见的Envoy性能基本分歧,在上方性能中定义了一个Prometheus监听器,用来暴露Prometheus监控目的,还定义了一个Agent监听器,用来暴露肥壮审核接口,另外还定义了一个zipkin集群,用来定义链路追踪的性能。另外经过
dynamicResources
定义了灵活性能发现服务信息,就是用来定义Envoy与Pilot之间的xDS通讯的。
ListenersConfigDump
这里存储着Envoy的性能,也就是Envoy的监听器。Envoy在阻拦到恳求后,会依据恳求的地址与端口,将恳求交给婚配的处置。
咱们看到这个
ListenersConfigDump
中的性能分红了
static_listners
和
dynamic_listeners
,区分对应Envoy的静态性能和灵活性能,静态性能,是Envoy性能文件中间接指定的,而
dynamic_listeners
的listener则是经过协定为Envoy下发的。
雷同咱们也可以经常使用
istioctlproxy-configlistener
命令来检查这局部性能:
istioctlproxy-configlisteneristio-ingressgateway-9c8b9b586-s6s48-nistio-system-oyaml
对应的性能文件如下所示:
-accessLog:-filter:responseFlagFilter:flags:-NRname:envoy.access_loggers.filetypedConfig:"@type":type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLoglogFormat:textFormatSource:inlineString:|[%START_TIME%]"%REQ(:METHOD)%%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%%PROTOCOL%"%RESPONSE_CODE%%RESPONSE_FLAGS%%RESPONSE_CODE_DETAILS%%CONNECTION_TERMINATION_DETAILS%"%UPSTREAM_TRANSPORT_FAILURE_REASON%"%BYTES_RECEIVED%%BYTES_SENT%%DURATION%%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"%REQ(X-FORWARDED-FOR)%""%REQ(USER-AGENT)%""%REQ(X-REQUEST-ID)%""%REQ(:AUTHORITY)%""%UPSTREAM_HOST%"%UPSTREAM_CLUSTER%%UPSTREAM_LOCAL_ADDRESS%%DOWNSTREAM_LOCAL_ADDRESS%%DOWNSTREAM_REMOTE_ADDRESS%%REQUESTED_SERVER_NAME%%ROUTE_NAME%path:/dev/stdoutaddress:socketAddress:address:0.0.0.0portValue:8080continueOnListenerFiltersTimeout:truefilterChains:-filters:-name:istio_authntypedConfig:"@type":type.googleapis.com/udpa.type.v1.TypedStructtypeUrl:type.googleapis.com/io.istio.network.authn.Config-name:envoy.filters.network.http_connection_managertypedConfig:"@type":type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManageraccessLog:-name:envoy.access_loggers.filetypedConfig:"@type":type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLoglogFormat:textFormatSource:inlineString:|[%START_TIME%]"%REQ(:METHOD)%%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%%PROTOCOL%"%RESPONSE_CODE%%RESPONSE_FLAGS%%RESPONSE_CODE_DETAILS%%CONNECTION_TERMINATION_DETAILS%"%UPSTREAM_TRANSPORT_FAILURE_REASON%"%BYTES_RECEIVED%%BYTES_SENT%%DURATION%%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"%REQ(X-FORWARDED-FOR)%""%REQ(USER-AGENT)%""%REQ(X-REQUEST-ID)%""%REQ(:AUTHORITY)%""%UPSTREAM_HOST%"%UPSTREAM_CLUSTER%%UPSTREAM_LOCAL_ADDRESS%%DOWNSTREAM_LOCAL_ADDRESS%%DOWNSTREAM_REMOTE_ADDRESS%%REQUESTED_SERVER_NAME%%ROUTE_NAME%path:/dev/stdoutforwardClientCertDetails:SANITIZE_SEThttpFilters:-name:istio.metadata_exchangetypedConfig:"@type":type.googleapis.com/udpa.type.v1.TypedStructtypeUrl:type.googleapis.com/io.istio.http.peer_metadata.Configvalue:upstream_discovery:-istio_headers:{}-workload_discovery:{}upstream_propagation:-istio_headers:{}-name:envoy.filters.http.grpc_statstypedConfig:"@type":type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfigemitFilterState:truestatsForAllMethods:false-name:istio.alpntypedConfig:"@type":type.googleapis.com/istio.envoy.config.filter.http.alpn.v2alpha1.FilterConfigalpnOverride:-alpnOverride:-istio-http/1.0-istio-http/1.0-alpnOverride:-istio-http/1.1-istio-http/1.1upstreamProtocol:HTTP11-alpnOverride:-istio-h2-istio-h2upstreamProtocol:HTTP2-name:envoy.filters.http.faulttypedConfig:"@type":type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault-name:envoy.filters.http.corstypedConfig:"@type":type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors-name:istio.statstypedConfig:"@type":type.googleapis.com/stats.PluginConfigdisableHostHeaderFallback:true-name:envoy.filters.http.routertypedConfig:"@type":type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterhttpProtocolOptions:{}normalizePath:truepathWithEscapedSlashesAction:KEEP_UNCHANGEDrds:configSource:ads:{}initialFetchTimeout:0sresourceApiVersion:V3routeConfigName:http.8080requestIdExtension:ktypedConfig:"@type":type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfiguseRequestIdForTraceSampling:trueserverName:istio-envoysetCurrentClientCertDetails:cert:truedns:truesubject:trueuri:truestatPrefix:outbound_0.0.0.0_8080streamIdleTimeout:0stracing:#......upgradeConfigs:-upgradeType:websocketuseRemoteAddress:truename:0.0.0.0_8080trafficDirection:OUTBOUND-address:socketAddress:address:0.0.0.0portValue:15090#......-address:socketAddress:address:0.0.0.0portValue:15021#......
只管上方看到的listener性能还是很长,然而咱们应该也还是十分相熟的,实质就是Envoy的性能文件中的listener性能。咱们这里重点看下灵活性能对应的性能,静态的就是前面指定prometheus和agent对应的监听器性能。
咱们可以看到上方的灵活性能对应的监听器称号为
0.0.0.0_8080
,对应的监听地址为
0.0.0.0:8080
,也就是说在Envoy中监听了端口:
address:socketAddress:address:0.0.0.0portValue:8080
而前面咱们是不是创立了一个Gateway资源对象,并指定了8080端口,其实这个端口就是咱们前面创立的Gateway对象中定义的端口,这个监听器的性能就是经过经过协定下发的。
那么恳求是如何抵达这个监听器的呢?咱们可以检查下
istio-ingressgateway
组建的Service数据:
$kubectlgetsvcistio-ingressgateway-nistio-systemNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEistio-ingressgatewayLoadBalancer10.103.227.57<pending>15021:32459/TCP,80:31896/TCP,443:30808/TCP,31400:31535/TCP,15443:30761/TCP46h
咱们可以看到
istio-ingressgateway
组件的Service中定义了5个端口,还记得前面咱们去访问Productpage的时刻是如何访问的吗?是不是经过
http:// $GATEWAY_URL/productpage
访问的,而咱们这里没有LoadBalancer,所以间接经常使用NodePort方式访问就行,最终咱们是经过
来访问运行的,而这个端口对应
istio-ingressgateway
组件的Service中定义的端口,也就是说咱们的恳求是经过端口抵达
istio-ingressgateway
组件的,那么这个端口是如何抵达
istio-ingressgateway
组件的呢?
$kubectldescribesvcistio-ingressgateway-nistio-systemName:istio-ingressgatewayNamespace:istio-system#......Port:http280/TCPTargetPort:8080/TCPNodePort:http231896/TCPEndpoints:10.244.2.52:8080
咱们检查Service的定义就明确了,实践上
istio-ingressgateway
这个Service定义的端口对应的是
istio-ingressgateway
组件Pod的端口,也就是说咱们的恳求是经过端口抵达
istio-ingressgateway
组件的端口的,而这个端口就是咱们前面在Envoy性能中看到的监听器的端口了,所以当咱们访问
http:// $GATEWAY_URL/productpage
的时刻恳求抵达了
istio-ingressgateway
这个组件的8080端口了。
当恳求抵达
istio-ingressgateway
组件时,就会被这个监听器所婚配,而后将恳求交给
http_connection_manager
这个filter来处置,当然前面就是用各种详细的filter来处置恳求了,比如
envoy.filters.http.fault
这个filter就是用来处置缺点注入的,
envoy.filters.http.router
则是用来处置路由转发的、
envoy.filters.http.cors
则是用来处置跨域恳求的等等。
然而咱们的恳求进到Envoy后是又该如何路由呢?我应该将恳求转发到哪里去呢?这个是不是就是Envoy中的路由性能来选择的了,关于静态性能咱们分明间接在Envoy性能文件中就可以看到,比如:
routeConfig:virtualHosts:-domains:-"*"name:backendroutes:-match:prefix:/healthz/readyroute:cluster:agent
然而咱们这里的路由性能是灵活性能的,咱们看到对应的性能中有一个字段,这个字段就是用来指定灵活路由性能的,其中的
routeConfigName
字段就是用来指定对应的路由性能称号的:
rds:configSource:ads:{}initialFetchTimeout:0sresourceApiVersion:V3routeConfigName:http.8080
RoutesConfigDump
这外面保留着Envoy的路由性能,和listeners一样,
RoutesConfigDump
也分为
static_route_configs
和
dynamic_route_configs
,区分对应着静态的路由性能和灵活下发的路由性能。
雷同咱们也可以经常使用
istioctlproxy-configroute
命令来检查这局部性能:
istioctlproxy-configrouteistio-ingressgateway-9c8b9b586-s6s48-nistio-system-oyaml
对应的性能如下所示:
-ignorePortInHostMatching:truemaxDirectResponseBodySizeBytes:1048576name:http.8080validateClusters:falsevirtualHosts:-domains:-"*"includeRequestAttemptCount:truename:"*:8080"routes:-decorator:operation:productpage.default.svc.cluster.local:9080/productpagematch:caseSensitive:truepath:/productpagemetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s-decorator:operation:productpage.default.svc.cluster.local:9080/static*match:caseSensitive:trueprefix:/staticmetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s-decorator:operation:productpage.default.svc.cluster.local:9080/loginmatch:caseSensitive:truepath:/loginmetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s-decorator:operation:productpage.default.svc.cluster.local:9080/logoutmatch:caseSensitive:truepath:/logoutmetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s-decorator:operation:productpage.default.svc.cluster.local:9080/api/v1/products*match:caseSensitive:trueprefix:/api/v1/productsmetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s-virtualHosts:-domains:-"*"name:backendroutes:-match:prefix:/stats/prometheusroute:cluster:prometheus_stats-virtualHosts:-domains:-"*"name:backendroutes:-match:prefix:/healthz/readyroute:cluster:agent
前面的两个
virtualHosts
就是咱们的静态路由性能,第一个是灵活的路由性能,咱们可以看到该性能的称号就是,是不是和前面的
routeConfigName
是分歧的。那么这特性能又是什么中央定义的呢?
其实细心看这外面的性能和前面咱们创立的
VirtualService
这个资源对象是不是很像,咱们再看下前面创立的
VirtualService
对象的定义:
apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:bookinfospec:hosts:-"*"gateways:-bookinfo-gatewayhttp:-match:-uri:exact:/productpage-uri:prefix:/static-uri:exact:/login-uri:exact:/logout-uri:prefix:/api/v1/productsroute:-destination:host:productpageport:number:9080
咱们可以看到在
VirtualService
对象中定义了5个路由规定,而这里的
RoutesConfigDump
中也定义了5个路由规定,
VirtualService
中定义的5个路由区分为
/productpage
、、、、
/api/v1/products
,而
RoutesConfigDump
中定义的5个路由区分为
/productpage
、、、、
/api/v1/products
,是不是逐一对应的。最终婚配这些路由规定的恳求是被转发到
productpage
这个服务的端口的。
比如
/productpage
这个路由规定对应的Envoy性能如下所示:
-domains:-"*"includeRequestAttemptCount:truename:"*:8080"routes:-decorator:operation:productpage.default.svc.cluster.local:9080/productpagematch:caseSensitive:truepath:/productpagemetadata:filterMetadata:istio:config:/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinforoute:cluster:outbound|9080||productpage.default.svc.cluster.localmaxGrpcTimeout:0sretryPolicy:hostSelectionRetryMaxAttempts:"5"numRetries:2retriableStatusCodes:-503retryHostPredicate:-name:envoy.retry_host_predicates.previous_hoststypedConfig:"@type":type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicateretryOn:connect-failure,refused-stream,unavailable,cancelled,retriable-status-codestimeout:0s
这特性能就是咱们相熟的Envoy的关于虚构服务器局部的性能,比如当咱们恳求的门路为
/productpage
时,就会被这个路由规定婚配到,而后就用经过字段来形容咱们的路由目的了,针对这个目录,可以看到有一些相似于
retry_policy
、等字段来性能这个目的的超时、重试战略等,不过最关键的还是这个字段,它指定了这个路由目的对应着哪个抢先集群,Envoy最终将恳求发送到这个Cluster,比如咱们这里的集群称号为
outbound|9080||productpage.default.svc.cluster.local
,关于其详细性能咱们就要去检查
ClustersConfigDump
中的性能了。
ClustersConfigDump
该局部是用来存储Envoy的集群性能的,雷同也分为
static_clusters
和
dynamic_active_clusters
,区分对应着静态性能和灵活下发的性能。这里的Cluster集群是Envoy外部的概念,它是指Envoy衔接的一组逻辑相反的抢先服务器,并不是说K8s集群,只是大少数状况下咱们可以把这个
集群
了解为K8s集群中的一个Service,一个Service理论对应着一组Pod,由这组Pod照应恳求并提供同一种服务,而Envoy的这个
集群
实践可以了解成这种
Pod汇合
。不过Envoy的一个集群也不必定就对应着一个Service,由于集群是
一组逻辑相反的抢先服务器
,所以也有或许是别的合乎定义的物品,比如说是服务的一个特定版本(如只是版本的服务)。istio的版本灰度才干就是基于这个做的,由于两个版本的同一服务虚际上可以分红两个集群。
雷同咱们可以经常使用
istioctlproxy-configcluster
命令来检查这局部性能:
istioctlproxy-configclusteristio-ingressgateway-9c8b9b586-s6s48-nistio-system-oyaml
该性能文件会十分长,它会将K8s集群中的Service都转换成Envoy的Cluster,这里咱们只看下
productpage
这个服务对应的Cluster性能,如下所示:
-circuitBreakers:#thresholds:-maxConnections:4294967295maxPendingRequests:4294967295maxRequests:4294967295maxRetries:4294967295trackRemaining:truecommonLbConfig:localityWeightedLbConfig:{}connectTimeout:10sedsClusterConfig:edsConfig:ads:{}initialFetchTimeout:0sresourceApiVersion:V3serviceName:outbound|9080||productpage.default.svc.cluster.localfilters:-name:istio.metadata_exchangetypedConfig:"@type":type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchangeprotocol:istio-peer-exchangelbPolicy:LEAST_REQUESTmetadata:filterMetadata:istio:services:-host:productpage.default.svc.cluster.localname:productpagenamespace:defaultname:outbound|9080||productpage.default.svc.cluster.localtransportSocketMatches:-match:tlsMode:istioname:tlsMode-istiotransportSocket:name:envoy.transport_sockets.tlstypedConfig:"@type":type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContextcommonTlsContext:alpnProtocols:-istio-peer-exchange-istiocombinedValidationContext:defaultValidationContext:matchSubjectAltNames:-exact:spiffe://cluster.local/ns/default/sa/bookinfo-productpagevalidationContextSdsSecretConfig:name:ROOTCAsdsConfig:apiConfigSource:apiType:GRPCgrpcServices:-envoyGrpc:clusterName:sds-grpcsetNodeOnFirstMessageOnly:truetransportApiVersion:V3initialFetchTimeout:0sresourceApiVersion:V3tlsCertificateSdsSecretConfigs:-name:defaultsdsConfig:apiConfigSource:apiType:GRPCgrpcServices:-envoyGrpc:clusterName:sds-grpcsetNodeOnFirstMessageOnly:truetransportApiVersion:V3initialFetchTimeout:0sresourceApiVersion:V3tlsParams:tlsMaximumProtocolVersion:TLSv1_3tlsMinimumProtocolVersion:TLSv1_2sni:outbound_.9080_._.productpage.default.svc.cluster.local-match:{}name:tlsMode-disabledtransportSocket:name:envoy.transport_sockets.raw_buffertypedConfig:"@type":type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffertype:EDS
咱们可以看到这个EnvoyCluster的称号为
outbound|9080||productpage.default.svc.cluster.local
,和前面的路由性能中的字段是分歧的,称号大少数会由分红四个局部,区分是或代表入向流量或出向流量、端口号、
subcluster
称号(就是对应着
destinationrule
里的)、
ServiceFQDN
,由istio的服务发现启动性能,经过这个咱们很容易就能看进去这个集群对应的是K8s集群的哪个服务。
而后性能的负载平衡战略是
LEAST_REQUEST
,另外比拟关键的这里的性能的类型为,也就是会经过EDS来发现抢先的服务器服务,这个EDS的性能如下所示:
edsClusterConfig:edsConfig:ads:{}initialFetchTimeout:0sresourceApiVersion:V3serviceName:outbound|9080||productpage.default.svc.cluster.local
基于EDS去灵活发现抢先服务器的性能,其真实前面的Envoy章节咱们曾经引见过了,和这里是不是简直是分歧的,
serviceName
其实就对应着K8s集群中的
productpage
这个Service对象的9080端口,而这个Service对象对应着一组Pod,这组Pod就是咱们的抢先服务器了。当然这是经过协定下发的,咱们可以经过
istioctlproxy-configendpoint
命令来检查这局部性能:
istioctlproxy-configendpointistio-ingressgateway-9c8b9b586-s6s48-nistio-system-oyaml
该局部数据十分多,上方只截取
productpage
相关的数据,如下所示:
-addedViaApi:truecircuitBreakers:thresholds:-maxConnections:4294967295maxPendingRequests:4294967295maxRequests:4294967295maxRetries:4294967295-maxConnections:1024maxPendingRequests:1024maxRequests:1024maxRetries:3priority:HIGHedsServiceName:outbound|9080||productpage.default.svc.cluster.localhostStatuses:-address:socketAddress:address:10.244.2.62portValue:9080healthStatus:edsHealthStatus:HEALTHYlocality:{}stats:-name:cx_connect_fail-name:cx_totalvalue:"1"-name:rq_error-name:rq_successvalue:"4"-name:rq_timeout-name:rq_totalvalue:"4"-name:cx_activetype:GAUGE-name:rq_activetype:GAUGEweight:1name:outbound|9080||productpage.default.svc.cluster.localobservabilityName:outbound|9080||productpage.default.svc.cluster.local
可以看到上方的性能中就蕴含一个真正的后端服务地址:
address:socketAddress:address:10.244.2.62portValue:9080
这个地址其实就是
productpage
这个K8sService关联的Pod的地址。这样一个恳求从进入到Envoy到最终转发到后端服务的环节就分明了。
SecretsConfigDump
由于网格中的Envoy之间相互通讯会经常使用mTLS形式,因此每个Envoy通讯时都须要提供本上班负载的证书,同时为了签发证书还须要istioca的根证书,这些证书的信息保留在该性能项之下。
总结
到这里咱们就把Envoy的整特性能文件都了解了一遍,它们区分是Bootstrap、Listeners、Routes、Clusters、Secrets几特性能,其中又触及到VirtualHost等细分概念。
全体上一个恳求在Envoy外部的处置与转发环节中,listener、route、cluster这几特性能是严密相连的,它们经过性能的name一层又一层地向下援用(listener内的filter援用route、route内的virtual_host援用cluster),构成了一条援用链,最终将恳求从listener递交到详细的cluster。
咱们可以经常使用envoyui.solo.io这个在线的Envoy性能可视化工具来检查Envoy的性能,只有要将咱们的Envoy性能dump进去上行过去即可:
经过上方的剖析咱们也明确了其实Istio并没有成功很多复杂的逻辑,服务控制相关的性能比如负载平衡、缺点注入、权重路由等都是Envoy自身就有的才干,Istio只是将这些才干形象成了一个个资源对象,而后经过Envoy的xDS协定下发到Envoy中,这样就能够成功对Envoy的流量控制了。所以重点还是须要咱们先了解Envoy的性能,而后再去了解Istio的性能,这样才干更好的了解Istio,不然你就不分明Gateway、VirtualService等这些资源对象究竟是干什么的,它们是如何影响Envoy的性能的。
当然咱们这里还只是剖析的IstioIngressGateway的性能,而关于Sidecar形式的Envoy代理又是如何去性能的呢?它又是如何将Pod的流量启动阻拦的呢?这些咱们前面会继续剖析。
Istio是什么?
Istio是由Google、IBM和Lyft开源的微服务管理、保护和监控框架。Istio为希腊语,意思是”起航“使用istio可以很简单的创建具有负载均衡、服务间认证、监控等功能的服务网络,而不需要对服务的代码进行任何修改。你只需要在部署环境中,例如Kubernetes的pod里注入一个特别的sidecar proxy来增加对istio的支持,用来截获微服务之间的网络流量。
特性:使用istio的进行微服务管理有如下特性:流量管理:控制服务间的流量和API调用流,使调用更可靠,增强不同环境下的网络鲁棒性。可观测性:了解服务之间的依赖关系和它们之间的性质和流量,提供快速识别定位问题的能力。
策略实施:通过配置mesh而不是以改变代码的方式来控制服务之间的访问策略。服务识别和安全:提供在mesh里的服务可识别性和安全性保护。未来将支持多种平台,不论是kubernetes、Mesos、还是云。同时可以集成已有的ACL、日志、监控、配额、审计等。
正是 Istio 的出现使 “Service Mesh”( 服务网格 ) 这一概念开始流行起来。在深入介绍 Istio 的细节之前,让我们首先简单地了解一下 Service Mesh 是什么,以及它的重要性体现在哪里。我们都已经了解单体应用所面对的挑战,一种显而易见的方案是将其分解为多个微服务。虽然这种方式简化了单个服务的开发,但对于成百上千的微服务的通信、监控以及安全性的管理并不是一件简单的事。直至目前,对于这些问题的解决方案也只是通过自定义脚本、类库等方式将服务串联在一起,并且投入专门的人力以处理分布式系统的管理任务。但这种方式降低了各个团队的效率,并且提高了维护的成本。这正是 Service Mesh 大显身手的时机
Istio以及Service Mesh的未来
Service Mesh 浅析:从概念、产品到实践
近几年,微服务架构逐渐发展成熟,从最初的星星之火到现在大规模的落地和实践,几乎已经成为分布式环境下的首选架构。 然而软件开发没有银弹,基于微服务构建的应用系统在享受其优势的同时,痛点也越加明显。 Service Mesh 技术也因此而生,受到越来越多的开发者关注,并拥有了大批拥趸。 本文会从概念介绍开始,让大家理解 Service Mesh 技术出现的原因以及愿景;接着会对目前最主流的两个产品 Istio 和 AWS App Mesh 进行详细的比较;最后简要介绍一下我们目前在该领域的一些探索与实践。 Service Mesh - 服务通信的济世良方 Service Mesh 是什么? Service Mesh(中文译做服务网格)这一概念由 Buoyant 公司的 CEO,William Morg」n 首先提出。 2017 年 4 月该公司发布了第一个 Service Mesh 产品 Linkerd,这篇同一时间发表的文章 What’s a service mesh? And why do I need one? 也被业界公认是 Service Mesh 的权威定义。 “A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.” 其定义翻译为:Service Mesh 是一个处理服务通讯的专门的基础设施层。 它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。 在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,对应用服务透明。 这段话有点晦涩难懂,但只要抓住下面 4 个关键点就能轻松理解: 本质:基础设施层 功能:请求分发 部署形式:网络代理 特点:透明 如果用一句话来总结,我个人对它的定义是:Service Mesh 是一组用来处理服务间通讯的网络代理。 为什么需要 Service Mesh? 上面晦涩抽象的定义很难让你真正理解 Service Mesh 存在的意义。 你可能会想,服务间通信(service-to-service communication)无非就是通过 RPC、HTTP 这些方式进行,有什么可处理的?没错,服务间只需要遵循这些标准协议进行交互就可以了,但是在微服务这样的分布式环境下,分散的服务势必带来交互的复杂性,而规模越大的系统其通信越加错综复杂。 分布式计算下的 8 个谬论 很好的归纳了分布式环境下存在的网络问题。 而为了解决这些问题,提高系统的容错能力和可用性,出现了服务注册与发现、负载均衡、熔断、降级、限流等等和通信相关的功能,而这些才是 Service Mesh 要真正处理的问题。 Pattern:Service Mesh 这篇文章详细的讲述了微服务架构下通讯处理的演进,由此引出 Service Mesh 出现的意义和核心价值。 下图为服务通信演变的过程:最初,流量管理和控制能力(比如图例中的熔断、服务发现)是和业务逻辑耦合在一起,即便以引用包的方式被调用,依然解决不了异构系统无法重用的问题。 流控功能和业务耦合相当不美好,于是出现了提供这些功能的公共库和框架。 但这些库通常比较复杂,无论是学习使用,与业务系统整合、维护都会带来很大的成本。 为避免花费太多时间开发和维护这些通用库,人们希望流量控制能力可以下沉到网络通讯栈的层面,但几乎无法实现。 于是另一种思路出现,就是将这些功能独立成一个代理,由它先接管业务服务的流量,处理完成后再转发给业务服务本身,这就是 Sidecar 模式。 为统一管理 Sidecar,该模式进一步进化,形成网络拓扑,增加了控制平面,演变成 Service Mesh(最后的网格图中,绿色代表业务服务,蓝色代表 sidecar 服务)。 可以说,Service Mesh 就是 Sidecar 的网络拓扑形态,Mesh 这个词也由此而来。 (关于 Sidecar 模式这里不做讨论,你可以自行 Google)。 业务系统的核心价值应该是业务本身,而不是服务,微服务只是一种实现手段,实现业务才是目标。 现有的微服务架构下,为解决可能出现的网络通信问题,提升系统的弹性,开发人员不得不花费大量时间和精力去实现流量控制相关的非业务需求,不能聚焦在业务本身。 而 Service Mesh 的出现解决了这一问题,带来了下面 2 个变革: 解决了微服务框架中的服务流量管理的痛点,使开发人员专注于业务本身; 将服务通信及相关管控功能从业务程序中分离并下层到基础设施层,使其和业务系统完全解耦。 在云原生应用中,面对数百个服务或数千个实例,单个业务链路的请求经由服务的拓扑路径可能会非常复杂,单独处理非常必要。 这就是 Service Mesh 的意义所在。 Service Mesh 的主要功能 那么 Service Mesh 到底能带来哪些实用的功能呢?可以把它们归纳为下面 4 个部分: 流量控制:流控是最主要也是最重要的功能,通过 Service Mesh,我们可以为应用提供智能路由(蓝绿部署、金丝雀发布、A/B test)、超时重试、熔断、故障注入、流量镜像等各种控制能力; -安全:在安全层面上,授权和身份认证也可以托管给 Service Mesh; 策略:可以为流量设置配额、黑白名单等策略; 可观察性:服务的可观察性一般是通过指标数据、日志、追踪三个方式展现的,目前的 Service Mesh 产品可以很容易和和主流的后端设施整合,提供给应用系统完整的监控能力。 通过上面的讲述,我相信 Service Mesh 的概念大家都已经有所了解。 接下来我们来介绍两个重要的网格产品,让大家进一步了解 Service Mesh 的产品形态是什么样的。 Istio vs AWS App Mesh - 开源与闭环之争 目前市面上比较成熟的开源服务网格主要有下面几个:Linkerd,这是第一个出现在公众视野的服务网格产品,由 Twitter 的 finagle 库衍生而来,目前由 Buoyant 公司负责开发和维护;Envoy,Lyft 开发并且是第一个从 CNCF 孵化的服务网格产品,定位于通用的数据平面或者单独作为 Sidecar 代理使用;Istio,由 Google、IBM、Lyft 联合开发的所谓第二代服务网格产品,控制平面的加入使得服务网格产品的形态更加完整。 从今年的风向看,作为构建云原生应用的重要一环,Service Mesh 已经被各大云厂商认可,并看好它的发展前景。 在 Istio 红透半边天的情况下,作为和 Google 在云服务市场竞争的 Amazon 来说,自然不愿错失这块巨大的蛋糕。 他们在今年 4 月份发布了自己的服务网格产品:AWS App Mesh。 这一部分内容我们会聚焦于 Istio 和 App Mesh 这两个产品,通过横向的对比分析让大家对 Service Mesh 的产品形态和两大云厂商的策略有一个更深入的认识。 产品定位 从官方的介绍来看,Istio 和 App Mesh 都明确的表示自己是一种服务网格产品。 Istio 强调了自己在连接、安全、控制和可视化 4 个方面的能力;而 App Mesh 主要强调了一致的可见性和流量控制这两方面能力,当然也少不了强调作为云平台下的产品的好处:托管服务,无需自己维护。 从某种程度上讲,Istio 是一个相对重一点的解决方案,提供了不限于流量管理的各个方面的能力;而 App Mesh 是更加纯粹的服务于运行在 AWS 之上的应用并提供流控功能。 笔者认为这和它目前的产品形态还不完善有关(后面会具体提到)。 从与 AWS 技术支持团队的沟通中可以感觉到,App Mesh 应该是一盘很大的棋,目前只是初期阶段。 核心术语 和 AWS 里很多产品一样,App Mesh 也不是独创,而是基于 Envoy 开发的。 AWS 这样的闭环生态必然要对其进行改进和整合。 同时,也为了把它封装成一个对外的服务,提供适当的 API 接口,在 App Mesh 这个产品中提出了下面几个重要的技术术语,我们来一一介绍一下。 服务网格(Service mesh):服务间网络流量的逻辑边界。 这个概念比较好理解,就是为使用 App mesh 的服务圈一个虚拟的边界。 虚拟服务(Virtual services):是真实服务的抽象。 真实服务可以是部署于抽象节点的服务,也可以是间接的通过路由指向的服务。 虚拟节点(Virtual nodes):虚拟节点是指向特殊工作组(task group)的逻辑指针。 例如 AWS 的 ECS 服务,或者 Kubernetes 的 Deployment。 可以简单的把它理解为是物理节点或逻辑节点的抽象。 Envoy:AWS 改造后的 Envoy(未来会合并到 Envoy 的官方版本),作为 App Mesh 里的数据平面,Sidecar 代理。 虚拟路由器(Virtual routers):用来处理来自虚拟服务的流量。 可以理解为它是一组路由规则的封装。 路由(Routes):就是路由规则,用来根据这个规则分发请求。 上面的图展示了这几个概念的关系:当用户请求一个虚拟服务时,服务配置的路由器根据路由策略将请求指向对应的虚拟节点,这些节点最终会与集群中某个对外提供服务的 DNS 或者服务名一一对应。 那么这些 App Mesh 自创的术语是否能在 Istio 中找到相似甚至相同的对象呢?我归纳了下面的表格来做一个对比: App MeshIstio 服务网格(Service mesh)Istio并未显示的定义这一概念,我们可以认为在一个集群中,由Istio管理的服务集合,它们组成的网络拓扑即是服务网格。 虚拟服务(Virtual services)Istio中也存在虚拟服务的概念。 它的主要功能是定义路由规则,使请求可以根据这些规则被分发到对应的服务。 从这一点来说,它和App Mesh的虚拟服务的概念基本上是一致的。 虚拟节点(Virtual nodes)Istio没有虚拟节点的概念,可以认为类似Kubernetes里的Deployment。 虚拟路由器(Virtual routers)Istio也没有虚拟路由器的概念。 路由(Routes)Istio中的目标规则(DestinationRule)和路由的概念类似,为路由设置一些策略。 从配置层面讲,其中的子集(subset)和App Mesh路由里选择的目标即虚拟节点对应。 但Istio的目标规则更加灵活,也支持更多的路由策略。 从上面的对比看出,App Mesh 目前基本上实现了最主要的流量控制(路由)的功能,但像超时重试、熔断、流量复制等高级一些的功能还没有提供,有待进一步完善。 架构 AWS App Mesh 是一个商业产品,目前还没有找到架构上的技术细节,不过我们依然可以从现有的、公开的文档或介绍中发现一些有用的信息。 从这张官网的结构图中可以看出,每个服务的橙色部分就是 Sidecar 代理:Envoy。 而中间的 AWS App Mesh 其实就是控制平面,用来控制服务间的交互。 那么这个控制平面具体的功能是什么呢?我们可以从今年的 AWS Summit 的一篇 PPT 中看到这样的字样: 控制平面用来把逻辑意图转换成代理配置,并进行分发。 熟悉 Istio 架构的朋友有没有觉得似曾相识?没错,这个控制平面的职责和 Pilot 基本一致。 由此可见,不管什么产品的控制平面,也必须具备这些核心的功能。 那么在平台的支持方面呢?下面这张图展示了 App Mesh 可以被运行在如下的基础设施中,包括 EKS、ECS、EC2 等等。 当然,这些都必须存在于 AWS 这个闭环生态中。 而 Istio 这方面就相对弱一些。 尽管 Istio 宣称是支持多平台的,但目前来看和 Kubernetes 还是强依赖。 不过它并不受限于单一的云平台,这一点有较大的优势。 Istio 的架构大家都比较熟悉,数据平面由 Envoy sidecar 代理组成,控制平面包括了 Pilot、Mixer、Citadel、Galley 等控件。 它们的具体功能这里就不再赘述了,感兴趣的同学可以直接去 官网 查看详细信息。 功能与实现方式 部署 无论是 Istio 还是 App Mesh 都使用了控制平面+数据平面的模式,且 Sidecar 都使用了 Envoy 代理。 Istio 的控制平面组件较多,功能也更复杂,1.0.x 版本完整安装后的 CRD 有 50 个左右。 架构修改后 Mixer 的一些 adapter 被独立出去,crd 有所降低。 下面是最新的 1.4 版本,安装后仍然有 24 个 crd。 而 App Mesh 就简单得多,只针对核心概念添加了如下 3 个 crd,用一个 controller 进行管理。 尽管 Istio 更多的 crd 在一定程度上代表了更加丰富的功能,但同时也为维护和 troubleshooting 增加了困难。 流量控制 尽管两者的数据平面都基于 Envoy,但它们提供的流量控制能力目前还是有比较大的差距的。 在路由的设置方面,App Mesh 提供了相对比较丰富的匹配策略,基本能满足大部分使用场景。 下面是 App Mesh 控制台里的路由配置截图,可以看出,除了基本的 URI 前缀、HTTP Method 和 Scheme 外,也支持请求头的匹配。 Istio 的匹配策略更加完善,除了上面提到的,还包括 HTTP Authority,端口匹配,请求参数匹配等,具体信息可以从官方文档的虚拟服务设置查看。 下面两段 yaml 分别展示了两个产品在虚拟服务配置上的差异。 App Mesh 配置:Istio 配置:另外一个比较大的不同是,App Mesh 需要你对不同版本的服务分开定义(即定义成不同的虚拟服务),而 Istio 是通过目标规则 DestinationRule 里的子集 subsets 和路由配置做的关联。 本质上它们没有太大区别。 除了路由功能外,App Mesh 就显得捉襟见肘了。 就在笔者撰写本文时,AWS 刚刚添加了重试功能。 而 Istio 借助于强大的 Envoy,提供了全面的流量控制能力,如超时重试、故障注入、熔断、流量镜像等。 安全 在安全方面,两者的实现方式具有较大区别。 默认情况下,一个用户不能直接访问 App Mesh 的资源,需要通过 AWS 的 IAM 策略给用户授权。 比如下面的配置是容许用户用任意行为去操作网格内的任意资源:因此,App Mesh 的授权和认证都是基于 AWS 自身的 IAM 策略。 Istio 提供了两种认证方式,基于 mTLS 的传输认证,和 基于 JWT 的身份认证。 而 Istio 的授权是通过 RBAC 实现的,可以提供基于命名空间、服务和 HTTP 方法级别的访问控制。 这里就不具体展示了,大家可以通过官网 文档 来查看。 可观察性 一般来说,可以通过三种方式来观察你的应用:指标数据、分布式追踪、日志。 Istio 在这三个方面都有比较完整的支持。 指标方面,可以通过 Envoy 获取请求相关的数据,同时还提供了服务级别的指标,以及控制平面的指标来检测各个组件的运行情况。 通过内置的 Prometheus 来收集指标,并使用 Grafana 展示出来。 分布式追踪也支持各种主流的 OpenTracing 工具,如 Jaeger、Zipkin 等。 访问日志一般都通过 ELK 去完成收集、分析和展示。 另外,Istio 还拥有 Kiali 这样的可视化工具,给你提供整个网格以及微服务应用的拓扑视图。 总体来说,Istio 在可观察方面的能力是非常强大的,这主要是因为 Mixer 组件的插件特性带来了巨大的灵活性。 App Mesh 在这方面做的也不错。 从最新发布的 官方 repo 中,App Mesh 已经提供了集成主流监控工具的 helm chart,包括 Prometheus、Grafana、Jaeger 等。 同时,AWS 又一次发挥了自己闭环生态的优势,提供了与自家的监控工具 CloudWatch、X-Ray 的整合。 总的来说,App Mesh 在对服务的可观察性上也不落下风。 Amazon 与 Google 的棋局 AWS App Mesh 作为一个 2019 年 4 月份才发布的产品(GA),在功能的完整性上和 Istio 有差距也是情有可原的。 从 App Mesh 的 Roadmap 可以看出,很多重要的功能,比如熔断已经在开发计划中。 从笔者与 AWS 的支持团队了解的信息来看,他们相当重视这个产品,优先级很高,进度也比较快,之前还在预览阶段的重试功能在上个月也正式发布了。 另外,App Mesh 是可以免费使用的,用户只需要对其中的实例资源付费即可,没有额外费用。 对 AWS 来说,该产品的开发重点是和现有产品的整合,比如 Roadmap 列出的使用 AWS Gateway 作为 App Mesh 的 Ingress。 借助着自己的生态优势,这种整合即方便快捷的完善了 App Mesh,同时又让生态内的产品结合的更紧密,使得闭环更加的牢固,不得不说是一步好棋。 和 App Mesh 目前只强调流控能力不同,Istio 更多的是把自己打造成一个更加完善的、全面的服务网格系统。 架构优雅,功能强大,但性能上受到质疑。 在产品的更迭上貌似也做的不尽如人意(不过近期接连发布了 1.3 到 1.4 版本,让我们对它的未来发展又有了期待)。 Istio 的优势在于 3 大顶级技术公司加持的强大资源,加上开源社区的反哺,利用好的话容易形成可持续发展的局面,并成为下一个明星级产品。 然而 Google 目前对 Istio 的态度有一些若即若离,一方面很早就在自家的云服务 gcloud 里提供了 Istio 的默认安装选项,但同时又发布了和 Istio 有竞争关系的 Traffic director 这个托管的控制平面。 笔者的猜测是 Google 也意识到 Istio 的成熟不可能一蹴而就,鉴于网格技术托管需求的越发强烈,先提供一个轻量化的产品以占领市场。 目前各大厂商都意识到了网格技术的重要性并陆续推出了自己的产品(包括 AWS App Mesh,Kong 的 Kuma,国内的蚂蚁金服、腾讯云等),竞争也会逐渐激烈。 未来是三分天下还是一统山河,让我们拭目以待。 我们的实践 - 从 Service Mesh 迈向云原生 最后这部分给大家简要介绍一下我们(FreeWheel)在 Service Mesh 领域的实践。 希望通过一些前瞻性的探索,总结出最佳实践,为我们将来的微服务应用全面拥抱云原生提供一定的经验和指导。 目前我们已经开发完成的 Data service 项目就整合了 AWS App Mesh,即将上线,并使用网格的能力进行智能路由和发布。 Data service 项目只包含两个服务:Forecast service 和 Query service,前者作为业务服务通过 Query service 查询来自持久层(ClickHouse)的数据;后者作为数据访问代理,从持久层获取数据并进行对象化的封装。 这个 mini 的微服务系统非常适合作为一个先行者为我们探索网格的功能、性能、易用性等方面的能力,且范围足够小,不会影响到其他业务系统。 选择 AWS App Mesh 作为该项目的网格产品主要原因如下: FreeWheel 是一个重度使用 AWS 各项服务的公司,未来所有的服务也都会全部托管的 AWS 上。 作为一个闭环生态,App Mesh 可以和现有服务无缝整合,提高易用性; 相比 Istio 这样还不太成熟的开源产品,我们可以得到 AWS 技术团队的全力支持; 数据平面基于成熟高效的 Envoy,控制平面不存在 Istio 中的性能问题; 完全免费 下图是该项目的部署视图。 前端请求从我们的业务系统 UIF 发送到 Forecast service,它作为 App Mesh 的一个虚拟节点,调用 Data service 进行数据查询。 Data service 作为数据平面,会注入 App Mesh 的 sidecar 代理。 这两个服务组成了一个 Mesh 网格,并无缝整合在 AWS 的 EKS 中。 下图是网格内部的逻辑视图,展示了如何利用 App Mesh 进行智能路由。 Forecast service 作为调用者被定义为虚拟节点,Data service 作为虚拟服务,挂载着虚拟路由,内部根据需要可以设定若干路由规则。 用 App Mesh 实现一个金丝雀发布的过程非常简单:假设在 Data service 的新版本(V2)发布前,流量都被指向 V1 版本;此时我们在 App Mesh 里配置好一个新的路由规则,将 10%的流量指向新的 V2 版本;只需要将新的规则通过 kubectl apply -f 应用到集群中,金丝雀发布就可以完成,且无缝切换,对用户透明。 在后续的工作中,我们会先验证 App Mesh 的性能和可靠性,然后逐渐的将更多的流量控制(如超时重试、熔断等)功能添加进来,并总结出一整套可行的实施方案,供大家参考。 也欢迎对 Service Mesh 感兴趣的同学加入到我们的团队中,一起学习,共同进步。 总结 解耦是软件开发中永恒的主题,开发人员对消除重复的偏执是推动软件、以及架构模式演进的主要动力。 而 Service Mesh 的核心价值就是将服务通信功能从业务逻辑中解耦,并下沉为基础设施,由控制平面统一管理。 有人将 Service Mesh、Kubernetes 和 Serverless 技术称为云原生应用开发的三驾马车。 Kubernetes 是云应用实际意义上的操作系统;Service Mesh 将服务通信功能剥离,实现了与业务的解耦;Serverless 让你不用关心应用的服务器。 这三项技术让我们有能力实现应用开发的终极目标,那就是:只关注业务本身。 而它们,也会引领我们通向未来云原生应用的诗和远方。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。