联邦学习KubeFATE开源项目的K8s和Ingress详解

fb252c32269159e9ac85fe43ec1b3384.png

题图摄于奥林匹克体育中心

企业中使用 Kubernetes 构建云原生联邦学习平台是最佳的选择,本文详细解析了 KubeFATE 的技术要点。作者:马陈龙,VMware 中国研发中心云原生实验室工程师,KubeFATE 开源项目维护者。

一、文章背景

企业级联邦学习开源项目 KubeFATE 最新版本v1.8.0有一个新功能,可以让用户指定 Ingress 类,切换不同的 Ingress 控制器。

从社区来看,Ingress 的配置和 Ingress 控制器一直是社区讨论比较多的问题。从FATE社区发布的调研报告看到,不少用户因为配置 Ingress 的复杂性,认为 Kubernetes 部署方式太复杂,而大量把实验用途的 Docker-compose 模式当作生产使用。

借这篇短文我们小谈一下为什么我们使用Kubernetes,以及从原理上解析 Ingress。

二、为什么使用Kubernetes?

KubeFATE 目前有 Docker-compose,以及Kubernetes两种部署方式。Docker-compose的定位很简单,就是为了体验使用的,它的优点和缺点都很突出。

docker-compose方式的优点是:

  1. 基于 Docker 的部署,所有FATE的依赖包都已经在容器镜像里打包好,所以不需要管理复杂的依赖关系,也不会因为某些包的版本冲突造成各种小问题。当然由于国内网络、校园网限制、Docker hub免费用户政策等原因,有些同学会碰到镜像下载问题。但是这些问题,可以参考文档内的使用本地源,离线部署等方法很容易解决;

2.每一方使用且只使用一个主机(虚拟机或物理机)来真实部署,所以可以看作一个真实的实验环境,如果有需要调试网络联通、网络数据压缩类需求的用户也可以使用。而相对于Kubernetes,Docker-compose对物理网络只引入一个虚拟网桥,所以不会对网络调试任务带来过多复杂度;

3.每一方是一个完整的部署,相对于standalone的方式,docker-compose可以调试架构相关模块。

docker-compose方式的缺点是:

  1. 除非基于docker swarm,每一方只能是一台机器,所以对于大任务是不适合支持的。譬如Docker-compose可以支持测试Spark+HDFS的方式,但是3个HDFS的节点会被部署在一台机器内,是除调试外不具备实用性的;

2.Docker(特指免费版本的Docker engine)本身是一个发布服务的打包执行工具,并不具备基础设施管理功能,更不具备集群管理功能,所以使用Docker-compose部署完后是不提供管理能力的。我们可以从Docker-compose的能力看出,它更多是为了提供实验,相对于standalone部署方式可以支持完整架构类的试验。

针对于Docker-compose的问题,KubeFATE在v1.3.0版本开始提供Kubernetes部署方式,就是为了提供一种集群的,带运维方案部署方式。其实前文提到的docker-swarm也是一种类似的方案,另外还有几种商业方案,但是Kubernetes在事实上已经成为了业界的标准。

基于KubeFATE,FATE支持在Kubernetes上部署、管理、运维,这里的 Kubernetes 不单单是指我们教程上的Minikube,也不单单是开源的Kubernetes,或者像 VMware 的Tanzu Kubernetes Grid 这样的企业级产品,而是 Kubernetes 这个事实标准。

