《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——6. ASM Istio 模式架构设计(下)

简介: 《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——6. ASM Istio 模式架构设计(下)

更多精彩内容,欢迎观看:

《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——6. ASM Istio 模式架构设计(中):https://developer.aliyun.com/article/1221373?spm=a2c6h.13148508.setting.16.15f94f0eCydDfj


Bootstrap

Envoy的初始化配置,与前文中的envoy-rev0.json是一致的。其中

drainDuration —— 热重启期间Envoy关闭连接的时间(以秒为单位),默认是45s

parentShutdownDuration —— 热重启期间,在完全关闭父进程之前,等到的最大时间,默认60s。此数值应该大于drainDuration

 

terminationDrainDuration —— 默认5s。proxy在关闭之前,允许连接关闭时间。通过前文,我们知道pod流量先过istio再被转发到业务容器。当应用发版时候,如果保证现有连接优雅关闭,保证istio-proxy容器在业务容器完全关闭现有连接后,再退出是发版更新时候需要考虑的问题,此值是实现业务平滑更新需要考虑的。

image.png

static_resources

config_dump中静态资源,是来自envoy-rev0.json,

里面包含了prometheus_stats、agent、sds-grpc、xds-grpc和zipkin等配置

image.png

dynamic_resources

动态资源,是通过xDS接口下发到每个istio-proxy容器生效的ASM Istio的配置。也是上述reviews dr,vs配置后通过ASM管控侧下发的。我们接下来关注动态资源配置

Listeners

Envoy采用的listener 来接受到达Envoy的流量请求。Listener和IP Sock、Unix Domain Socket绑定,也可以不绑定到具体的端口,而是接收从其他listener转发来的流量。ASM Istio就是利用了Envoy listener的这一特性来实现转发给不同的服务请求交给不同的Listeners来处理。

 

还是以productpage访问reviews来举例,productpage访问的是reviews的9080端口,根据上文我们知道productpage container访问 外部的9080端口会被先转发到15001 端口,所以我们先看下15001的端口listeners。


VirtualOutbound Listeners

Envoy在15001 端口创建了Listeners,所有被iptables转发的对外请求都会被转到envoy的15001 端口。可以从配置看到,envoy接受到了流量后,并不会做相关的业务动作,而是根据 "use_original_dst": true, 这个配置,依据请求的目的端口转发到相应的listeners 进行处理。

image.png 

那么肯定有个疑问了,如果请求端口并没有配置相关listeners设置,流量该如何进行处理呢?这个取决于outboundTrafficPolicy配置,详情请见
https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-OutboundTrafficPolicy-Mode


Name

Description

REGISTRY_ONLY

只有被注册到服务网格集群内的serviceentry才可以被成功转发出去。如果访问的目的端未被注册到服务网格集群内,请求会被转发到BlackHoleCLuster,由于找不到匹配的upstream host,则会被丢弃。

ALLOW_ANY

无论外部请求是否注册,都可以发送到目的地址。如果目的地址未被listeners,则会将流量转发到PassthroughCluster的TCP proxy filter,请求将会被发送到原始目的地址。

 

Outbound Listeners

outbound 监听命名是0.0.0.0_9080,表明发向任何IP地址的9080端口都被此监听涵盖。"bind_to_port”: false此值表明监听没有绑定到tcp端口,流量是有virtualOutbound转发而来的。

 

那么首先我们需要区别这个监听是为了入方向还是出方向呢?对于入方向,流量会经过15006端口的virtualInbound的listeners,是不会进入0.0.0.0_9080的listeners。

image.png

 

从配置上可以看到filter中并没有特殊的志敏筛选条件,说明接受任何流量,其中config_source 为ads,表明这个是来自动态发现。

 

根据前文可以可看到revirews,ratings,details几个service都是9080端口,这些应用都被同一个服务网格注入,那么productpage访问的目的地址的9080,Envoy如何刚知道是哪个service?是如何判断如果目的端口未9080的地址不是网格内,该如何处理呢?通过上图"route_config_name": "9080" 可以看到存在一个‘9080’的路由规则,在这个路由规则中规定不同的请求目的地的不同的处理结果,下一小节我们将讨论。

Route

前文我们已经知道productpage 应用访问reviews的9080端口会被listeners outbound 0.0.0.0_9080 路由规则到 9080的路由。以下是‘9080’ 路由的全部信息。我们可以看到一共有5个virtual_hosts,分别是allow_any、details、productpage、ratings、和reviews。其中后面4个对应4个不同outbound的cluster,allow_any 对应的是PassthroughCluster,当出方向请求找到相应的Cluster规则时候,会采用默认直接通过。

 

