文章

搭建 MinIO S3 存储

搭建 MinIO S3 存储

最近发现用于备份 NAS 的 MinIO S3 存储服务器使用容量已经超过 80%,因此决定将数据迁移至一台更大的服务器,降低占用率,以防哪天把磁盘写满的惨剧发生。

我最早是 2 年前接触到 MinIO 这款可自部署的对象存储软件,最初的目的是降低备份成本,替代了原本使用 BackBlaze B2 备份的策略。不过没想到这款软件出奇的稳定,除了几次 SSL 证书过期的问题,几乎没怎么折腾,因此这次迁移决定还是继续使用 MinIO 这款软件。

不过当下来说,MinIO 未必是最佳选择。就在今年 5 月份,MinIO 的创始人在 GitHub Discussion 上发布通知1,移除了社区版 Web 控制台的管理功能,其创始人评论到:

We initially explored a basic admin UI for the community branch, but we haven’t actively maintained it. Building and supporting separate graphical consoles for both the community and commercial branches is a substantial undertaking. Honestly, it is challenging to duplicate this work for the community branch. A whole team is involved in console development alone, including design, UX, front-end, back-end, and pen testing. This commit introduces an enhanced object browser but removes the unmaintained admin UI code.

Unlike the S3 RESTful APIs, admin actions in the console lack corresponding security protections. Without dedicated maintenance, this code risks introducing security vulnerabilities and creating misleading expectations for the community. For context, see past issues like the “Console Filename Masking Vulnerability” and “Metadata Bucket Name Bypass.”

我觉得创始人首要考量因素还是维护成本的问题,移除控制台的管理功能确实降低了被攻击的潜在风险。但是在未通知社区的情况下强制移除,确实显得有些不够厚道2

因此在这篇文章中,我们会使用 mc 命令对 MinIO 做一些必要的配置。

官方文档

部署文档:https://docs.min.io/community/minio-object-store/index.html

mc 使用文档:https://docs.min.io/community/minio-object-store/reference/minio-mc.html

安装 MinIO

  1. 下载 MinIO 运行二进制文件

    1
    
     wget https://dl.min.io/server/minio/release/darwin-amd64/minio
    
  2. 赋予运行权限并移动至可执行程序目录

    1
    2
    
     sudo chmod +x minio
     sudo mv minio /usr/local/bin
    
  3. 新建 MinIO 数据储存目录

    1
    
     mkdir /home/minio/data
    
  4. 新建 MinIO 配置文件

    1
    
     sudo vim /etc/default/minio
    

    参考下面的 MinIO 配置文件示例,可修改以下内容:

    • MINIO_ROOT_USERMINIO_ROOT_PASSWORD 是 MinIO 的管理员用户名与密码
    • MINIO_VOLUMES 为 MinIO 的存储目录
    • MINIO_OPTS 可以设置 API 与 Web UI 面板的访问端口
    • MINIO_SERVER_URL 为访问控制台的域名 + 端口
    • MINIO_BROWSER 可以关闭 Web UI 面板,当仍可以通过 mc 或 s3 兼容的客户端访问
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
     # MINIO_ROOT_USER and MINIO_ROOT_PASSWORD sets the root account for the MinIO server.
     # This user has unrestricted permissions to perform S3 and administrative API operations on any resource in the deployment.
     # Omit to use the default values 'minioadmin:minioadmin'.
     # MinIO recommends setting non-default values as a best practice, regardless of environment
    
     MINIO_ROOT_USER=1234567890
     MINIO_ROOT_PASSWORD=1234567890
    
     # MINIO_VOLUMES sets the storage volume or path to use for the MinIO server.
    
     MINIO_VOLUMES="/home/minio/data"
    
     MINIO_OPTS="--address :9000 --console-address :9001"
    
     # MINIO_SERVER_URL sets the hostname of the local machine for use with the MinIO Server
     # MinIO assumes your network control plane can correctly resolve this hostname to the local machine
    
     # Uncomment the following line and replace the value with the correct hostname for the local machine and port for the MinIO server (9000 by default).
    
     MINIO_SERVER_URL="https://example.com:9000"
     MINIO_DOMAIN="example.com"
    
     # MINIO Console Token Setting
     MINIO_BROWSER_SESSION_DURATION=1h
     #MINIO_BROWSER_LOGIN_ANIMATION=off
    
     # Manage the maximum wait period for the scanner when balancing MinIO read/write performance to scanner processes.
     # MinIO utilizes the scanner for bucket replication, site replication, and lifecycle management tasks.
     #MINIO_SCANNER_SPEED=fastest
    
     # Disable MINIO Browser
     MINIO_BROWSER=off
    
  5. 新建一个守护进程配置

    1
    
     sudo vim /usr/lib/systemd/system/minio.service
    

    参考文件示例,需要修改以下内容:

    • usergroup 为运行 MinIO 的用户和组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
     [Unit]
     Description=MinIO
     Documentation=https://min.io/docs/minio/linux/index.html
     Wants=network-online.target
     After=network-online.target
     AssertFileIsExecutable=/usr/local/bin/minio
    
     [Service]
     WorkingDirectory=/usr/local
    
     User=minio
     Group=minio
     ProtectProc=invisible
    
     EnvironmentFile=-/etc/default/minio
     ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
     ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
    
     # MinIO RELEASE.2023-05-04T21-44-30Z adds support for Type=notify (https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=)
     # This may improve systemctl setups where other services use `After=minio.server`
     # Uncomment the line to enable the functionality
     # Type=notify
    
     # Let systemd restart this service always
     Restart=always
    
     # Specifies the maximum file descriptor number that can be opened by this process
     LimitNOFILE=65536
    
     # Specifies the maximum number of threads this process can create
     TasksMax=infinity
    
     # Disable timeout logic and wait until process is stopped
     TimeoutStopSec=infinity
     SendSIGKILL=no
    
     [Install]
     WantedBy=multi-user.target
    
     # Built for ${project.name}-${project.version} (${project.name})
    
    
  6. 启动 MinIO 服务

    1
    2
    
     sudo systemctl start minio
     sudo systemctl enable minio # 开机自动启动
    

