这篇文章主要记录一下,在生产环境中,Minio集群的部署方式。而想要在生产环境中部署一套高可靠的Minio集群,则需要对Minio的知识有深入的理解。 同时,在生产环境中,Minio集群的部署方式,需要考虑到以下几点: 1、数据丢失的风险 2、数据丢失的情况下的恢复方案 3、在数据安全和存储效率之间的权衡 4、集群备份方案的选型

其实在生产环境的部署中,一般会和kes,vault一起部署使用。Kes是一个无状态的密钥服务,用于存储和管理密钥。vault是一个有状态的密钥服务,用于存储和管理密钥。所以,生产环境中,对vault的高可靠部署方式也是一个非常需要关注的问题。在本文中我并未涉及。 在实际的对vault的KMS密钥的备份是非常关键的一个问题。

同时kes的证书问题,也是在生产环境中需要考虑的一个问题,手动运维的方式是非常不推荐的。

1、官方文档推荐

部署架构 中提到,对于生产环境中,至少部署4个具有相同存储资源和计算资源的节点。Minio 会将这些资源聚合成一个服务器资源,并将其自身呈现为一个对象存储服务。

2、纠错码

参考文档:

2.1 纠错码(EC:M)

纠错码本身的作用,就是给存入到 Minio 中的数据,增加冗余信息。方便在数据丢失或者发生损坏的时候,能够恢复原始数据。

纠错码M的设置范围,最小是0,最大是一个纠错码集合中drivers的数量。假设你的一个纠错码集合的drivers是16,那么 0<M<=8

2.2 纠错码的作用

要明白纠错码的作用,我们需要了解,在一个object存入到Minio 中发生了什么,这里假设纠错码集N=16, 纠错码EC=4。

  1. 首先一个object会被分片成为 16-4=12 个 数据分片
  2. 然后根据这 12 个数据分片,计算出 4 个 检验分片
  3. 将12 + 4 = 16 个分片尽可能均匀的存放到16个drivers中。

当这16个drivers中的一个dirvers发生了故障,数据不可访问。此时如果Minio接收到 GET 或者 OPTION 请求。就会发现数据损坏。然后就会根据剩下的 15 个分片,将原始数据恢复出来。

但是 drivers 损坏的数量是有限的,像我们这里 采用 12 + 4 的模式下面。最大允许 4 个drivers的数据不可访问。任然可以恢复原来的数据。其实就是这4个drivers正好是4个校验分片丢失的情况。当数据丢失的数量超过这个限制的时候,数据将不能恢复了。

其实只要损坏的drivers数量小于等于纠错码EC:M的数量,就能恢复原来的数据。

2.3 仲裁

假设纠错码集合数量为:N

纠错码EC: M

  1. 读取仲裁 在损坏的drivers数量小于等于 M 数量的情况下, Minio 任然可以保持对外提供读取服务。

  2. 写入仲裁

    1. 当M<N/2的时候,损坏drivers数量小于等于 M 数量的情况下, Minio任然可以对外提供写入服务。

    2. 当M=N/2的时候,drivers数量必须保持在 M + 1 的数量,才能对外提供写入数据的服务。这是为了防止脑裂的情况出现。

      例如有 16 个drivers在一个纠错集合中,EC设置为了8,这时候,要保持能对外提供写入服务,需要至少9个drivers的数据能够正常访问。

2.4 图标总结(假设16个1TB的driver)

奇偶校验 总存储空间 存储比例 用于读取操作的最小驱动器 用于写操作的最小驱动数量
EC:4 12TB 0.75 12 12
EC:6 10TB 0.625 10 10
EC:8 8TB 0.50 8 9

2.5 实际存储

部署架构:未开启KMS加密,4个driver,一个erasure set,erasure code为M

部署完成之后,每个drivers中占用 100Kb左右的内存,这是本次统计的误差

以下所有测试数据均用于上面的部署架构:

EC值 实际文件大小 minio查询大小 增量
2 100MB 51*4=204 MB 104 MB
2 500MB 251*4=1,004 MB 504MB
2 1024MB 513*4=2,052 MB 1028MB

所以,在部署的时候,除了要考虑到数据的安全性,还需要考虑内存的利用率。

1
2
3
4
5
6
7
du -sh /netdata/netdatavolume/pvc-a57d59c5-efd2-494e-bb82-031dfac9c4b6/

