使用KubeFATE在Kubernetes上部署聯邦學習集羣

FATE(Federated AI Technology Enabler)是聯邦機器學習技術的一個框架,其旨在提供安全的計算框架來支持聯邦 AI 生態。在本專題,我們將介紹如何基於FATE架構從0到1部署聯邦學習集羣,本文是該系列的第四篇文章,旨在解決在Kubernetes部署運維FATE的問題。

背景及KubeFATE架構

在之前的文章中,我們介紹瞭如何使用KubeFATE部署一個基於Docker Compose的FATE聯邦學習集羣,以便於快速嘗試體驗聯邦學習。但隨着聯邦學習的正式投入使用,訓練集、模型都會逐漸變大。在生產環境裏,我們會遇到以下問題:

1、FATE集羣如何適應企業組織內部各種安全、合規要求,以及網絡、安全域等IT環境;
2、一臺服務器已經無法支撐聯邦學習的算力需求,如何部署多計算節點,並易於管理;
3、某些節點出現問題,是否有自愈能力,保證服務的可靠性;
4、能否實現橫向擴展,適應業務的成長;
5、FATE版本能否很好的升級管理;
6、一個組織內是否可以有不同的聯邦集羣,對應不同的業務、合作伙伴、應用場景需要,如何管理多個集羣。

Kubernetes是目前最流行的基礎設施平臺,大量的實踐證明,Kubernetes很適合作爲企業內部運維大規模分佈式系統的平臺。根據Ovum的統計,截至2019年底,一半的大數據負載都運行在Kubrenetes之上。我們團隊也推薦Kubernetes作爲運行FATE聯邦學習集羣生產環境的平臺。KubeFATE提供了在Kubernetes部署運維FATE的解決方案。

KubeFATE的Kubernetes部署兩大模塊:

1、KubeFATE命令行工具:KubeFATE的命令行是一個可執行的二進制文件,用戶可以用它快速初始化、部署、管理FATE集羣。KubeFATE的命令行可以運行在Kubernetes外,與KubeFATE服務交互。中間使用https協議,可以進行SSL加密,並適配企業的防火牆規則。它的功能模塊如下圖所示:

2、KubeFATE服務:KubeFATE服務作爲應用部署在Kubernetes上,對外提供Restful APIs,可以容易與企業已有的網管運維等系統進行整合。

快速使用KubeFATE在一臺Linux服務器上基於MiniKube部署兩方聯邦學習

爲了更好的體驗KubeFATE的功能,下面我們會一步一步演示如何使用KubeFATE部署一個兩方的聯邦學習集羣並進行驗證。最終的部署結構如下圖:

本文共出現兩臺機器:

1、用來做Demo的機器,是一臺Linux機器,參照前置條件第一點;
2、使用瀏覽器訪問FATE-Board的機器,要求可以訪問用來執行Demo的機器。

前置條件

1、一臺Linux的服務器,我們測試好的OS版本是Ubuntu 18.04 LTS,由於需要跑多方計算,服務器的推薦配置爲:8核,16G內存以上;
2、兩個域名分別給KubeFATE服務和FATE-board使用。如果沒有DNS解析條件,可以通過設置hosts方式,後面的介紹基於這種情況;
3、Linux服務器需要預先安裝好Docker環境,具體參考Install Docker in Ubuntu;
4、要保證安裝機器可以正常訪問Docker Hub,以及Google存儲;
5、預先創建一個目錄,以便整個過程使用該目錄作爲工作目錄,命令如下:

cd ~ && mkdir demo && cd demo

注意:下文介紹的MiniKube機器IP地址是10.160.112.145。請修改爲你準備的實驗機器IP地址!!!

安裝需要的工具

爲了使用KubeFATE部署FATE,我們需要以下工具:

1、MiniKube v1.7.3,如果我們已經有Kubernetes環境,可以直接跳轉到部署KubeFATE服務;

2、kubectl v1.17.3:Kubernetes的命令行,需要與具體Kubernetes版本對應,這裏的版本是對應MiniKube v1.7.3;

3、KubeFATE:

   - Release: v1.3.1-a
   - 服務版本:v1.0.2
   - 命令行版本:v1.0.2

安裝kubectl

curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kubectl && chmod +x ./kubectl && sudo mv ./kubectl /usr/bin

執行完後可以驗證是否成功

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

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

驗證安裝結果:

layne@machine:~/demo$ minikube version

minikube version: v1.7.3

commit: 436667c819c324e35d7e839f8116b968a2d0a3ff

下載KubeFATE的發佈包並安裝KubeFATE的命令行

我們從Github上 KubeFATE Release頁面找到Kuberetes部署的下載包,並下載。

