istio网络转发分析

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

2000元阿里云代金券免费领取,2核4G云服务器仅664元/3年,新老用户都有优惠,立即抢购>>>


阿里云采购季(云主机223元/3年)活动入口:请点击进入>>>,


阿里云学生服务器(9.5元/月)购买入口:请点击进入>>>,

背景介绍

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
目录
相关文章
|
3天前
|
安全 网络安全 数据库
01-Web 网络安全纵观与前景分析
01-Web 网络安全纵观与前景分析
|
3天前
|
机器学习/深度学习 自然语言处理 运维
随机森林填充缺失值、BP神经网络在亚马逊评论、学生成绩分析研究2案例合集2
随机森林填充缺失值、BP神经网络在亚马逊评论、学生成绩分析研究2案例合集
|
3天前
|
机器学习/深度学习 存储 数据采集
随机森林填充缺失值、BP神经网络在亚马逊评论、学生成绩分析研究2案例合集1
随机森林填充缺失值、BP神经网络在亚马逊评论、学生成绩分析研究2案例合集
|
3天前
|
机器学习/深度学习 监控 数据可视化
R语言SOM神经网络聚类、多层感知机MLP、PCA主成分分析可视化银行客户信用数据实例2
R语言SOM神经网络聚类、多层感知机MLP、PCA主成分分析可视化银行客户信用数据实例
|
3天前
|
机器学习/深度学习 数据可视化 算法
R语言SOM神经网络聚类、多层感知机MLP、PCA主成分分析可视化银行客户信用数据实例1
R语言SOM神经网络聚类、多层感知机MLP、PCA主成分分析可视化银行客户信用数据实例
|
9天前
|
机器学习/深度学习 数据可视化 TensorFlow
Python用线性回归和TensorFlow非线性概率神经网络不同激活函数分析可视化
Python用线性回归和TensorFlow非线性概率神经网络不同激活函数分析可视化
|
13天前
|
机器学习/深度学习 PyTorch TensorFlow
TensorFlow、Keras 和 Python 构建神经网络分析鸢尾花iris数据集|代码数据分享
TensorFlow、Keras 和 Python 构建神经网络分析鸢尾花iris数据集|代码数据分享
|
13天前
|
分布式计算 数据可视化 数据挖掘
R语言进行相关矩阵分析及其网络可视化
R语言进行相关矩阵分析及其网络可视化
|
13天前
|
机器学习/深度学习 算法 计算机视觉
人工神经网络ANN中的前向传播和R语言分析学生成绩数据案例
人工神经网络ANN中的前向传播和R语言分析学生成绩数据案例
|
14天前
|
机器学习/深度学习 测试技术 TensorFlow
PYTHON用RNN神经网络LSTM优化EMD经验模态分解交易策略分析股票价格MACD
PYTHON用RNN神经网络LSTM优化EMD经验模态分解交易策略分析股票价格MACD
http://www.vxiaotou.com