MinIO - 从部署到使用

MinIO 是根据 GNU Affero 通用公共许可证 v3.0 发布的高性能对象存储系统。它与 Amazon S3 云存储服务 API 兼容。它能够处理非结构化数据,例如照片、视频、日志文件、备份和容器映像,支持的最大对象大小为 50TB。

本文将详细讲解使用 docker-compose 方式部署MinIO服务以及如何使用MinIO。

因为博主资源限制,本文只能从单节点方式进行讲解,欢迎通过文末或爱发电赞赏赞助博主,以提供更好的服务更优质的内容。

部署

  1. 切换到minio的部署空文件夹下
  2. 新建 data 空文件夹和 config 空文件夹
  3. 新建 compose.yaml 文件并粘贴以下内容
    version: '3'
    services:
        minio:
            image: minio/minio:RELEASE.2024-04-18T19-09-19Z
            container_name: minio
            deploy:
                resources:
                    limits:
                        # cpus: 'lower'
                        memory: 4G
            ports:
                - 19000:9000
                - 19001:9001
            restart: always
            command: server /data --console-address :9000 --address :9001
            environment:
                MINIO_ROOT_USER: TEST
                MINIO_ROOT_PASSWORD: password
             logging:
                options:
                    max-size: "5M"
                    max-file: "10"
                driver: json-file
              volumes:
                  - ./data:/data
                  - ./config:/root/.minio
              network_mode: "bridge"
    

参数说明

  • image:镜像名,最新镜像版本可以在 hub.docker 中获取
  • container_name:自定义容器名
  • ports:自定义映射端口,需要将9000和9001端口映射出来
  • environment:环境变量
    • MINIO_ROOT_USER:管理员用户名
    • MINIO_ROOT_PASSWORD:管理员密码

访问

访问的方式很多,例如可以直接用IP配合端口访问或使用代理方式访问。这里主要讲解下使用代理方式访问MinIO的配置。

Nginx

upstream minio_s3 {
        least_conn;
        server minio-01.internal-domain.com:9000;
        server minio-02.internal-domain.com:9000;
        server minio-03.internal-domain.com:9000;
        server minio-04.internal-domain.com:9000;
}
        upstream minio_console {
        least_conn;
        server minio-01.internal-domain.com:9001;
        server minio-02.internal-domain.com:9001;
        server minio-03.internal-domain.com:9001;
        server minio-04.internal-domain.com:9001;
}
        server {
        listen       80;
        listen  [::]:80;
        server_name  minio.example.net;
        
        # Allow special characters in headers
        ignore_invalid_headers off;
        # Allow any size file to be uploaded.
        # Set to a value such as 1000m; to restrict file size to a specific value
        client_max_body_size 0;
        # Disable buffering
        proxy_buffering off;
        proxy_request_buffering off;
        
        location / {
            proxy_set_header Host $http_host;
            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_connect_timeout 300;
            # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            chunked_transfer_encoding off;
        
            proxy_pass https://minio_s3; # This uses the upstream directive definition to load balance
        }
        
        location /minio/ui/ {
            rewrite ^/minio/ui/(.*) /$1 break;
            proxy_set_header Host $http_host;
            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 X-NginX-Proxy true;
        
            # This is necessary to pass the correct IP to be hashed
            real_ip_header X-Real-IP;
        
            proxy_connect_timeout 300;
        
            # To support websockets in MinIO versions released after January 2023
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            # Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
            # Uncomment the following line to set the Origin request to an empty string
            # proxy_set_header Origin '';
        
            chunked_transfer_encoding off;
        
            proxy_pass https://minio_console; # This uses the upstream directive definition to load balance
        }
}

OpenResty

我使用 OpenResty 分别代理的两个地址,便于我后面的区分

使用域名 minio.cnkj.site 代理 MinIO 的 UI 页面

minio-openresty-1.webp

使用域名 api.minio.cnkj.site 代理MinIO 的API 地址,同时因为我主要是图片访问,为了避免频繁请求的压力过大,可以开启缓存

minio-openresty-2.webp

当我们上传文件到MinIO中后,例如我通过 minio.cnkj.site 地址上传文件到 blog.cnkj.site这个桶中后,我们在页面上点预览或者分享返回的链接都是一个比较复杂的串,这个时候就可以使用api.minio.cnkj.site 这个API 地址直接访问。

需要注意的是,API 地址方式访问需要为 URL+桶名+文件完整路径,例如:https://api.minio.cnkj.site/blog.cnkj.site/backup/logo-doiw.png

使用

部署完成后经可以通过访问 9000 端口映射的对应端口进行访问了,9001 端口是控制 API服务的端口,是不能直接访问的

Region