可能有小伙伴很奇怪productpage不直接调用ratings服务,为什么productpage envoy配置会包含ratings的信息。

 

这是因为ASM Istio控制面是无法感知到数据面各个服务之间是如何调用的,因此会将所有的配置信息都下发到被注入的envoy里面,这样保证了网格配置的一致性,但是随着网格服务配置的增多,每个envoy接受和本envoy不相关的配置信息就会变多,这样对envoy资源使用会有一定影响,如果小伙伴有很好的envoy开发能力,并且对业务之间调用非常熟悉,想去除掉本pod中envoy无关的规则,可以通过sidecar规则自定义配置对egress和ingress进行调整,详情请见:

https://istio.io/latest/docs/reference/config/networking/sidecar/

{
 "version_info": "2023-01-30T06:25:21Z/19",
 "route_config": {
 "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
 "name": "9080",
 "virtual_hosts": [
 {
 "name": "allow_any",
 "domains": [
 "*"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "cluster": "PassthroughCluster",
 "timeout": "0s",
 "max_grpc_timeout": "0s"
 },
 "name": "allow_any"
 }
 ],
 "include_request_attempt_count": true
 },
 {
 "name": "details.istio-inject.svc.cluster.local:9080",
 "domains": [
 "details.istio-inject.svc.cluster.local",
 "details.istio-inject.svc.cluster.local:9080",
 "details",
 "details:9080",
 "details.istio-inject.svc",
 "details.istio-inject.svc:9080",
 "details.istio-inject",
 "details.istio-inject:9080",
 "192.168.1.125",
 "192.168.1.125:9080"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "cluster": "outbound|9080||details.istio-inject.svc.cluster.local",
 "timeout": "0s",
 "retry_policy": {
 "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
 "num_retries": 2,
 "retry_host_predicate": [
 {
 "name": "envoy.retry_host_predicates.previous_hosts",
 "typed_config": {
 "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
 }
 }
 ],
 "host_selection_retry_max_attempts": "5",
 "retriable_status_codes": [
 503
 ]
 },
 "max_stream_duration": {
 "max_stream_duration": "0s",
 "grpc_timeout_header_max": "0s"
 }
 },
 "decorator": {
 "operation": "details.istio-inject.svc.cluster.local:9080/*"
 },
 "name": "default"
 }
 ],
 "include_request_attempt_count": true
 },
 {
 "name": "istio-ingressgateway.istio-system.svc.cluster.local:9080",
 "domains": [
 "istio-ingressgateway.istio-system.svc.cluster.local",
 "istio-ingressgateway.istio-system.svc.cluster.local:9080",
 "istio-ingressgateway.istio-system",
 "istio-ingressgateway.istio-system:9080",
 "istio-ingressgateway.istio-system.svc",
 "istio-ingressgateway.istio-system.svc:9080",
 "192.168.1.250",
 "192.168.1.250:9080"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "cluster": "outbound|9080||istio-ingressgateway.istio-system.svc.cluster.local",
 "timeout": "0s",
 "retry_policy": {
 "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
 "num_retries": 2,
 "retry_host_predicate": [
 {
 "name": "envoy.retry_host_predicates.previous_hosts",
 "typed_config": {
 "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
 }
 }
 ],
 "host_selection_retry_max_attempts": "5",
 "retriable_status_codes": [
 503
 ]
 },
 "max_stream_duration": {
 "max_stream_duration": "0s",
 "grpc_timeout_header_max": "0s"
 }
 },
 "decorator": {
 "operation": "istio-ingressgateway.istio-system.svc.cluster.local:9080/*"
 "name": "default"
 }
 ],
 "include_request_attempt_count": true
 },
 }, 
 {
 "name": "productpage.istio-inject.svc.cluster.local:9080",
 "domains": [
 "productpage.istio-inject.svc.cluster.local",
 "productpage.istio-inject.svc.cluster.local:9080",
 "productpage",
 "productpage:9080",
 "productpage.istio-inject.svc",
 "productpage.istio-inject.svc:9080",
 "productpage.istio-inject",
 "productpage.istio-inject:9080",
 "192.168.6.226",
 "192.168.6.226:9080"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "cluster": "outbound|9080||productpage.istio-inject.svc.cluster.local",
 "timeout": "0s",
 "retry_policy": {
 "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
 "num_retries": 2,
 "retry_host_predicate": [
 {
 "name": "envoy.retry_host_predicates.previous_hosts",
 "typed_config": {
 "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
 }
 }
 ],
 "host_selection_retry_max_attempts": "5",
 "retriable_status_codes": [
 503
 ]
 },
 "max_stream_duration": {
 "max_stream_duration": "0s",
 "grpc_timeout_header_max": "0s"
 }
 },
 "decorator": {
 "operation": "productpage.istio-inject.svc.cluster.local:9080/*"
 },
 "name": "default"
 }
 ],
 "include_request_attempt_count": true
 },
 {
 "name": "ratings.istio-inject.svc.cluster.local:9080",
 "domains": [
 "ratings.istio-inject.svc.cluster.local",
 "ratings.istio-inject.svc.cluster.local:9080",
 "ratings",
 "ratings:9080",
 "ratings.istio-inject.svc",
 "ratings.istio-inject.svc:9080",
 "ratings.istio-inject",
 "ratings.istio-inject:9080",
 "192.168.1.172",
 "192.168.1.172:9080"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "cluster": "outbound|9080||ratings.istio-inject.svc.cluster.local",
 "timeout": "0s",
 "retry_policy": {
 "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
 "num_retries": 2,
 "retry_host_predicate": [
 {
 "name": "envoy.retry_host_predicates.previous_hosts",
 "typed_config": {
 "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
 }
 }
 ],
 "host_selection_retry_max_attempts": "5",
 "retriable_status_codes": [
 503
 ]
 },
 "max_stream_duration": {
 "max_stream_duration": "0s",
 "grpc_timeout_header_max": "0s"
 }
 },
 "decorator": {
 "operation": "ratings.istio-inject.svc.cluster.local:9080/*"
 },
 "name": "default"
 }
 ],
 "include_request_attempt_count": true
 },
 {
 "name": "reviews.istio-inject.svc.cluster.local:9080",
 "domains": [
 "reviews.istio-inject.svc.cluster.local",
 "reviews.istio-inject.svc.cluster.local:9080",
 "reviews",
 "reviews:9080",
 "reviews.istio-inject.svc",
 "reviews.istio-inject.svc:9080",
 "reviews.istio-inject",
 "reviews.istio-inject:9080",
 "192.168.4.113",
 "192.168.4.113:9080"
 ],
 "routes": [
 {
 "match": {
 "prefix": "/"
 },
 "route": {
 "weighted_clusters": {
 "clusters": [
 {
 "name": "outbound|9080|v1|reviews.istio-inject.svc.cluster.local",
 "weight": 10
 },
 {
 "name": "outbound|9080|v2|reviews.istio-inject.svc.cluster.local",
 "weight": 40
 },
 {
 "name": "outbound|9080|v3|reviews.istio-inject.svc.cluster.local",
 "weight": 50
 }
 ],
 "total_weight": 100
 },
 "timeout": "0s",
 "retry_policy": {
 "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
 "num_retries": 2,
 "retry_host_predicate": [
 {
 "name": "envoy.retry_host_predicates.previous_hosts",
 "typed_config": {
 "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
 }
 }
 ],
 "host_selection_retry_max_attempts": "5",
 "retriable_status_codes": [
 503
 ]
 },
 "max_stream_duration": {
 "max_stream_duration": "0s",
 "grpc_timeout_header_max": "0s"
 }
 },
 "metadata": {
 "filter_metadata": {
 "istio": {
 "config": "/apis/networking.istio.io/v1alpha3/namespaces/istio-inject/virtual-service/reviews"
 }
 }
 },
 "decorator": {
 "operation": "reviews:9080/*"
 },
 "name": "route"
 }
 ],
 "include_request_attempt_count": true
 }
 ],
 "validate_clusters": false
 },
 "last_updated": "2023-01-30T06:25:21.804Z"
 },

 我们还是以productpage调用reviews来举例,Envoy 会根据 HTTP header 中的domains 来匹配 VirtualHost中domain,所以可以看到domains中列举了reviews的集群内的长短域名,和svc的地址。match “/” 会路由到三个Cluster "outbound|9080|v1|reviews.istio-inject.svc.cluster.local"、"outbound|9080|v2|reviews.istio-inject.svc.cluster.local"和"outbound|9080|v3|reviews.istio-inject.svc.cluster.local",权重分别为10,40,50,名称是‘route’,看到这里是不是有点熟悉?

 

