早在2021年,Istio就开始了共享代理模式的探索,并于2022年9月推出的Ambient Mesh——无Sidecar的全新数据平面模式,目前还未发布正式版本。
这篇博客是花了好多时间收集整理出来的,按照学习思路,先简介了 Istio Ambient Mesh与Sidecar模式的区别,再了解Istio-CNI网络管理机制的实现,最后介绍ztunnel组件的工作方式,以及Istio零信任安全机制等。
在探索Ambient Mesh L4网络模型工作原理时,遇到了很多底层网络概念,如有错误,欢迎指正。
目前Istio通过向服务Pod注入Envoy容器的方式,来实现流量控制,通信安全,以及可观测性等。Envoy是一个开源的高性能通信总线,是Istio的数据平面的关键组件,但它也存在一些缺点,例如:
Istio最新推出的Ambient Mesh将原本Sidecar的能力分为了两层:L7(waypoint)和L4(ztunnel),ztunnel负责在传输层实现零信任微服务集群,waypoint负责在应用层实现所有L7 策略 。waypoint和ztunnel做为节点中的共享代理被部署为DaemonSet,这意味Ambient Mesh具有更好可维护性和更好的伸缩性来适应集群流量。
当Istio向服务Pod注入Sidecar容器时,首先会利用 Init Container在pod中配置iptables,此配置可确保容器的入站和出站流量被Envoy代理截获。
什么是iptables?
iptables 是 Linux 上一个用于过滤和转发IP数据包的工具。通过配置iptables,可以对进出节点的网络流量进行过滤和管理。例如,修改数据包的源地址和目标地址等。
在 Kubernetes 中,iptables 规则用于实现服务暴露和负载均衡等功能。通过 iptables 规则,将来自服务的请求转发到正确的目标 Pod,以及实现流量的负载均衡和故障转移。
Init Container的缺点之一是: 容器需要net_admin和net_raw权限。二者都是Linux非常重要的权限。
net_admin权限的作用是管理系统防火墙和路由表
net_raw权限的作用是创建网络套接字,直接访问和操作网络层的数据。
Istio CNI插件可以用来替代Istio InitContainer,如下图所示,Istio CNI插件作为DaemonSet被部署在每个集群节点上。
Kubernetes支持CNI(容器网络接口)。当 Kubernetes为容器设置网络时,k8s容器运行时会将事件通知给CNI插件。每个节点上的 Istio CNI 实例处理在该节点上运行的容器的网络,管理iptables,以便流量被代理拦截。
虽然 Istio CNI 插件仍然需要相应的 Kubernetes RBAC 权限,但不再与服务Pod耦合在一起。
在Ambient Mesh中,Istio-CNI 是必选组件。Istio-CNI 中新增Ambient处理模块,该模块会监听Namespace以及 Pod的变化,为所在节点的应用设置路由和iptables规则:
路由:设置路由表,将本节点应用发出的流量路由到 ztunnel,以及将本节点接收的流量路由到ztunnel。
iptables:在ztunnel容器中设置iptables规则,将流量透明拦截至 ztunnel 对应的端口上
Istio-CNI支持两种重定向机制:iptables与GENEVE隧道组合重定向(默认)和eBPF重定向。eBPF是一种高效、可编程的虚拟机技术,可以在 Linux 内核中执行安全的、高性能的网络数据包过滤和处理操作,这里不过多深入。
在认识了Istio中基本的网络概念之后,我们开始进一步了解ztunnel组件的工作内容。ztunnel主要工作可以分为两部分:ztunnel网络模型与零信任隧道。
我们先来看一个问题:在使用Ambient Mesh的集群中,当一个Pod想要访问另一个节点上的服务时,流量路径是怎样的?
CNI插件会初始化每个节点上的路由与iptables,ipset 规则(ipset 规则常用于定义网络访问策略和访问控制列表),并在每个节点上设置了两个虚拟接口:istioin和istioout。
顾名思义,它们分别负责处理入站流量和出站流量。
ztunnel Pod同样有两个处理出站/入站流量的网络接口:pistioint和pistioout,二者与节点的istio接口之间通过GENEVE隧道连接。
Ambient Mesh集群中,每个Pod的网络流量都会经过iptables和路由规则,被拦截到节点的istioin和istioout接口上,之后转发给ztunnel Pod做进一步处理,Istio L4策略也是由此开始实现。
下图为我们直观的展示了节点上出站流量的工作过程:
1. 当服务A需要跨节点请求服务B时,首先需要去匹配服务A所在节点的iptables和路由规则。
2. Ambient Mesh中的每个服务IP都被添加在IP set当中,因此该请求将被打上标记。
3. 带有标记的请求会被转发到istioin和istioout两个节点网络接口,这里是出站流量,所以转发到了istioout。
4. 流量通过GENEVE隧道转发到ztunnel Pod的pistioout接口
5. ztunnel透明网关代理将流量转发到ztunnel的15001端口上,这是出站流量端口。
再之后,两个节点的ztunnel将通过HBONE隧道连接,实现Ambient Mesh L4层面的功能,如传输安全,链路追踪等。
人们往往认为集群内部服务之间的网络请求是安全的,因此通常采用http的形式进行直接调用。但真是如此吗?随着分布式,微服务,混合云等技术的迅速发展,服务架构和网络环境也越来越复杂,零信任的架构概念也因此诞生了。
即使是集群内部,也应该对请求者进行身份验证。这里的身份验证并不是应用级别的权限控制,而是网络层面的身份认证机制。
Istio则提供了维护网络安全方面的能力。
Citadel是Istio控制面板组件之一,负责网格中的服务身份和证书管理,分发服务之间的安全通信所需的证书和密钥,以及服务之间的相互 TLS 通信的加密和解密。不了解TLS的同学可以看这里:答疑解惑:开发者必须彻底搞懂的 SSL/TLS 协议
Citadel 使用 Kubernetes 的 Secrets 对象来存储和管理证书,将证书作为 Secrets 提供给相关的服务。
如图:Istio-agent在启动时向Istiod发出证书签名请求,CA签发证书给Istio-agent,Envoy Proxy可以从Istio-agent请求证书用于之后的通信,stio-agent将负责维护证书的有效性。
ztunnel之间使用HBONE隧道进行连接,使用mTLS协议保证通信安全。其中最关键的问题是,通信双方的身份从何而来?与sidecar模式类似,ztunnel 将会充当CA客户端的角色,它将负责代理服务的CSR,管理节点上的mTLS证书。
如图所示:节点之间的ztunnel通过mTLS建立HBONE隧道以确保通信加密,并且ztunnel都使用了所代理服务的身份证书进行通信。
虽然我们只介绍了ztunnel的工作原理,但是相信大家已经看到了Ambient Mesh带来的许多优势。
1. 应用程序与数据平面实现解耦,Ambient Mesh实现了无感知部署,升级等。
2. ztunnel模式更加多样,ztunnel独立部署于节点,可以使用更多技术方案去实现L4策略。
3. ztunnel在运营,成本和性能之间有更出色的平衡能力。
4. ztunnel更加安全可靠,ztunnel只负责L4层面的工作,可攻击范围大大减小。
最后,Istio作为k8s关键的基础设施,它必须是稳定,安全,便于维护的。根据官方的介绍,Ambient Mesh的目的并不是为了推翻Sidecar模式,两者是各有取舍的,Ambient Mesh的出现给了用户新的选项。