使用 KubeFATE 管理 FATE,其实相当于在基础设施添加了一个抽象层,用户可以按需要,把 FATE 部署在:

  1. 单机

    Kubernetes提供了多种本机使用的方案,如果你是Linux环境,可以使用Minikube或Kind;如果你是Mac或者Windows,可以使用Docker Desktop (https://www.docker.com/products/docker-desktop) 的Kubernetes环境(但是需要注意的是,Docker Desktop以及类似的工具提供Kubernetes其实是等于在你本机起了一个虚拟机,所以会多一个虚拟NAT或者其他虚拟网络设备,网络上会有一定变化,请参考相关工具具体文档)。社区经常问的,FATE能否支持Mac, Windows,其实如果使用KubeFATE的Kubernetes,答案是可以的,只是方案太多,我们不提供相关支持,需要大家查阅文档或者社区里讨论。

2.云部署

基本上主流的云提供商都提供Kubernetes集群,KubeFATE已经测试过AWS, GCE以及Azure的支持。而国内云提供商也都可以直接创建Kubernetes,然后使用KubeFATE把FATE部署上去测试使用,譬如:

  • 阿里云的ACK: https://www.alibabacloud.com/zh/product/kubernete

  • 腾讯云的TKE: https://cloud.tencent.com/product/tke 

  • 华为云的CCE: https://support.huaweicloud.com/cce/index.html

  • UCloud的UK8S: https://m.ucloud.cn/mobile/product/uk8s.html 

还有很多,就不一一列举了。甚至据笔者所知,一些高校都对在校学生提供Kubernetes的云服务,所以完全FATE是可以直接部署在这些服务上,然后使用云计算的弹性进行联邦建模训练;

3.私有云

目前基本上所有的做私有云的提供商都提供基于Kubernetes,或者兼容Kubernetes接口的私有云方案。譬如我们VMware的VMware Cloud Foundation(https://www.vmware.com/asean/products/cloud-foundation.html)甚至还提供了混合多云的方案。基于KubeFATE,我们的 FATE 可以部署在 VMware 的产品上,并且有能力进行多云的管理。我们还有一篇官方白皮书描述:

https://blogs.vmware.com/virtualblocks/2021/10/18/kubefate-vmware-cloud-foundation-tanzu

4.IoT与Edge设备

经常有误解,Kubernetes非常重量级,但是其实Kubernetes有很多适用IoT设备及edge的版本,譬如:

  • K3s: https://k3s.io/

  • KubeEdge: https://kubeedge.io/en/

Kubernetes是一个标准,所以我们可以把应用服务部署在不同的Kubernetes版本上,可以屏蔽具体底层。我们团队去年底就成功使用KubeFATE把FATE部署在我们公司的SD-WAN设备上,并跑了FATE自带的所有算法。

我们的愿景是可以提供统一的工具让FATE运行在any cloud, any device上, 而联邦学习的优势又可以让不同的FATE互联互通,创作价值。这就是我们推荐生产环境使用Kubernetes的原因。

如上所说,如果使用云服务,或者使用商业版本,那Kubernetes是不会有部署问题的。但如果需要自己部署Kubernetes,从社区反映的问题,大多是镜像源的问题,这里可以解决网络问题,或者在部署工具里设置使用本地或者国内源即可。

从调查报告的数据,大多数用户碰到的问题是Kubernetes部署好了,但没有Ingress,或者Ingress配置不当引起网络不通。我们可以重点讨论下Ingress。

三、关于Ingress

聊Ingress,我们先要明白Kubernetes其实提供了一个供应用使用的资源池,而你的应用部署在这个池里。如果一个应用需要被访问,也就是对外提供服务,被定义为Service (参考:https://kubernetes.io/docs/concepts/services-networking/service ),由一组pod组成。

Kubernetes会把所有的应用部署在一个 “内网” 内。Kubernetes内的服务可以通过ClusterIP互相访问协作,但是如果从Kubernetes集群外访问服务,则需要通过类似网关把内网的服务对外暴露出来。这里网关的概念可以基本等同于我们熟悉的物理网络的网关,那现实中网关的配置方法大家应该都很熟悉,对应的Kubernetes也提供了一下四种常见方式:

1.Proxy方式

也就是 kubectl proxy (七层)命令或者 kubectl port-forward (四层)命令,这是最基础的向外暴露内网方式,等于利用 API Server 作为服务的一个反向代理。所以对该服务的访问保护是基于 API Server 本身的,也就是 Kubernetes 用户的访问控制。所以就注定只有在开发调试,或者一些演示情况下适用;

2. NodePort

NodePort 等于是一个分布式的端口映射。当宿主机需要访问内部一个服务,一般来说就是外部可访问的服务器内使用一个端口映射为服务监听端口。但是由于Kubernetes是分布式系统,所以需要保证外部流量访问到任意一个可访问服务器都需要可以映射到正确的服务监听端口。所以 Kubernetes 的 NodePort 是所有可访问服务器为一个服务(其实就是ClusterIP)绑定一个端口,任意流量到达任意一台服务器该端口,将会被映射到被绑定的服务。那局限性就明显了:

  • 一个端口只能绑定一个服务;

  • 端口数有限,而且在Kubernetes内默认只允许使用30000到32767端口可以做NodePort。

  • 需要自行管理节点IP变换情况。

以上两种方式都是在特殊情况下使用的情况,而后面两种方式则是更常用在生产环境的方案:

3.LoadBalancer (负载均衡)

负载均衡是常见的互联网暴露服务方式。在Kubernetes里,等于通过分配一个固定IP,转发所有流量到服务上。所以可以认为LoadBalancer解决上文NodePort的第三个局限问题。

另外值得一说的是,Kubernetes的负载均衡是与物理服务器的负载均衡兼容的,所以企业可以使用已有的负载均衡设备作为 Kubernetes 的 LoadBalancer。目前,基本所有的云服务提供商都通过 LoadBalancer 为使用者提供单独IP。LoadBalancer的缺点也很明显,由于它不解决 NodePort 的第一和第二个局限,一个IP业务上只能绑定一种服务,所以它更为昂贵。

4.Ingress

Ingress是解决NodePort第一第二个局限而存在的。为了解决当有多个服务需要暴露,且不愿意为每个服务购买一个IP,我们需要一个前置服务,作为所有服务的“路由”。接着根据配置路由(Virtual Host或者URL Path)规则把流量转到不同的服务去。

0696097d627713a2091afab89a757956.png

(来源:Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what? URL: https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

而实现这个路由工作的组件就叫Ingress Controller。Ingress Controller是一个实现了Kubernetes定义Ingress代理路由功能的应用,本质是一个部署在Kubernetes内的pod。不同的Ingress Controller在实现基本功能外,各有不同的特点,譬如有些Ingress Controller支持七层路由,有些则支持四层路由;有些是硬件实现,有些基于软件等。

目前Kubernetes维护的Ingress Controller有AWS, GCE以及NGINX Ingress。而第三方还有大量的Ingress Controller实现,提供各异功能,详见:Ingress Controller(参考:https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers) 。

Ingress Controller不是Controller Manager的一部分,所以新安装的Kubernetes不会安装Ingress Controller;但作为Kubernetes对外提供服务最重要的模块之一,一般运行中的Kubernetes集群都已经安装Ingress Controller,作为集群级服务。所以KubeFATE默认情况下不会安装Ingress Controller。因为这个原因,所以不少初次使用KubeFATE安装FATE的同学往往碰到需要自己安装Ingress Controller的情况,这里需要一些系统知识。

Ingress Controller本质也是一个Kubernetes服务。所以它本身页面对前面讨论的需要对外暴露服务。所以它本身也需要采用上面四种方式(Proxy, NodePort, LoadBalancer和Ingress)之一来向外服务,一般我们有两种部署Ingress Controller的方式: 使用NodePort或者LoadBalancer。

大部分公有云的部署方式都通过Cloud LoadBalancer暴露Ingress Controller。

337348cb00dbb9b15396c20f6488e5ae.png

(来源:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/)

而企业或者比较正规的部署一般也建议采用硬件或者软件的LoadBalancer暴露Ingress Controller。

在KubeFATE的教程中,我们用Minikube作为演示,这里Minikube把Ingress作为内置插件安装,其实等于封装了软件LoadBalancer暴露Nginx Ingress Controller. 而社区里如果一般开发者,没有前置LoadBalancer的情况,我们一般建议使用NGINX Ingress,默认的方案是使用NodePort,如下图:

256c9ab3ab86ad9abf2a4f856086e6e3.png

(来源:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/)

所以大家在绑定KubeFATE服务,和其他部署的服务会需要带一个端口。

在Kubernetes中支持同时部署多个Ingress Controller,在v1.18的时候支持了Ingress 通过Ingress Class来选择不同的Ingress Controller。在KubeFATE v1.8.0,我们也支持了通过配置Ingress Class Name选择不同的Ingress Controller。

四、如何使用Ingress?

接下来介绍下如何在KubeFATE部署的FATE中如何使用Ingress。

首先需要有一个Kubernetes集群,不论是云服务商提供的或者是自己部署的。这里的Kubernetes是通过Kubeadm部署的,Ingress Controller使用NGINX Ingress Controller(参考:https://kubernetes.github.io/ingress-nginx/)。

查看自己的Kubernetes的版本,通过 kubectl version 命令查看。

f857ef54d1ea9f6a8e8aafafe325b91e.png

部署NGINX Ingress Controller,这里我们通过下面的一条命令就可以部署。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/baremetal/deploy.yaml

NOTE:除了上面的Bare metal clusters的安装方式,你也可以根据自己的Kubernetes类型选择合适的部署方式,不同的安装方式(参考:Installation Guide - NGINX Ingress Controller https://kubernetes.github.io/ingress-nginx/deploy/)。

接下来使用 kubectl get all -n ingress-nginx 命令,查看部署结果

e94bb63ab8755afc61f1e7cf65ca07ff.png

如上图,如果 POD 的状态是 Completed 和 Running,说明已经部署成功。否则可以通过 kubectl pod describe 来查看具体遇到的问题,多数情况下会遇到镜像无法拉取的错误 ImagePullBackOff,这时候可以通过其他的镜像源拉取。

当前的 NGINX Ingress Controller 是通过 NodePort 的方式对外提供服务(在Kubernetes 集群外可以访问内部的资源,通常情况是无法直接访问的)。80和443端口分别通过 31046 和 3043 0两个 NodePort 的端口暴露给集群外访问。

NGINX Ingress Controller 安装的同时也会创建一个 Ingress Class。使用`kubectl get ingressclass` 查看已经部署的 Ingress Class。

848c9d73a7428082370a8d4d5467c8ed.png

当一个Ingress资源的“ingressClassName”定义为“nginx”,就会匹配到当前部署的NGINX Ingress Controller。

NGINX Ingress Controller安装完成后,就可以安装KubeFATE来使用Kubernetes的Ingress功能。

KubeFATE的安装

下载安装包,更多版本的安装包可以在KubeFATE 项目Release找到(https://github.com/FederatedAI/KubeFATE/releases)

$ wget 

https://github.com/FederatedAI/KubeFATE/releases/download/v1.8.0/kubefate-k8s-v1.8.0.tar.gz

$ tar -xzf ./kubefate-k8s-${release_version}.tar.gz

$ cd kubefate && chmod +x ./kubefate && sudo mv ./kubefate /usr/local/bin

然后安装KubeFATE service

$ kubectl apply -f ./rbac-config.yaml

$ kubectl apply -f ./kubefate.yaml

安装KubeFATE service的时候默认也会就会安装一个Ingress。使用这个命令:

$ kubectl get ingress -n kube-fate

a7cefdf5882dbf7da1f248e6ad751326.png

可以查看部署的Ingress资源,ADDRESS 通常就是Kubernetes的NodeIP或者LoadBalancer服务分配的IP。HOSTS 默认情况下是example.com,不过可以修改`kubefate.yaml`的host: example.com字段,修改成你自己的任意值。

默认情况下 kubefate.yaml 里面有一个ingressClassName: nginx的值,定义了KubeFATE的Ingress Controller使用的是NGINX Ingress Controller。如果要使用其他的Ingress Controller,修改`ingressClassName`这个字段就可以。

运行kubectl get pod -n kube-fate命令验证KubeFATE的所有pod的运行正常。

f86b17b7a4093d21f1d27e5419a2a189.png

当KubeFATE的所有Pod都运行成功,则可以通过下面的命令验证是否部署成功。

curl -H "Host:example.com" 10.xxx.xxx.25:31046

b685fa777c1e5ec7d6bd5aaf3e339c40.png

验证部署成功。

接下来就可以通过 example.com 来访问 KubeFATE Service的服务了。通常情况下是KubeFATE的命令行工具访问。

在使用KubeFATE命令行工具之前还需要修改host文件和config.yaml

1.     首先是修改host

sudo -- sh -c "echo \"10.xxx.xxx.25 example.com\"  >> /etc/hosts"

修改之后,所有 example.com 这个URL的访问都会转到你定义的IP。此外如果配合自定义HOSTS和DNS也可以省略这一步。

使用 curl example.com:31046 可以验证hosts文件是否修改成功并生效。

b7890d9419d830cf146a359774f491f5.png

2.     然后是修改 config.yaml

在`serviceurl: example.com`后面加上端口号,`serviceurl: example.com:31046`,这里主要是因为`ingress-nginx-controller`的外部访问方式是NodePort,而80对应的NodePort是31046。

完成以上两步就可以查看KubeFATE的命令行工具是否可以使用了,使用`kubefate version`,如果可以得到`kubefate service`的版本号说明KubeFATE的命令行工具已经可以用了。

a8b451afcc6271726d194ff35fa96ea4.png

如果要使用浏览器访问 FATE 的 UI 页面,那么还需要部署一个FATE集群。

如何使用KubeFATE在Kubernetes上部署FATE可以参考这个文章:使用KubeFATE在Minikube的Kubernetes上部署FATE

https://github.com/FederatedAI/KubeFATE/blob/master/docs/tutorials/Build_Two_Parties_FATE_Cluster_in_One_Linux_Machine_with_MiniKube_zh.md

部署FATE的时候FATE的配置文件cluster.yaml 里面 ingressClassName 默认是nginx,所以FATE集群的 Ingress 都会匹配 NGINX Ingress Controller。

$ kubefate cluster install -f cluster.yaml

使用上面的命令部署好FATE之后,可以查看FATE集群的Ingress资源。

$ kubectl get ingress -n fate-9999

5672ce4ad40f3cd3f06992ba85a15032.png

找一台有浏览器的机器,修改hosts文件

$ sudo -- sh -c "echo \"10.xxx.xxx.25 fateboard.example.com\"  >> /etc/hosts"

$ sudo -- sh -c "echo \"10.xxx.xxx.25 notebook.example.com\"  >> /etc/hosts"

然后在浏览器打开 http://fateboard.example.com:31046 就可以查看 FATEBoard 的页面了。

00020e0f345281525a9bd7d99c120935.png

如果使用 443 对应的端口 30430 就可以使用https访问FATEBoard(https://fateboard.example.com:30430)。默认情况下会使用NGINX Ingress Controller自签的证书,如果要使用自己的证书,可以通过 cluster.yaml 配置。

至此就可以成功使用 Ingress,包括 KubeFATE 命令行使用和访问 FATE 集群的 UI FATEBoard。

相关链接

KubeFATE 安装包下载:

https://github.com/FederatedAI/KubeFATE/releases

使用KubeFATE在Minikube的Kubernetes上部署FATE:

https://github.com/FederatedAI/KubeFATE/blob/master/docs/tutorials/Build_Two_Parties_FATE_Cluster_in_One_Linux_Machine_with_MiniKube_zh.md

需要加入 KubeFATE 开源项目群的朋友,可以关注本公众号 亨利笔记 ,后台回复 kubefate 即可。


要想了解云原生、机器学习和区块链等技术原理,请立即关注本公众号亨利笔记 ( henglibiji ),以免错过更新。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值