开启 https 访问

由于使用明文 http 传输任何数据非常不安全,因此我们需要开启 https 访问。

由于证书按照后需要重启 MinIO 服务,因此推荐在 root 用户安装 acme.sh。

  1. 切换至 root 用户

    1
    
     sudo -i
    
  2. 安装 acme.sh

    1
    
     curl https://get.acme.sh | sh -s email=my@example.com
    
  3. 打开 acme.sh 配置文件

    1
    
     sudo vim ~/.acme.sh/account.conf
    
  4. 这里以 Cloudflare 为例,添加 API 访问权限用于签发证书

    将下列模板写入文件中(具体设置方法请参考 acme.sh API 配置官方文档

    1
    2
    3
    
     # For a single domain
     export CF_Token="zfNp-Xm0VhSaCNun7dkLzwnw0UN7FNjaMurUZ8vf"
     export CF_Zone_ID="3cc91d809a6ff7a93eb48877bf0ec3ef"
    
  5. 使用 acme.sh 签发一张新证书

    1
    
     acme.sh --issue --dns dns_cf -d example.com
    
  6. 安装证书并重启 MinIO 服务

    FYI: MinIO 会默认在当前用户下创建一个 .minio 的文件夹,我们需要将证书的公钥和私钥拷贝到 .minio/certs 路径内。

    1
    2
    3
    4
    
     acme.sh --install-cert -d example.com \
     --key-file       /home/minio/.minio/certs/private.key  \
     --fullchain-file /home/minio/.minio/certs/public.crt \
     --reloadcmd      "chown minio:minio /home/minio/.minio/certs/private.key  /home/minio/.minio/certs/public.crt && systemctl restart minio"
    
  7. 查看当前 MinIO 服务状态

    1
    
     sudo systemctl restart minio
    

使用 mc 命令配置 MinIO

由于 MinIO 社区版移除了绝大多数 WebUI 功能,因此我们这里使用 mc 命令操作。

安装 MinIO (mc) 客户端

  1. 下载 mc

    1
    
     wget https://dl.min.io/client/mc/release/linux-amd64/mc
    
  2. 赋予执行权限

    1
    
     chmod +x mc
    
  3. 移动到执行文件目录,方便后续使用

    1
    
     sudo mv mc /usr/local/bin
    

添加 MinIO 服务器

可以使用下列格式添加一台 MinIO 服务器

1
mc alias set [ALIAS] [HOSTNAM] [ACCESS_KEY] [SECRET_KEY]

例如:

1
mc alias set myminio https://example.com:9000 1234567890 1234567890

用户管理

虽然我们可以在每个客户端使用管理员账号,但是这样会导致没有任何权限管理。因此我推荐给每个客户端新建一个账号,并绑定对应的策略实施管控。

  1. 在创建用户之前,我们可以先列出目前已有的策略

    1
    
     mc admin policy list myminio
    

    该命令应该会返回以下内容

    1
    2
    3
    4
    5
    
     diagnostics
     readonly
     readwrite
     writeonly
     consoleAdmin
    

    这是 MinIO 给我们提供的默认策略,请参考官方文档查阅详细信息。

  2. 查看某个策略的定义

    1
    
     mc admin policy info myminio readwrite
    
  3. 创建新用户

    1
    
     mc admin user add myminio user1 StrongPassw0rd!
    
  4. user1 绑定到 readwrite 策略

    1
    
     mc admin policy attach myminio --user user1 readwrite
    
  5. 查看所有用户

    1
    
     mc admin user list myminio
    
  6. 查看当前用户绑定的策略

    1
    
     mc admin user info myminio user1
    

新增策略

如果官方给的默认策略不足以满足需求,我们还可以自定义策略。

  1. 新建自定义策略文件

    1
    
     vim readonly2.json
    

    粘贴下列策略示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
     {
       "Version": "2012-10-17",
       "Statement": [
         {
           "Effect": "Allow",
           "Action": [
             "s3:GetBucketLocation",
             "s3:GetObject",
             "s3:ListAllMyBuckets",
             "s3:ListBucket"
           ],
           "Resource": [
             "arn:aws:s3:::*",
             "arn:aws:s3:::*/*"
           ]
         }
       ]
     }
    
  2. 添加策略到 MinIO

    1
    
     mc admin policy create myminio readonly2 readonly2.json
    
  3. 验证策略是否存在

    1
    2
    
     mc admin policy list myminio | grep readonly2
     mc admin policy info myminio readonly2
    

常用命令

查看 myminio MinIO 的服务状态(该用户必须为管理员才可以执行此命令):

1
mc admin info myminio

新建存储桶(文件夹):

1
mc mb myminio/example-bucket

列出所有存储桶:

1
mc ls myminio
  1. https://github.com/minio/minio/discussions/21320 ↩︎

  2. https://us.v2ex.com/t/1145209 ↩︎

本文由作者按照 CC BY 4.0 进行授权