建议先填写 region 信息,便于后面在Halo博客系统中使用S3存储的时候可以正常使用

minio-region.webp

Buckets

存储桶。可以新建存储桶,配置桶容量、有效期、版本控制等操作

点击右侧的 Create Bucket 按钮可以创建桶

  • Versioning:版本控制,开启后会占用很多桶容量
  • Object Locking:桶删除控制,开启后无法直接删除
  • Quota:桶容量控制,可以设置桶最大容量
  • Retention:施加规则以防止在一段时间内删除对象。必须启用版本控制才能设置存储桶保留策略

minio-buckets-version.webp
minio-buckets-lock.webp
minio-buckets-capacity.webp

完成桶创建后可以点击进入桶设置,修改相关内容

  • Summary
    • Access Policy:设置为 Public 便于匿名访问桶内数据
    • Quota:容量控制,可以随时调整桶容量

minio-summary-access.webp

  • Lifecycle
    • Lifecycle Rules:桶内容生命周期规则设置,需要注意的是,这个生命周期和git等其他版本控制是不一样的,例如我设置生命周期为7天,那么当数据时间超过7天就会自动删除,并不会保留最近一个版本或者最近7天的版本,所以如果不是频繁的重复文件写入,并不建议开启

minio-lifecycle.webp

  • Access
    • Access Audit:权限控制,可以用策略组或者用户的方式选择当前桶的可访问、可读写权限。策略配置可以参考本文后面的策略配置内容

minio-access.webp

Policies

策略控制,是minio中对桶控制、用户权限控制的重点

我们可以看到MinIO已经给我们内置了一些常用的策略了,但是我们可能有特殊的需求,就可以通过点击右侧的 Create Poliy 创建一个新的策略

例如我想要创建一个通过用户名控制用户能访问的桶的策略,即每个用户只能访问和他用户名相同的桶名的桶。策略可以这么写:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:HeadBucket",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:ListenBucketNotification",
                "s3:PutObject",
                "s3:DeleteBucket",
                "s3:GetBucketLocation",
                "s3:GetBucketNotification",
                "s3:AbortMultipartUpload",
                "s3:GetObject",
                "s3:ListMultipartUploadParts",
                "s3:DeleteObject",
                "s3:GetBucketPolicy",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": [
                "arn:aws:s3:::${aws:username}/*"
            ]
        }
    ]
}

重点就在于末尾的 "arn:aws:s3:::${aws:username}/*"Action 配置的是能操作的权限动作

minio-create-policy.webp

配置完成新的策略后,我们创建新的桶的时候,在 Access - Access Audit 中讲我们新建的策略添加进去即可完成控制

如果我们想要配置策略只能控制指定的桶呢,例如用户 zhangsan 只能操作 lsky-pro 这个桶,我们就可以配置下面的策略,并在 User 中找到 zhangsan 这个用户,修改他的策略组为新的这个策略配置即可

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:ListBucket",
                "s3:ListenBucketNotification",
                "s3:GetBucketPolicy",
                "s3:DeleteObject",
                "s3:GetBucketNotification",
                "s3:GetObject",
                "s3:DeleteBucket",
                "s3:HeadBucket",
                "s3:ListAllMyBuckets",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::lsky-pro/*"
            ]
        }
    ]
}

Identity

用户控制、新增用户、用户策略权限控制、用户组控制、用户组权限操作、第三方登录等行为操作都在这里控制

Users

在这里可以新建用户,并对用户设置策略、用户组等内容

minio-user.webp

Groups

在这里可以新增用户组、用户组策略控制等操作

minio-user-group.webp

新增用户组的时候可以不用选择策略,可以等创建完成后单独写用户组策略也是可以的

minio-user-group-policy.webp

Access Keys

在外部使用S3方式访问MinIO都是需要创建 Access Keys 的,是不能直接使用用户名密码的方式进行写操作的

在2024年后的新版本中,MinIO官方提供了UI页面上对key的描述、过期控制等操作,因此建议部署MinIO的版本最好使用新版本

在创建新 Access Key 的时候需要记住生成的 Access KeySecret Key ,点击保存后就不会再显示了,同时建议开启 Policy 策略,这样可以控制当前key的权限,例如控制当前key只能访问某一个指定的桶

accessKeys.webp

以下为控制 key 只能访问指定的 lsky-pro 桶的策略配置示例:

{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Effect": "Allow",
   "Action": [
    "s3:ListAllMyBuckets",
    "s3:ListBucket",
    "s3:PutObject",
    "s3:DeleteObject",
    "s3:GetBucketLocation",
    "s3:GetObject"
   ],
   "Resource": [
    "arn:aws:s3:::lsky-pro/*"
   ]
  }
 ]
}