istio网络转发分析

本文涉及的产品
推荐全链路深度定制开发平台,高级版 1个月
简介: 通过demo分析istio的网络转发流程,从而对istio实现原理有更为直观的认识。本文先介绍了涉及到的相关概念和背景知识,然后对具体应用进行分析。背景知识概念分散,参考文章较多,敬请谅解。

背景介绍

service mesh 和 istio概述

Service Mesh是专用的基础设施层,轻量级高性能网络代理。提供安全的、快速的、可靠地服务间通讯,与实际应用部署一起,但对应用透明。

为了帮助理解, 下图展示了服务网格的典型边车部署方式:
sidecar.jpg

图中应用作为服务的发起方,只需要用最简单的方式将请求发送给本地的服务网格代理,然后网格代理会进行后续的操作,如服务发现,负载均衡,最后将请求转发给目标服务。当有大量服务相互调用时,它们之间的服务调用关系就会形成网格,如下图所示:
mesh.jpg

Istio——一个用来连接、管理和保护微服务的开放service mesh平台。Istio提供一种简单的方式来建立已部署服务网络,具备负载均衡、服务间认证、监控等功能,而不需要改动任何服务代码。想要为服务增加对Istio的支持,您只需要在环境中部署一个特殊的边车(sidecar),使用Istio控制面板功能配置和管理代理,拦截微服务之间的所有网络通信。
istio结构如下图所示:
istio结构.jpg

kubernetes网络概述

pods间通信

为了解决docker容器间跨主机通信的问题,k8s引入了flannel等overlay网络通信机制。
flannel是CoreOS提供用于解决Docker集群跨主机通讯的覆盖网络工具。它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN等进行报文的封装和转发。
flannel.jpg

flannel底层采用了vxlan机制作为跨网段转发基础。
vxlan作用:
vxlan概览.png

vxlan主要用于在不同网段上构建局域网,通过udp隧道机制,在三层网络上组建一个二层vlan。
vxlan报文结构:

vxlan报文结构.png

k8s的service机制 && kube-proxy

Pod的IP是在docker0网段动态分配的,当发生重启,扩容等操作时,IP地址会随之变化。当某个Pod(frontend)需要去访问其依赖的另外一组Pod(backend)时,如果backend的IP发生变化时,如何保证fronted到backend的正常通信变的非常重要。由此,引出了Service的概念。
service对外暴露一个Virtual IP,也成为Cluster IP, 集群内通过访问这个Cluster IP:Port就能访问到集群内对应的serivce下的Pod。
service是通过Selector选择的一组Pods的服务抽象,其实就是一个微服务,提供了服务的LB和反向代理的能力。
service另外一个重要作用是,一个服务后端的Pods可能会随着生存灭亡而发生IP的改变,service的出现,给服务提供了一个固定的IP,而无视后端Endpoint的变化。

在实际生产环境中,对Service的访问可能会有两种来源:Kubernetes集群内部的程序(Pod)和Kubernetes集群外部,为了满足上述的场景,Kubernetes service有以下三种类型:

ClusterIP:提供一个集群内部的虚拟IP以供Pod访问。
NodePort:在每个Node上打开一个端口以供外部访问。
LoadBalancer:通过外部的负载均衡器来访问。

cluster ip

此模式用于集群内部的互相访问,会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的pod之间通信使用。
k8s_service.png

nodeport

此模式用于集群外网络访问集群内网络,Kubernetes将会在每个Node上打开一个端口并且每个Node的端口都是一样的,通过:NodePort的方式Kubernetes集群外部的程序可以访问Service。

kube-proxy实现

kube-proxy其实就是管理service的访问入口,包括集群内Pod到Service的访问和集群外访问service。
kube-proxy管理sevice的Endpoints,负责service的实现。
kube-proxy有两种实现方式:userspace和iptables。其中userspace mode是v1.0及之前版本的默认模式,从v1.1版本中开始增加了iptables mode,在v1.2版本中正式替代userspace模式成为默认模式。