curl -LO https://github.com/FederatedAI/KubeFATE/releases/download/v1.3.0-a/kubefate-k8s-v1.3.0-a.tar.gz && tar -xzf ./kubefate-k8s-v1.3.0-a.tar.gz

然後我們可以查看下載解壓的安裝包內容:

layne@machine:~/demo$ ls

cluster.yaml  config.yaml  kubefate  kubefate-k8s-v1.3.0-a.tar.gz  kubefate.yaml  rbac-config.yaml

由於KubeFATE命令行是可執行二進制文件,可以直接移動到path目錄方便使用。

chmod +x ./kubefate && sudo mv ./kubefate /usr/bin

然後,我們測試下kubefate命令是否可用。

layne@machine:~/demo$ kubefate version

* kubefate service connection error, Get http://kubefate.net/v1/version: dial tcp: lookup kubefate.net: no such host

* kubefate commandLine version=v1.0.2

我們發現獲取KubeFATE服務版本報了個錯,這是因爲我們還沒部署KubeFATE的服務;而命令行的版本已經正常顯示出來了。

至此,我們需要的工具已經安裝完成。

使用MiniKube安裝Kubernetes

MiniKube支持使用不同的虛擬機來部署Kubernetes,但是在Linux環境下,我們建議直接使用Docker方式。這個方式非常簡單,只需要設置–vm-driver=none即可。更多的說明參考:Install MiniKube - Install a Hypervisor。

sudo minikube start --vm-driver=none

根據屏幕指引,稍等一小會。待到命令沒有錯誤返回,我們可以驗證下:

layne@machine:~/demo$ sudo minikube status

host: Running

kubelet: Running

apiserver: Running

kubeconfig: Configured

如果你的顯示和上面一樣,那恭喜你,一個單節點的Kubernetes已經部署好在你的服務器裏了!但是,還有一個小步驟要做,因爲我們KubeFATE通過Ingress向外提供服務,而MiniKube默認並沒有啓動Ingress模塊,所以需要手動啓動。

sudo minikube addons enable ingress

到此,我們的Kubernetes也準備好了。

部署KubeFATE服務

創建kube-fate的命名空間以及賬號

在我們的安裝包裏已經包含了相關的yaml文件rbac-config.yaml,並且前面的準備工作已解壓這個文件到你的工作目錄。我們只需要直接執行。

kubectl apply -f ./rbac-config.yaml

在kube-fate命名空間裏部署KubeFATE服務

相關的yaml文件也已經準備在工作目錄,直接使用kubectl apply。

kubectl apply -f ./kubefate.yaml

稍等一會,大概10幾秒後用下面命令看下KubeFATE服務是否部署好kubectl get all,ingress -n kube-fate。如果返回類似下面的信息(特別是pod的STATUS顯示的是Running狀態),則KubeFATE的服務就已經部署好並正常運行:

layne@machine:~/demo$ kubectl get all,ingress -n kube-fate

NAME                                                    READY    STATUS     RESTARTS   AGE

pod/kubefate-6d576d6c88-mz6ds   1/1        Running    0               16s

pod/mongo-56684d6c86-4ff5m         1/1        Running    0               16s



NAME                           TYPE             CLUSTER-IP          EXTERNAL-IP   PORT(S)     AGE

service/kubefate   ClusterIP   10.111.165.189   <none>            8080/TCP    16s

service/mongo         ClusterIP   10.98.194.57       <none>           27017/TCP   16s



NAME                                          READY    UP-TO-DATE   AVAILABLE   AGE

deployment.apps/kubefate   1/1       1                     1                   16s

deployment.apps/mongo         1/1       1                     1                   16s



NAME                                                                DESIRED   CURRENT   READY   AGE

replicaset.apps/kubefate-6d576d6c88   1               1              1           16s

replicaset.apps/mongo-56684d6c86         1               1              1           16s



NAME                                                 HOSTS                 ADDRESS                PORTS   AGE

ingress.extensions/kubefate   kubefate.net   10.160.112.145   80        16s

添加kubefate.net到hosts文件

因爲我們要用 kubefate.net 域名來訪問KubeFATE服務(該域名在ingress中定義,有需要可自行修改),需要在運行kubefate命令行所在的機器配置hosts文件(注意不一定是Kubernetes所在的機器)。如果網絡環境有域名解析服務,可配置kubefate.net域名指向MiniKube機器的IP地址,這樣就不用配置hosts文件。注意:下面地址10.160.112.145 要替換爲你的MiniKube機器地址。

sudo -- sh -c "echo \"10.160.112.145 kubefate.net\"  >> /etc/hosts"

添加完畢後,可以驗證是否生效:

layne@machine:~/demo$ ping -c 2 kubefate.net

PING kubefate.net (10.160.112.145) 56(84) bytes of data.

