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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——6. ASM Istio 模式架构设计(中)

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

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


4) Istio-proxy

image.png

 可以看到15001和15006 被envoy应用所监听,而envoy应用就是istio-proxy容器程序。Init 容器启动的时候根据所设置的参数中指定将出入站流量重定向到 Envoy的模式为“REDIRECT”或者“TPROXY”。

 

使用REDIRECT方式,一旦Pod注入了Sidecar代理之后,所有入站流量都是从Envoy重定向,Envoy将流量发送到绑定了本地地址(127.0.0.1)的应用程序,所以应用看不到真正的原始IP。

 

在服务网格环境下如何保持服务访问时的客户端源IP呢?可以使用TPROXY模式,目前ASM已经支持了 TPROXY模式,具体详情请见https://help.aliyun.com/document_detail/464794.html

在TPROXY模式下,Pod的网络命名空间的iptables会有mangle配置。

ADS聚合服务发现

image.png

我们已经知道了服务网格会在每个注入的Pod内注入两个容器:istio-init和istio-proxy。一旦在网格控制面进行相关配置的修改,会通过pilot下发到每个istio-proxy容器去生效。而istio是通过xDS服务接口去实现相关配置的动态下发的,其中xDS包含了LDS(Listener Discover Service)、CDS(Cluster Discover Service)、EDS(Endpoint Discovery Service)和RDS(Route Discover Service)。

 

一般情况下,在更新配置过程中应该先更新Cluster->之后CLuster的Endpoint 开始更新->开始更新Cluster和Endpoint相对应的Listener -> Route开始更新配置的Listener信息->最后删除不在使用 Cluster和Endpoint 以保证更新过程中流量无损。但是这些xDS接口是相互独立,所以在配置下发的时候,存在某些依赖关系的DS因配置生效前后关系造成了部分流量被丢弃,这在某些生产环境中是无法接受的。

 

为了保证数据面配置的一致性,服务网格利用gRPC流来进行ADS聚合发现服务,通过一个gRPC流来保证各个xDS接口的调用顺序,避免各个接口独立性造成数据配置的不匹配。详细信息可以参考:
https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol

envoy-rev.json

image.png

 可以看到istio-proxy 启动了pilot-agent 程序,pilot-agent 作为父进程启动了子进程/usr/local/bin/envoy。其中/etc/istio/proxy/envoy-rev.json 是envoy初始化的配置文件。

 

Node
包含了istio-proxy所在节点,当前Pod,istio版本、ACK集群ID、ASM版本、必要端口等相关信息。

image.png

 

admin

istio-proxy相关日志,管理端口等信息

image.png

 

dynamic_resources

ADS相关配置信息,比如api协议,版本,超时时间等

image.png

 

static_resources

包含了prometheus_stats、agent、sds-grpc、xds-grpc和zipkin五个cluster和一个在15090上监听的listener,xds-grpc cluster对应前面dynamic_resources中ADS配置。prometheus_stats cluster和15090用于对外提供prometheus采集端口。zipkin cluster是外部的zipkin服务器调用地址。

image.png

 

tracing

分布式链路跟踪,这里的collector_cluster是前面static_resources里面定义的zipkin cluster。

image.png

 

访问日志分析

通过前文,我们已经知道两个互相被注入的pod访问,流量会被各自的istio-proxy所劫持并处理,那么只要分析客户端和服务端的istio-proxy日志并进行加工,就可以对流量进行可观测性解读。

 

我们在这里还是以官方例子来举例访问 http:///productpage,productpage 应用会自动调用details服务,reviews服务。我们以productpage和details之间链路来进行举例分析。

 

productpage-v1-797d845774-dndmk IP 是10.0.1.130,details 应用的svc的名称是details,svc地址是192.168.1.125,svc端口是9080

 

请求发送方 productpage-v1-797d845774-dndmk的istio-proxy日志

{"upstream_host":"10.0.1.127:9080","downstream_remote_address":"10.0.1.130:49586","downstream_local_address":"192.168.1.125:9080","duration":6,"upstream_cluster":"outbound|9080||details.istio-inject.svc.cluster.local","path":"/details/0","protocol":"HTTP/1.1","upstream_local_address":"10.0.1.130:50026","method":"GET","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36","route_name":"default","request_id":"834147c2-435f-94a7-af11-8491df9ab4f8","start_time":"2023-01-31T14:23:20.603Z","upstream_transport_failure_reason":null,"upstream_service_time":"5","response_flags":"-","bytes_received":0,"authority_for":"details:9080","authority":"details:9080","requested_server_name":null,"istio_policy_status":null,"trace_id":"9712c9f3da936a8c927f227bfe536c16","response_code":200,"x_forwarded_for":null,"bytes_sent":178}

 

