随着国内云计算厂商的政策缩紧,国内云计算厂商之前各种小羊毛慢慢都在“温暖升级”,比如腾讯云的COS就从一开始的新老用户免费50G到后面的新用户50G免费6个月,免费期过后2022年9月1日起老用户“对象存储服务 COS 存储容量、请求及数据取回计费项将由按月结算升级为按日结算”,官方的功能升级目的为“便于您通过日结账单做更精细的费用管理”,我放在腾讯云COS的文件不多,就是网站的图片文件,也就200MB不到,如果是之前的按月结算,可能一个月也就不到1分钱,但是新政策之后,腾讯云每天至少从我账户扣除1分钱,钱虽然不多,但是这一天天的每天都在扣费有点肉疼,薅了这么久腾讯云的羊毛,也不能说人家不好,正好最近接触到了MinIO这个替代品,服务器资源也足够,干脆将这部分功能自建好了,于是有了这篇折腾记录。
为什么需要MinIO
包括我手上的几个网站,以及偶尔写文档时,需要有个地方用来保存图片及文件。之前本站的网站图片我都是使用uPic传到腾讯云COS,配合腾讯云每个月的10G免费CDN流量,再通过CDN加速COS分发到浏览器,因为我本身放在COS的文件比较少,每个月COS即使没有购买套餐也花不了几个钱,但是现在腾讯云COS政策更改,出于长远考虑,我还是选择将这部分功能自建好了,恰好MinIO就是我了解之后觉得各方面都比较符合我这个需求的软件之一。
MinIO简介
MinIO官网:https://minio.io/
根据MinIO官网的介绍,MinIO是一个使用Go语言编写的提供高性能S3协议兼容的对象存储服务,免费且开源。
我选择MinIO也是看中这几点,第一,S3协议兼容,可以利用现有众多的S3协议客户端;第二,对象存储,可以直接无缝从COS迁移;第三,免费开源,可以在现有服务器上部署,无需额外成本。
MinIO安装
MinIO支持众多平台,我现在网站服务器系统是Debian,选择AMD64系统类型的即可,下载:
wget https://dl.min.io/server/minio/release/linux-amd64/minio
赋予可执行权限及移动到bin目录:
chmod +x minio
mv minio /usr/local/bin/
为MinIO单独创建一个不可登录的用于用来运行MinIO服务:
useradd -r minio -s /sbin/nologin
chown minio:minio /usr/local/bin/minio
如果上述过程无意外,执行如下命令即可查看MinIO的版本信息:
minio --version
为MinIO创建文件保存目录,我是选择保存在/data/minio,如果跟我不一样的话,下述配置文件记得一并更改:
mkdir /data/minio -p
chown minio:minio /data/minio
创建配置文件:
vim /etc/default/minio
MINIO_ACCESS_KEY="cloudbool_minio_access"
MINIO_SECRET_KEY="cloudbool_minio_secret"
MINIO_VOLUMES="/data/minio"
MINIO_OPTS="--address :9001 --console-address :9000"
这里说几点需要留意的。
MINIO_ACCESS_KEY及MINIO_SECRET_KEY为后续登录控制面板及API的凭证,如果是放到公网的话,一定要注意设置复杂一点。
MINIO_VOLUMES为MinIO保存对象文件及基础文件的目录,我上面设置的是/data/minio,如果跟我不一样,需要注意MinIO运行的用户对这个目录具有写入权限。
MINIO_OPTS后面的两个参数信息分别是API的端口号及控制面板端口号,如果只需要其中之一,选择对应的一个也可以,留意设定的端口号没有被占用以及跟别的服务不冲突即可。
进程管理服务:
vim /etc/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
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
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=1048576
# 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})
注意上述指定的User及Group对应的用户名及分组名存在及有相应的权限。
进程控制:
systemctl daemon-reload
systemctl start minio
systemctl restart minio
systemctl status minio
到这一步如果没有错误已经可以访问MinIO了,访问服务器IP:console-address例如192.168.1.10:9000即可访问MinIO的控制面板并进行创建bucket、上传对象文件等操作了。
Nginx反代MinIO
就我实际使用情况来说,MinIO不会放在内网,肯定是在公网方便访问的,所以我选择使用Nginx来反代MinIO顺带加上HTTPS确保链路安全。
如果跟我上面配置一样,MinIO其实是提供两个入口的,分别是控制面板及API节课,经过我的实际测试,这两个入口没法放在同一个域名下面,所以我最终使用了两个域名来反代MinIO服务,分别是控制面板及API端口,两个域名的配置分别如下。
首先是MinIO控制面板,也就是9000端口:
# cat minio.conf
server{
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name minio.cloudbool.com;
ssl_certificate /ssl/cloudbool.crt;
ssl_certificate_key /ssl/cloudbool.key;
client_max_body_size 100M;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:9000;
}
access_log /var/log/nginx/minio.log;
error_log /var/log/nginx/minio-error.log;
}
server
{
listen 80;
server_name minio.cloudbool.com;
location / {
rewrite ^/(.*)$ https://minio.cloudbool.com/$1 permanent;
}
}
然后是API及桶文件相关配置:
# cat minio-api.conf
server{
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name minio-api.cloudbool.com;
ssl_certificate /ssl/cloudbool.crt;
ssl_certificate_key /ssl/cloudbool.key;
client_max_body_size 100M;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://localhost:9001;
}
location /imgs/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://localhost:9001;
}
access_log /var/log/nginx/minio-api.log;
error_log /var/log/nginx/minio-api-error.log;
}
server
{
listen 80;
server_name minio-api.cloudbool.com;
location / {
rewrite ^/(.*)$ https://minio-api.cloudbool.com/$1 permanent;
}
}
如果一切正常,可以访问两个域名登录控制面板及上传图片了,如图:
MinIO创建存储桶及权限设置
在上传文件之前,还需要创建存储桶,这点跟腾讯云COS逻辑是一样的。
打开MinIO的控制面板,例如我上面设置的minio.cloudbool.com,即可看到上面截图的样子,账号密码是之前在/etc/default/minio文件设置的。
登录之后,点击页面上的Create Bucket,如图:
然后输入合适的名字作为存储桶名称,如图:
如果需要公开访问,还需要将存储桶的Access Policy设置为Public,否则无法公开访问,可能需要带上相关签名信息才允许访问。
创建完成之后,回到存储桶列表,点击对应存储桶后面的Manage按钮,如图:
如图,将Access Policy从下拉选项中设置成Public。
uPic上传文件到MinIO
因为我上面已经准备好了使用uPic上传文件到MinIO,所以我其实只需要登录一次MinIO的控制面板创建存储桶及设置存储桶的权限,后续就可以完全通过uPic上传文件及获取文件的URL,不需要每次都登录MinIO控制面板进行图片上传操作。
我的uPic设置如下:
其中,uPic中的Access Key及Secret Key分别是/etc/default/minio中的MINIO_ACCESS_KEY及MINIO_SECRET_KEY。
如果一切正常,使用uPic上传图片之后应该能正确返回图片的URL,直接就能在浏览器访问:
MinIO使用体验
总体来说,MinIO对我来说,完全可以代替之前的MinIO,免费且功能还能满足我的需要,最重要的是文件在自己手里可控。
我上面只是最基础的MinIO配置过程,MinIO配合Nginx还能做一些别的事情,例如使用CDN加速分发,还能利用Nginx的模块给图片打水印,或者利用第三方对图片进行压缩、裁切等操作。