对的,这和前文 [1.3 Envoy配置简读-背景] 中 reviews的VS中的设置,故我们在vs中的相关配置信息,最终envoy会转为route的配置加载后生效。

image.png

image.png

 

 

 通过前面我们还可以看到默认超时是0s,默认重试次数是2次,重试条件是"connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes"

 

Cluster

outbound cluster

 

根据上一下小节,productpage访问reviews,会被productpage中的istio-proxy匹配到‘9080’路由-> 依据vs配置的相关信息,进入三个cluster( "outbound|9080|v1|reviews.istio-inject.svc.cluster.local"、"outbound|9080|v2|reviews.istio-inject.svc.cluster.local"和"outbound|9080|v3|reviews.istio-inject.svc.cluster.local")中一个。

 

这里我们就以"outbound|9080|v1|reviews.istio-inject.svc.cluster.local"Cluster 为例

 image.png

image.png

outbound|9080|v1|reviews.istio-inject.svc.cluster.local cluster配置中可以看到,其类型为EDS,即表示该Cluster的endpoint来自于动态发现,动态发现中eds_config则表明是由ads下发的。同样可以看到与前文 [1.3 Envoy配置简读-背景] 中 reviews的dr中的设置熟悉的配置,比如connectionpool,outlierDetection等这些相关配置信息,最终envoy会转为cluster的配置加载后生效。

 