请求接受方 details-v1-6758dd9d8d-dtbdc的istio-proxy日志

{"x_forwarded_for":null,"start_time":"2023-01-31T14:23:20.608Z","method":"GET","response_flags":"-","route_name":"default","istio_policy_status":null,"requested_server_name":"outbound_.9080_._.details.istio-inject.svc.cluster.local","bytes_received":0,"request_id":"834147c2-435f-94a7-af11-8491df9ab4f8","response_code":200,"upstream_host":"10.0.1.127:9080","trace_id":"9712c9f3da936a8c927f227bfe536c16","downstream_remote_address":"10.0.1.130:50026","protocol":"HTTP/1.1","bytes_sent":178,"upstream_transport_failure_reason":null,"downstream_local_address":"10.0.1.127:9080","upstream_local_address":"127.0.0.6:46225","authority":"details:9080","authority_for":"details:9080","upstream_service_time":"0","upstream_cluster":"inbound|9080||","duration":1,"path":"/details/0","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"}

 日志内容解读

 

"upstream_host":"10.0.1.127:9080",————对于outbound,此是上游某个Endpoint地址和端口

downstream_remote_address":"10.0.1.130:49586"," ————对于outbound,此为本pod-ip:随机端口1

downstream_local_address":"192.168.1.125:9080","————对于outbound,此为目svc-ip:svc-port

duration":6," ———— 整个请求时间,单位ms

upstream_cluster":"outbound|9080||details.istio-inject.svc.cluster.local",———— cluster信息

"path":"/details/0"

"protocol":"HTTP/1.1"

"upstream_local_address":"10.0.1.130:50026", ————对于outbound,此为本pod-ip:随机端口2

"method":"GET"

"user_agent":"Mozilla/5.0(Windows NT 10.0; Win64; x64)

AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"

"route_name":"default",———— 路由名称

"request_id":"834147c2-435f-94a7-af11-8491df9ab4f8"

"start_time":"2023-01-31T14:23:20.603Z"

"upstream_transport_failure_reason":null

"upstream_service_time":"5",———— 上游返回请求时间,单位ms

"response_flags":"-",———— 返回标志,关于连接或返回详细信息

"bytes_received":0

"authority_for":"details:9080"

"authority":"details:9080"

"requested_server_name":null

"istio_policy_status":null

"trace_id":"9712c9f3da936a8c927f227bfe536c16",———— 此ID为唯一值,可以在上游istio-proxy对应

"response_code":200,———— 返回状态码

"x_forwarded_for":null

"bytes_sent":178

 

日志解读可以详细见官方连接:
https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage

 

 

UPSTREAM_HOST

上游主机的host,表示从 envoy 发出的请求的目的端

通常来说,对于 outbound cluster,此值是「上游pod-ip :Pod-port」,而对于 inbound cluster,此值是「本pod-ip :Pod-port」

 

UPSTREAM_LOCAL_ADDRESS

上游连接中,当前 envoy的本地地址

通常来说,对于 outbound cluster,此值是「本pod-ip : 随机端口2」,而对于 inbound cluster,此值是「127.0.0.6: 随机端口3」,此处的127.0.0.6 对应了 【1.2 Pod流量转发-Init Container】 中的iptables会将来自127.0.0.6的流量免于istio代理,因为这个流量是从sidecar本身发出的

 

DONSTREAM_LOCAL_ADDRESS

下游连接中,当前 envoy的本地地址。通常来说,对于 outbound cluster,此值是「目的service-ip : service-port 」,而对于 inbound cluster,此值是「当前pod-ip :Pod-port,此处和下游的upstream_host应该相对应。

 

DOWNSTREAM_REMOTE_ADDRESS

通常来说,对于 outbound cluster,此值是「当前pod-ip : 随机端口 」,而对于 inbound cluster,此值是「下游pod-ip : 随机端口2」,此处和下游的upstream_local_address相对应


5 Envoy配置简读(数据链路)

背景

image.png

