自建S3服务
Overview
1. 前言
S3全称为Simple Storage Service,是由AWS设计的对象存储服务,由于诞生的早且有AWS的大力发展,目前几乎是云厂商对象存储服务的通用协议,可以说没有不兼容S3的对象存储。
笔者在选择K3S的etcd备份时采用S3兼容层接入了公司的对象存储服务,初步了解了一些S3的知识,考虑到过去也常有使用VPS中转国外文件的需求,于是想到部署一个私有的S3服务。这里选择使用单机版minio提供S3服务,使用nginx作为前端处理TLS和转发。
minio文档:MinIO Quickstart Guide
2. 部署
2.1 部署minio
这里采用docker运行minio
1docker run -d --restart unless-stopped --network host --name minio -v /root/others/minio/data:/data -e MINIO_ROOT_USER=xxxxxxxxxxx -e MINIO_ROOT_PASSWORD=xxxxxxxxxxx -e MINIO_SERVER_URL=https://s3.wbuntu.com -e MINIO_BROWSER_REDIRECT_URL=https://s3-console.wbuntu.com minio/minio:latest server /data --address "127.0.0.1:9000" --console-address "127.0.0.1:9001"
如上所示:
- 使用宿主机网络,再指定minio监听本地9000端口作为s3服务,9001端口作为console服务
- 挂载一个目录到/data,并在启动服务时指定该目录
- 通过环境变量设置root用户名、root用户密码,s3服务URL、console服务URL
启动后检查日志:
1➜ docker logs -f --tail=100 minio
2API: https://s3.wbuntu.com
3
4Console: https://s3-console.wbuntu.com
5
6Documentation: https://docs.min.io
2.2 配置nginx
笔者已经通过 acme.sh 签发了泛域名证书,设置了默认TLS参数,这里就不做展开,下面是两个域名的转发配置:
1server {
2 listen 443 ssl http2;
3 listen [::]:443 ssl http2;
4 include /etc/nginx/custom.conf.d/https.conf;
5 include /etc/nginx/custom.conf.d/gzip.conf;
6 server_name s3.wbuntu.com;
7 # 忽略无效头部
8 ignore_invalid_headers off;
9 # 设置body大小,为0时表示不限制大小
10 client_max_body_size 0;
11 # 关闭代理缓存
12 proxy_buffering off;
13 location /favicon.ico {
14 log_not_found off;
15 access_log off;
16 }
17 location / {
18 proxy_set_header X-Real-IP $remote_addr;
19 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
20 proxy_set_header X-Forwarded-Proto $scheme;
21 proxy_set_header Host $http_host;
22 proxy_connect_timeout 300;
23 # 默认为HTTP/1, keepalive只在HTTP/1.1中启用
24 proxy_http_version 1.1;
25 proxy_set_header Connection "";
26 # 关闭chunked传输编码
27 chunked_transfer_encoding off;
28 proxy_pass http://127.0.0.1:9000;
29 }
30}
31
32server {
33 listen 443 ssl http2;
34 listen [::]:443 ssl http2;
35 include /etc/nginx/custom.conf.d/https.conf;
36 include /etc/nginx/custom.conf.d/gzip.conf;
37 server_name s3-console.wbuntu.com;
38 # 忽略无效头部
39 ignore_invalid_headers off;
40 # 设置body大小,为0时表示不限制大小
41 client_max_body_size 0;
42 # 关闭代理缓存
43 proxy_buffering off;
44 location /favicon.ico {
45 log_not_found off;
46 access_log off;
47 }
48 location / {
49 proxy_set_header X-Real-IP $remote_addr;
50 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
51 proxy_set_header X-Forwarded-Proto $scheme;
52 proxy_set_header Host $http_host;
53 proxy_http_version 1.1;
54 proxy_pass http://127.0.0.1:9001;
55 }
56}
注意s3-console的转发配置中也需要解除body大小限制,因为在网页上操作文件上传与下载都是经过该域名而不是s3域名。
3. 使用
3.1 控制台
启动服务后,访问 s3.wbuntu.com 自动跳转 s3-console.wbuntu.com,使用刚才预设的账号密码登录后,进入控制台页面,如下:
这里创建了一个bucket,设置访问策略为Public,允许所有人访问:
通过控制台上传文件是经过s3-console的,如果console域名未解除body大小限制,会出现无法上传和下载大文件的现象。
允许公开访问的bucket可以直接按目录和文件名组成的URL访问,上传到一张图片641193.jpg到这个bucket下,点击Share可以获取到一个s3链接:
https://s3.wbuntu.com/static/641193.jpg
如果是点击Download下载,则是一个需要鉴权的s3-console链接:
https://s3-console.wbuntu.com/77aef684-c127-47af-9204-4749abfc9137
3.2 命令行工具
3.2.1 安装
minio提供了一个命令行工具mc,直接下载安装即可:
Linux
1wget https://dl.min.io/client/mc/release/linux-amd64/mc
2chmod a+x mc
3mv mc /usr/local/bin
macOS
1brew install minio/stable/mc
3.2.2 使用
配置访问凭证
mc alias命令用于管理服务器凭证,默认保存在配置文件:$HOME/.mc/config.json,我们可以设置多个alias,例如在服务器上设置local的URL为 http://localhost:9000,使用内网访问,在本地可以设置s3的URL为 https://s3.wbuntu.com,通过公网访问。
1 ➜ ~ mc alias set s3 https://s3.wbuntu.com Access-Key(用户名) Secret-Key(密码)
2 ➜ ~ mc alias set local http://localhost:9000 Access-Key(用户名) Secret-Key(密码)
3 ➜ ~ mc alias ls
4gcs
5 URL : https://storage.googleapis.com
6 AccessKey : YOUR-ACCESS-KEY-HERE
7 SecretKey : YOUR-SECRET-KEY-HERE
8 API : S3v2
9 Path : dns
10
11local
12 URL : http://localhost:9000
13 AccessKey : xxxxxxxxxxx
14 SecretKey : xxxxxxxxxxx
15 API : s3v4
16 Path : auto
17
18play
19 URL : https://play.min.io
20 AccessKey : Q3AM3UQ867SPQQA43P2F
21 SecretKey : zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG
22 API : S3v4
23 Path : auto
24
25s3
26 URL : https://s3.wbuntu.com
27 AccessKey : xxxxxxxxxxx
28 SecretKey : xxxxxxxxxxx
29 API : s3v4
30 Path : auto
Access-Key和Secret-Key可以使用初始化时配置的用户名和密码,也可以在Identify-Users中单独创建,并设置权限:
操作文件
在设置了alias后,可以像操作本地文件一样操作s3上的文件,每个alias就像一个目录,bucket是alias下的子目录。
1➜ ~ mc ls s3
2[2022-02-21 22:50:34 CST] 0B static/
3➜ ~ mc mb s3/golang
4Bucket created successfully `s3/golang`.
5➜ ~ mc cp go1.15.15.linux-amd64.tar.gz s3/golang
6...go1.15.15.linux-amd64.tar.gz: 115.49 MiB / 115.49 MiB ┃▓▓▓▓▓▓▓▓▓┃ 25.85 MiB/s 4s
7➜ ~ mc ls s3/golang
8[2022-02-21 22:50:39 CST] 116MiB STANDARD go1.15.15.linux-amd64.tar.gz
9➜ ~ mc cp local/golang/go1.15.15.linux-amd64.tar.gz /tmp
10...go1.15.15.linux-amd64.tar.gz: 115.49 MiB / 115.49 MiB ┃▓▓▓▓▓▓▓▓▓┃ 190.02 MiB/s 0s
3.3 权限管理
policy
minio使用policy管理权限,预设了5个policy,其中consoleAdmin权限如下:
1{
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Effect": "Allow",
6 "Action": [
7 "admin:*"
8 ]
9 },
10 {
11 "Effect": "Allow",
12 "Action": [
13 "s3:*"
14 ],
15 "Resource": [
16 "arn:aws:s3:::*"
17 ]
18 }
19 ]
20}
group
minio使用group管理用户组,支持为group关联policy,所有加入到group中的user会被赋予group关联的policy权限。
user
user是使用minio接口的凭证,Access-Key和Secret-Key对应user的用户名和密码,一个用户可以关联多个policy,也可以加入多个group。
service account
service account是user的子账号,继承user的所有权限,并有独立的Access-Key和Secret-Key。