自建S3服务

文章目录

1. 前言

S3全称为Simple Storage Service,是由AWS设计的对象存储服务,由于诞生的早且有AWS的大力发展,目前几乎是云厂商对象存储服务的通用协议,可以说没有不兼容S3的对象存储。

笔者在选择K3S的etcd备份时采用S3兼容层接入了公司的对象存储服务,初步了解了一些S3的知识,考虑到过去也常有使用VPS中转国外文件的需求,于是想到部署一个私有的S3服务。这里选择使用单机版minio提供S3服务,使用nginx作为前端处理TLS和转发。

minio文档:MinIO Quickstart Guide

2. 部署

graph LR; A[客户端] -->|HTTPS| B(服务端:nginx) B --> C{域名转发} C -->|HTTP:s3.wbuntu.com| D[minio s3] C -->|HTTP:s3-console.wbuntu.com| E[minio console]

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。