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

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

近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的IaaS化到现在的微服务化,客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度,也一直在高速的发展和演进中,这必然对客户对云原生网络的可观测性带来了极高的门槛和挑战。

 

为了提高云原生网络的可观测性,同时便于客户和前后线同学增加对业务链路的可读性,ACK产研和AES联合共建,合作开发ack net-exporter和云原生网络数据面可观测性系列,帮助客户和前后线同学了解云原生网络架构体系,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学处理疑难问题的体验,提高云原生网络的链路的稳定性。image.png

图: 服务网格示例

image.png

图 Istio数据面示意图

 

Kubernetes的横空出现打破了底层服务器、底层网络等计算资源的界限,给业务的灵活部署、快速恢复、弹性伸缩,资源效率最大化带来了无限可能。

 

但是业务场景的‘贪婪’是无限的,随着微服务趋势大肆发展,业务上对于同一个service,不同版本和流量控制有着更精细化的颗粒度的需求,最好能实现Pod维度的流量控制,可观测性等等。这些在kubernetes上是无法实现的:

 

从流量角度,k8s最小控制维度是service其他比如金丝雀 等发布,借助各种ingress controller或者其他组件实现,并且这些也无法实现Pod之间流量和连接状态可观测性

k8s给服务微型化,小型化创造了条件如果前后端服务存在调用关心,他们如果使用共享通信库,则会在开发阶段就要求所有微服务使用相同逻辑语言和堆栈,这从某种程度上又大大限制微服务独立化,无法实现完全‘漠不关心’

将原来集成在同一个ECS上服务拆分成不同模块,这些模块之间调用涉及跨ECS等,那么必然需要在代码开发阶段需要考虑超时,重试,连接失败等逻辑机制,而这些与微服务最核心服务应用其实没有太大关系,但是开发工作往往耗费大量经历在逻辑设计上

 

那么,有没有办法实现上述和微服务的业务完全隔离呢?Istio的出现给这个带来了相对完美的解决方案,让应用这和开发者更加关注业务本身的开发迭代。Istio利用了k8s的Pod概念,会根据使用者的配置,在每个被注入的Pod部署时,自动注入istio-proxy 容器和initial 容器。

 

Initial容器的目的是通过修改Pod 单独网络命名空间的iptables规则,让需要代理的流量进入到istio-proxy 监听的端口,istio-proxy 监听出入 两个端口,根据网格配置,来实现对出入流量的代理实现和干预。而被同一个istio注入的载体,都被视为同一个服务网格之内,他们之间的调用已经脱离了service的层面,会命中相关的istio cluster配置的endpoint,这样我们就可以实现Pod维度的流量管理、观测性、安全性等配置。

 

1) Pod注入

ASM默认提供了一个Webhook控制器,可以将Sidecar代理自动添加到可用的Pod中。通过下面的命令可以看到ASM注入的集群有个 istio-sidecar-injector-1-15-3的mutatingwebhookconfiguration,查看webhook内容,可以看到其中一条就是有 istio-inject: enabled 标签的namespace  里的pod创建时候会自动注入。

image.pngimage.png

除了命名空间维度,还有Pod维度,其他注解方式等多种维度实现K8s集群是否被加入到Istio服务网格中。为了充分利用服务网格的所有特性,服务网格中ACK集群的应用Pod必须包含一个Sidecar代理。除了手动注入方式外,通常建议启用自动注入的方式来简化部署,ASM已经实现了注入配置的可视化操作,具体请见多种方式灵活开启自动注入

image.png

 

2) Pod流量转发

通过describe被注入的Pod,可以发现Pod中除了设置好的业务container,还多出两个容器:istio-proxy和init container:istio-init。这两个容器的镜像是一样的,只是运行的命令的不一样,这样的好处是只需要拉取一份镜像,节省了拉取镜像的时间。

image.png

 

3) Init Container

Init container 利用的是k8s的特性,一种具有特权的特殊容器,在Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。每个Pod中可以包含多个容器和多个Init 容器。他与普通容器很像,但是有自己独特点:

 

多个init 容器是串行运行的。也就是说多个init 容器会依序运行,等上一个init 容器运行完毕结束后,才会开始运行下一个容器

只有等到所有init 容器全部运行结束退出后,业务容器才开始启动,在这之前,pod不会处于ready

如果Pod的Init 容器失败,kubelet 根据pod设置restartPolicy 进行相应action

 

既然现在了解了Init container的作用,那我们来看一下istio-init在启动的过程中做了哪些事情,可以通过下面的命令:

kubectl logs -n istio-inject productpage-v1-797d845774-dndmk -c istio-init

image.png

image.png

可以看到istio-init在启动过程中进行了一连串的iptables规则的生成和配置,比如出方向转发到15001端口;入方向转发到15006端口;访问15008端口,直接return不进行流量劫持等等。

 

那有什么办法可以自定义配置么?查看pod的信息可以看到相关配置的启动参数,也就通过相关规则实现了出入流量重定向到设置的端口。

image.png

 

-p: 所有出方向的流量被iptables重定向到15001端口

-z: 所有入方向的流量被iptables重定向到15006端口