userspace mode
userspace是在用户空间,通过kube-proxy来实现service的代理服务。废话不多说,其原理如下如图所示:
kubeproxy-user.png
可见,这种mode最大的问题是,service的请求会先从用户空间进入内核iptables,然后再回到用户空间,由kube-proxy完成后端Endpoints的选择和代理工作,这样流量从用户空间进出内核带来性能损耗。
而ServiceMesh正式基于这种机制,并极大增强了kube-proxy的功能,比如流量限制,流量灰度,流量追踪。

另一种mode是iptables,它完全利用内核iptables来实现service的代理和LB。是v1.2及之后版本默认模式,其原理图如下所示:
kubeproxy-iptables.png
如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,会打折扣。

kube-dns

kube-dns可以解决Service的发现问题,k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务。
kube-dns-原理.png
SkyDNS是用于服务发现的开源框架,构建于etcd之上。作用是为k8s集群中的Pod提供DNS查询接口。kube2sky是k8s实现的一个适配程序,它通过名为kubernetes的Service(通过kubectl get svc可以查看到该Service,由集群自动创建)调用k8s的list和watch API来监听k8s Service资源的变更,从而修改etcd中的SkyDNS记录。

通过示例程序,分析istio网络转发过程

示例程序部署环境

示例程序bookinfo结构:
image.png
在本示例中,我们将部署一个简单的应用程序,显示书籍的信息,类似于网上书店的书籍条目。在页面上有书籍的描述、详细信息(ISBN、页数等)和书评。

BookInfo 应用程序包括四个独立的微服务:

productpage:productpage(产品页面)微服务,调用 details 和 reviews 微服务来填充页面。
details:details 微服务包含书籍的详细信息。
reviews:reviews 微服务包含书籍的点评。它也调用 ratings 微服务。
ratings:ratings 微服务包含随书评一起出现的评分信息。

开发环境的k8s集群部署在两个Node上:
image

master node 和 other node

示例程序包括如下四个服务:
image

和如下一些POD:
image

PODS网段为10.244.0.0/16

Ingress流程(流量外部入口)

查看外部端口

$sudo kubectl get svc -n istio-system | grep ingress
image
通过此命令得知服务监听30701端口,通过kubernetes的LoadBalance方式部署,因为没有外部负载均衡,无法获取外部ip,所以只能通过NodePort的方式转发(在任意节点上,发送
到这个端口的流量都被转发到istio-ingress服务中)
那么我们就可以通过此地址访问服务 http://(your-node-ip):30701/productpage

然后我们逐步分析,请求数据包是怎么传递,响应数据包是怎么返回给浏览器的。
首先思路在iptables,因为k8s支持2种proxy模式,userspace和iptables。 从v1.2版本开始,默认采用iptables proxy。
 
kube-proxy: https://ieevee.com/tech/2017/01/20/k8s-service.html
iptables详解: http://blog.csdn.net/reyleon/article/details/12976341

在任意node上查看30701端口转发规则
$sudo iptables-save | grep -i 30701
image
得知流量被转发到KUBE-SVC-JSIH6CCNAROIS6ON服务中
继续跟踪
image
最终流量被转发到10.244.1.150:80

查看该ip对应的pod
image

得知流量被转发到istio-ingress-84c7ddcb7f-kx7gn pod中

查看istio-ingress服务内部转发逻辑

$sudo kubectl exec istio-ingress-84c7ddcb7f-kx7gn -n istio-system -i -t -- /bin/bash
进入此pod

root@istio-ingress-84c7ddcb7f-kx7gn:/# ps -efw
image.png
发现pod中运行了envoy转发服务

root@istio-ingress-84c7ddcb7f-kx7gn:/# netstat -anop | head
image.png
80端口也确实被enovy监听

查看envoy路由规则
image.png
/productpage路径下的流量被转发到out.productpage.default.svc.cluster.local cluster中对应的k8s service为productpage.default.svc.cluster.local

root@istio-ingress-84c7ddcb7f-kx7gn:/# ping productpage.default.svc.cluster.local
image.png
对应的ip为10.109.223.13
image
该ip对应到productpage service

查看iptable转发流程
image
最后被转发到10.244.1.176:9080
image
对应的pod为productpage-v1-6fc75ff57-bbxcq

