这篇文章主要记录一下,在生产环境中,Minio集群的部署方式。而想要在生产环境中部署一套高可靠的Minio集群,则需要对Minio的知识有深入的理解。 同时,在生产环境中,Minio集群的部署方式,需要考虑到以下几点: 1、数据丢失的风险 2、数据丢失的情况下的恢复方案 3、在数据安全和存储效率之间的权衡 4、集群备份方案的选型
其实在生产环境的部署中,一般会和kes,vault一起部署使用。Kes是一个无状态的密钥服务,用于存储和管理密钥。vault是一个有状态的密钥服务,用于存储和管理密钥。所以,生产环境中,对vault的高可靠部署方式也是一个非常需要关注的问题。在本文中我并未涉及。 在实际的对vault的KMS密钥的备份是非常关键的一个问题。
同时kes的证书问题,也是在生产环境中需要考虑的一个问题,手动运维的方式是非常不推荐的。
1、官方文档推荐
部署架构 中提到,对于生产环境中,至少部署4个具有相同存储资源和计算资源的节点。Minio 会将这些资源聚合成一个服务器资源,并将其自身呈现为一个对象存储服务。
2、纠错码
参考文档:
- https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html
- https://min.io/docs/minio/linux/operations/concepts/healing.html
2.1 纠错码(EC:M)
纠错码本身的作用,就是给存入到 Minio 中的数据,增加冗余信息。方便在数据丢失或者发生损坏的时候,能够恢复原始数据。
纠错码M的设置范围,最小是0,最大是一个纠错码集合中drivers的数量。假设你的一个纠错码集合的drivers是16,那么 0<M<=8
2.2 纠错码的作用
要明白纠错码的作用,我们需要了解,在一个object存入到Minio 中发生了什么,这里假设纠错码集N=16, 纠错码EC=4。
- 首先一个object会被分片成为 16-4=12 个 数据分片
- 然后根据这 12 个数据分片,计算出 4 个 检验分片
- 将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
-
读取仲裁 在损坏的drivers数量小于等于 M 数量的情况下, Minio 任然可以保持对外提供读取服务。
-
写入仲裁
-
当M<N/2的时候,损坏drivers数量小于等于 M 数量的情况下, Minio任然可以对外提供写入服务。
-
当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 对等节点之间都复制哪些东西
- 存储桶和对象的创建、修改、删除
- 存储桶和对象配置
- 策略(权限)
- 标签
- 加密设置
- 创建和删除IAM用户、组、策略以及到用户或组的策略映射。
- 为可从本地root凭据验证的会话令牌创建安全令牌服务(sts)凭据
- 创建和删除访问密钥,root用户除外。
3.2 对等站点之间不复制哪些东西
- 桶通知
- 生命周期管理(ILM)配置文件
- 站点配置文件和设置
3.3 同步复制和异步复制
参考文档(如果对以下总结有任何疑问,都可自行阅读官方文档):
- https://min.io/docs/minio/linux/operations/install-deploy-manage/multi-site-replication.html
3.3.1 同步复制
在源节点收到一个PUT请求之后,需要所有其他的参与复制的节点都接收到了并确认了数据之后,才开始复制。
这个可以保证节点之间的一致性,当源节点在这次PUT操作发生故障的时候,可以从其他节点恢复
3.3.2 异步复制
在源节点收到PUT请求之后,不需要参与复制节点立即拥有最新的数据副本。数据首先被写入到源节点,然后逐步复制到其他节点。
异步复制会导致在一段时间之内,各个节点之间的数据不一致。如果在这期间源发生了故障,那么数据的恢复会更加复杂
3.3.3 官方推荐
官方强烈推荐使用异步复制的方式。因为同步复制对各个节点之间的网络延迟非常敏感,会降低PUT操作的性能。
3.4 针对加密
如果在源站点中使用通过 KMS 实现加密,则所有站点都必须能访问到中央KMS部署。可以有两种方案:
- 部署一个中央KMS,多个Minio集群直接都访问到同一个KMS服务。
- 部署多个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 的基础上面注意以下操作即可:
- 首先你要准备一个 minio3
- 然后执行以下命令:
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、桶数据复制
参考文档:
- https://min.io/docs/minio/linux/administration/bucket-replication.html
默认使用异步桶复制
4.1 复制需要版本控制
minio 依赖于版本控制提供的不可变性来支持复制和重新同步。可以使用mc version info命令来查看,源桶和目标桶的版本状态。如果没有开启的话。
就使用 mc version enable minio1/bucketName 来开启两个minio集群中桶的版本控制。
4.1.1 版本的不可变性
一旦一个对象的某个版本被创建并存储,它就不能被修改。任何对对象的更改都会创建一个新的版本,而不是覆盖当前的版本。
4.1.2 版本控制的使用
-
开启和查看版本
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,版本号,文件名称等等。
- 下载指定版本
1 2
# 将指定版本的文件下载当前文件夹中 mc cp --version-id=id minio/test/filename .
- 删除指定版本
1
mc rm --vesion-id=id minio/test/filename
- 软删除
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]#
-
版本管理 随着时间的增加,版本越来越多必然会导致内存越来越大。所以要使用( 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 双向服务器端桶复制
-
在minio1集群上面执行一次单向服务器端桶复制
-
在minio2集群上面执行一次单向服务器端桶复制
这样就完成了双向服务器端桶复制
5、Minio 集群扩容/缩容
参考文档:
- https://blog.min.io/decommissioning/
- 使用 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 │ └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
-
然后修改tenant.yaml。增加一个pools的配置。然后执行kubectl apply -f tenant.yaml。应用这个新pool
- 重新查看: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 │ └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
-
最后一步,将pool-1退化:
1
mc admin decommission start v1/ https://myminio-pool-0-{0...3}.myminio-hl.v1.svc.cluster.local/export{0...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) │ 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。
-
最后需要删除第一个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 │ └─────┴──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
至此换盘就换完成了。但是需要注意以下问题:
- 当开始退化的时候,pool就会进入到只读状态,已经在执行的写入操作会执行完毕。但是新的写入请求会重定向到新的pool。具体情况没有实践过在pool一仍有大规模的写入的时候,退化的情况。还是需要根据实际情况来应对。最好选择在使用量比较小的时候,进行数据的迁移。
6、桶开启加密
1
mc encrypt set sse-s3 minio1/test
4、当Minio集群发生disk损坏时,如何进行更新
参考文档:
- https://blog.min.io/troubleshooting-disk-failures/
可以看到这篇文章介绍的是