前言
secretflow是阿里一个关于隐私计算的开源项目,关于它的介绍可以去官网(隐语 SecretFlow)进行查看,这里不做赘述。
写在前面:本篇文章只包含如何本地启动 secretflow/kuscia(go 项目) 的master节点,Lite节点 (这个将在下一篇提及),以及前端部分 secretflow/secretpad(java项目),secretflow/secretfrontend(react项目) 这两个项目。本次文章仅仅包含的是,以容器的方式启动kuscia,其余两个则是在本地启动.
因为没有启动secretflow的计算功能,所以根据本文章启动后,关于隐私计算的功能是不能演示的。后续会出一期把全部串起来的教程。
文章力图让不太懂的人,都可以照着一步步部署成功
启动的方式并不唯一,文章仅仅介绍本人摸索出来的其中一种,
文章会由 快照 和详细步骤组成,快照仅仅包含简单说明和全部指令
环境准备
1. 操作系统: 演示用的是 linux的Ubuntu(有图形界面比较方便),使用的是虚拟机,本教程的内容都是基于linux系统的的,window是系统肯定不得行。
2. IDE: 使用到的集成开发工具是 idea 这个随意,你甚至用文本编辑器都可以,因为有java项目( secretflow/secretpad),所以个人就沿用的idea,比较方便
3. 基本环境:
go(最好装最新的版本) ,
npm(最好用最新的),
nodejs(版本至少 18.x.x版本以上)
jdk17 (java项目至少需要jdk17)
libprotoc(本人装的是 3.12.4)
docker(没有什么特殊要求,尽量用新一点的版本就好)
其余启动过程中如果有缺失自行补全,文章中也会引导安装一部分,像make这种一般都会有的,但是有些镜像确实没预装,这就需要自己去补全了。
4.去git上拉代码,建议去gitee上搜secretFlow,github有点慢,这个就不再赘述了,直接拉下来就可以
(注意前端代码目前没在gitee上找到所以附上前端的github地址:
前端:GitHub - secretflow/secretpad-frontend: The frontend repo for secretpad
一,kuscia启动master节点
快照
每个部分我都会提供一个快照,把必要指令或者过程简洁的列出来,但是不会加上详细说明
# 根目录下
# 构建 kuscia的二进制文件
make build
# 构建本地镜像
make image
# 复制本地镜像的tag,并替换deploy.sh 的 KUSCIA_IMAGE={$生成的tag}
# 启动
./scripts/deploy/deploy.sh master -i 1.1.1.1 -p 1080 -k 8082 -g 8083
我们从git上把kuscia的源码拉取下来后,首先进入项目根目录下,项目结构就是这样,(后续版本更新可能会略有不同):
(这里就不去讲每个文件夹下是什么了,本文的目的也不在于此,而是想办法让你把他启动起来)
第一步,编译kuscia文件
在目录下,我们执行以下指令
make build
# 这个指令,主要是会去执行这个脚本 ./kuscia/hack/build.sh
# 并在 /kuscia/build/apps/kuscia 这个目录下生成一个名为 kuscia 的二进制文件
执行结果如图:
第二步,构建image并推到docker
执行完第一步后,我们就可以执行这个命令:
make image
#
# 这个命令会根据dockerfile构建一个镜像,
# dockerfile在目录 ./home/passerby/projects 里面,感兴趣可以去看看,暂时不讨论
# 执行成功,它会把镜像的tag打印出来
输出结果如图
记住这个tag,或者复制下来,后面要用,执行成功后我再去docker看镜像是否已经有了
在命令行输入
docker images
# 这个命令会列出镜像列表
到这里,我们的镜像就算是构建成功了
第三步,执行deploy脚本
首先我们复制第二步,命令行输出的 tag,记得复制全完整的应该是长这样
secretflow/kuscia:76702f5-20231120152518-76702f5
然后我们打开 /kuscia/scripts/deploy/deploy.sh
这个文件,搜索 KUSCIA_IMAGE
把 KUSCIA_IMAGE=secretflow-registry.cn-hangzhou.cr.aliyuncs.com/secretflow/kuscia:latest 用 # 注释掉
紧随其后添加
KUSCIA_IMAGE=上一步你复制过来的tag,注意等号两边不要有空格
如图:
更改完成后,我们在项目的根目录下,执行这个命令
./scripts/deploy/deploy.sh master -i 1.1.1.1 -p 1080 -k 8082 -g 8083
# master表明启动的是master节点
# 这里暴露了8083端口后1080端口,这些端口后续pad会用到
# 如果复制过去这个指令不能用,那就手敲一下吧,有时候复制过去会出现 no such file的问题
如图,就算是启动成功了,成功启动了一个容器,这个容器的名字是 你的linux用户名+ -kuscia-master
那么到这里,我们的kuscia的master节点就算是启动成功了,接下来的一节会介绍这个过程中可能的一些问题,不感兴趣的可以直接跳转到第二节,本地启动secretpad
可能会遇到的问题的解决办法
第一个:
lib64/libc.so.6: version `GLIBC_2.34' not found
这个问题我猜测是编译的libc版本和容器运行时的版本不一致,容器运行的libc版本是2.28,我本地的是2.35.
提供一个解决的办法,就是卸载gcc,怀疑是本地的gcc版本太高引入了一些依赖导致,卸载后在重新make clean,make build, make image再启动就可以了
第二个:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/build?buildargs=%7B%22DEPS_IMAGE%22%3A%22secretflow%2Fkuscia-deps%3A0.1.0b0%22%2C%22KUSCIA_ENVOY_IMAGE%22%3A%22secretflow%2Fkuscia-envoy%3A0.2.0b0%22%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=build%2Fdockerfile%2Fkuscia-anolis.Dockerfile&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&shmsize=0&t=secretflow%2Fkuscia%3Ae455437-20231115134856-e455437&target=&ulimits=null&version=1": dial unix /var/run/docker.sock: connect: permission denied
这个是因为,,,搞忘了,总之解决办法就是
运行 `sudo usermod -aG docker your-user` 将 `your-user` 替换为您的用户名,将当前用户添加到 `docker` 组中。这样,当前用户就可以以非 `root` 用户的身份访问 Docker。
第三个:权限拒绝,这个的话可以使用这个指令
chmod -R 777 filename
可以暂时放开filename这个文件夹的权限,让所有用户都可以读写和运行
第四个:go下载缓慢
这个就换个代理就行,可以参照我以前的文章,或者百度一下,很好找的
二,本地启动secretpad
快照
1.,pom文件增加以下内容:
<resources>
<resource>
<directory>../config</directory>
<targetPath>${project.basedir}/config</targetPath>
</resource>
<resource>
<directory>../scripts/test</directory>
<targetPath>${project.basedir}/config</targetPath>
</resource>
</resources>更改maven源为阿里云,然后刷新依赖 : mvn clean package -DskipTests
2. 在.secretpad/config下面创建certs目录 ,修改yaml文件的 key-store: 为自己创建的目录的绝对路径
3. 生成server.jks: ./scripts/gen_secretpad_serverkey.sh secretpad /home/passerby/projects/secretpad/config/certs 路径记得换成自己创建的目录
4. 从 kuscia的 ./kuscia/kuscia-master-kuscia-system-certs 目录复制
ca.crt、ca.key、kusciaapi-client.crt(改名为client.crt)、kusciaapi-client.csr(改名为client.csr)、kusciaapi-client.key(改名为client.pem)、token。文件放于secretpad工程./config/certs目录下5. 修改yaml,port:443 改为 port:${大于1024的端口} ,修改 address: 127.0.0.1:18083为
address: 127.0.0.1:8083,
6. 安装 sqlite,项目根目录下创建名为 db的文件夹
7. mvn clean package -DskipTests 打包 ,然后启动
8. 更改/secretpad/scripts/register_account.sh的第一行 DB_PATH="${db文件夹的绝对路径}/secretpad/db/secretpad.sqlite"
9. 修改yaml的 mode: always 为 mode: EMBEDDED 避免第二次启动时重新执行sql覆盖数据
启动完成!
还是一样,我们先从git上把secretpad项目拉下来,就不放项目结构截图了,
第一步,刷新maven依赖
我们先去修改一下项目根目录下的pom文件。不然执行的时候可能会发现始终拉不下来,
我们网pom文件添加这些内容。还是直接去改一下maven的setting.xml 文件吧
我们在命令行输入
mvn -v
它会输出maven
的版本信息和安装路径,如下,每个人的不一致
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.2, vendor: Oracle Corporation, runtime: /opt/jdk-17
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "6.2.0-36-generic", arch: "amd64", family: "unix"
我们进入安装路径,进入 conf文件夹,找到setting.xml
# 在命令行输入
sudo vim setting.xml
# 在<mirrors></mirrors>里面加入这些内容
<mirror>
<id>alimaven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
这个让我们去阿里的镜像源拉依赖,还有这个加到<build></build>标签之间,后面要用到
<resources>
<resource>
<directory>../config</directory>
<targetPath>${project.basedir}/config</targetPath>
</resource>
<resource>
<directory>../scripts/test</directory>
<targetPath>${project.basedir}/config</targetPath>
</resource>
</resources>
然后我们就可以开始拉依赖了,如果是用idea的话,直接点一下刷新按钮就行了,如果不是的话,执行一下这个指令
mvn clean package -DskipTests
# 现在打包也没有关系,我们后面调整完还要再打包一次
有点慢,多等一会,去连跪几把回来应该就搞定了,
build完我们可以先启动一下(这次肯定会启动失败)我们找到启动类
/secretpad/secretpad-web/src/main/java/org/secretflow/secretpad/web/SecretPadApplication.java
选择dev 环境启动(把 active profile设置为dev,这个就不过多解释了,实在不了解的去搜一下怎么设置就好,不复杂)
启动后大概率会报这样的错:
这里只截取了一部分
Caused by: java.lang.IllegalStateException: Could not load store from 'file:./config/server.jks'
at org.springframework.boot.ssl.jks.JksSslStoreBundle.loadKeyStore(JksSslStoreBundle.java:118) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.ssl.jks.JksSslStoreBundle.createKeyStore(JksSslStoreBundle.java:84) ~[spring-boot-3.1.0.jar:3.1.0]
... 17 common frames omitted
Caused by: java.io.FileNotFoundException: ./config/server.jks (没有那个文件或目录)
at java.base/java.io.FileInputStream.open0(Native Method) ~[na:na]
at java.base/java.io.FileInputStream.open(FileInputStream.java:216) ~[na:na]
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157) ~[na:na]
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111) ~[na:na]
at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86) ~[na:na]
at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189) ~[na:na]
at java.base/java.net.URL.openStream(URL.java:1161) ~[na:na]
at org.springframework.boot.ssl.jks.JksSslStoreBundle.loadKeyStore(JksSslStoreBundle.java:113) ~[spring-boot-3.1.0.jar:3.1.0]
... 18 common frames omitted
其实根据报错我就知道接下来应该做什么了,既然缺少 server.jks,那么我们就用脚本去生成一个
第二步,生成server.jks
我们先来梳理一下我们需要哪些东西:
1、根据上面的报错提示,我们需要一个server.jks的文件,那么这个文件要怎么生成放在哪里呢?
2、我们secretpad需要和前面启动的kuscia交互,这是怎么交互的,需要哪些配置
3、secretpad对应的页面需要登录,那么初始的账号密码是怎么样的,要怎么查看,或者怎么配置,
这些我们回拆分成一个个步骤来说明
首先,调整 application-dev.yaml 配置.这个文件在 /secretpad/config/ 这个目录下,找到这部分
server:
tomcat:
accesslog:
enabled: true
directory: /var/log/secretpad
http-port: 8080
port: 443
ssl:
enabled: true
key-store: "file:./config/server.jks"
key-store-password: secretpad
key-alias: secretpad-server
key-password: secretpad
key-store-type: JKS
改两个东西
第一把 port: 443 改为
port: 1443
(建议是大于1024的端口,linux小于1024的端口不让用,不然会启动失败,如果1443也不能启动就再换一个)
第二把 key-store: "file:./config/server.jks"改为绝对路径,
(这里建议在/secretpad/config/目录下在建一个certs目录,放在这里,后续的证书也放这里,这样方便管理)
在/secretpad/config/ 创建certs文件夹
key-store: "file:/home/passerby/projects/secretpad/config/certs/server.jks"
自己本地的绝对路径是哪个就改成哪个,不要照着复制啊
然后我们在项目的根目录下执行这个脚本
./scripts/gen_secretpad_serverkey.sh secretpad /home/passerby/projects/secretpad/config/certs (这个存放路径要改成自己的,这里只是例子,如果还是出现复制过去无法执行的情况就手动敲一下,并不复杂)
# 还是来解释一下这个脚本,前面没什么好说的, 第一个参数 secretpad 是这个脚本的密码,代码写死了是 secretpad
# 第二个参数是脚本生成应该放的位置, 这个应该和上面我们配置文件里面改的要一致,不要盲目复制啊,不然虽然生成了,但是项目启动依然会找不到
执行完我们在certs目录下就可以看到有server.jks这个文件了,如图
第二步就算完成了,接下来就是复制证书
第三步,复制证书
这里我们要先说明,复制证书的目的是访问kuscia的时候https能够通过,所以我们这一步,不仅要复制证书,还要让复制的证书能够被找到。
我们打开 kuscia项目,可以看到,我们之前由于启动了master节点,在项目目录下 多了两个文件夹, 分别是 ./kuscia/kuscia-master-kuscia-system-certs 以及 ./kuscia/kuscia-master-kuscia-system-data。如图:图看不清就继续往下看
我们进入到 ./kuscia/kuscia-master-kuscia-system-certs 目录下 可以看到有一堆证书,但是我们并不需要复制全部,我们只需要复制一部分即可
我们需要把以下这些复制到 secretpad的crets目录下,也就是就是我们之前新建的那个。[ ./secretpad/config/certs ]
ca.crt (直接复制即可)
ca.key (直接复制即可)
kusciaapi-client.crt - -》 (复制过去需要改名为 client.crt )
kusciaapi-client.csr - -》 (复制过去需要改名为 client.csr )
kusciaapi-client.key - -》 (复制过去需要改名为 client.pem )
token (直接复制即可)
如图:
那么证书相关的操作就算是做完了
第四步,再次修改yaml文件
还是打开 secretpa/config/ 目录下的 application-dev.yaml 这个文件。我们找到这部分
kusciaapi:
address: 127.0.0.1:18083
tls:
cert-file: config/certs/client.crt
key-file: config/certs/client.pem
ca-file: config/certs/ca.crt
token-file: config/certs/token
# 把这段
address: 127.0.0.1:18083
# 更改为
address: 127.0.0.1:8083
为什么要改成8083端口呢?,因为我们之前启动master节点暴露的就是8083端口,所以如果不改,会出现 grpc调用不到kuscia的问题
第五步,检查sqlite
secretpad没有用常见的分布式数据库,而是采用的 内存数据库,sqlite,所以启动之前要先确保你的linux系统安装了sqlite,我们打开命令行,输入
sqlite
# 如果安装了sqlite,则会打印如下的版本信息,并进入 sqlite的 命令行
SQLite version 2.8.17
Enter ".help" for instructions
sqlite>我们按crtl + z 退出
最后,我们在项目根目录下,创建一个名为 db 的文件夹,这将是本地存放 sqlite文件的地方
第六步,再次打包,pad,启动!
执行 打包指令
mvn clean package -DskipTests
然后直接启动即可!如图,就算是启动成功了,db目录的是sqlite的文件
这样pad就算是启动成功了,但是我们的工作还差一步,
差哪里呢,就是我们前端登录需要一个账号和密码,但是我们的初始化sql并没有初始化一个用户,所以我们需要用脚本去生成一个。
启动之后
我们再找到yaml的这段:
sql:
init:
schema-locations:
- file:./config/schema/v1.sql
- file:./config/schema/v2.sql
data-locations: file:./config/data/data.sql
mode: always
continue-on-error: true
# 把
mode: always
# 改为,大小写都可以
mode: EMBEDDED
改这里主要是避免每次启动都去初始化数据库脚本,
第七步,创建登录账户
首先,我们找到 /secretpad/scripts/ 目录下的 register_account.sh 这个脚本
打开他
把第一行的
DB_PATH="/app/db/secretpad.sqlite"
改为你项目存放sqlite文件的地方,也就是我们之前创建的db文件夹下,记得改成绝对路径
如下:
DB_PATH="/home/passerby/projects/secretpad/db/secretpad.sqlite"
记得改成你自己的路径啊,不要瞎复制
然后我们打开命令行,进行项目的根目录下,执行这个
./scripts/register_account.sh -n admin -p Admin@123
-n 表示用户名
-p 表示密码,密码有强度要求, 至少包含字母大小写,特殊字符,数字,,按照这个,密码可以和我给的不一样
然后,我们就可以用这个账号密码来登录我们的前端了
三,本地启动前端页面
去github拉取前端的代码,这个是真的有点慢,
第一步,增加.env文件
前端代码的启动比较简单,没有说明特殊的,唯一要注意的是,我们如果要本地启动,需要在 /secretpad-frontend-main/apps/platform 这个目录下添加一个.env文件,这个文件名就叫 .env ,内容是
PROXY_URL = http://localhost:8080
# 也可以把这个8080端口换成你pad启动的端口
第二步,跟着readme一步步走
这里就不放快照了,没什么东西
是的就和标题一样,这个前端的文档还是比较全面,
我们打开项目根目录下的README.zh-Hans.md文件,一步一步的执行下去就好
sudo npm -g install pnpm nx
sudo npm -g exec pnpm setup
sudo pnpm bootstrap
sudo pnpm dev
执行完,在浏览器输入 localhost:8000 就可以了,这就是页面了:
如图。
然后我们用之前创建的用户名密码登录就可以进去了,
那么到这里,我们的secretflow的kuscia,pad,front这几个部分就启动成功了。
本文只启动了master节点,其余的会在后续文章体现,不然太长了,文章如果有说明错误,希望大家直接指出来,共同进步,笔者也是小白,有纰漏是难免的,共勉!