Docker部署Minio
# Docker部署Minio、SpringBoot整合Minio
# 1. 概述
MinIO
是一个开源的对象存储服务器,它兼容Amazon S3(Simple Storage Service)API
。它被设计用于构建分布式存储架构,提供高可用性、高性能和可扩展的对象存储解决方案。
下面是MinIO的一些主要特点和功能:
对象存储:
MinIO
以对象为基本存储单元,可以存储和管理任意大小的文件、数据对象。它提供了标准的对象存储操作,如上传、下载、删除和元数据管理。简单性:简单性是百万兆次级数据基础设施的基础 - 无论是在技术上还是在操作上。
MinIO
使用和部署非常简单,没有其他对象存储可以让您在最快的时间内实现下载到生产环境的部署。分布式架构:
MinIO
采用分布式架构,可以在多个节点上部署,并将数据分布和复制在不同的节点上。这提供了高可用性和数据冗余,确保数据的持久性和可靠性。高性能:
MinIO
是世界上最快的对象存储,没有之一。在 32 个 NVMe 驱动器节点和 100Gbe 网络上发布的 GET/PUT 结果超过 325 GiB/秒和 165 GiB/秒。安全性:
MinIO
支持数据加密和访问控制,保护存储在其中的数据的安全性和隐私性。它提供了传输层加密(TLS/SSL)和服务器端加密选项,以及身份验证和访问控制机制。
总结一下,MinIO
是一个开源的高性能对象存储服务器,是一种高性能、S3兼容的对象存储。 它专为大规模 AI/ML、数据湖和数据库工作负载而构建,并且它是由软件定义的存储。 不需要购买任何专有硬件,就可以在云上和普通硬件上拥有分布式对象存储。 MinIO拥有开源 GNU AGPL v3 和商业企业许可证的双重许可。官网就是这么说的。
# 2. 相关资料
- 社区地址: slack.min.io (opens new window)
- 官方文档: docs.min.io (opens new window)
- 中文文档: docs.minio.org.cn/docs (opens new window)
- 博客地址: blog.min.io (opens new window)
- 官网地址: min.io (opens new window)
# 3. Docker部署
前文提到Minio是一个分布式架构,支持多节点,多硬盘部署,本次仅演示单机部署,按照简单的来,能用就是目的 本文仅作为入门级部署,类似Minio的纠删码(Erasure Code),高性能部署等功能还是再去参考下其他资料吧
# 验证Docker是否存在
docker -v #显示命令不存在/未找到,先行安装Docker,本文重点讲解Minio部署
# 搜索Minio镜像
docker search minio
# 拉取Minio最新镜像
docker pull minio/minio #默认拉取最新版本,需要指定版本在后面添加版本号
docker images | grep minio #查看镜像是否安装成功
2
# 服务启动(Minio管理端和API)
此处做了处理 分别创建两个服务,作为minio的服务端和Api
# 启动服务端
docker run -p 9090:9090 \
--name minio_console \
-d --restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=a0aCb4%1Om" \
-v /data/app/minio/data:/data \
-v /data/app/minio/config:/root/.minio \
minio/minio server \
/data --console-address ":9090"
2
3
4
5
6
7
8
9
解释一下
docker run
命令用于启动一个MinIO服务器容器,并配置了一些关键的参数。
-p 9090:9090: 端口映射,将容器内的9090端口映射到宿主机的9090端口。这样,你就可以通过访问宿主机的9090端口来访问MinIO服务器。
--name minio_console: 为容器指定一个名称,便于后续管理和操作。这里,容器的名称被设置为 minio_console。
-d: 以分离模式(detached mode)运行容器,也就是后台运行。
--restart=always: 设置容器在退出时总是自动重启。
-e "MINIO_ACCESS_KEY=admin": 设置环境变量 MINIO_ACCESS_KEY,这是MinIO服务器的访问密钥。在这里,它被设置为 admin。
-e "MINIO_SECRET_KEY=a0aCb4%1Om": 设置环境变量 MINIO_SECRET_KEY,这是MinIO服务器的秘密密钥。在这里,它被设置为 a0aCb4%1Om。
-v /data/app/minio/data:/data: 卷挂载,将宿主机上的 /data/app/minio/data 目录挂载到容器内的 /data 目录。这通常用于持久化存储MinIO的数据。
-v /data/app/minio/config:/root/.minio: 将宿主机上的 /data/app/minio/config 目录挂载到容器内的 /root/.minio 目录,用于存储MinIO的配置信息。
minio/minio: 要运行的Docker镜像名称。
server /data --console-address ":9090": 容器启动后要执行的命令。这里告诉MinIO服务器使用/data目录作为存储位置,并将Web控制台的地址设置为:9090。
访问http:xxxxip:9090
Minio中桶(Bucker)的概念 相当于我们的存储目录 在其中管理文件对象 通过创建容器命令中使用的MINIO_ACCESS_KEY和MINIO_SECRET_KEY登录管理系统,创建一个桶
# 启动API 与服务端启动同理
docker run -p 9080:9080 \
--name minio_api \
-d --restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=a0aCb4%1Om" \
-v /data/app/minio/data:/data \
-v /data/app/minio/config:/root/.minio \
minio/minio server \
/data -address ":9080"
2
3
4
5
6
7
8
9
解释一下
docker run
命令用于启动一个MinIO服务器容器,并配置了一些关键的参数。
-p 9080:9080: 端口映射,将容器内的9080端口映射到宿主机的9080端口。这样,你就可以通过访问宿主机的90800端口来访问MinIOAPI。
--name minio_api: 为容器指定一个名称,便于后续管理和操作。这里,容器的名称被设置为 minio_api。
-d: 以分离模式(detached mode)运行容器,也就是后台运行。
--restart=always: 设置容器在退出时总是自动重启。
-e "MINIO_ACCESS_KEY=admin": 设置环境变量 MINIO_ACCESS_KEY,这是MinIO服务器的访问密钥。在这里,它被设置为 admin。
-e "MINIO_SECRET_KEY=a0aCb4%1Om": 设置环境变量 MINIO_SECRET_KEY,这是MinIO服务器的秘密密钥。在这里,它被设置为 a0aCb4%1Om。
-v /data/app/minio/data:/data: 卷挂载,将宿主机上的 /data/app/minio/data 目录挂载到容器内的 /data 目录。这通常用于持久化存储MinIO的数据。
-v /data/app/minio/config:/root/.minio: 将宿主机上的 /data/app/minio/config 目录挂载到容器内的 /root/.minio 目录,用于存储MinIO的配置信息。
minio/minio: 要运行的Docker镜像名称。
server /data -address ":9080": 在容器内启动MinIOAPI的命令。/data 是存储数据的目录,-address ":9080" 指定MinIO服务器监听的地址和端口。
# 3. SpringBoot整合Minio
# 3.1 依赖导入
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>选择自己的版本</version>
</dependency>
2
3
4
5
# 3.2 创建一个Minio工具类
主要用于封装一些通用的API接口,实现某些功能
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@Component
public class MinioUtils {
@Autowired
private RedisUtils redisUtils;
private void bucketExists(MinioClient minioClient, String bucketName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
boolean exists = redisUtils.isMemberSet("Bucket_List", bucketName);
if (exists) return;
// 检查存储桶是否已经存在
boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder()
.bucket(bucketName)
.build());
if (!isExist) {
throw new RuntimeException("Bucket not already exists");
}
redisUtils.addSet("Bucket_List",bucketName);
}
/**
* 上传文件
*
* @param multipartFile 文件
* @param fileAlias 文件名称(带后缀)
* @param bucketName 桶标记
*/
public void uploadFile(MinioClient minioClient, MultipartFile multipartFile, String fileAlias, String bucketName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
bucketExists(minioClient, bucketName);
try (InputStream in = multipartFile.getInputStream()) {
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(fileAlias)
.stream(in, multipartFile.getSize(), -1)
.contentType(multipartFile.getContentType())
.build()
);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
/**
* 下载文件
* @param fileName 文件名称(带后缀)
* @param bucketName 桶别名
* @param response response
*/
public void getFile(MinioClient minioClient, String fileName, String bucketName, HttpServletResponse response) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
bucketExists(minioClient, bucketName);
try (InputStream fis = minioClient.getObject(GetObjectArgs
.builder()
.bucket(bucketName)
.object(fileName)
.build());
ServletOutputStream os = response.getOutputStream()) {
IOUtils.copy(fis, os);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 3.3 定义一些配置
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioConfig {
// Minio服务器的端点(API服务的地址)
@Value("${minio.endpoint}")
private String endpoint;
// 认证密钥
@Value("${minio.accessKey}")
private String accessKey;
// 认证私钥
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient client() {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
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