# Minio 部署
# docker-compose.yml | |
version: "3.7" | |
services: | |
minio: | |
image: minio/minio:latest | |
command: server --console-address ":9001" /data | |
volumes: | |
- ./data/configs/minio:/root/.minio | |
- ./data/data/minio:/data | |
environment: | |
- MINIO_ACCESS_KEY=admin | |
- MINIO_SECRET_KEY=admin123 | |
ports: | |
- "9000:9000" | |
- "9001:9001" | |
restart: always |
# 安装 sdk
go get github.com/minio/minio-go/v7 |
# Minio 操作
# 连接客户端
func InitMinio() *minio.Client { | |
endpoint := "127.0.0.1:9000" | |
accessKeyID := "yxJZ0Ik5DFCEDhn8ojbX" | |
secretAccessKey := "PKYmEQsdjrMLbl1tRDbvgSzfQNPptyIAGsO4hqCB" | |
// Initialize minio client object. | |
minioClient, err := minio.New(endpoint, &minio.Options{ | |
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), | |
Secure: false, | |
}) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
return minioClient | |
} |
# 对象存储
func Upload() { | |
bucketName := "mybuc" | |
objectName := "golden-oldies.txt" | |
filePath := "./tmp/golden-oldies.txt" | |
contentType := "application/json" | |
info, err := MC.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType}) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
log.Printf("Successfully uploaded %s of size %d\n", objectName, info.Size) | |
} |
filePath
指要上传文件的路径objectName
指上传指桶里的路径
func Download() { | |
if err := MC.FGetObject(context.Background(), bucket, object, "./test", minio.GetObjectOptions{}); err != nil { | |
log.Fatalln(err) | |
} | |
log.Println("Successfully saved") | |
} |
FGetObject
和FPutObject
都使用文件路径方式上传和下载。
object, err := minioClient.GetObject(context.Background(), "mybucket", "myobject", minio.GetObjectOptions{}) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer object.Close() | |
localFile, err := os.Create("/tmp/local-file.jpg") | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer localFile.Close() | |
if _, err = io.Copy(localFile, object); err != nil { | |
fmt.Println(err) | |
return | |
} |
- 可用 io 流操作的写法
file, err := os.Open("my-testfile") | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer file.Close() | |
fileStat, err := file.Stat() | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
uploadInfo, err := minioClient.PutObject(context.Background(), "mybucket", "myobject", file, fileStat.Size(), minio.PutObjectOptions{ContentType:"application/octet-stream"}) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
fmt.Println("Successfully uploaded bytes: ", uploadInfo) |
# 访问控制
func SetPolicy() { | |
bucketName := "mybuc" | |
// 定义访问控制策略 | |
policy := `{"Version":"2012-10-17","Statement":[{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::` + bucketName + `/*"],"Sid":""},{"Action":["s3:PutObject"],"Effect":"Deny","Principal":{"AWS":["123456789012"]},"Resource":["arn:aws:s3:::` + bucketName + `/*"],"Sid":"DenyUser"}]}` | |
// 设置存储桶策略 | |
err := MC.SetBucketPolicy(context.Background(), bucketName, policy) | |
if err != nil { | |
log.Fatalln("SetBucketPolicy failed:", err) | |
} | |
log.Println("SetBucketPolicy successfully!") | |
} |
- 请注意,policy 不要换行,否则会读取到
\n
访问控制是 MinIO 中的一项重要功能,它允许您配置对存储桶和对象的访问权限。访问控制采用 IAM(Identity and Access Management)策略,用于控制哪些用户或实体可以执行哪些操作。让我们来详细了解 MinIO 中访问控制的各个字段和选项:
在 MinIO 中,访问控制的字段包括:
Version
:策略版本,目前只有一个版本 "2012-10-17"。Statement
:策略规则的数组,每个规则都是一个 JSON 对象。
在每个策略规则中,包含以下字段:
Action
:一个数组,定义允许或拒绝执行的操作。可以是对象和桶级别的操作,如 "s3:GetObject"、"s3:PutObject"、"s3:ListBucket" 等。Effect
:规定操作是 "Allow"(允许)还是 "Deny"(拒绝)。Principal
:指定允许或拒绝执行操作的实体,可以是特定的 AWS 账号(使用 AWS 的账号 ID 或 ARN)或者是通配符 "*" 表示允许所有实体。Resource
:定义策略适用的资源,可以是存储桶的 ARN(Amazon Resource Name)或者存储桶内的对象的 ARN,也可以使用通配符指定一类资源。Sid
:一个可选的标识符,用于在策略规则中标识唯一的规则。
# 预签名
预签名(Presigned URL)的作用在于实现对存储对象的临时授权访问,而无需提供实际的访问凭证。它通常用于对象存储服务(比如 Minio、AWS S3 等)中,允许临时授权一个或多个 HTTP 请求来读取或上传对象。
主要作用如下:
临时授权: 预签名 URL 提供了一种临时授权访问对象的方式。通过生成预签名 URL,可以在特定时间窗口内,让任何人可以通过该 URL 来执行授权的操作,如读取对象或上传对象,无需共享实际的访问凭证。
安全性: 使用预签名 URL,可以避免将实际的访问凭证(比如访问密钥)暴露给公共网络。预签名 URL 只有在有效期内才可用,有效期过后,即使泄露也无法再访问。
简化权限管理: 预签名 URL 允许实现对象级别的临时授权,而无需为每个用户或应用程序单独创建访问凭证。这简化了权限管理,减少了访问凭证的创建和管理的工作量。
限制访问范围: 可以通过预签名 URL 的有效期和权限设置,限制特定 URL 的访问范围。例如,可以设置只允许读取指定对象的预签名 URL,或者只允许在特定时间范围内上传对象。
共享链接: 预签名 URL 可以方便地共享给其他用户或应用程序,让它们在授权有效期内进行特定的操作。
预签名 URL 在云存储服务和需要临时授权访问的场景中特别有用,它提供了一种安全且便捷的方式来控制对存储对象的访问权限,并且不需要在代码中传递敏感的访问凭证。
// Generates a url which expires in a day. | |
expiry := time.Second * 24 * 60 * 60 // 1 day. | |
presignedURL, err := minioClient.PresignedPutObject(context.Background(), "mybucket", "myobject", expiry) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
fmt.Println("Successfully generated presigned URL", presignedURL) |
// Set request parameters for content-disposition. | |
reqParams := make(url.Values) | |
reqParams.Set("response-content-disposition", "attachment; filename=\"your-filename.txt\"") | |
// Generates a presigned url which expires in a day. | |
presignedURL, err := minioClient.PresignedGetObject(context.Background(), "mybucket", "myobject", time.Second * 24 * 60 * 60, reqParams) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
fmt.Println("Successfully generated presigned URL", presignedURL) |
# 对象锁定
对象锁定是一种机制,用于确保在一段时间内对象的内容不被修改或删除。这在某些情况下非常有用,例如合规性要求、法规要求或法律保留期要求等。
# 桶复制
桶复制(Bucket Replication)是指在 MinIO 对象存储系统中将一个存储桶的数据自动复制到另一个存储桶的功能。通过桶复制,您可以在不同的 MinIO 服务器之间或在同一服务器的不同存储桶之间实现数据的复制和同步。
# 生命周期管理
生命周期管理(Lifecycle Management)是 MinIO 对象存储系统中的一项功能,它允许您自动管理对象的生命周期,包括对象的转换、迁移、删除等操作。通过生命周期管理,您可以根据对象的年龄、大小、存储类别等条件来定义规则,并根据这些规则自动执行操作。
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"time" | |
"github.com/minio/minio-go/v7" | |
"github.com/minio/minio-go/v7/pkg/credentials" | |
"github.com/minio/minio-go/v7/pkg/lifecycle" | |
) | |
func main() { | |
ctx := context.Background() | |
endpoint := "your-minio-endpoint" | |
accessKeyID := "your-access-key-id" | |
secretAccessKey := "your-secret-access-key" | |
useSSL := false | |
minioClient, err := minio.New(endpoint, &minio.Options{ | |
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), | |
Secure: useSSL, | |
}) | |
if err != nil { | |
log.Fatalln("Error initializing Minio client:", err) | |
} | |
bucketName := "your-bucket-name" | |
ruleID := "rule1" | |
// 设置规则过滤条件,只选择前缀为 "documents/" 的对象 | |
filter := lifecycle.Filter{ | |
Prefix: "documents/", | |
} | |
// 设置过期条件,对象在 30 天后过期并自动删除 | |
expiration := lifecycle.Expiration{ | |
Days: 30, | |
} | |
// 创建生命周期配置规则 | |
rule := lifecycle.Rule{ | |
ID: ruleID, | |
Status: "Enabled", | |
RuleFilter: filter, | |
Expiration: expiration, | |
} | |
// 将规则添加到存储桶的生命周期配置中 | |
config := lifecycle.Configuration{ | |
Rules: []lifecycle.Rule{rule}, | |
} | |
err = minioClient.SetBucketLifecycle(ctx, bucketName, &config) | |
if err != nil { | |
log.Fatalln("Error setting bucket lifecycle:", err) | |
} | |
fmt.Println("Bucket lifecycle configuration set successfully.") | |
} |
func main() { | |
// 连接到 Minio 服务器 | |
endpoint := "your-minio-endpoint" | |
accessKeyID := "your-access-key-id" | |
secretAccessKey := "your-secret-access-key" | |
useSSL := false // 设置为 true 如果使用 HTTPS,否则设置为 false | |
ctx := context.Background() | |
minioClient, err := minio.New(endpoint, &minio.Options{ | |
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), | |
Secure: useSSL, | |
}) | |
if err != nil { | |
log.Fatalln("Error initializing Minio client:", err) | |
} | |
bucketName := "your-bucket-name" | |
ruleID := "rule1" | |
// 创建生命周期配置规则 | |
rule := lifecycle.Rule{ | |
ID: ruleID, | |
Status: "Enabled", // 启用规则 | |
RuleFilter: lifecycle.Filter{Prefix: "documents/"}, | |
Transition: lifecycle.Transition{ | |
Days: 30, | |
StorageClass: "STANDARD_IA", // 标准 - 低频访问存储类 | |
}, | |
Expiration: lifecycle.Expiration{ | |
Days: 60, // 对象过期时间为 60 天 | |
}, | |
NoncurrentVersionTransition: lifecycle.NoncurrentVersionTransition{ | |
NoncurrentDays: 90, | |
StorageClass: "GLACIER", // 冷冻存储类 | |
}, | |
} | |
// 将规则添加到存储桶的生命周期配置中 | |
config := lifecycle.Configuration{ | |
Rules: []lifecycle.Rule{rule}, | |
} | |
err = minioClient.SetBucketLifecycle(ctx, bucketName, &config) | |
if err != nil { | |
log.Fatalln("Error setting bucket lifecycle:", err) | |
} | |
fmt.Println("Bucket lifecycle configuration set successfully.") | |
} |
# 按图索骥
直接把官网的表格 copy 下来了,方便查看有哪些可用的方法,随便点哪个都能进