题图摄于北京长安街
(本文作者系 VMware 中国研发云原生实验室架构师,联邦学习 KubeFATE / FATE-Operator 开源项目维护者。)
需要加入KubeFATE开源项目讨论群的同学,请关注本公众号后回复 “kubefate” 即可。
目标
本文我们会介绍如何在一台 Linux 的机器上通过安装 MiniKube,然后使用 KubeFATE 部署一个两方的联邦学习集群,并在上面跑一个测试的联邦学习训练任务。
我们的总体架构如下:
本文共出现两台机器:
- 用来做 Demo 的机器,是一台 Linux 机器,参照前置条件第一点;
- 使用浏览器访问 Jupyter Notebook, FATE-Board 的机器,要求可以访问用来执行 Demo 的机器。可以是任何客户端。
前置条件
- 一台 Linux 的服务器,我们测试好的 OS 版本是 Ubuntu 18.04 LTS,由于需要跑多方计算,服务器的推荐配置为:8核,16GB内存以上;
- 三个域名分别给 KubeFATE 服务,Jupyter Notebook 和 FATE-board 使用。如果没有 DNS 解析条件,可以通过设置 hosts 方式,后面的介绍基于这种情况;
- Linux 服务器需要预先安装好 Docker 环境,具体参考 Install Docker in Ubuntu;
- 要保证安装机器可以正常访问 Docker Hub 或者网易云镜像仓库,以及Google 存储;
- 预先创建一个目录,以便整个过程使用该目录作为工作目录,命令如下:
export version=v1.5.0 && export kubefate_version=v1.2.0 && cd ~ && mkdir demo && cd demo
注意:下文介绍的 MiniKube 机器IP地址是 192.168.100.123。请修改为你准备的实验机器IP地址!!!
开始安装
安装需要的工具
为了使用KubeFATE部署FATE,我们需要以下工具:
- MiniKube: v1.7.3
- kubectl: v1.17.3
- kubefate:
- 发布版本: v1.5.0
- 服务版本: v1.2.0
- 命令行版本: v1.2.0
安装 kubectl
代码语言:javascript复制curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kubectl && chmod x ./kubectl && sudo mv ./kubectl /usr/bin
执行完后可以验证是否成功,
代码语言:javascript复制layne@machine:~/demo$ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-11T18:14:22Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?
安装MiniKube
代码语言:javascript复制curl -LO https://github.com/kubernetes/minikube/releases/download/v1.7.3/minikube-linux-amd64 && mv minikube-linux-amd64 minikube && chmod x minikube && sudo mv ./minikube /usr/bin
验证安装结果:
代码语言:javascript复制layne@machine:~/demo$ minikube version
minikube version: v1.7.3
commit: 436667c819c324e35d7e839f8116b968a2d0a3ff
使用 MiniKube 安装 Kubernetes
MiniKube 支持使用不同的虚拟机来部署 Kubernetes,但是在 Linux 环境下,我们建议直接使用Docker方式。这个方式非常简单,只需要设置 --vm-driver=none 即可。
代码语言:javascript复制sudo minikube start --vm-driver=none
根据屏幕指引,稍等一小会。待到命令没有错误返回,我们可以验证下,
代码语言:javascript复制layne@machine:~/demo$ sudo minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
如果你的显示和上面一样,那恭喜你,一个单节点的Kubernetes已经部署好在你的服务器里了!但是,还有一个小步骤要做,因为我们KubeFATE通过Ingress向外提供服务,而MiniKube默认并没有启动Ingress模块,所以需要手动启动,
代码语言:javascript复制sudo minikube addons enable ingress
到此,我们的 Kubernetes 也准备好了。
下载 KubeFATE 的发布包, KubeFATE服务镜像v1.2.0,并安装命令行
我们从 Github上 KubeFATE Release 页面找到 Kuberetes 部署的下载包,并下载对应版本,如前面环境变量设置v1.5.0
,
curl -LO https://github.com/FederatedAI/KubeFATE/releases/download/${version}/kubefate-k8s-${version}.tar.gz && tar -xzf ./kubefate-k8s-${version}.tar.gz
然后我们可以查看下下载解压的安装包内容,
代码语言:javascript复制layne@machine:~/demo$ ls
cluster-serving.yaml cluster.yaml config.yaml examples kubefate kubefate-k8s-v1.5.0.tar.gz kubefate.yaml rbac-config.yaml
由于 KubeFATE 命令行是可执行二进制文件,可以直接移动到path目录方便使用,
代码语言:javascript复制chmod x ./kubefate && sudo mv ./kubefate /usr/bin
然后我们测试下 kubefate 命令是否可用,
代码语言:javascript复制layne@machine:~/demo$ kubefate version
* kubefate service connection error, Post http://kubefate.net/v1/user/login: dial tcp: lookup kubefate.net: no such host
* kubefate commandLine version=v1.2.0
我们发现获取 KubeFATE 服务版本报了个错,这是因为我们还没部署 KubeFATE 的服务;而命令行的版本已经正常显示出来了。
接着,我们下载 KubeFATE 服务镜像v1.2.0,
代码语言:javascript复制curl -LO https://github.com/FederatedAI/KubeFATE/releases/download/${version}/kubefate-${kubefate_version}.docker
然后读入本地 Docker 环境。请注意,因为本文使用的 MiniKube ,是 all-in-one 的 Kubernetes 环境,所以只需要导入本地 Docker 环境即可给 kubelet 拉取。如果你运行的是集群形式的 Kubernetes,容器镜像需要读入 Docker Registry 或者 Harbor。关于如何集成使用 Harbor,可以参考:https://github.com/FederatedAI/KubeFATE/blob/master/registry/README.md
代码语言:javascript复制layne@machine:~/demo$ docker load < ./kubefate-v1.2.0.docker
7a5b9c0b4b14: Loading layer [==================================================>] 3.031MB/3.031MB
8edfcca02080: Loading layer [==================================================>] 44.02MB/44.02MB
b7ffb386319e: Loading layer [==================================================>] 2.048kB/2.048kB
Loaded image: federatedai/kubefate:v1.2.0
部署KubeFATE服务
创建 kube-fate 的命名空间以及账号
在我们的安装包里已经包含了相关的 yaml 文件rbac-config.yaml
,并且前面的准备工作已解压这个文件到你的工作目录。我们只需要直接执行,
kubectl apply -f ./rbac-config.yaml
(可选)使用网易云镜像仓库
因为近期 Docker Hub 调整了下载限制服务条例 Docker Hub latest limitation, 我建议使用国内网易云的镜像仓库代替官方Docker Hub
代码语言:javascript复制sed 's/mariadb:10/hub.c.163.com/federatedai/mariadb:10/g' kubefate.yaml > kubefate_163.yaml
sed 's/registry: ""/registry: "hub.c.163.com/federatedai"/g' cluster.yaml > cluster_163.yaml
在 kube-fate 命名空间里部署 KubeFATE 服务
相关的 yaml 文件也已经准备在工作目录,直接使用kubectl apply
,
kubectl apply -f ./kubefate_163.yaml
稍等一会,大概10几秒后用下面命令看下KubeFATE服务是否部署好kubectl get all,ingress -n kube-fate
。如果返回类似下面的信息(特别是 pod 的 STATUS显示的是 Running 状态),则 KubeFATE 的服务就已经部署好并正常运行:
添加 kubefate.net 到 hosts 文件
因为我们要用 kubefate.net 域名来访问 KubeFATE 服务(该域名在 ingress 中定义,有需要可自行修改),需要在运行 kubefate 命令行所在的机器配置 hosts 文件(注意不一定是 Kubernetes 所在的机器)。如果网络环境有域名解析服务,可配置 kubefate.net 域名指向 MiniKube 机器的 IP 地址,这样就不用配置 hosts 文件。注意:下面地址 192.168.100.123 要替换为你的 MiniKube 机器地址。
代码语言:javascript复制sudo -- sh -c "echo "192.168.100.123 kubefate.net" >> /etc/hosts"
添加完毕后,可以验证是否生效:
代码语言:javascript复制layne@machine:~/demo$ ping -c 2 kubefate.net
PING kubefate.net (192.168.100.123) 56(84) bytes of data.
64 bytes from kubefate.net (192.168.100.123): icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from kubefate.net (192.168.100.123): icmp_seq=2 ttl=64 time=0.054 ms
--- kubefate.net ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1006ms
rtt min/avg/max/mdev = 0.054/0.067/0.080/0.013 ms
验证 KubeFATE 服务
当 kubefate.net
顺利设置, KubeFATE 服务的版本号应该就可以正常显示,
layne@machine:~/demo$ kubefate version
* kubefate service version=v1.2.0
* kubefate commandLine version=v1.2.0
到此,所有准备工作完毕,下面我们可以开始安装 FATE 了。需要注意的是,上面的工作只需要做一次,后面如果添加、删除、更新 FATE 集群,上面的不需要重新执行。
使用KubeFATE安装FATE
按照前面的计划,我们需要安装两联盟方,ID 分别 9999 与 10000。现实情况,这两方应该是完全独立、隔绝的组织,为了模拟现实情况,所以我们需要先为他们在Kubernetes上创建各自独立的命名空间(namespace)。
创建命名空间
我们创建命名空间fate-9999用来部署9999,fate-10000部署10000
代码语言:javascript复制kubectl create namespace fate-9999
kubectl create namespace fate-10000
准备各自的集群配置文件
KubeFATE 安装包包含了集群配置的简要配置参考文件 cluster.yaml ,我们可以给每个参与方复制一份来修改配置。如果前面的步骤正确,这个文件已经在工作目录里。运行下面命令复制文件:
代码语言:javascript复制cp ./cluster_163.yaml fate-9999.yaml && cp ./cluster_163.yaml fate-10000.yaml
注意:我们强烈建议阅读以下文档 cluster.yaml
中具体配置的含义,请参考:
https://github.com/FederatedAI/KubeFATE/blob/master/docs/configurations/FATE_cluster_configuration.md
我们把 fate-9999.yaml 按以下内容修改。再次强调这里的192.168.100.123
需要替换成你的 MiniKube 机器地址。
fate-10000按以下内容修改:
如果一切没有问题,那就可以使用kubefate cluster install
来部署两个fate集群了,
这时候,KubeFATE 会创建两个任务去分别部署两个FATE集群。我们可以通过kubefate job ls
来查看任务,或者直接watch
KubeFATE 中集群的状态,直至变成Running
layne@machine:~/demo$ watch kubefate cluster ls
UUID NAME NAMESPACE REVISION STATUS CHART ChartVERSION AGE
51476469-b473-4d41-b2d5-ea7241d5eac7 fate-9999 fate-9999 1 Running fate v1.5.0 88s
dacc0549-b9fc-463f-837a-4e7316db2537 fate-10000 fate-10000 1 Running fate v1.5.0 69s
因为这个步骤需要到网易云镜像仓库去下载约 10GB 的镜像,所以第一次执行视乎你的网络情况需要一定时间。另外一个方案是我们可以通过下载离线的容器镜像,导入本地环境,具体做法本文就不做赘述了。
验证FATE的部署
访问集群
通过以上的 kubefate cluster ls
命令, 我们得到 fate-9999
的集群ID是 51476469-b473-4d41-b2d5-ea7241d5eac7
, 而 fate-10000
的集群ID是 dacc0549-b9fc-463f-837a-4e7316db2537
. 我们可以通过kubefate cluster describe
查询集群的具体访问信息,
layne@machine:~/demo$ kubefate cluster describe 51476469-b473-4d41-b2d5-ea7241d5eac7
UUID 51476469-b473-4d41-b2d5-ea7241d5eac7
Name fate-9999
NameSpace fate-9999
ChartName fate
ChartVersion v1.5.0
Revision 1
Age 2m22s
Status Running
Spec backend: eggroll
chartName: fate
chartVersion: v1.5.0
istio:
enabled: false
modules:
- rollsite
- clustermanager
- nodemanager
- mysql
- python
- fateboard
- client
name: fate-9999
namespace: fate-9999
partyId: 9999
persistence: false
pullPolicy: null
python:
grpcNodePort: 30092
httpNodePort: 30097
type: NodePort
registry: hub.c.163.com/federatedai
rollsite:
nodePort: 30091
partyList:
- partyId: 10000
partyIp: 192.168.100.123
partyPort: 30101
type: NodePort
Info dashboard:
- 9999.notebook.kubefate.net
- 9999.fateboard.kubefate.net
ip: 192.168.100.123
pod:
- clustermanager-5fcbd4ccc6-fj6tq
- mysql-7cf4d4dcb8-wvl4j
- nodemanager-0-6cbbc86769-fk77x
- nodemanager-1-5c6dd78f99-bgt2w
- python-57668d4497-qwnbb
- rollsite-f7476746-5cxh8
status:
modules:
client: Running
clustermanager: Running
fateboard: Running
mysql: Running
nodemanager-0: Running
nodemanager-1: Running
python: Running
rollsite: Running
从返回的内容中,我们看到Info->dashboard
里包含了:
- Jupyter Notebook 的访问地址:
9999.notebook.kubefate.net
。这个是我们准备让数据科学家进行建模分析的平台。已经集成了FATE-Clients; - FATEBoard 的访问地址:
9999.fateboard.kubefate.net
。我们可以通过FATEBoard 来查询当前训练的状态。
类似的命令我们得到,fate-10000
的 Jupyter Notebook 和 FATEBoard 地址分别是:10000.notebook.kubefate.net
以及10000.fateboard.kubefate.net
。
在浏览器访问 FATE 集群的机器上配置相关的Host信息
注意: 如果 DNS 已经配置了相关的解析,这步可以跳过
在 Linux 或者 MacOS 机器可以通过以下命令配置,
如果是Windows机器,我们需要把相关域名解析配置到C:WINDOWSsystem32driversetchosts
,请查阅相关文档。
执行 Toy_Example 进行验证
如果一切顺利,我们可以通过浏览器访问fate-9999
和fate-10000
各自的Jupyter Notebook 与 FATEBoard,共 4 个 Dashboards,
我们点击FATEBoard of fate-9999
和FATEBoard of fate-10000
中RUNNING
菜单,以观察任务的状态。然后在Notebook of FATE-9999
中选择进入Toy_Example目录,我们可以看到toy_example_submit_job.ipynb
. ipynb
是Jupyter Notebook的文件格式,具体可参考:https://jupyter-notebook.readthedocs.io/en/stable/
打开该文件,在第二个代码块中,修改以下内容
因为我们希望fate-9999
与fate-10000
双方进行共同训练。
在第五个代码块中,修改以下内容
然后我们点击第一个块,也就是Submit Training Job Demo
,确保程序从最开始执行。点击工具栏中的Run
按钮,逐步执行程序。
注意:每点击一次Run
按钮,执行一步操作。执行过程中,代码块前的变成*
。需等到变成数字才表明该步骤执行完毕。更多请参考Jupyter Notebook相关说明。(本文为公众号:亨利笔记 原创文章)
在我们执行到第五个代码块时,我们可以看到fate-9999
与fate-10000
的FATEBoard
会各产生一个正在执行的任务。
等待一会,到第五个代码块的执行结果显示为Success
。可以到FATEBoard
中的任务已经执行成功,如下图。
下一步
- Toy_Example 是非常简单的 FATE 联邦学习例子。我们可以在 Notebook 的目录上找到更多其他的联邦学习算法。但需要注意,这些例子都是按单边写的,所以,需要修改他们在已经部署的
fate-9999
与fate-10000
共同训练。大多数情况下,需要保证host方已经把数据导入; - FML_Manager将会在下个版本与FATE-Clients合并,请参考FATE-Clients的文档:https://fate.readthedocs.io/en/latest/_build_temp/python/fate_client/flow_sdk/README.html. FATE-Clients 已经默认安装在 Jupyter Notebook 中,可以直接使用;
- 现在你已经部署了一个基本版本的FATE集群,我们在Github上准备了不同FATE的集群部署例子(https://github.com/FederatedAI/KubeFATE/tree/master/k8s-deploy/examples ),包括:
- FATE-Serving 的部署;
- Spark 作为计算引擎的部署。
我们也会推出系列文章介绍以上内容。
需要加入KubeFATE开源项目讨论群的同学,请先关注本公众号,然后回复 “kubefate” 即可。
参考文档:
https://github.com/FederatedAI/KubeFATE/blob/v1.5.0/docker-deploy/README.md
https://github.com/FederatedAI/FATE/blob/v1.5.0/examples/toy_example/README.md