还是用官方的示例,以productpage 访问 reviews 服务来举例。

image.png

image.png

image.png

image.png

通过Kubernets 集群资源,我们可一看到reviews有三个版本 分贝为v1,v2,v3,Pod数量各一个。SVC reviews 是ClusterIP模式,svc端口是9080,targetport是pod的9080端口,v1,v2,v3 都被加到了reviews SVC的endpointslice。

 

在未被istio注入的情况下,集群内productpagePod访问 reviews.istio-inject 服务,会被netfilter以round-robin的方式平均转发到v1,v2,v3三个pod上,每个pod应该承受1/3的流量。在传统的k8s集群中,是无法通过k8s的resource控制不同版本的流量分配。但是实际的生产环境,我们是有这方面的需求的。

 

比如v1版本是线上业务版本,承载了主要业务流量,v2版本是开发完毕预上线版本,本质上是不希望影响线上流量的,可能需要引流线上流量的5%到预发版本进行一段时间观察,来判断新版本是否有问题,之后再进一步扩大引流比例直至100%之后,v1版本才进行下线,从而实现从业务角度的平滑迁移。

 

或者比如v3是测试版本,我们希望观察流量在网络波动超时情况下,业务的自我容灾和恢复情况的行为是否符合预期,以前这种需求需要通过在业务代码中写好熔断代码,不同熔断环境都需要重新发版。那么像这种流量控制在ASM Istio就可以很容易的实现。

 

下面就是一个ASM Istio中的vs和dr的配置。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
 creationTimestamp: '2023-01-30T06:25:21Z'
 generation: 1
 name: reviews
 namespace: istio-inject
 resourceVersion: '651722274'
 uid: 63f715c9-b253-4fbb-8351-5313371df14e
spec:
 hosts:
 - reviews.istio-inject.svc.cluster.local
 http:
 - name: route
 route:
 - destination:
 host: reviews
 subset: v1
 weight: 10
 - destination:
 host: reviews
 subset: v2
 weight: 40
 - destination:
 host: reviews
 subset: v3
 weight: 50

 其中在reviews vs的定义了集群内访问reviews.istio-inject.svc.cluster.local 是的http协议的规则。其中指明了v1版本权重10%,v2版本权重40%,v3版本权重 50%

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
 creationTimestamp: '2023-01-30T06:28:46Z'
 generation: 2
 name: reviews
 namespace: istio-inject
 resourceVersion: '654863578'
 uid: fdbdfcea-1fcd-453e-96fb-ce41c91ded9b
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3
 trafficPolicy:
 connectionPool:
 http:
 http2MaxRequests: 1000
 maxRequestsPerConnection: 10
 tcp:
 maxConnections: 100
 outlierDetection:
 baseEjectionTime: 15m
 consecutive5xxErrors: 7
 interval: 5m

 reviews dr的定义了集群内reviews的几个版本,并定义了相关流量策略。其中http2MaxRequests 表明http最大的请求数。maxRequestsPerConnection 表明每个连接最大的请求数。tcp最大连接数是100。在熔断配置中,每隔5min中检测一次,连续7次5xx,把后端移除endpoint 15min。

 

通过前文我们知道pilot通过xDS接口将服务网格的配置下发到每个被注入的pod中的istio-proxy中。那么对于每个pod中的istio-proxy,我们是否有办法去查看相关的加载的配置信息呢?istio-proxy通过15000端口对外暴露管理端口,我们可以通过如图所示的命令获取到相关的配置信息。

 

其中可以通过curl 127.0.0.1:15000/config_dump 可以获取到完整的配置信息,由于此配置信息超过1万多行,我们就不在这里做全部的展示

 

感兴趣的同学可以自行研究下,下文会针对此config_dump信息中的cluster,Listener,endpoint,route等关键信息做个相关展示和简要说明,同时也和前文的xDS做个呼应。

kubectl exec -n istio-inject productpage-v1-797d845774-dndmk -c istio-proxy -it -- curl 127.0.0.1:15000/config_dump

image.png

 

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

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