接下来我们稍微探讨下其他几个特殊的cluster。

BlackHoleCluster

Envoy对于找不到后端处理请求的会默认丢弃,所以会有统一的一个blackholecluster,没有任何指明的后端svc。任何无匹配后端的流量会被转发到这个cluster。

image.png


PassthroughCluster

和BlackHoleCluter正好相反,发向PassthroughCluster的请求会被直接发送到器请求连接中的原始目地的,type类型是"type": "ORIGINAL_DST",表明其发到原始的目的地址:端口

 image.png


Inbound Cluster

inbound Cluster是为了pod上的入方向的请求,对于reviews来说,其对应的Inbound Cluster只有一个inbound|9080。

 image.png


Endpoint

从endpoint文件内容可以看到,

reviews Cluster “outbound|9080|v1|reviews.istio-inject.svc.cluster.local”只有1 个endpoint地址,是reviews-v1-74fb8fdbd8-qwsjqpod ip 10.0.3.29

 image.png

image.png

 

至此,我们大概梳理完毕服务网格内两个服务之间访问,istio-proxy日志解读和配置对应关系。

 

6) Tips

前文的config_dump文件太长,解读起来其实比较费力,服务网格提供了asmctl工具可以很方便的去解读listeners,route,cluster,endpoint等,详细信息请见
https://help.aliyun.com/document_detail/313187.html