du -sh /netdata/netdatavolume/pvc-fd92ad20-1193-40fb-b7da-6bf264f8b7bb/

du -sh /netdata/netdatavolume/pvc-285543fe-8822-41ed-8778-92b59aa02406/

du -sh /netdata/netdatavolume/pvc-671e6d02-8fbb-4b69-bd38-497378445a91/

3、站点数据复制

3.1 对等节点之间都复制哪些东西

  1. 存储桶和对象的创建、修改、删除
    1. 存储桶和对象配置
    2. 策略(权限)
    3. 标签
    4. 加密设置
  2. 创建和删除IAM用户、组、策略以及到用户或组的策略映射。
  3. 为可从本地root凭据验证的会话令牌创建安全令牌服务(sts)凭据
  4. 创建和删除访问密钥,root用户除外。

3.2 对等站点之间不复制哪些东西

  1. 桶通知
  2. 生命周期管理(ILM)配置文件
  3. 站点配置文件和设置

3.3 同步复制和异步复制

参考文档(如果对以下总结有任何疑问,都可自行阅读官方文档):

3.3.1 同步复制

在源节点收到一个PUT请求之后,需要所有其他的参与复制的节点都接收到了并确认了数据之后,才开始复制。

这个可以保证节点之间的一致性,当源节点在这次PUT操作发生故障的时候,可以从其他节点恢复

3.3.2 异步复制

在源节点收到PUT请求之后,不需要参与复制节点立即拥有最新的数据副本。数据首先被写入到源节点,然后逐步复制到其他节点。

异步复制会导致在一段时间之内,各个节点之间的数据不一致。如果在这期间源发生了故障,那么数据的恢复会更加复杂

3.3.3 官方推荐

官方强烈推荐使用异步复制的方式。因为同步复制对各个节点之间的网络延迟非常敏感,会降低PUT操作的性能。

3.4 针对加密

如果在源站点中使用通过 KMS 实现加密,则所有站点都必须能访问到中央KMS部署。可以有两种方案:

  1. 部署一个中央KMS,多个Minio集群直接都访问到同一个KMS服务。
  2. 部署多个KMS服务,一一对应。

3.5 存储桶复制和站点复制

存储桶复制和站点复制是互斥的。在统一部署中午发同时使用两种方法。如果希望使用站点复制的话,首先就需要删除在原来的桶复制规则。可以直接在命令行中使用:mc replicate rm 删除桶复制规则。

3.4 操作

准备两个相同的集群,然后在主节点机器上面执行以下命令:

1
2
3
4
5
mc alias set minio1 http://host1:9000
mc alias set minio2 http://host2:9000
mc admin replicate add minio1 minio2
# 最后使用查看是否设置成功
mc admin replicate infor minio1

3.5 扩展复制站点

你需要在 标题 3.4 的基础上面注意以下操作即可:

  1. 首先你要准备一个 minio3
  2. 然后执行以下命令:
1
2
mc alias set minio3 http://host2:9000
mc admin replicate add minio1 minio2 minio3

关键的错误点,就是一定要记得这里不要忘记写:minio2 了!

3.6 删除复制站点

注意mc的版本,如果比较旧的话,使用不了rm命令的。

1
mc admin replicate rm minio1 minio2 --force

4、桶数据复制

参考文档:

默认使用异步桶复制

4.1 复制需要版本控制

minio 依赖于版本控制提供的不可变性来支持复制和重新同步。可以使用mc version info命令来查看,源桶和目标桶的版本状态。如果没有开启的话。

就使用 mc version enable minio1/bucketName 来开启两个minio集群中桶的版本控制。

4.1.1 版本的不可变性

一旦一个对象的某个版本被创建并存储,它就不能被修改。任何对对象的更改都会创建一个新的版本,而不是覆盖当前的版本。

