前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mac 上学习k8s系列(12)minio

mac 上学习k8s系列(12)minio

作者头像
golangLeetcode
发布2022-08-02 19:25:59
7050
发布2022-08-02 19:25:59
举报
文章被收录于专栏:golang算法架构leetcode技术php

Minio (https://github.com/minio/minio)提供对象存储服务,兼容了 AWS S3 存储协议,用于非结构化的数据存。非结构化对象,比如图像,音、视频,日志文件,备份镜像…等等管理不方便,不定长,大小变化大、类型多,云端的访问复杂,minio就是来解决这种场景的。非结构化的文件从数KB到5TB都能很好的支持。开源并且用Go语言开发,有web操作界面,我们可以用它来搭建兼容S3协议的存储云服务。

对象存储呈现出来的是一个“桶”(bucket),你可以往“桶”里面放“对象(Object)”。这个对象包括三个部分:Key、Data、Metadata。

Key:可以理解文件名,是该对象的全局唯一标识符(UID)。Key是用于检索对象,服务器和用户不需要知道数据的物理地址,也能通过它找到对象。这种方法极大地简化了数据存储。

Data:也就是用户数据本体。这个不用解释了。

Metadata:Metadata叫做元数据,它是对象存储一个非常独特的概念。元数据有点类似数据的标签,标签的条目类型和数量是没有限制的,可以是对象的各种描述信息。在传统的文件存储里,这类信息属于文件本身,和文件一起封装存储。而对象存储中,元数据是独立出来的,并不在数据内部封装。元数据的好处非常明显,可以大大加快对象的排序,还有分类和查找。

以往像FAT32这种文件系统,是直接将一份文件的数据与metadata一起存储的,存储过程先将文件按照文件系统的最小块大小来打散(如4M的文件,假设文件系统要求一个块4K,那么就将文件打散成1000个小块),再写进硬盘里面,过程中没有区分数据/metadata的。而每个块最后会告知你下一个要读取的块的地址,然后一直这样顺序地按图索骥,最后完成整份文件的所有块的读取。

  这种情况下读写速度很慢,因为就算你呦100个机械手臂在读写,但是由于你只有读取到第一块,才能知道下一个在哪里,其实相当于只能有一个机械手臂在实际工作。对象存储将元数据独立出来,控制节点叫元数据服务器(服务器+对象存储管理软件),里面主要负责存储对象的属性(主要是对象的数据被打散存放到了那几台分布式服务器中的信息),而其他负责存储数据的分布式服务器叫做OSD,主要负责存储文件的数据部分。当用户访问对象,会先访问元数据服务器,元数据服务器只负责反馈对象存储在那些OSD,假设反馈文件A存储在B、C、D三台OSD,那么用户就会再次直接访问3台OSD服务器去读取数据。这时候由于是3台OSD同时对外传输数据,所以传输的速度就加快了。当OSD服务器数量越多,这种读写速度的提升就越大,通过这种方式,实现了读写快的目的。

Minio使用纠删码erasure code和校验和checksum来保护数据免受硬件故障和无声数据损坏。即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。

什么是纠删码erasure code?纠删码是一种恢复丢失和损坏数据的数学算法, Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复。

什么是位衰减bit rot保护?位衰减又被称为数据腐化Data Rot、无声数据损坏Silent Data Corruption,是目前硬盘数据的一种严重数据丢失问题。硬盘上的数据可能会神不知鬼不觉就损坏了,也没有什么错误日志。正所谓明枪易躲,暗箭难防,这种背地里犯的错比硬盘直接咔咔宕了还危险。不过不用怕,Minio纠删码采用了高速 HighwayHash 基于哈希的校验和来防范位衰减。

直接在docker上可以按照如下方法部署,但是数据会重启丢失。

代码语言:javascript
复制
docker run -p 9000:9000 --name my_minio \
  -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  -v  ~/Downloads:/data \
  -v  ~/Downloads:/root/.minio \
  minio/minio server /data

在k8s上如何部署呢?和部署redis mac 上学习k8s系列(10)PV PVC一样,我们采用挂载volume的方式,先声明pv

代码语言:javascript
复制
apiVersion: v1
kind: PersistentVolume
metadata:
  labels:
    app: minio
    release: minio
  name: minio
  namespace: default
spec:
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: minio-pv-claim
    namespace: default
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  hostPath:
    path: /Users/xiazemin/source/k8s_learn/minio/k8s/standalone/minio/

然后声明pvc

代码语言:javascript
复制
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # This name uniquely identifies the PVC. Will be used in deployment below.
  name: minio-pv-claim
  labels:
    app: minio-storage-claim
spec:
  # Read more about access modes here: https://kubernetes.io/docs/user-guide/persistent-volumes/#access-modes
  accessModes:
    - ReadWriteOnce
  resources:
    # This is the request for storage. Should be available in the cluster.
    requests:
      storage: 2Gi
  # Uncomment and add storageClass specific to your requirements below. Read more https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1
  #storageClassName:

部署pod

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  # This name uniquely identifies the Deployment
  name: minio-deployment
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: minio
  template:
    metadata:
      labels:
        # Label is used as selector in the service.
        app: minio
    spec:
      # Refer to the PVC created earlier
      volumes:
      - name: storage
        persistentVolumeClaim:
          # Name of the PVC created earlier
          claimName: minio-pv-claim
      containers:
      - name: minio
        # Pulls the default MinIO image from Docker Hub
        image: minio/minio
        args:
        - server
        - /storage
        - --console-address
        - ":9001"
        env:
        # MinIO access key and secret key
        - name: MINIO_ACCESS_KEY
          value: "admin123"
        - name: MINIO_SECRET_KEY
          value: "admin123"
        ports:
        - containerPort: 9000
          name: api
        - containerPort: 9001
          name: console
        # Mount the volume into the pod
        volumeMounts:
        - name: storage # must match the volume name, above
          mountPath: "/storage"

部署service

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: minio-service
spec:
  type: NodePort
  ports:
    - port: 9000
      targetPort: 9000
      nodePort: 30000
      name: api
      protocol: TCP
    - port: 9001
      name: console
      targetPort: 9001
      nodePort: 30001
      protocol: TCP
  selector:
    app: minio

部署完毕,我们测试下

代码语言:javascript
复制
% curl -iv http://127.0.0.1:30000
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 30000 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:30000
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Content-Length: 226
Content-Length: 226
< Content-Security-Policy: block-all-mixed-content
Content-Security-Policy: block-all-mixed-content
< Content-Type: application/xml
Content-Type: application/xml
< Server: MinIO
Server: MinIO
< Strict-Transport-Security: max-age=31536000; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
< Vary: Origin
Vary: Origin
< Vary: Accept-Encoding
Vary: Accept-Encoding
< X-Amz-Request-Id: 16A012A7AEDC24F7
X-Amz-Request-Id: 16A012A7AEDC24F7
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< X-Xss-Protection: 1; mode=block
X-Xss-Protection: 1; mode=block
< Date: Mon, 30 Aug 2021 11:39:36 GMT
Date: Mon, 30 Aug 2021 11:39:36 GMT

< 
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host 127.0.0.1 left intact
<Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Resource>/</Resource><RequestId>16A012A7AEDC24F7</RequestId><HostId>bd78d817-8f16-4589-a8fd-e7db8569033e</HostId></Error>* Closing connection 0

说明api端口是ok的,因为没事指定密码认证,说返回错误了

代码语言:javascript
复制
 % curl -iv http://127.0.0.1:30001
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 30001 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:30001
> User-Agent: curl/7.64.1
> Accept: */*
> 
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server
* Closing connection 0

测试下,发现console端口不ok,为啥呢?

我们对比docker单机版和k8s版本发现args少了两个参数,补充下面参数

代码语言:javascript
复制
  args:
  - server
  - /storage
  - --console-address
  - ":9001"

再测试下ok

访问下面连接,可以进入控制台,输入用户名,密码可以看到后台信息:

代码语言:javascript
复制
http://127.0.0.1:30001/dashboard

我我们用golang api连接下

代码语言:javascript
复制
package main

import (
  "context"
  "log"

  "github.com/minio/minio-go/v7"
  "github.com/minio/minio-go/v7/pkg/credentials"
)

func main() {
  ctx := context.Background()
  endpoint := "127.0.0.1:30000"
  accessKeyID := "admin123"
  secretAccessKey := "admin123"
  /*
    endpoint := "127.0.0.1:9000"
    accessKeyID := "AKIAIOSFODNN7EXAMPLE"
    secretAccessKey := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  */
  useSSL := false

  // Initialize minio client object.
  minioClient, err := minio.New(endpoint, &minio.Options{
    Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
    Secure: useSSL,
  })
  if err != nil {
    log.Fatalln(err)
  }

  // Make a new bucket called mymusic.
  bucketName := "mymusic"
  location := "us-east-1"

  err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
  if err != nil {
    // Check to see if we already own this bucket (which happens if you run this twice)
    exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
    if errBucketExists == nil && exists {
      log.Printf("We already own %s\n", bucketName)
    } else {
      log.Fatalln(err)
    }
  } else {
    log.Printf("Successfully created %s\n", bucketName)
  }

  // Upload the zip file
  objectName := "test.tar"
  filePath := "./test.tar"
  contentType := "application/zip"

  // Upload the zip file with FPutObject
  info, err := minioClient.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)

  if err := minioClient.FGetObject(context.Background(), bucketName, objectName, filePath, minio.GetObjectOptions{}); err != nil {
    log.Fatalln(err)
  }
  log.Println("Successfully get", filePath)
}

发现成功了,在本地目录看下

代码语言:javascript
复制
 minio % tree
.
|____.minio.sys
| |____buckets
| | |____.usage-cache.bin
| | |____.minio.sys
| | | |____buckets
| | | | |____.usage-cache.bin
| | | | | |____fs.json
| | | | |____.bloomcycle.bin
| | | | | |____fs.json
| | | | |____mymusic
| | | | | |____.usage-cache.bin
| | | | | | |____fs.json
| | | | |____.usage.json
| | | | | |____fs.json
| | |____.bloomcycle.bin
| | |____mymusic
| | | |____.usage-cache.bin
| | | |____test.tar
| | | | |____fs.json
| | | |____.metadata.bin
| | |____.tracker.bin
| | |____.usage.json
| |____config
| | |____config.json
| | |____iam
| | | |____policydb
| | | | |____sts-users
| | | | | |____378MNUH1NQR65ZY5ZPLR.json
| | | |____format.json
| | | |____sts
| | | | |____378MNUH1NQR65ZY5ZPLR
| | | | | |____identity.json
| |____format.json
|____mymusic
| |____test.tar

至此,我们k8s搭建minio完毕。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档