Docker 安装 SeaweedFS
官方镜像:https://hub.docker.com/r/chrislusf/seaweedfs
Github: https://github.com/seaweedfs/seaweedfs
官方文档:https://github.com/seaweedfs/seaweedfs/wiki
端口说明
端口说明:https://github.com/seaweedfs/seaweedfs/blob/master/docker/Dockerfile.local
| 端口 | 描述 |
|---|---|
| 9333 | master server shared http port |
| 8080 | volume server http port |
| 8888 | filer server http port |
| 8333 | s3 server http port |
| 23646 | Admin UI |
| 7333 | webdav server http port |
| 19333 | master server shared grpc port |
| 18080 | volume server grpc port |
| 18888 | filer server grpc port |
关于应该开放哪些端口的问题:
- 如果只使用 master 服务上传文件:需开放 master server 9333 上传端口,需开放 volume server 8080 的下载端口,并且 volume server 启动时,要使用 -publicUrl 参数指定外部访问地址。
- 如果只使用 filer 服务上传/下载文件:需开放 filer server 8888 端口。
- 如果只使用 s3 服务上传/下载文件:需开放 s3 server 8333 端口。
- 如果使用 Admin UI 服务(Web 控制台):需开放 Admin UI 23646 端口。
单机快速启动(推荐)
一条命令启动所有组件(master, volume, filer, s3),简单快捷。适用于开发测试、快速体验。
# 查看更多配置参数 `weed server --help` 帮助命令
docker run --rm seaweedfs:3.99 server --helpdocker run \
--name seaweedfs \
--restart=unless-stopped \
--network network_default \
-p 9333:9333 \
-p 8080:8080 \
-p 8888:8888 \
-p 8333:8333 \
-v /opt/seaweedfs/data:/data \
-d chrislusf/seaweedfs:3.99 server -filer -s3 -dir="/data" -volume.publicUrl="<公网ip或域名>:<端口>"其它
weed server --help命令的参数可根据需要添加。-filer和-s3也可以根据需要只使用其中的一个。-filer:启用 filer server。-s3:启用 s3 server。
-dir="/data": 默认数据路径是/tmp。-volume.publicUrl="seaweedfs.volume.aday.fun:8080": 指定 volume 的公网外部访问地址。
master 服务浏览器访问:
http://localhost:9333volume 服务浏览器访问:
http://localhost:8080/ui/index.html,也可从 master ui 页面点击进入。filer 服务浏览器访问(未验证):
http://localhost:8888s3 服务浏览器访问(未验证):
http://localhost:8333
Admin UI 需单独部署
# 查看 `weed admin --help` 所有参数
docker run --rm seaweedfs:3.99 admin --helpdocker run \
--name seaweedfs-admin \
--restart=unless-stopped \
--network network_default \
-p 23646:23646 \
-d chrislusf/seaweedfs:3.99 admin -adminUser="admin" -adminPassword="123456" -masters="seaweedfs:9333"-adminUser="admin":指定 Web 登录页面的用户名。-adminPassword="123456":指定 Web 登录页面的密码。不增加该参数则默认无需登录,这在公网环境下不安全。-masters="seaweedfs:9333": 配置容器名称(seaweedfs)的前提是:需要通过--network network_default参数把 seaweedfs 和 seaweedfs-admin 放在同一个网络中。
分离模式启动
分别启动各个组件,配置更灵活。适用于生产环境、集群部署。
- 单机模式不推荐,得多启动一些服务。
- 集群模式下推荐。
master 服务
# 查看帮助
docker run --rm seaweedfs:3.99 master --helpdocker run \
--name seaweedfs-master \
--restart=unless-stopped \
--network network_default \
-p 9333:9333 \
-d chrislusf/seaweedfs:3.99 mastervolume 服务
# 查看帮助
docker run --rm seaweedfs:3.99 volume --helpdocker run \
--name seaweedfs-volume \
--restart=unless-stopped \
--network network_default \
-p 8080:8080 \
-d chrislusf/seaweedfs:3.99 volume -mserver=<master_host>:9333 -port=8080 -publicUrl="你的公网IP或域名:8080"filer 服务
# 查看帮助
docker run --rm seaweedfs:3.99 filer --helpdocker run \
--name seaweedfs-filer \
--restart=unless-stopped \
--network network_default \
-p 8888:8888 \
-d chrislusf/seaweedfs:3.99 filer -mserver=<master_host>:9333s3 服务
# 查看帮助
docker run --rm seaweedfs:3.99 s3 --helpdocker run \
--name seaweedfs-s3 \
--restart=unless-stopped \
--network network_default \
-p 8333:8333 \
-d chrislusf/seaweedfs:3.99 s3 -mserver=<master_host>:9333Admin UI 服务
和上面相同,此处省略。
master 文件上传
如果使用 master 服务端口来进行文件上传,需要开放 master server 9333 端口用作上传,需要开放 volume server 8080 端口用作文件下载。
启动的时候也只需要 master 和 volume 两个服务。
API 分两步上传
调用 masert HTTP API 来上传文件,首先,需要向 Master 节点的 /dir/assign 接口请求,获取一个可供上传的文件卷位置和一个唯一的 FID。
从 Master 获取文件卷和 FID
# 后缀固定值:/dir/assign
curl http://localhost:9333/dir/assign
# 返回值
{"fid":"1,017aebc93e","url":"172.18.0.2:8080","publicUrl":"172.18.0.2:8080","count":1}返回的 JSON 结果中,fid 字段(例如 1,017aebc93e)和 url 字段(例如 172.18.0.2:8080)是下一步所需的关键信息。
向 Volume 服务器上传文件
拿到 FID 和 Volume 服务器的 URL 后,就可以使用 HTTP POST 请求将文件内容发送到指定的 Volume 服务器。
curl -F file=@/path/to/your/file.txt http://172.18.0.2:8080/1,017aebc93e
# 示例
# 创建一个 demo.txt 文件到当前目录
echo "这是一个测试文件!" > demo.txt
# 上传当前目录下的 demo.txt 文件到服务器
curl -F file=@$PWD/demo.txt http://localhost:8888/test/但是此处的 volume ip 是 docker 内网的 ip, 外部是无法访问的,咱没研究该如何解决。
API 一步直接上传(推荐)
一步直接上传,可通过 master 服务的 /submit 接口直接上传,免去了通过 /dir/assign 接口申请 fid 的步骤。
# 后缀固定值:/submit
curl -F file=@/path/to/your/file.txt http://localhost:9333/submit
# 示例
# 创建一个 demo.txt 文件到当前目录
echo "这是一个测试文件!" > demo.txt
# 上传当前目录下的 demo.txt 文件到服务器
curl -F file=@$PWD/demo.txt http://localhost:9333/submit
# 返回
{"eTag":"e13f6ed2","fid":"1,017aebc93e","fileName":"demo.txt","fileUrl":"172.18.0.2:8080/1,017aebc93e","size":17}master 文件下载(实际是通过 volume)
如果已知文件存储的 volume server 的话,可通过:http://<volume_server_ip>:8080/<fid> 来下载文件。其中 8080 为 volume server 的端口号。
另外,一般上传后,会返回一个 fileUrl,比如:172.18.0.2:8080/1,017aebc93e,可通过这个地址下载(实际上还是 volume server 的下载地址和端口)。
# 示例
curl -X GET -o download.txt "http://localhost:8080/1,017aebc93e"master 文件删除
跟 master 文件下载 章节类似,只是 http 请求方式需要为 DELETE。
curl -X DELETE http://localhost:8080/1,017aebc93efiler 文件上传
请求格式:向 http://<filer地址>:<端口>/<路径> 发起一个 multipart/form-data 类型的 POST 请求。
其中,文件数据放在名为 file 的表单字段中。示例(使用 curl):
假设你的 Filer 运行在 localhost:8888,想将本地文件 demo.txt 上传到 Filer 的 /test 目录下。
curl -F file=@/path/to/your/local/demo.txt http://localhost:8888/test/
# 创建一个 demo.txt 文件到当前目录
echo "这是一个测试文件!" > demo.txt
# 上传当前目录下的 demo.txt 文件到服务器
curl -F file=@$PWD/demo.txt http://localhost:8888/test/如果上传成功,Filer 会返回一个包含文件详细信息的 JSON 响应。
{
"name":"demo.txt",
"size":364581
}filer 文件下载
通过 Admin UI 可以查看文件,需要先安装 Admin UI 服务。
curl 下载
访问格式:http://<filer地址>:<端口>/<文件路径># 示例:使用 curl 调用 Filer 接口
# 直接查看文件的内容
curl http://localhost:8888/test/demo.txt
# 下载文件并重命名到当前所在目录
curl -o download.txt http://localhost:8888/test/demo.txt浏览器下载
# 浏览器访问 8888 filer server 即可下载。
http://localhost:8888/test/demo.txt
# filer 总目录
http://localhost:8888全局启动 JWT 认证
默认 volume server 没有认证,,这在内网环境下问题不大,但如果要暴露到公网,就需要添加 JWT 保护。
生成默认的配置文件 security.toml
# 在宿主机上执行此命令,生成默认的 security.toml 文件到路径 /opt/seaweedfs/security.toml 下
docker run --rm chrislusf/seaweedfs:3.99 scaffold -config=security > /opt/seaweedfs/security.toml生成密钥 key
需要为 jwt.filer_signing.key 和 jwt.filer_signing.read.key 分别生成两个不同的密钥 key。
后续需要根据这个 key 来使用 JWT 工具栏生成一个 JWT token,以供文件的上传和下载使用。
# 执行两次,生成两个密钥
openssl rand -base64 32
# 生成结果类似这样的两个字符串
AfpqdFEUpOzBQkwFWBW8lWiC9D33wRXycKBKOAh6wvM=修改密钥
把上面生成的密码配置到如下位置:
# 如果此JWT密钥已配置,则Filer仅接受使用此JWT签名的HTTP写入请求[citation:1]
[jwt.filer_signing]
key = "你的写入密钥" # 在此处填入你的密钥字符串
expires_after_seconds = 10 # seconds
# 如果此JWT密钥已配置,则Filer仅接受使用此JWT签名的HTTP读取请求[citation:1]
[jwt.filer_signing.read]
key = "你的读取密钥" # 在此处填入你的密钥字符串
expires_after_seconds = 10 # seconds挂载配置文件启动
注意:把 security.toml 挂载到 /etc/seaweedfs/security.toml 位置,即可自动读取。
# Put this file to one of the location, with descending priority
# ./security.toml
# $HOME/.seaweedfs/security.toml
# /etc/seaweedfs/security.toml
# this file is read by master, volume server, filer, and workerdocker run \
--name seaweedfs \
--restart=unless-stopped \
-p 8888:8888 \
-v /opt/seaweedfs/security.toml:/etc/seaweedfs/security.toml \
-v /opt/seaweedfs/data:/data \
-d chrislusf/seaweedfs:3.99 server -filer -s3 -dir="/data"注:这里只映射了 8888 filer 端口,即只选择了使用 filer 服务来上传/下载文件。
使用 JWT 来上传或下载文件的三种使用方式
- Bearer Token: 通过设置请求头:
Authorization: Bearer <token> - jwt=token 后缀:通过请求的查询参数:
http://localhost:8888/buckets/all?jwt=token - 在一个名为AT(访问令牌)的 HTTP-only cookie 中
生成 JWT token
@Test
public void generateJwt() {
// 这里的 key 就是使用 openssl 生成的密钥 key
String key = "AfpqdFEUpOzBQkwFWBW8lWiC9D33wRXycKBKOAh6wvM=";
String token = JWTUtil.createToken(null, key.getBytes(StandardCharsets.UTF_8));
log.info(token);
boolean verify = JWTUtil.verify(token, key.getBytes(StandardCharsets.UTF_8));
Assertions.assertTrue(verify);
}生成的 JWT 格式:eyJ0eXAiO4JKV1QiLCJhbGciO3JIUzI1NiJ9.e30.xtrTYsadhSeqg6bjBR4gMUkIETvADSI1EJQItCP8Uds
filer 启用 JWT 后的文件上传
格式:这里要用写操作的 JWT 令牌。即通过 jwt.filer_signing.key 生成的 token
curl -X POST \
-H "Authorization: Bearer 你的写操作JWT令牌" \
-F "file=@/path/to/your/local/file.jpg" \
http://127.0.0.1:8888/path/to/upload/# 格式(这里要用写操作的 JWT 令牌。即通过 `jwt.filer_signing.key` 生成的 token)
curl -X POST \
-H "Authorization: Bearer 你的写操作JWT令牌" \
-F "file=@/path/to/your/local/file.jpg" \
http://127.0.0.1:8888/path/to/upload/
# 示例 (使用 Authorization 请求头)
curl -X POST \
-H "Authorization: Bearer eyJ0eXAiO4JKV1QiLCJhbGciO3JIUzI1NiJ9.e30.xtrTYsadhSeqg6bjBR4gMUkIETvADSI1EJQItCP8Uds" \
-F "file=@/path/to/your/local/file.jpg" \
http://127.0.0.1:8888/path/to/upload/
# 示例 (使用 jwt 查询参数)
curl -X POST \
-F "file=@/path/to/your/local/file.jpg" \
http://127.0.0.1:8888/path/to/upload?jwt=eyJ0eXAiO4JKV1QiLCJhbGciO3JIUzI1NiJ9.e30.xtrTYsadhSeqg6bjBR4gMUkIETvADSI1EJQItCP8Udsfiler 启用 JWT 后的文件下载
格式:这里要用读操作的 JWT 令牌。即通过 jwt.filer_signing.read.key 生成的 token
curl -X GET \
-H "Authorization: Bearer 你的读操作JWT令牌" \
-o downloaded_file.jpg \
http://127.0.0.1:8888/path/to/your/file.jpg# 示例 (Authorization 请求头)
curl -X GET \
-H "Authorization: Bearer eyJ0eXAiO4JKV1QiLCJhbGciO3JIUzI1NiJ9.e30.xtrTYsadhSeqg6bjBR4gMUkIETvADSI1EJQItCP8Uds" \
-o downloaded_file.jpg \
http://127.0.0.1:8888/path/to/your/file.jpg
# 示例 (jwt 查询参数)
curl -X GET \
-o downloaded_file.jpg \
http://127.0.0.1:8888/path/to/your/file.jpg?jwt=eyJ0eXAiO4JKV1QiLCJhbGciO3JIUzI1NiJ9.e30.xtrTYsadhSeqg6bjBR4gMUkIETvADSI1EJQItCP8Uds
# 使用浏览器访问下载
http://127.0.0.1:8888/path/to/your/file.jpg?jwt=你的读操作JWT令牌