4.1.2 版本控制的使用

  1. 开启和查看版本

    1
    2
    3
    4
    
    # 开启bucket的版本控制
    mc version enable alias/bucketName
    # 查看bucket的版本
    mc ls --version alias/bucketName
    

    在输出内容中,可以看到:

    1
    2
    3
    4
    
    [2024-12-30 15:10:09 CST]    22B STANDARD f161546b-5690-47c0-a693-e59c033a8a82 v3 PUT start.yaml
    [2024-12-30 15:09:24 CST]    10B STANDARD 0804778f-8d31-4a12-99da-f06132849682 v2 PUT start.yaml
    [2024-12-30 15:06:10 CST] 7.7KiB STANDARD e8ea822e-a019-45c7-ac84-91c40757f4c3 v1 PUT start.yaml
    [2024-12-30 15:07:36 CST] 7.7KiB STANDARD 6b3ee35a-e0f1-46ec-af26-956f1f200809 v1 PUT v2.yaml
    

    其中 有各个版本的上传时间,文件的大小,版本id,版本号,文件名称等等。

  2. 下载指定版本
    1
    2
    
    # 将指定版本的文件下载当前文件夹中
    mc cp --version-id=id minio/test/filename .
    
  3. 删除指定版本
    1
    
    mc rm --vesion-id=id minio/test/filename
    
  4. 软删除
    1
    
    mc rm minio/test/filename
    

    执行上述命令之后,会将最新版本加上一个删除的标记,但是没有真的删除。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    [root@iZbp108b5djx9wspy4wfezZ download]# mc rm v2/test/start.yaml
    Created delete marker `v2/test/start.yaml` (versionId=4856645a-c686-4b92-a921-31fea80bd513).
    [root@iZbp108b5djx9wspy4wfezZ download]# mc ls --versions v2/test
    [2024-12-30 15:38:40 CST]     0B STANDARD 4856645a-c686-4b92-a921-31fea80bd513 v3 DEL start.yaml
    [2024-12-30 15:10:09 CST]    22B STANDARD f161546b-5690-47c0-a693-e59c033a8a82 v2 PUT start.yaml
    [2024-12-30 15:09:24 CST]    10B STANDARD 0804778f-8d31-4a12-99da-f06132849682 v1 PUT start.yaml
    [2024-12-30 15:07:36 CST] 7.7KiB STANDARD 6b3ee35a-e0f1-46ec-af26-956f1f200809 v1 PUT v2.yaml
    [root@iZbp108b5djx9wspy4wfezZ download]# mc ls v2/test
    [2024-12-30 15:07:36 CST] 7.7KiB STANDARD v2.yaml
    [root@iZbp108b5djx9wspy4wfezZ download]#
    

    接下来只要将标记删除的版本删除,数据就会恢复:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    [root@iZbp108b5djx9wspy4wfezZ download]# mc rm --version-id=4856645a-c686-4b92-a921-31fea80bd513 v2/test/start.yaml
    Removed `v2/test/start.yaml` (versionId=4856645a-c686-4b92-a921-31fea80bd513).
    [root@iZbp108b5djx9wspy4wfezZ download]# mc ls v2/test
    [2024-12-30 15:10:09 CST]    22B STANDARD start.yaml
    [2024-12-30 15:07:36 CST] 7.7KiB STANDARD v2.yaml
    [root@iZbp108b5djx9wspy4wfezZ download]# mc ls --versions v2/test
    [2024-12-30 15:10:09 CST]    22B STANDARD f161546b-5690-47c0-a693-e59c033a8a82 v2 PUT start.yaml
    [2024-12-30 15:09:24 CST]    10B STANDARD 0804778f-8d31-4a12-99da-f06132849682 v1 PUT start.yaml
    [2024-12-30 15:07:36 CST] 7.7KiB STANDARD 6b3ee35a-e0f1-46ec-af26-956f1f200809 v1 PUT v2.yaml
    [root@iZbp108b5djx9wspy4wfezZ download]#
    
  5. 版本管理 随着时间的增加,版本越来越多必然会导致内存越来越大。所以要使用( Information Lifecycle Management)对bucket版本进行管理

    1
    
    mc ilm add --expiry-days=30 myminio/mybucket
    

    我们对目标桶设置,非当前版本的数据设置过期时间。这里设置,非当前版本的数据只保留30天

    可以用以下命令查看生命周期管理:

    1
    2
    3
    4
    5
    6
    7
    8
    
    [root@iZbp108b5djx9wspy4wfezZ download]# mc ilm ls v1/test
    ┌───────────────────────────────────────────────────────────────────────────────────────┐
    │ Expiration for latest version (Expiration)                                            │
    ├──────────────────────┬─────────┬────────┬──────┬────────────────┬─────────────────────┤
    │ ID                   │ STATUS  │ PREFIX │ TAGS │ DAYS TO EXPIRE │ EXPIRE DELETEMARKER │
    ├──────────────────────┼─────────┼────────┼──────┼────────────────┼─────────────────────┤
    │ ctp4va60eg5kln8aqn00 │ Enabled │ -      │ -    │            365 │ false               │
    └──────────────────────┴─────────┴────────┴──────┴────────────────┴─────────────────────┘
    