[root@shycmain ~]# asmctl --asmconfig asmconfig pc listeners productpage-v1-797d845774-dndmk.istio-inject --port 9080
ADDRESS PORT MATCH DESTINATION
0.0.0.0 9080 Trans: raw_buffer; App: HTTP Route: 9080
0.0.0.0 9080 ALL PassthroughCluster
[root@shycmain ~]# asmctl --asmconfig asmconfig pc routes productpage-v1-797d845774-dndmk.istio-inject --name 9080
NOTE: This output only contains routes loaded via RDS.
NAME DOMAINS MATCH VIRTUAL SERVICE
9080 details /*
9080 istio-ingressgateway.istio-system /*
9080 productpage /*
9080 ratings /*
9080 reviews /* reviews.istio-inject
[root@shycmain ~]# asmctl --asmconfig asmconfig pc Cluster productpage-v1-797d845774-dndmk.istio-inject --fqdn reviews.istio-inject.svc.cluster.local
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
reviews.istio-inject.svc.cluster.local 9080 - outbound EDS reviews.istio-inject
reviews.istio-inject.svc.cluster.local 9080 v1 outbound EDS reviews.istio-inject
reviews.istio-inject.svc.cluster.local 9080 v2 outbound EDS reviews.istio-inject
reviews.istio-inject.svc.cluster.local 9080 v3 outbound EDS reviews.istio-inject
[root@shycmain ~]# asmctl --asmconfig asmconfig pc endpoint productpage-v1-797d845774-dndmk.istio-inject --Cluster "outbound|9080|v1|reviews.istio-inject.svc.cluster.local"
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.0.3.29:9080 HEALTHY OK outbound|9080|v1|reviews.istio-inject.svc.cluster.local

 7) 小结

本篇文章主要聚焦ASM Istio服务网格模式下,被注入pod的数据面流量转发链路情况。istio灵活注入实现了在Pod维度对流量的定制化配置和观测性,带来了业务链路角度实现的更多种的可能。在服务网格中配置gateway,virtualservice,destinationrule等规则在通过xDS下发到envoy后,会通过listeners,route、cluster、endpoint多个环节最终体现在流量转发规则上

 

那么在运用ASM遇到不符合预期情况时,这些环节都是需要考虑的方向。ASM 除了流量管理,还有安全,鉴权,可观测方面的便捷运用,这些方面的配置,最终也会体现在相关的网格服务资源配置上,感兴趣的小伙伴可以参考ASM官方文档

目录
打赏
0
0
0
0
50
分享
相关文章
阿里云携手神州灵云打造云内网络性能监测标杆 斩获中国信通院高质量数字化转型十大案例——金保信“云内网络可观测”方案树立云原生运维新范式
2025年,金保信社保卡有限公司联合阿里云与神州灵云申报的《云内网络性能可观测解决方案》入选高质量数字化转型典型案例。该方案基于阿里云飞天企业版,融合云原生引流技术和流量“染色”专利,解决云内运维难题,实现主动预警和精准观测,将故障排查时间从数小时缩短至15分钟,助力企业降本增效,形成可跨行业复制的数字化转型方法论。
134 6
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
57 0
云原生应用网关进阶:阿里云网络ALB Ingress 全面增强
云原生应用网关进阶:阿里云网络ALB Ingress 全面增强
102 6
云原生技术演进之旅:从容器到服务网格
在云计算的浪潮中,云原生技术以其独特的灵活性和可扩展性引领了新的技术革命。本文将深入探讨云原生技术的发展脉络,从容器技术的突破,到Kubernetes的集群管理,再到服务网格的微服务通信解决方案,揭示云原生如何不断适应和塑造现代应用的需求。文章将通过数据支撑和案例分析,展示云原生技术在实际应用中的优势和挑战,并预测其未来的发展趋势。
129 28
云计算与网络安全:技术融合与挑战云原生技术在现代软件开发中的应用
【8月更文挑战第28天】在数字时代的浪潮中,云计算和网络安全成为信息技术领域的两大支柱。本文将探讨云计算服务的分类、特点及其面临的安全威胁,分析网络安全的基本概念、重要性以及信息安全的关键要素。同时,文章将深入讨论云计算环境下的网络安全问题,包括数据保护、访问控制和合规性挑战,并提出相应的解决策略和技术措施。最后,通过一个代码示例,展示如何在云计算环境中实现基本的数据加密,以增强信息的安全性。 【8月更文挑战第28天】 随着云计算技术的飞速发展,云原生技术已成为推动软件行业创新的关键力量。本文将深入探讨云原生的核心概念、优势以及如何在现代软件开发中有效利用云原生技术。我们将通过具体案例,展示
云原生应用网关进阶:阿里云网络ALB Ingress 全能增强
在过去半年,ALB Ingress Controller推出了多项高级特性,包括支持AScript自定义脚本、慢启动、连接优雅中断等功能,增强了产品的灵活性和用户体验。此外,还推出了ingress2Albconfig工具,方便用户从Nginx Ingress迁移到ALB Ingress,以及通过Webhook服务实现更智能的配置校验,减少错误配置带来的影响。在容灾部署方面,支持了多集群网关,提高了系统的高可用性和容灾能力。这些改进旨在为用户提供更强大、更安全的云原生网关解决方案。
1020 25
云原生技术探索:容器化与微服务架构的实践之路网络安全与信息安全:保护数据的关键策略
【8月更文挑战第28天】本文将深入探讨云原生技术的核心概念,包括容器化和微服务架构。我们将通过实际案例和代码示例,展示如何在云平台上实现高效的应用部署和管理。文章不仅提供理论知识,还包含实操指南,帮助开发者理解并应用这些前沿技术。 【8月更文挑战第28天】在数字化时代,网络安全和信息安全是保护个人和企业数据的前线防御。本文将探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性。文章旨在通过分析网络安全的薄弱环节,介绍如何利用加密技术和提高用户警觉性来构建更为坚固的数据保护屏障。
kubevela可观测体系问题之KubeVela云原生时代可观测性挑战的问题如何解决
kubevela可观测体系问题之KubeVela云原生时代可观测性挑战的问题如何解决
云原生入门指南:Kubernetes和容器化技术云计算与网络安全:技术融合的新篇章
【8月更文挑战第30天】在云计算的浪潮中,云原生技术如Kubernetes已成为现代软件部署的核心。本文将引导读者理解云原生的基本概念,探索Kubernetes如何管理容器化应用,并展示如何通过实践加深理解。
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问