64 bytes from kubefate.net (10.160.112.145): icmp_seq=1 ttl=64 time=0.080 ms

64 bytes from kubefate.net (10.160.112.145): 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 version,顯示就會一切正常。

layne@machine:~/demo$ kubefate version

* kubefate service version=v1.0.2

* kubefate commandLine version=v1.0.2

到此,所有準備工作完畢,下面我們可以開始安裝FATE了。需要注意的是,上面的工作只需要做一次,後面如果添加、刪除、更新FATE集羣,上面的不需要重新執行。

使用KubeFATE安裝FATE

按照前面的計劃,我們需要安裝兩聯盟方,ID分別9999與10000。現實情況,這兩方應該是完全獨立、隔絕的組織,爲了模擬現實情況,所以我們需要先爲他們在Kubernetes上創建各自獨立的命名空間(namespace)。

創建命名空間

我們創建命名空間fate-9999用來部署9999,fate-10000部署10000

kubectl create namespace fate-9999

kubectl create namespace fate-10000

準備各自的集羣配置文件

KubeFATE安裝包包含了集羣配置的簡要配置參考文件cluster.yaml,我們可以給每個參與方複製一份來修改配置。如果前面的步驟正確,這個文件已經在工作目錄裏。運行下面命令複製文件:

cp ./cluster.yaml fate-9999.yaml && cp ./cluster.yaml fate-10000.yaml

按下面的配置修改fate-9999.yaml

name: fate-9999

namespace: fate-9999

version: v1.3.0-a

partyId: 9999

modules:

  - proxy

  - egg

  - fateboard

  - fateflow

  - federation

  - metaService

  - mysql

  - redis

  - roll

  - python

proxy:

  type: NodePort

  nodePort: 30009

  partyList:

    - partyId: 10000

      partyIp: 10.160.112.145

      partyPort: 30010

egg:
  count: 1

主要修改內容有:

1、刪除exchange部分,爲了簡化配置,這裏使用點對點連接的方式;
2、更改proxy模塊的配置,設置監聽的端口爲30009;
3、更改partyList部分,配置另外一端10000的proxy的IP與監聽端口。注意,這裏的10.160.112.145需要替換成你的服務器IP地址!端口需要與後面fate-10000.yaml裏的proxy所設置的監聽端口一致;
4、把egg的count由3改爲1。egg是FATE的計算模塊,由於我們用一臺服務器模擬,爲了節省資源,避免由於資源不夠產生的報錯,這裏建議修改爲1。

fate-10000.yaml的配置按照以下修改:

name: fate-10000

namespace: fate-10000

version: v1.3.0-a

partyId: 10000

modules:

  - proxy

  - egg

  - fateboard

  - fateflow

  - federation

  - metaService

  - mysql

  - redis

  - roll

  - python



proxy:

  type: NodePort

  nodePort: 30010

  partyList:

    - partyId: 9999

      partyIp: 10.160.112.145

      partyPort: 30009



egg:

  count: 1

與fate-9999.yaml的修改類似,

1、修改name爲fate-10000;
2、namespace使用前面爲10000方創建的fate-10000;
3、partyId設置爲10000;
4、刪除exchange部分;
5、proxy的nodePort修改爲30010,這個需要與fate-9999.yaml的partyList信息對應;
6、修改partyList,使其指向fate-9999.yaml裏的proxy配置;
7、同樣修改egg模塊的count爲1。

如果一切沒有問題,那就可以使用kubefate cluster install來部署兩個fate集羣。

layne@machine:~/demo$ kubefate cluster install -f ./fate-9999.yaml

create job success, job id=a3dd184f-084f-4d98-9841-29927bdbf627

layne@machine:~/demo$ kubefate cluster install -f ./fate-10000.yaml

create job success, job id=370ed79f-637e-482c-bc6a-7bf042b64e67

這個步驟需要去Docker Hub下載相關鏡像,所以具體速度與服務器的網速有很大關係,如果網速快,或者鏡像已經準備好在服務器上的話,大概2、3分鐘可以部署完成。我們可以使用kubefate job ls命令觀察部署情況。

layne@machine:~/demo$ kubefate job ls

UUID                                                                   CREATOR METHOD                STATUS   STARTTIME                       CLUSTERID

a3dd184f-084f-4d98-9841-29927bdbf627    admin   ClusterInstall  Success 2020-03-10 12:26:39     2a15d783-67cd-4723-8a5c-50eb6355b6b0

370ed79f-637e-482c-bc6a-7bf042b64e67    admin   ClusterInstall  Success 2020-03-10 12:27:06     16270e8a-20b1-43c7-9c6c-385977d8dfc8

如果發現STATUS如上面那樣變成了Success,證明部署成功完成。

驗證FATE的部署

執行FATE自帶的toy_example進行測試

