背景
笔者接到上级任务,需要根据用户特征做全链路的灰度发布,经过讨论采用istio作为技术方案,istio上手极为简单, 在部署好istio后,只需要对namespace加一个标签istio-injection=enabled,即可将此namespace下的pod纳入istio服务网关, 从而实现流量转移,镜像等功能。笔者不禁好奇,加了这个标签后istio做了啥。
istio-injection=enabled背后的原理
先说结论
istio通过注入sidecar(istio-prxoy)到容器里,因为与处于同一pod的应用同用一个network namspace,从而可以实现对应用进出口流量进行劫持。
"为啥处于同一个 network namspace,就可以实现流量劫持?",感兴趣可以参考我往期文章《用nsenter排查容器网络问题及原理》
分步剖析
理解istio的sidecar模式
sidecar模式:设计的核心思想在于控制和逻辑分离。我们只需要专注地做好和业务逻辑相关的代码,然后由sidecar来实现这些与业务逻辑没有关系的控制功能,比如监视、日志记录、限流、熔断等。
对istio而言,istio-proxy组件就是sidecar,跟业务容器伴生,非侵入式地将业务容器纳入服务网格中。
istio-proxy的原理
istio-proxy容器内部运行着 pilot-agent 与 envoy。 Pilot-agent:基于kubernetesAPI资源对象为envoy初始化可用的bootstrap配置进行启动,在运行后管理envoy运行状态,如配置变更,出错重启等。 envoy:数据平面的执行层,由 pilot-agent 所启动的,从xDS API动态获取配置信息。Envoy并通过流量拦截机制处理入栈及出栈的流量。
sidecar的注入
k8s 有一种准入控制器机制 Admission Webhook,它可以拦截kube-apiserver的请求。istio的sidecar-injector就是一种自定义的Admission Webhook---- mutatingwebhookconfigurations 可以通过如下命令查看
kubectl get mutatingwebhookconfigurations istio-sidecar-injector
当我们调用kube-apiserver为创建pod时,会调用webhook,webhook会检查pod的标签(istio-injection=enabled),如果匹配则注入istio-proxy容器。
sidecar注入以后干了啥
我们可以查看开启了服务治理的容器,可以看到sidecar更改了容器iptables规则,从而实现了流量劫持。
再用nsenter这条命令可以初步看出所有进入pod的inBound流量首先被PREROUTING链拦截,经过后面一系列规则链后先是到达了Envony应用, Envony应用根据规则配置决定是否将数据包转发到应用。
nsenter -t 60960 -n iptables -t nat -S
附:istio安装方式
istio官网给的在线安装方式极为简单,以下为本人整理内网离线部署方案(版本:1.11.5),以供参考。
1、下载离线镜像
下载地址: 链接:pan.baidu.com/s/13zHrx0dH… 提取码:ey1o
2、 导入离线镜像
tar -zxvf istio_images.tar.gz &&
cd istio_images &&
ls *.tar | xargs -I {} docker load -i {}
3、部署istio
istioctl install --set profile=minimal -y
4、namespace注入istio
kubectl label namespace {namespaces} istio-injection=enabled
5.部署可视化相关组件
kubectl -n istio-system apply -f istio-1.11.5/samples/addons/