-u: 用于排除用户ID为1337,可以视为envoy应用本身使用UID 1337

-m: 流量重定向模式,“REDIRECT” 或 “TPROXY”

-i: 重定向出方向的地址范围,“*” 表示重定向所有出站流量。

-x: 指将从重定向出方向中排除的IP 地址范围

-b: 重定向入站端口列表

-d: 重定向入站端口中排除的端口列表

 

我们从Pod的视角去观察,将Pod视为一个整体,里面有istio-proxy容器和业务容器APP container

入方向流量转发

image.png

 

根据上文的iptables 规则,我们可以归纳出被入方向代理转发的端口,比如80等,在Pod的网络命名空间netfilter模块经过流程是Client -> RREROUTING -> ISTIO_INBOUND -> ISTIO_IN_REDIRECT -> INPUT -> Envoy 15006(Inbound)-> OUTPUT -> ISTIO_OUTPUT -> POSTROUTING -> APP。这样就实现了入方向流量先被转发到sidecar容器后,在转发到业务容器的监听端口。其中在步骤5和6 之间,流量会按照设置好的istio规则进行处理。

 

出方向流量转发

image.png

 

根据上文的iptables 规则,我们可以归纳出被入方向代理转发的端口,比如80等,在Pod的网络命名空间netfilter模块经过流程是APP > OUTPUT -> ISTIO_OUTPUT -> ISTIO_REDIRECT -> Envoy 15001(Outbound)-> OUTPUT -> ISTIO_OUTPUT -> POSTROUTING -> DST。这样就实现了出方向流量先被转发到sidecar容器后,在转发到目的监听端口。其中在步骤d和e 之间,流量会按照设置好的istio规则进行处理。

入方向流量免转发

image.png

 

对于入方向的某些端口或者自定义端口,我们不需要它经过sidecar容器,iptables规则会设置将符合条件的入方向流量避免转发到15006端口,直接转发到业务容器监听端口 RREROUTING -> ISTIO_INBOUND -> INPUT -> APP。

 出方向流量免转发

image.png

 

对于出方向的某些端口或者自定义端口,我们不需要它经过sidecar容器,iptables规则会设置将符合条件的入方向流量避免转发到15001端口,直接离开Pod的网络命名空间 APP -> OUTPUT -> ISTIO_OUTPUT -> POSTROUTING -> DST。


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

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


相关文章
|
6月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
6月前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
535 2
|
6月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
2038 0
|
9月前
|
Cloud Native 中间件 调度
云原生信息提取系统:容器化流程与CI/CD集成实践
本文介绍如何通过工程化手段解决数据提取任务中的稳定性与部署难题。结合 Scrapy、Docker、代理中间件与 CI/CD 工具,构建可自动运行、持续迭代的云原生信息提取系统,实现结构化数据采集与标准化交付。
743 1
云原生信息提取系统:容器化流程与CI/CD集成实践
|
10月前
|
Docker 容器
Docker网关冲突导致容器启动网络异常解决方案
当执行`docker-compose up`命令时,服务器网络可能因Docker创建新网桥导致IP段冲突而中断。原因是Docker默认的docker0网卡(172.17.0.1/16)与宿主机网络地址段重叠,引发路由异常。解决方法为修改docker0地址段,通过配置`/etc/docker/daemon.json`调整为非冲突段(如192.168.200.1/24),并重启服务。同时,在`docker-compose.yml`中指定网络模式为`bridge`,最后通过检查docker0地址、网络接口列表及测试容器启动验证修复效果。
1569 39
|
9月前
|
存储 Linux 容器
【Container App】在容器中抓取网络包的方法
本文介绍在Azure Container App中安装tcpdump抓取网络包,并通过Storage Account上传抓包文件的方法。内容包括使用curl和nc测试外部接口连通性、长Ping端口、安装tcpdump、抓取网络包、以及通过crul命令上传文件至Azure Storage。适用于需要分析网络请求和排查网络问题的场景。
259 0
|
9月前
|
缓存 Cloud Native Java
Java 面试微服务架构与云原生技术实操内容及核心考点梳理 Java 面试
本内容涵盖Java面试核心技术实操,包括微服务架构(Spring Cloud Alibaba)、响应式编程(WebFlux)、容器化(Docker+K8s)、函数式编程、多级缓存、分库分表、链路追踪(Skywalking)等大厂高频考点,助你系统提升面试能力。
939 0
|
11月前
|
存储 Cloud Native 关系型数据库
PolarDB开源:云原生数据库的架构革命
本文围绕开源核心价值、社区运营实践和技术演进路线展开。首先解读存算分离架构的三大突破,包括基于RDMA的分布式存储、计算节点扩展及存储池扩容机制,并强调与MySQL的高兼容性。其次分享阿里巴巴开源治理模式,涵盖技术决策、版本发布和贡献者成长体系,同时展示企业应用案例。最后展望技术路线图,如3.0版本的多写多读架构、智能调优引擎等特性,以及开发者生态建设举措,推荐使用PolarDB-Operator实现高效部署。
500 4
|
11月前
|
Kubernetes Cloud Native 区块链
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
330 0