相关文章
|
4月前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
20天前
|
运维 Kubernetes 网络协议
基于虚拟服务配置的渐进式迁移实践:Istio集群至ASM集群的平滑切换
本文介绍了从Istio+k8s环境迁移到阿里云ASM+ACK环境的渐进式方法,通过配置虚拟服务和入口服务实现新老集群间的服务调用与流量转发,确保业务连续性与平滑迁移
554 132
|
11天前
|
负载均衡 容灾 Cloud Native
云原生应用网关进阶:阿里云网络ALB Ingress 全面增强
云原生应用网关进阶:阿里云网络ALB Ingress 全面增强
|
14天前
|
人工智能 安全 API
容器化AI模型的安全防护实战:代码示例与最佳实践
本文基于前文探讨的容器化AI模型安全威胁,通过代码示例展示如何在实际项目中实现多层次的安全防护措施。以一个基于TensorFlow的图像分类模型为例,介绍了输入验证、模型加密、API认证和日志记录的具体实现方法,并结合最佳实践,如使用安全容器镜像、限制权限、网络隔离等,帮助构建更安全的AI服务。
|
2月前
|
负载均衡 容灾 Cloud Native
云原生应用网关进阶:阿里云网络ALB Ingress 全能增强
在过去半年,ALB Ingress Controller推出了多项高级特性,包括支持AScript自定义脚本、慢启动、连接优雅中断等功能,增强了产品的灵活性和用户体验。此外,还推出了ingress2Albconfig工具,方便用户从Nginx Ingress迁移到ALB Ingress,以及通过Webhook服务实现更智能的配置校验,减少错误配置带来的影响。在容灾部署方面,支持了多集群网关,提高了系统的高可用性和容灾能力。这些改进旨在为用户提供更强大、更安全的云原生网关解决方案。
757 25
|
7月前
|
Cloud Native 安全 网络安全
云计算与网络安全:技术融合与挑战云原生技术在现代软件开发中的应用
【8月更文挑战第28天】在数字时代的浪潮中,云计算和网络安全成为信息技术领域的两大支柱。本文将探讨云计算服务的分类、特点及其面临的安全威胁,分析网络安全的基本概念、重要性以及信息安全的关键要素。同时,文章将深入讨论云计算环境下的网络安全问题,包括数据保护、访问控制和合规性挑战,并提出相应的解决策略和技术措施。最后,通过一个代码示例,展示如何在云计算环境中实现基本的数据加密,以增强信息的安全性。 【8月更文挑战第28天】 随着云计算技术的飞速发展,云原生技术已成为推动软件行业创新的关键力量。本文将深入探讨云原生的核心概念、优势以及如何在现代软件开发中有效利用云原生技术。我们将通过具体案例,展示
|
2月前
|
人工智能 运维 监控
容器服务Kubernetes场景下可观测体系生产级最佳实践
阿里云容器服务团队在2024年继续蝉联Gartner亚洲唯一全球领导者象限,其可观测体系是运维的核心能力之一。该体系涵盖重保运维、大规模集群稳定性、业务异常诊断等场景,特别是在AI和GPU场景下提供了全面的观测解决方案。通过Tracing、Metric和Log等技术,阿里云增强了对容器网络、存储及多集群架构的监控能力,帮助客户实现高效运维和成本优化。未来,结合AI助手,将进一步提升问题定位和解决效率,缩短MTTR,助力构建智能运维体系。
|
3月前
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
5月前
|
缓存 监控 测试技术
掌握容器化持续集成/持续部署(CI/CD)的最佳实践
【10月更文挑战第8天】本文介绍了容器化持续集成/持续部署(CI/CD)的最佳实践,涵盖容器化CI/CD的概念、优势和实施步骤。通过使用容器技术,可以实现环境一致性、快速迭代和易于扩展,提高软件开发的效率和可靠性。文章还详细讨论了编写高效的Dockerfile、自动化测试、安全性、监控和日志管理等方面的最佳实践。
|
7月前
|
安全 网络安全 数据安全/隐私保护
云原生技术探索:容器化与微服务架构的实践之路网络安全与信息安全:保护数据的关键策略
【8月更文挑战第28天】本文将深入探讨云原生技术的核心概念,包括容器化和微服务架构。我们将通过实际案例和代码示例,展示如何在云平台上实现高效的应用部署和管理。文章不仅提供理论知识,还包含实操指南,帮助开发者理解并应用这些前沿技术。 【8月更文挑战第28天】在数字化时代,网络安全和信息安全是保护个人和企业数据的前线防御。本文将探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性。文章旨在通过分析网络安全的薄弱环节,介绍如何利用加密技术和提高用户警觉性来构建更为坚固的数据保护屏障。

热门文章

最新文章