运行环境
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.
祝玩的开心~