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