toy_example 是FATE提供的快速測試集羣連通性的用例。測試腳本設定10000爲host端,9999是guest端。我們採用集羣模式執行。這個例子的具體說明可以參見:toy_example的README

FATE規定由guest端發起訓練,所以我們需要進入fate-10000的python容器。

layne@machine:~/demo$ kubectl get pod -n fate-10000|grep python*

python-dc94c9786-8jsgh          2/2     Running   0          3m13s

其中,python-dc94c9786-8jsgh是python這個pod的ID(注意,下面命令的這個ID需要替換成你執行以上命令返回的具體ID值),我們用kubectl exec命令進入該容器。

kubectl exec -it python-dc94c9786-8jsgh -n fate-10000 -- /bin/bash

並在容器內運行toy_example。

(venv) [root@python-dc94c9786-8jsgh python]# cd examples/toy_example/ && python run_toy_example.py 10000 9999 1

stdout:{

    "data": {

        "board_url": "http://fateboard:8080/index.html#/dashboard?job_id=202003110905332206371&role=guest&party_id=10000",

        "job_dsl_path": "/data/projects/fate/python/jobs/202003110905332206371/job_dsl.json",

        "job_runtime_conf_path": "/data/projects/fate/python/jobs/202003110905332206371/job_runtime_conf.json",

        "logs_directory": "/data/projects/fate/python/logs/202003110905332206371",

        "model_info": {

            "model_id": "guest-10000#host-9999#model",

            "model_version": "202003110905332206371"

        }

    },

    "jobId": "202003110905332206371",

    "retcode": 0,

    "retmsg": "success"

}

job status is running

job status is running

job status is running

job status is running

job status is running

job status is running

job status is running

"2020-03-11 09:05:39,911 - secure_add_guest.py[line:101] - INFO: begin to init parameters of secure add example guest"

"2020-03-11 09:05:39,911 - secure_add_guest.py[line:104] - INFO: begin to make guest data"

"2020-03-11 09:05:42,576 - secure_add_guest.py[line:107] - INFO: split data into two random parts"

"2020-03-11 09:05:51,661 - secure_add_guest.py[line:110] - INFO: share one random part data to host"

"2020-03-11 09:05:52,444 - secure_add_guest.py[line:113] - INFO: get share of one random part data from host"

"2020-03-11 09:05:57,566 - secure_add_guest.py[line:116] - INFO: begin to get sum of guest and host"

"2020-03-11 09:05:58,571 - secure_add_guest.py[line:119] - INFO: receive host sum from guest"

"2020-03-11 09:05:58,643 - secure_add_guest.py[line:126] - INFO: success to calculate secure_sum, it is 2000.0"

(venv) [root@python-dc94c9786-8jsgh toy_example]#

如果你的輸出與上面相似,最後返回INFO: success to calculate secure_sum, it is xxxx,即表明訓練成功,換言之,也就是FATE-Cluster順利安裝。

查看FATE-Board

KubeFATE會配置FATE-Board以格式http://${party_id}.fateboard.${serviceurl}服務。所以:

FATE-9999的FATE-Board的URL爲:http://9999.fateboard.kubefate.net/
FATE-10000的FATE-Board的URL爲:http://10000.fateboard.kubefate.net/

如果我們沒有相關的DNS服務,我們需要在訪問以上域名的機器,也就是瀏覽器所在的機器配上相關的hosts,使上面域名指向部署FATE的服務器。在本例子裏,就是10.160.112.145,這個需要根據你實際的IP地址來配置。如果是MacOS或者Linux可以使用以下命令配置:

sudo -- sh -c "echo \"10.160.112.145 9999.fateboard.kubefate.net\"  >> /etc/hosts"

sudo -- sh -c "echo \"10.160.112.145 10000.fateboard.kubefate.net\"  >> /etc/hosts"

如果是Windows,我們需要:

10.160.112.145 9999.fateboard.kubefate.net

10.160.112.145 10000.fateboard.kubefate.net

添加到C:\WINDOWS\system32\drivers\etc\hosts,具體方法也可以參考相關資料。然後我們就可以用瀏覽器訪問Party-9999和Party-10000的FATE-Board。

Party-9999會顯示爲host端任務完成

Party-10000會顯示爲guest端任務完成

KubeFATE開源項目:

https://github.com/FederatedAI/KubeFATE

FATE開源項目:

https://github.com/FederatedAI/FATE

作者介紹:

彭麟,VMware 雲原生實驗室工程師,FATE/KubeFATE 項目貢獻者。

相關文章:

《用 FATE 進行圖片識別的聯邦學習實踐》
《使用 KubeFATE 快速部署聯邦學習實驗開發環境(一)》
《使用 KubeFATE 快速部署聯邦學習實驗開發環境(二)》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章