Kubernetes部署Minio集群存储的选择,使用DirectPV CSI作为分布式存储的最佳实践
个人理解浅谈
1. 关于在kubernetes上部署分布式存储服务,K8s存储的选择
在非云环境部署Kubernets时,一般采用的都是本地的直连式存储和文件系统,如hostpath、或者local卷,即使是利用K8s存储的PV卷,都需要本地已经有提前准备好的块存储或者已经创建好文件目录,若利用local卷还会有亲和性问题的限制,node节点故障时,会因为local卷和node的绑定关系导致pod调度失败。
K8s也支持利用网络存储,如NAS、NFS等方式给k8s提供存储资源,但是网络存储首先需要事先在每台节点部署网络存储服务不仅增加了复杂性,另外不可避免的问题就是网络存储服务具有单点故障,若服务出现问题不可用,将导致数据丢失,影响到k8s的所有pod的数据。
2. 使用DirectPV作为部署k8s minio集群存储的最佳实践
DirectPV
DirectPV是一个分布式持久卷管理器,是用于直连存储(DAS)的容器存储接口(CSI)驱动程序。
K8s hostpath、local和本地静态配置都有的痛点即需要事先在node节点准备好可用的块存储或文件系统,例如对插入的硬盘,或者磁盘阵列做分区格式化,文件系统则需提前创建好k8s即将利用的挂载目录,并且两种方法都会有亲和性限制,无法做到让k8s自身的去调度让数据卷分布在不同的node节点上。
在传统的基于SAN或NASCSI 驱动程序(网络 PV)上部署minio集群的局限性
若利用传统的SAN或者NAS的CSI存储驱动(网络PV)来为minio集群提供存储,minio集群本身就分布式存储和保障高可用的特点,不仅会在数据路径中增加另一层复制/擦除编码和额外的网络跃点。这种额外的分解层还会导致复杂性增加和性能下降的问题。
DirectPV优势
而DirectPV正是为了解决这些问题,DirectPV做到了跨服器发现可用存储资源、跨服器格式化存储、创建供k8s PV使用的存储池,由k8s API通过DirectPV CSI调度存储资源为POD分配直连式存储PV,分布式地在node节点创建符合PVC申请要求的PV。DirectPV创建的存储资源统一由部署DirectPV的节点监视和维护。
通俗点讲,即在master节点部署后DirectPV后,只需在node节点插入硬盘或者组建磁盘阵列,后续的格式化只需在安装了DirectPV的master节点上操作,node节点无需后续操作,PV由k8s自行调度和创建,并由PV卷将数据持久化。
DirectPV局限性
DirectPV本质上是利用节点磁盘创建并挂载了一个挂载分区供k8s pod使用,始终还是规避不了节点单点故障和硬盘损坏的问题,并且数据的持久化受到由DirectPV分配的PV卷的限制。
minio集群特性
-
分布式
minio集群将数据分布在每个minio集群节点上,每个集群节点至少拥有4个驱动器,数据被均匀分布在每个集群节点的驱动器上,一半的驱动器空间用于数据备份利用,一半的空间用于存储。 -
高可用
minio集群的高可用特性,即驱动器只要有总数的N/2在线,即可完整的同步和还原数据,解决了硬盘单点故障导致数据丢失的问题。只要minio的集群节点数量够多,也能规避minio集群节点故障大面积的驱动器掉线导致存储数据丢失的问题。
DirectPV结合Minio集群突破DirectPV的局限性
每个minio集群节点上由K8s调度,而每个集群节点的驱动器使用的PV由DirectPV调度,也就是说驱动器实际使用的存储资源是由DirectPV随机的从属于K8s的DirectPV存储池中分配出来的,那实际的数据会随机的分布在node节点上的硬盘上。
-
硬盘单点故障
若是k8s node节点本身使用的是JOBD存储,那自然已经没有硬盘单点故障的问题,即使没有使用JOBD存储,因为minio集群存储的数据是分布式地在各个不同minio集群节点的驱动器上,本质上就是在各个k8
s node节点的不同硬盘上,只要node节点硬盘数量够多,很大程度上可以规避硬盘单点故障的问题 -
k8s node节点单点故障
同样的,node节点上故障时将会有大量的PV不可用,从而导致minio集群驱动器大量的掉线,规避该问题的方法既是存在有大量的k8s node节点,保证实际的驱动器数据分布在不同的节点硬盘上
2. 部署实践
2.1. 安装使用DirectPV
DirectPV设计为轻量级,可扩展到1000个驱动器中的10个。它由三个组件组成:控制器、节点驱动程序、用户界面
在进行卷声明时,控制器会从无池驱动器统一调配卷。DirectPV知道pod的关联约束,并将卷从本地驱动器分配到pod。请注意,每个群集只运行一个活动的controller实例
节点驱动程序实现卷管理功能,例如发现、格式化、装载和监视节点上的驱动器。每个存储服务器上都运行一个节点驱动程序实例。
存储管理员可以使用kubectl CLI插件来选择、管理和监视驱动器。基于Web的UI目前正在开发中。
2.2. 在K8s Master节点上部署Directpv
安装先决条件
- 已经安装Krew插件工具(参考博文:安装Kubernetes Krew工具)
- Node节点有可用的磁盘
# 安装directpv插件(未上网可能会下载失败,亲测尝试多次后即可成功)
kubectl krew install directpv
# 使用directpv插件在k8s集群安装directpv的组件
kubectl directpv install
# 查看directpv信息
kubectl directpv info
# 查看可用的驱动器
kubectl directpv drives ls
# 选择供directpv管理的驱动器进行格式化后加入存储池{a...c}=a,b,c、{1...3}=1,2,3
kubectl directpv drives format --drives /dev/sd{a...f} --nodes directpv-{1...4}
#执行完毕后等待一会,使用kubectl directpv drives ls可用看到驱动器状态为Ready,即可供PVC声明使用
#--drives后接实践磁盘分区位置,博主的为:/dev/sd{b...c}
#--nodes后接k8s node节点的名称,博主的为:node0{1...2}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
2.3. 使用DirectPV案例
2.3.1. 创建PVC
vim pvc-direct.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-pvc-2
namespace: default
spec:
storageClassName: directpv-min-io #Directpv使用的SC,directpv-min-io,在安装directpv时自动创建
accessModes:
- ReadWriteOnce #注意directpv不支持多节点写入模式
resources:
requests:
storage: 1024Mi #申请PV空间大小
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
kubectl create -f pvc-direct.yaml
2.3.2 创建使用Directpv PVC的Pod
vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: csipod-2
spec:
volumes:
- name: pvc-storage
persistentVolumeClaim:
claimName: csi-pvc-2 #指定使用刚刚创建的PVC:csi-pvc-2
containers:
- image: busybox:1.28
name: box
args: [/bin/sh, -c, while true; do echo "$(date)" >> /tmp/1.log && sleep 10; done]
resources:
requests:
cpu: 100m
volumeMounts:
- name: pvc-storage
mountPath: /tmp #PV挂载至容器里的/tmp目录
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
kubectl create -f pod.yaml
2.4. 查看实际PV创建的位置
2.4.1. PV在Pod实际调度的节点上被创建,首先查看Pod被调度到node2节点
2.4.2. 确认分配的pvc的名称
2.4.3. 进入node2节点查看到有两个硬盘被用于directpv的存储池,切换到/var/lib/direct-csi/mnt/
2.4.4. 使用tree命令查看到pvc实际被创建在了38296a09-bc76-47f0-8861-d5bd52ff1855下
2.5. 测试挂载的PV
2.5.1. 在pv下创建文件
2.5.2. 查看pod的tmp目录确认
2.5. 使用Directpv CSI创建PV提供给minio集群使用
2.5.1. 使用Deployment部署minio集群
- 每个驱动器需要对应一个PVC,即一个集群至少创建四个PVC
- 这里实例使用单节点minio集群
2.5.2. 创建PVC
vim minio-pv.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data-d0
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: directpv-min-io
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data-d1
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: directpv-min-io
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data-d2
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: directpv-min-io
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data-d3
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: directpv-min-io
resources:
requests:
storage: 1Gi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
kubectl create -f minio-pv.yaml
成功创建PVC
2.5.3. 创建Deployment
vim minio-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio
namespace: default
spec:
selector:
matchLabels:
name: minio
replicas: 1
template:
metadata:
labels:
name: minio
spec:
containers:
- name: minio
env:
- name: MINIO_ROOT_USER
value: minioadmin
- name: MINIO_ROOT_PASSWORD
value: miniopassword
image: docker.io/minio/minio
args:
- server
- /data0
- /data1
- /data2
- /data3
- --console-address
- ":9090"
ports:
- containerPort: 9000
- containerPort: 9090
volumeMounts:
- name: data0
mountPath: /data0
- name: data1
mountPath: /data1
- name: data2
mountPath: /data2
- name: data3
mountPath: /data3
volumes:
- name: data0
persistentVolumeClaim:
claimName: pvc-data-d0
- name: data1
persistentVolumeClaim:
claimName: pvc-data-d1
- name: data2
persistentVolumeClaim:
claimName: pvc-data-d2
- name: data3
persistentVolumeClaim:
claimName: pvc-data-d3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
kubectl create -f minio-deployment.yaml
2.5.4. directpv成功分配PV给pod使用
pod成功创建
2.5.5. 暴露Minio集群访问端口(pod内部端口为9090,宿主机即k8s集群端口为30513)
2.5.7. 登录minio控制台(使用浏览器:http://{k8s-address}:30513访问)
- 账号:minioadmin
- 密码:miniopassword
2.5.8. 确认驱动器
手动创建使用DirectPV CSI的PVC部署K8s Minio集群的实践分享至此完毕,使用Depolyment方式部署的Minio集群维护起来相对麻烦,而最佳实践使用MinIO Operator工具创建Minio集群,是最推荐的方式。
MinIO Operator
MinIO Operator 致力于在Kubernetes上创建/配置/管理 MinIO 集群,也是一种将私有和公共云基础设施(混合云)最佳的minio部署方法。
MinIO Operator会自动调用DirectPV创建PVC和PV,并且直接通过一个命令技能创建自定义minio节点和驱动器数量的Minio集群。
MinIO Operator的使用及利用Minio存储桶(对象存储)作为K8s存储的经验将在后续的博文介绍分享,挖个坑~~~
引用
https://min.io/directpv
https://github.com/minio/directpv