值得注意的是enovy应该并没有通过iptables(kube-proxy)转发,而是使用out.productpage.default.svc.cluster.local cluster标记目的地址,直接进行转发。

image.png
通过tcpdump抓包也可以证实这一点

内部SideCar 和 Route逻辑

查看pod中sidecar启动方式
$sudo kubectl get pod productpage-v1-6fc75ff57-bbxcq --output=yaml
image.png
image.png

得知该pod中有两个continer:productpage 和 istio-proxy 其中 istio-proxy 作为 proxy 以sidecar的方式启动,自动代理所有网络流量。

进入该pod
$sudo kubectl exec productpage-v1-6fc75ff57-bbxcq -i -t -- /bin/bash
root@productpage-v1-6fc75ff57-bbxcq:/opt/microservices# iptables-save
image
得知所有进出流量确被转发至continer:istio-proxy中的envoy进程中

查看enovy转发规则
root@productpage-v1-6fc75ff57-bbxcq:/opt/microservices# curl http://127.0.0.1:15000/routes
image.png
将对应的流量转发对应的至cluster中

参考:

https://ieevee.com/tech/2017/01/20/k8s-service.html
http://blog.csdn.net/reyleon/article/details/12976341
https://yaoguais.github.io/article/istio/routing.html
https://www.hi-linux.com/posts/30481.html
https://zhuanlan.zhihu.com/p/29586032
http://developer.huawei.com/ict/cn/site-agile-network/article/site-doc-vxlan/
http://www.cnblogs.com/hbgzy/p/5279269.html
https://blog.csdn.net/liyingke112/article/details/76022267
https://www.cnblogs.com/ilinuxer/p/6188804.html
http://istio.doczh.cn/docs/guides/bookinfo.html

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
2月前
|
机器学习/深度学习 编解码 计算机视觉
【APFN】从大佬论文中探索如何分析改进金字塔网络
【APFN】从大佬论文中探索如何分析改进金字塔网络
45 0
|
2月前
|
机器学习/深度学习 分布式计算 资源调度
【社交网络分析】课程考试复盘 + 相关资料补充
【社交网络分析】课程考试复盘 + 相关资料补充
53 0
|
1月前
|
监控 Shell Linux
【Shell 命令集合 网络通讯 】Linux 分析串口的状态 statserial命令 使用指南
【Shell 命令集合 网络通讯 】Linux 分析串口的状态 statserial命令 使用指南
33 0
|
7天前
|
机器学习/深度学习 数据可视化 测试技术
深度学习:Keras使用神经网络进行简单文本分类分析新闻组数据
深度学习:Keras使用神经网络进行简单文本分类分析新闻组数据
21 0
|
8天前
|
Python 数据可视化 索引
PYTHON用GARCH、离散随机波动率模型DSV模拟估计股票收益时间序列与蒙特卡洛可视化
PYTHON用GARCH、离散随机波动率模型DSV模拟估计股票收益时间序列与蒙特卡洛可视化
24 0
PYTHON用GARCH、离散随机波动率模型DSV模拟估计股票收益时间序列与蒙特卡洛可视化
|
8天前
|
机器学习/深度学习 算法 数据可视化
用SPSS Modeler的Web复杂网络对所有腧穴进行关联规则分析3
用SPSS Modeler的Web复杂网络对所有腧穴进行关联规则分析3
17 0
用SPSS Modeler的Web复杂网络对所有腧穴进行关联规则分析3
|
8天前
|
存储 算法 前端开发
R语言中贝叶斯网络(BN)、动态贝叶斯网络、线性模型分析错颌畸形数据
R语言中贝叶斯网络(BN)、动态贝叶斯网络、线性模型分析错颌畸形数据
30 0
|
8天前
|
数据可视化 网络可视化
R语言混合图形模型MGM的网络可预测性分析
R语言混合图形模型MGM的网络可预测性分析
|
9天前
|
算法 定位技术 Windows
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
15 4
|
9天前
|
机器学习/深度学习 资源调度 数据可视化
使用Python和Keras进行主成分分析、神经网络构建图像重建
使用Python和Keras进行主成分分析、神经网络构建图像重建
13 1