今天 Istio 社区推出了 Ambient Mesh,这是一种新的 Istio 数据平面模式,旨在简化操作、扩大应用兼容性并降低基础设施成本。用户可以选择将 Ambient Mesh 集成到其基础设施的网格数据平面,放弃 sidecar 代理,同时保持 Istio 的零信任安全、遥测和流量管理等核心功能。该模式目前还是预览版,Istio 社区准备在未来几个月内将其推向生产就绪。
Ambient Mesh 推出的消息对于社区来说可能显得有些突然,但其实关于 sidecar 模式对于资源的消耗过大,以及简化服务网格的呼声在社区里已经存在很久了,Google 从多年前就在寻求 HBONE(HTTP-Based Overlay Network Environment,基于 HTTP 的重叠网络环境)解决方案,还有社区提出的多种 sidecar 部署模式、proxyless 模式 等都是为了解决这个问题。
Ambient 模式是 Istio 社区在 2022 年 9 月推出的一种无 sidecar 的 Istio 数据平面部署模式,下图展示了 Ambient 模式的架构。
从图中我们可以看到 Ambient 模式对应用程序本身没有任何侵入,而是在应用程序外围:
下面是 Ambient 模式的功能分层。
关于 Ambient 模式的更多介绍请阅读:
Ambient 模式中的 ztunnel 和 Waypoint proxy 目前还是使用 Envoy 来实现的,未来不排除使用其他语言(非 C++,如 Rust)来实现一个轻量级的 ztunnel。该模式的核心是所谓的 HBONE(HTTP Based Overlay Network Environment,基于 HTTP 的覆盖网络环境)。
HBONE 基于 HTTP/2 CONNECT,将工作负载之间的请求以流的形式进行隧道传输,尽可能地复用 HTTP/2 连接。HBONE 对工作负载来说是透明的,支持更好的传输机制:
其实 ambient 模式的出现,主要是因为 sidecar 模式有以下限制:
本文我将谈谈对 ambient 模式的几点看法:
参考 Istio 官网中的步骤安装:
检查 Kubernetes 版本,建议的大于等于 1.21;
安装 Ambient profile:
istioctl install --set profile=ambient
部署示例应用:
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/sleep.yaml
kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/notsleep.yaml
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
将应用添加到 Ambient Mesh:
kubectl label namespace default istio.io/dataplane-mode=ambient
发送测试流量:
kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1
在将 Pod 加入到 Ambient Mesh 中之后,就可以给这些 Pod 应用 L4 的授权策略:
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/sleep", "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
EOF
上面这个策略只允许 sleep 服务和 istio ingress gateway 访问 productpage。
应用 L7 策略:
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: productpage
annotations:
istio.io/service-account: bookinfo-productpage
spec:
gatewayClassName: istio-mesh
EOF
使用 Gateway API 创建了一个 Gateway,这里实际是在 default
命名空间下创建了一个 waypoint proxy,专门用于处理 L7 流量。
在给它应用授权策略:
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/sleep", "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
to:
- operation:
methods: ["GET"]
EOF
这个策略跟之前有所不同的是最后的 to
字段定义了 HTTP 方法,现在你在 sleep pod 中对 productpage 服务执行除 GET 以外的其他请求都将失败。从 notsleep pod 中对 productpage 服务的 GET 请求将成功。
现在你可以从前面创建的这个 productpage Gateway 中获取到 HTTP 请求的 Prometheus 指标信息。
kubectl exec deploy/bookinfo-productpage-waypoint-proxy -- curl -s http://localhost:15020/stats/prometheus | grep istio_requests_total
给 Reviews 服务创建 Gateway(Waypoint proxy),所有访问 Reviews 服务的 L7 流量都会经过它。
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: reviews
annotations:
istio.io/service-account: bookinfo-reviews
spec:
gatewayClassName: istio-mesh
EOF
再给它应用流量划分:
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-reviews.yaml
发送 100 次请求测试流量切分结果。
kubectl exec -it deploy/sleep -- sh -c 'for i in $(seq 1 100); do curl -s http://istio-ingressgateway.istio-system/productpage | grep reviews-v.-; done'
你将获得请求结果,说明一切运行正常。
清理环境和删除 Istio。
kubectl delete -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
kubectl delete -f samples/bookinfo/networking/destination-rule-reviews.yaml
kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl delete -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/sleep.yaml
kubectl delete -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/notsleep.yaml
kubectl delete namespace istio-system
kubectl label namespace default istio.io/dataplane-mode-
在安装有 Istio 的 Kubernetes 中部署了你的应用之后,如果想要给命名空间 ns-a
启用 Ambient Mode,只需要运行:
kubectl label namespace ns-a istio.io/dataplane-mode=ambient
Ambient Mesh 默认启用 L4 安全。
Ambient 模式的 L7 网络功能是按需启用的:假如你想给服务 A 访问服务 B 的路径开启 L7 网络功能,那么你需要给服务 B 创建 Gateway。
另外,L7 网络功能是与服务账户绑定的,假如服务 svc-a
的服务账户是 sa-svc-a
,那么给它部署一个 Gateway:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: svc-a
annotations:
istio.io/service-account: sa-svc-a
spec:
gatewayClassName: istio-mesh
然后你就可以创建 VirtualService
、DestinationRule
等资源管理服务 svc-a
。
该 Gateway 实际上是一个 Deployment,它可以部署在与应用程序不同的命名空间中,你可以对这个 Deployment 单独管理和扩缩容。
目前 ambient 模式的代码位于 Istio 代码库的 experimental-ambient
分支,根据 Matt Klein 和 Louis Ryan 的说法,ztunnel 和 Waypoint proxy 是用 Envoy 实现的,其中 ztunnel 是精简后的 Envoy,只负责 L4 功能且继续使用 xDS 协议来控制。但是 ambient 模式依然有很多限制,例如:
EnvoyFilter
;LoadBalancer
和 NodePort
方式访问,不过你可以部署一个入口网关(未启用 ambient 模式)以从外部访问服务;这里有安装 ambient 模式的详细环境要求。
以上就是笔者对 ambient 模式(外围模式)的看法,该模式还处于试验阶段,但绝不是玩具,据信已在某些场景试验过。笔者也将继续追踪该模式的最新进展,请保持关注。也欢迎更多关注 Istio 的朋友加入云原生社区 Istio 讨论群,与社区大咖一起探讨,或者在本文下面评论聊聊你的看法。
最后更新于 2024/09/06