openfaas请求处理流程详解
Service与Iptables
对于一个函数请求而言,其由一个客户端发出,首先访问的是openfaas的gateway的service(如下图)。
以ClusterIP的访问方式为例,即发出的http请求的访问地址为10.43.200.142,处理ClusterIP访问的方式是通过iptables。接下来详细看一下iptables中的处理流程。
从PREROUTING链开始,可以看到其中有一个KUBE-SERVICES链,这个链就是对Service访问进行处理的。
接着进入KUBE-SERVICES链,可以发现对于每个Service都有一个KUBE-SVC-XXX的链与之对应
对于访问的openfaas的gateway服务来说,可以找到如下图所示的处理流程,可以发现请求继续被转入KUBE-SVC-ZRMKUO636AMCDCTY链进行处理
接着进入KUBE-SVC-ZRMKUO636AMCDCTY链,发现由KUBE-SEP-LBVEOEISHEG4P3QA进行处理
再进入KUBE-SEP-LBVEOEISHEG4P3QA链,观察到其处理方式如下图,即进行了DNAT,将目的地址转成了10.42.0.239:8080
上述过程画成图就是如下图所示的过程
接着查看内核路由表,可以发现请求被转发到了cni0网卡。Cni0就是pod所连接的网卡
这里可以看到下图中也有flannel网卡,实际上因为上面的集群是单节点集群,如果是多机集群的话请求则会被路由到flannel1.1这个网卡上。
到这里就可以通过iptables将对于Service的访问路由到pod所连接的网卡了。
Pod的连接
这是一张基于flannel网络的拓补图,其中的docker0就是上述的cni0,可以发现每一个pod都是通过veth pair连接在cni0上,也就是说当请求通过DNAT之后被转发到cni0上后可以再通过cni0进行路由找到具体的pod。
由于前述的实验是在单节点机器上,所以不存在需要访问的pod不在同一个机器上的情况,所以也就没用到flannel网络。而在多节点集群中,上述流程中的不同点在于,请求进行DNAT之后会被转发到flannel网卡上,然后由一个flanneld的程序进行处理(也就是路由,flanneld通过etcd储存了一个集群的网络信息,通过此进行路由),接着flanneld会根据路由选择的结果将请求转发到目的pod所在机器上,而在目的pod所在机器上,请求先是被转发到flannel网卡上,但是这次由于pod就在本机,所以就被转发到本机的cni网卡上,接下来就是相同的步骤了。,
Pod内部容器的连接
经过前述处理,请求也终于到达了cni0,也找到了相应的pod,接下来只需要发送给具体的容器就好了。
在每个pod之中,都有一个pause容器,这是kubernetes创建的系统容器,pause容器会创建网络命名空间并将直接的网络桥接到cni0网桥(通过veth pair),然后所有的用户容器都会共享这个网络命名空间,即共享一块网卡。那么请求转发的流程就是直接在cni0通过veth pair传向了pod内的eth0,接着容器就可以直接接收网卡eth0上的信息了。
gateway中的请求处理
在gateway中设置了处理函数请求的handler,如下图所示
在处理请求时,还要分为两种情况,一种是允许0缩放的情况,这种情况下如果当前没有可用的pod要先进行scale操作,另一种就是不允许0缩放的情况
对于不允许0缩放的情况而言,处理方式如下,可以看到直接传送给了对应的Service
而在允许0缩放的情况下,可以看到多了一个scale操作
函数pod内部的请求处理
接下来gateway就会把请求转发给具体的function所对应的Service,这里Service的访问流程如前所述,但是也有一点需要注意,因为每个function都会对应多个pod副本,那么Service在进行iptables处理的时候就需要选择一个具体的pod来转发请求,这个时候就会有一个负载均衡的问题,而Kubernetes在这里的处理是随机选择一个pod进行转发。
对于openfaas来说,其函数的部署是通过watchdog的方式,目前有三种watchdog处理方式,如下图所示
而对于Tensorflow Serving这样的程序来说,应该选择第三种Http的方式。在Http的方式下当这个watchdog启动时,父进程会fork一个子进程(也就是用户提交的函数程序),这个函数程序不是简单的函数逻辑,也要包含一个Http服务器用来处理Http请求,且这个函数程序会一直运行,监听容器网卡上的端口以获得请求。
Tensorflow Serving内部的请求处理
当上述的Http方式中的函数程序是Tensorflow Serving时,请求会到达Tensorflow Serving所监听的端口,接下来就进入Tensorflow Serving的处理逻辑。
而对于Tensorflow Serving来说,其通常工作在batch模式,在batch处理模式下,每一种模型对应一个等待队列,每一个新请求都会被提交到相应的等待队列中,等待队列中的请求按照设置的batch大小被组织成一个个的batch。而处理这些batch的是一个线程池,这个线程池中的每个线程一次处理一个队列中的一个batch(即对其做前向传播),整个线程池会在不同的队列之间轮转处理。
本文地址:https://blog.csdn.net/weixin_38616705/article/details/107385293
上一篇: Redis主从复制