Go 连接Minio对象存储 | 青训营

790 阅读5分钟

对象存储可以说是存储界备受瞩目的“网红”选手。谈到对象存储,不能不提及“桶”(Bucket)和“对象”(Object)这两个概念。对象包含数据和元数据,每个对象都有一个唯一的“身份码”(对象ID)和“接入码”(Key),只有当“码”经过认证后,才能通过基于http协议的RESTful接口进行访问。不同于块存储和文件存储,对象是存在“桶”里的,桶就像万能的“百宝袋”,支持文件、照片、视频等不同类型的对象,而且再多的数据都能装得下。

一、Minio 介绍

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

  • MinIO 提供高性能、与S3 兼容的对象存储系统,让你自己能够构建自己的云储存服务。
  • MinIO原生支持Kubernetes,它可用于每个独立的公共云、每个 Kubernetes 发行版、私有云和边缘的对象存储套件。
  • MinIO是软件定义的,不需要购买其他任何硬件,在 GNU AGPL v3 下是 100% 开源的。

二、Minio 安装(docker)

1、拉取最新版的Minio镜像: docker pull minio/minio:latest

2、创建存放Minio必要配置的文件目录

# 创建根目录minio
mkdir -p /data/minio
# 创建用于存放Minio外部挂载的配置文件目录和存储上传文件的目录
mkdir -p /data/minio/{data,config}

3、创建Minio容器并运行

首先关闭防火墙或者放行9000和9001端口,然后运行下面命令部署minio,用户名为:admin,密码为:minio123!

docker run -p 9000:9000 -p 9001:9001  \
    -d --restart=always  --user=root --privileged=true \
    -e "MINIO_ROOT_USER=admin" \
    -e "MINIO_ROOT_PASSWORD=minio123!" \
    -v /data/minio/data:/data \
    -v /data/minio/config:/root/.minio \
    --name=minio  minio/minio server  /data --console-address ":9001" --address ":9000"

4、访问 http//:ip:9000,查看minio首页,使用之前定义的用户名和密码进行登录

OeMg744kdC.png

5、创建访问密钥

SjlHrCxuMg.png

三、Go 客户端配置minio

1、安装依赖

go get github.com/minio/minio-go

2、初始化minio

根据实际环境来修改下面初始化minio的相关参数,minioAccessKey和minioSecretKey是之前在web界面创建的访问密钥。

首先声明了一些变量用于设置MinIO连接的相关参数。其中"minioUrl"表示MinIO服务的URL地址,"minioPort"表示MinIO服务的端口号,"minioAccessKey"和"minioSecretKey"分别表示访问MinIO服务的Access Key和Secret Key。

然后,通过调用minio.New方法创建了一个MinIO客户端的实例"minioClient"。在创建客户端时,传入了MinIO服务的地址和端口号,并使用credentials.NewStaticV4方法创建了一个静态的认证凭证对象,其中包含了Access Key和Secret Key。

如果连接过程中发生错误,将通过log.Fatalln方法打印错误信息并退出程序。否则,打印"minio服务初始化完成!"的日志信息,并返回nil表示没有发生错误。

package main
​
import (
    "context"
    "fmt"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    "log"
    "net/url"
    "strconv"
    "time"
)
​
var minioClient *minio.Client // 定义全局的 MinIO 客户端对象
// 初始化minio 
func InitMinio() (err error) {
    minioUrl := ""
    minioPort := "9000"
    minioAccessKey := ""
    minioSecretKey := ""// 根据配置文件连接minio
    minioClient, err = minio.New(minioUrl+":"+minioPort, &minio.Options{Creds: credentials.NewStaticV4(minioAccessKey, minioSecretKey, "")})
    if err != nil {
        log.Fatalln("minio服务连接失败:", err.Error())
    }
    log.Println("minio服务初始化完成!")
    return nil
}

3、创建存储桶

在创建存储桶的之前,我们需要通过minioClient.BucketExists() 方法判断存储桶是否已经存在,如果存储桶已经存在,则代码提示用户存储桶已经存在了,跳过创建过程,如果不存在,则可以通过minioClient.MakeBucket()来创建我们需要的存储桶

// 判断存储桶是否存在
bucketName := ""
location := ""
var b bool
b, err = minioClient.BucketExists(context.Background(), bucketName)
if err != nil {
   log.Fatalln("存储桶判断是否存在失败:", err.Error())
}
if b {
   return nil
} else {
   // 存储桶不存在
   err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: location})
   if err != nil {
      log.Fatalln("存储桶创建失败:", err)
   }
   log.Println("存储桶创建成功!")
}

4、上传文件

需要接收4个参数::minioClient(MinIO客户端实例)、bucketName(桶名称)、objectName(对象名称)和filePath(文件路径),并返回两个值:objectURL(对象的访问链接)和err。

首先我们声明了一些变量用于设置MinIO连接的相关参数。其中"minioUrl"表示MinIO服务的URL地址,"minioPort"表示MinIO服务的端口号。

然后,通过调用minioClient的FPutObject方法将指定的文件(filePath)上传到指定的桶(bucketName)中,并指定对象的名称(objectName)。上传操作使用了context.Background()作为上下文,并且没有设置额外的上传选项(minio.PutObjectOptions{})。

如果上传过程中发生错误,将通过log.Fatalln方法打印错误信息并退出程序。

接着,根据MinIO服务的地址、端口号、桶名称和对象名称构建了对象的访问链接(objectURL)。使用fmt.Sprintf方法将这些参数拼接成一个URL,并通过url.PathEscape对对象名称进行转义,以确保URL的正确性。

最后,返回对象的访问链接(objectURL)和nil表示没有发生错误。

// 上传文件
func uploadObject(minioClient *minio.Client, bucketName, objectName, filePath string) (objectURL string, err error) {
   minioUrl := ""
   minioPort := "9000"
   _, err = minioClient.FPutObject(context.Background(), bucketName, objectName, filePath, minio.PutObjectOptions{})
   if err != nil {
      log.Fatalln("文件上传失败:", err.Error())
   }
   // 返回文件链接
   objectURL = fmt.Sprintf("http://%s:%s/%s/%s", minioUrl, minioPort, bucketName, url.PathEscape(objectName))
   return objectURL, nil
}