前情提要
- Kubernetes的持久化存储体系里面,提到最多的是对接外部ceph服务或者NFS服务。
 - 有时候,Kubernetes集群所在的环境不一定提供对应的外部存储服务,而且为了性能的需求(低延迟、高IOPS等),外部基于网络的存储无法很好的满足需求。
 - 除此之外想把数据存放到宿主机本地硬盘的做法就只有hostPath或者emptyDir,这种做法还是不够科学。
 - 在Kubernetes社区里面,对本地持久化存储的呼声非常高,因此在v1.10版本引入了
Local Persistent Volume即本地PV,然后v1.14版本正式GA。 - 本地PV并不适用于所有的应用,因为本地PV是直接跟节点绑定在一起的,如果Pod需要使用本地PV,在Pod调度过程中,会考虑本地PV的分布情况,然后选中有本地PV的节点作为调度目标节点。因此如果本地PV所在节点宕机,则可能会出现数据丢失的情况,需要应用自己能处理节点掉线数据无法访问的情况。
 
说明
- 仅记录操作过程和部署过程
 - 操作系统使用的
CentOS-7.6.1810 x86_64 - 虚拟机配置
4CPU 8G内存 30G系统盘 20G数据盘A 5G数据盘B - Kubernetes集群版本
v1.14.4 - 这里演示两种方式管理本地PV
- 手动管理本地PV
 - 使用社区提供的
local-volume-provisioner来简化本地PV的管理 
 
准备步骤
参考社区文档
查看硬盘
- 20G本地硬盘
/dev/sdb - 5G本地硬盘
/dev/sdc 
1  | NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT  | 
创建目录
作为provisioner发现本地PV的目录
1  | mkdir -p /mnt/disks  | 
格式化硬盘
注意,这里是一个本地PV对应一个硬盘
1  | mkfs.ext4 /dev/sdb  | 
获取硬盘UUID
1  | SDB_UUID=$(blkid -s UUID -o value /dev/sdb)  | 
创建挂载目录
这里使用硬盘UUID作为挂载目录
1  | mkdir -p /mnt/disks/$SDB_UUID  | 
挂载硬盘
1  | mount -t ext4 /dev/sdb /mnt/disks/$SDB_UUID  | 
输出示例
1  | NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT  | 
写入fstab
1  | echo "UUID=${SDB_UUID} /mnt/disks/${SDB_UUID} ext4 defaults 0 2" | tee -a /etc/fstab  | 
输出示例
1  | 
  | 
给节点打标签
1  | kubectl label node k8s-node1 local-pv=present  | 
检查一下节点标签
1  | kubectl get node -l local-pv=present  | 
输出示例
1  | NAME STATUS ROLES AGE VERSION  | 
手动管理本地PV
创建PV
1  | apiVersion: v1  | 
创建StorageClass
1  | apiVersion: storage.k8s.io/v1  | 
使用Provisioner管理本地PV
安装Helm
二进制安装
1  | wget -O - https://get.helm.sh/helm-v2.14.1-linux-amd64.tar.gz | tar xz linux-amd64/helm  | 
创建RBAC
1  | cat << EOF | kubectl apply -f -  | 
安装Helm服务端
1  | helm init --tiller-image gcr.azk8s.cn/google_containers/tiller:v2.14.1 \  | 
检查部署结果
查看Pod状态
1  | kubectl -n kube-system get pod -l app=helm,name=tiller  | 
输出示例
1  | NAME READY STATUS RESTARTS AGE  | 
查看Helm版本信息
1  | helm version  | 
输出示例
1  | Client: &version.Version{SemVer:"v2.14.1", GitCommit:"d325d2a9c179b33af1a024cdb5a4472b6288016a", GitTreeState:"clean"}  | 
部署local-volume-provisioner
下载项目代码
1  | git clone --depth=1 https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner.git  | 
修改配置
1  | vim sig-storage-local-static-provisioner/helm/provisioner/value.yaml  | 
修改如下
1  | #  | 
生成YAML文件
1  | helm template sig-storage-local-static-provisioner/helm/provisioner \  | 
部署YAML文件
1  | kubectl apply -f local-volume-provisioner.generated.yaml  | 
查看provisioner
1  | kubectl -n kube-system get pod -l app=local-volume-provisioner  | 
输出示例
1  | NAME READY STATUS RESTARTS AGE  | 
验证本地PV
查看PersistentVolume
1  | kubectl get pv  | 
输出示例
1  | NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE  | 
查看StorageClass
1  | kubectl get sc  | 
输出示例
1  | NAME PROVISIONER AGE  | 
部署StatefulSet
1  | vim localpv-sts.yaml  | 
内容如下
1  | apiVersion: apps/v1  | 
查看PV
1  | kubectl get pv  | 
输出示例
1  | NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE  | 
查看PVC
1  | kubectl get pvc  | 
输出示例
1  | local-vol-local-test-0 Bound local-pv-6e9321fd 4911Mi RWO local-storage 2m27s  | 
清理现场
删除StatefulSet
1  | kubectl delete -f localpv-sts.yaml  | 
删除pvc
1  | kubectl delete pvc local-vol-local-test-0  | 
删除pv
1  | kubectl delete pv local-pv-6e9321fd  | 
清理本地目录
1  | ssh root@k8s-node1 "rm -rf /mnt/disks/9e0ead5f-ca8e-4018-98ad-960979d9cb26/*"  |