4.1 单向服务器端桶复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mc alias set minio1 http://host1:9000
mc alias set minio2 http://host2:9000

# 同时在两个集群上面创建相同的桶
mc mb minio1/test
mc mb minio2/test

# 开启两个bucket的版本控制
mc version enable minio1/test
mc version enable minio2/test

mc replicate add minio1/test \
   --remote-bucket 'minio2/test' \
   --replicate "delete,delete-marker,existing-objects"
   
# 使用以下命令检查
mc replicate ls minio1/test
   

4.2 双向服务器端桶复制

  1. 在minio1集群上面执行一次单向服务器端桶复制

  2. 在minio2集群上面执行一次单向服务器端桶复制

这样就完成了双向服务器端桶复制

5、Minio 集群扩容/缩容

参考文档:

  1. 使用 mc admin decommission status alias-name/ 查看当前这个集群的pool
    1
    2
    3
    4
    5
    
    [root@iZbp108b5djx9wspy4wfezZ ~]# mc admin decommission status v1/
    ┌─────┬──────────────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
    │ ID  │ Pools                                                                        │ Drives Usage         │ Status   │
    │ 1st │ https://myminio-pool-0-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Active   │
    └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
    
  2. 然后修改tenant.yaml。增加一个pools的配置。然后执行kubectl apply -f tenant.yaml。应用这个新pool

  3. 重新查看:mc admin decommission status alias-name/
    1
    2
    3
    4
    5
    6
    
    [root@iZbp108b5djx9wspy4wfezZ ~]# mc admin decommission status v1/
    ┌─────┬──────────────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
    │ ID  │ Pools                                                                        │ Drives Usage         │ Status   │
    │ 1st │ https://myminio-pool-0-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Active   │
    │ 2nd │ https://myminio-pool-1-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Active   │
    └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
    
  4. 最后一步,将pool-1退化:

    1
    
    mc admin decommission start v1/ https://myminio-pool-0-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3}
    

  5. 重新查看:mc admin decommission status alias-name/
    1
    2
    3
    4
    5
    6
    
    [root@iZbp108b5djx9wspy4wfezZ ~]# mc admin decommission status v1/
    ┌─────┬──────────────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
    │ ID  │ Pools                                                                        │ Drives Usage         │ Status   │
    │ 1st │ https://myminio-pool-0-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Complete │
    │ 2nd │ https://myminio-pool-1-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Active   │
    └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
    

    当状态显示为 Complete 的时候,就表示数据已经迁移完成了。此时pool-1的数据已经成功迁移到了pool-2。

  6. 最后需要删除第一个pool-1。修改tenant.yaml文件,将原来pools中第一个pool的配置删除,使用 kubectl apply -f tenant.yaml 应用这次更新。 使用:mc admin decommission status alias-name/ 查看

    1
    2
    3
    4
    5
    
    [root@iZbp108b5djx9wspy4wfezZ ~]# mc admin decommission status v1/
    ┌─────┬──────────────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
    │ ID  │ Pools                                                                        │ Drives Usage         │ Status   │
    │ 2nd │ https://myminio-pool-1-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...3} │ 0.0% (total: 14 PiB) │ Active   │
    └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
    

至此换盘就换完成了。但是需要注意以下问题:

  1. 当开始退化的时候,pool就会进入到只读状态,已经在执行的写入操作会执行完毕。但是新的写入请求会重定向到新的pool。具体情况没有实践过在pool一仍有大规模的写入的时候,退化的情况。还是需要根据实际情况来应对。最好选择在使用量比较小的时候,进行数据的迁移。

6、桶开启加密

1
mc encrypt set sse-s3 minio1/test

4、当Minio集群发生disk损坏时,如何进行更新

参考文档:

可以看到这篇文章介绍的是