运行环境
OS和Golang版本:
go version go1.21.0 darwin/arm64
安装
源码安装
- 下载最新版本的源码,地址https://github.com/minio/minio后编译
cd minio
go build main.go
# 得到 116M Oct 19 15:49 main
把 main 改名为 minio
二进制安装
参考https://www.minio.org.cn/docs/minio/macos/index.html的安装步骤。
启动
minio server --address=0.0.0.0:8877 ./data
控制台输出如下信息
➜ minio minio server --address=0.0.0.0:8877 ./data
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ You are running an older version of MinIO released 2 years ago ┃
┃ Update: Run `mc admin update` ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
API: http://0.0.0.0:8877
RootUser: minioadmin
RootPass: minioadmin
Console: http://10.78.14.68:56056 http://192.168.255.10:56056 http://127.0.0.1:56056
RootUser: minioadmin
RootPass: minioadmin
Command-line: https://docs.min.io/docs/minio-client-quickstart-guide
$ mc alias set myminio http://0.0.0.0:8877 minioadmin minioadmin
Documentation: https://docs.min.io
启动控制台页面
使用浏览器打开 http://127.0.0.1:56056,使用账号密码登录(minioadmin/minioadmin)
创建aksk
在左侧菜单中选择 Account,点击Create Service Account,创建得到一个 aksk
创建Bucket
mc命令
mc命令安装
参考https://min.io/docs/minio/linux/reference/minio-mc.html
mc命令运行
mc给本地的minio链接做一个别名
➜ ~ mc alias set myminio http://0.0.0.0:8877
Enter Access Key: KLN00KFT1K5EP9I39I9N
Enter Secret Key:
Added `myminio` successfully.
mc查看 minio 节点信息
➜ ~ mc admin info myminio
● 0.0.0.0:8877
Uptime: 3 hours
Version: 2021-08-05T22:01:19Z
mc 对 minio 做 ping 检查链接是否 ok
➜ minio mc ping myminio
1: http://0.0.0.0:8877:8877 min=9.36ms max=9.36ms average=9.36ms errors=0 roundtrip=9.36ms
2: http://0.0.0.0:8877:8877 min=0.64ms max=9.36ms average=5.00ms errors=0 roundtrip=0.64ms
mc上传文件
➜ minio mc cp ./minio-dev.yaml myminio/mybucket/3.yaml
...o-dev.yaml: 1.46 KiB / 1.46 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.36 KiB/s 0s
mc下载文件
➜ minio mc cp myminio/mybucket/3.yaml ./3-get.yaml
...ket/3.yaml: 1.46 KiB / 1.46 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 67.56 KiB/s 0s
mc监听桶变化
➜ minio mc watch myminio/mybucket/
[2023-10-19T07:09:05.751Z] 1.5 KiB s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T07:27:35.675Z] 36 B s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:46.813Z] s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:58.157Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T08:11:38.631Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.633Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.634Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.638Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.644Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.653Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.655Z] s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/3.yaml
mc查看桶统计信息
➜ minio mc stat myminio/mybucket/
Name : 2.yaml
Date : 2023-10-19 14:59:57 CST
Size : 1.5 KiB
ETag : 34095c50340c4381e0fdc5fd61eecc76
Type : file
Metadata :
Content-Type: text/yaml
Name : 3.yaml
Date : 2023-10-19 15:09:05 CST
Size : 1.5 KiB
ETag : 34095c50340c4381e0fdc5fd61eecc76
Type : file
Metadata :
Content-Type: text/yaml
Name : minio-dev.yaml
Date : 2023-10-19 14:54:23 CST
Size : 1.5 KiB
ETag : 34095c50340c4381e0fdc5fd61eecc76
Type : file
Metadata :
Content-Type: text/yaml
Name : test/
Date : 2023-10-19 16:13:06 CST
Type : folder
这个etag 是怎么计算的呢?其实就是文件的 md5值
➜ minio md5 3-get.yaml
MD5 (3-get.yaml) = 34095c50340c4381e0fdc5fd61eecc76
mc列出桶中的文件
➜ minio mc ls myminio/mybucket/
[2023-10-19 14:59:57 CST] 1.5KiB STANDARD 2.yaml
[2023-10-19 15:09:05 CST] 1.5KiB STANDARD 3.yaml
[2023-10-19 14:54:23 CST] 1.5KiB STANDARD minio-dev.yaml
[2023-10-19 16:18:25 CST] 0B test/
服务端文件存储
启动时,将minio 的工作目录设置到 data 下,在 data 目录下主要有两个目录
- .minio.sys 是minio系统信息
- 包括桶定义和桶中的文件索引目录 ./.minio.sys/buckets/mybucket
- 账号信息和iam信息 ./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N
- mybucket 是创建的一个桶名称
➜ data find .
.
./.minio.sys
./.minio.sys/buckets
./.minio.sys/buckets/.usage-cache.bin
./.minio.sys/buckets/.minio.sys
./.minio.sys/buckets/.minio.sys/buckets
./.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin
./.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/.bloomcycle.bin
./.minio.sys/buckets/.minio.sys/buckets/.bloomcycle.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/mybucket
./.minio.sys/buckets/.minio.sys/buckets/mybucket/.usage-cache.bin
./.minio.sys/buckets/.minio.sys/buckets/mybucket/.usage-cache.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/.usage.json
./.minio.sys/buckets/.minio.sys/buckets/.usage.json/fs.json
./.minio.sys/buckets/.bloomcycle.bin
./.minio.sys/buckets/mybucket
./.minio.sys/buckets/mybucket/.usage-cache.bin
./.minio.sys/buckets/mybucket/test
./.minio.sys/buckets/mybucket/test/1.txt
./.minio.sys/buckets/mybucket/test/1.txt/fs.json
./.minio.sys/buckets/mybucket/minio-dev.yaml
./.minio.sys/buckets/mybucket/minio-dev.yaml/fs.json
./.minio.sys/buckets/mybucket/3.yaml
./.minio.sys/buckets/mybucket/3.yaml/fs.json
./.minio.sys/buckets/mybucket/2.yaml
./.minio.sys/buckets/mybucket/2.yaml/fs.json
./.minio.sys/buckets/mybucket/.metadata.bin
./.minio.sys/buckets/.tracker.bin
./.minio.sys/buckets/.usage.json
./.minio.sys/config
./.minio.sys/config/config.json
./.minio.sys/config/iam
./.minio.sys/config/iam/service-accounts
./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N
./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N/identity.json
./.minio.sys/config/iam/policydb
./.minio.sys/config/iam/policydb/sts-users
./.minio.sys/config/iam/policydb/sts-users/P1Y2O1AO30UYBE2UODBY.json
./.minio.sys/config/iam/policydb/users
./.minio.sys/config/iam/policydb/users/ak00123456789.json
./.minio.sys/config/iam/users
./.minio.sys/config/iam/users/ak00123456789
./.minio.sys/config/iam/users/ak00123456789/identity.json
./.minio.sys/config/iam/format.json
./.minio.sys/config/iam/sts
./.minio.sys/config/iam/sts/P1Y2O1AO30UYBE2UODBY
./.minio.sys/config/iam/sts/P1Y2O1AO30UYBE2UODBY/identity.json
./.minio.sys/multipart
./.minio.sys/format.json
./.minio.sys/tmp
./.minio.sys/tmp/07c1ffc6-ae6f-4a99-a57e-cb5e55530603
./mybucket
./mybucket/test
./mybucket/test/1.txt
./mybucket/minio-dev.yaml
./mybucket/3.yaml
./mybucket/2.yaml
aws-s3操作文件
aws-s3的 sdk 代码简单包装
go.mod
module minio-demo
go 1.18
require (
github.com/aws/aws-sdk-go v1.43.21
)
aws_s3.go
package minio
import (
"bytes"
"io"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
const (
//token暂时为空
DefaultToken = ""
//测试用的regin,调用方需自行配置
DefaultRegion = "us-east-1"
)
// AwsS3 aws s3服务应用层客户端
type AwsS3 struct {
SecretId string
SecretKey string
Region string
Bucket string
Endpoint string
Token string
Client *s3.S3
}
// NewAwsS3 创建aws s3实例
func NewAwsS3(secretId, secretKey, region, bucket, endpoint, token string) *AwsS3 {
var awsS3Instance AwsS3
awsS3Instance.SecretId = secretId
awsS3Instance.SecretKey = secretKey
awsS3Instance.Region = region
awsS3Instance.Bucket = bucket
awsS3Instance.Endpoint = endpoint
awsS3Instance.Token = token
config := &aws.Config{
Credentials: credentials.NewStaticCredentials(secretId, secretKey, token),
Region: aws.String(region),
Endpoint: aws.String(endpoint),
//DisableSSL: aws.Bool(true),
S3ForcePathStyle: aws.Bool(true),
}
sess := session.Must(session.NewSession(config))
awsS3Instance.Client = s3.New(sess)
return &awsS3Instance
}
// PutObject 根据内容上传文件对象
func (a *AwsS3) PutObject(awsPath string, content []byte) (string, error) {
putObjectInput := &s3.PutObjectInput{
Bucket: aws.String(a.Bucket),
Key: aws.String(awsPath),
Body: aws.ReadSeekCloser(bytes.NewReader(content)),
}
resp, err := a.Client.PutObject(putObjectInput)
if err != nil {
return "", err
}
return *(resp.ETag), nil
}
// GetObject 下载文件对象内容
func (a *AwsS3) GetObject(awsPath string) ([]byte, string, error) {
getObjectInput := &s3.GetObjectInput{
Bucket: aws.String(a.Bucket),
Key: aws.String(awsPath),
}
resp, err := a.Client.GetObject(getObjectInput)
if err != nil {
return nil, "", err
}
content, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", err
}
return content, *(resp.ETag), nil
}
// DeleteObject 删除文件对象
func (a *AwsS3) DeleteObject(awsPath string) error {
deleteObject := &s3.DeleteObjectInput{
Bucket: aws.String(a.Bucket),
Key: aws.String(awsPath),
}
_, err := a.Client.DeleteObject(deleteObject)
if err != nil {
return err
}
return nil
}
// HeadObject 获取对象元数据信息,包括md5和上次修改时间
func (a *AwsS3) HeadObject(awsPath string) (string, *time.Time, error) {
headObject := &s3.HeadObjectInput{
Bucket: aws.String(a.Bucket),
Key: aws.String(awsPath),
}
resp, err := a.Client.HeadObject(headObject)
if err != nil {
return "", nil, err
}
return *(resp.ETag), resp.LastModified, nil
}
minio_test.go
package minio
import (
"os"
"testing"
)
// minio测试配置
var (
SecretId = "KLN00KFT1K5EP9I39I9N"
SecretKey = "k******j"
Region = DefaultRegion
Bucket = "mybucket"
Token = DefaultToken
Endpoint = "http://127.0.0.1:8877"
)
var awsS3Instance = NewAwsS3(SecretId, SecretKey, Region, Bucket, Endpoint, Token)
上传文件 Put http://0.0.0.0:8877/mybucket/test/1.txt
func TestPutObject(t *testing.T) {
// 测试时修改本地路径
localFilePath := "./testdata/1.txt"
t.Logf("local file path %s", localFilePath)
fileContent, err := os.ReadFile(localFilePath)
if err != nil {
t.Fatalf("read file error: %s!", err.Error())
return
}
// 测试时修改aws路径
awsPath := "/test/1.txt"
_, err = awsS3Instance.PutObject(awsPath, fileContent)
if err != nil {
t.Fatalf("put object error: %s", err.Error())
}
t.Logf("put object success")
}
下载文件 Get http://0.0.0.0:8877/mybucket/test/1.txt
func TestGetObject(t *testing.T) {
// 测试时修改aws路径
awsPath := "/test/1.txt"
contentBytes, _, err := awsS3Instance.GetObject(awsPath)
if err != nil {
t.Fatalf("get object error: %s", err.Error())
}
//获取当前系统根目录
if err != nil {
t.Fatalf("get home dir error: %s!", err.Error())
return
}
// 测试时修改本地路径
localFilePath := "./testdata/1-get.txt"
err = os.WriteFile(localFilePath, contentBytes, 0644)
if err != nil {
t.Fatal("write error")
return
}
t.Logf("get object success")
}
Head文件 Head http://0.0.0.0:8877/mybucket/test/1.txt
func TestHeadObject(t *testing.T) {
// 测试时修改aws路径
awsPath := "/test/1.txt"
eTag, lastModifyTime, err := awsS3Instance.HeadObject(awsPath)
if err != nil {
t.Fatalf("head object error: %s", err.Error())
}
t.Logf("head object success,eTag : %s, lastModifyTime : %v", eTag, lastModifyTime)
}
删除文件 Delete http://0.0.0.0:8877/mybucket/test/1.txt
func TestDeleteObject(t *testing.T) {
// 测试时修改aws路径
awsPath := "/test/1.txt"
err := awsS3Instance.DeleteObject(awsPath)
if err != nil {
t.Fatalf("delete object error: %s", err.Error())
}
t.Logf("delete object success")
}
mc 监听桶 mybucket 的变化,可以看出
➜ minio mc watch myminio/mybucket/
[2023-10-19T07:27:35.675Z] 36 B s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:46.813Z] s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:58.157Z] s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T08:42:23.065Z] s3:ObjectRemoved:Delete http://0.0.0.0:8877/mybucket/test/1.txt
minio控制台页面统计信息
详细文档参考
https://min.io/docs/minio/kubernetes/upstream/index.html?ref=docs-redirect\&ref=con
done.
祝玩的开心~