前言:

参考k8s教程由浅入深(哔哩哔哩课程)  深入剖析Kubernetes(极客时间)

一、nfs网络存储

部署步骤:

1.在一台服务器上安装nfs

yaml install -y nfs-utils

设置挂载目录

vi /etc/export

[路径](例如:/data/nfs) *[代表所有内容](rw,no_root_squash)

2.启动nfs

systemctl start nfs

3.在k8s集群的node结点上也安装上k8s

 

二.在k8s上部署持久化网络存储

方案1:不使用pv/pvc在deployment中使用nfs

(1) 部署deployment

(2)暴露k8s端口

kubectl expose deployment [deployment名称] --port=80 --target-port=80 --type NodePort

方案2:使用pv/pvc

定义:

pv:持久化存储,对存储资源进行抽象,对外提供可以调用的地方(类似于接口)

pvc:用于调用,不需要关心内部实现细节(类似于实现)

(1).定义pv

(2).定义pvc与应用

 

三、原理

1.再谈pv/pvc

PV:描述持久化数据卷。这个 API 对象主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。

PVC:由开发人员创建,或者以PVC模板的方式成为StatefulSet的一部分,然后由StatefulSet控制器负责创建带编号的PVC。

2.PV与PVC绑定

PVC需要和PV绑定之后才可以被使用。绑定时需要检查

  • PVC和PV的spec字段。如PV的storage大小需要满足PVC要求
  • PV和PVC的storageClassName字段必须一样
  • 例子如下

PVC和PV的绑定:将这个PV对象名字填入PVC的spec.volumeName字段,kubelet只要获得PVC对象,就能找到它绑定的PV。

PV转变为容器的持久化存储过程:

  • 容器的Volume:将一个宿主机上的目录跟容器里的目录绑定挂载在一起
  • 持久化 Volume:宿主机上的volume宿主机上的目录具有持久性,其实现通常需要使用远程存储

持久化宿主机目录---两阶段处理:

一个pod调度到一个节点之后,kubectl就会负载为pod创建他的Volume目录。默认情况下,kubelet为Volume创建的目录是如下所示的一个宿主机的路径

/var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>

若Volume是远程块存储:

1).kubelet需要先调用远程API,将它提供的Persistent Disk挂载到pod所在的宿主机上。(attach阶段,此阶段可用参数为nodeName/宿主机名称)

相当于执行

gcloud compute instances attach-disk <虚拟机名字> --disk <远程磁盘名字>

2).格式化远程磁盘,并挂载到宿主机指定挂载点(Mount,此阶段可用参数为dir/宿主机目录)

相当于执行

# 通过lsblk命令获取磁盘设备ID
$ sudo lsblk
# 格式化成ext4格式
$ sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/<磁盘设备ID>
# 挂载到挂载点
$ sudo mkdir -p /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>

若为nfs:

nfs跳过第一阶段,直接执行mount,相当于执行

$ mount -t nfs <NFS服务器地址>:/ /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字> 

接下来,kubelet只需要把volume目录通过CRI里的Mounts参数,传递给docker,就可以为Pod里的容器挂载这个持久化的Volume了。

相当于执行了

$ docker run -v /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume类型>/<Volume名字>:/<容器内的目标目录> 我的镜像 ...

关于 PV 的“两阶段处理”流程,是靠独立于 kubelet 主控制循环(Kubelet Sync Loop)之外的两个控制循环来实现的.

attach阶段由Volume Controller负责维护,控制循环的名称为AttachDetachController。

mount阶段必须发生在pod所在宿主机上,所以必须是kubelet组件的一部分。此阶段控制循环名称:VolumeManagerReconciler。它是独立于主循环的goroutine

3. Volume Controller

作用:专门处理持久化存储的控制器,维护多个控制循环

运行结点:Volume Controller属于kube-controller-manage一部分,运行在master上

PersistentVolumeController :Volume Controller多个控制循环中的一个,会不断查看每一个PVC是不是已经Bound,如果不是,就遍历所有可用的PV,尝试进行绑定。

AttachDetachController:不断检查每一个pod的PV,和这个Pod所在宿主机之间挂载情况,从而决定是否需要对这个PV进行attach(或dettach)操作

4.StorageClass 对象(详情查看https://blog.csdn.net/bbwangj/article/details/82355357)

背景:PV需要手动创建,当PVC数量很多时,十分不方便。因此,Kubernetes提供Dynamic Provisioning以自动创建 PV 的机制。

StorageClass 对象的作用:创建PV模板

StorageClass 对象的定义:

1).PV的属性(存储类型、Volume大小)

2).创建PV需要用到的存储插件(Ceph)

在定义了对象后,k8s就能根据用户提交的PVC找到一个对应的StorageClass,然后k8s调用该StorageClass声明的存储插件,创建出需要的PV

部署步骤:

1).部署storageClass

# storageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: block-service
provisioner: kubernetes.io/gce-pd #Kubernetes 内置的 GCE PD 存储插件的名字
parameters:
  type: pd-ssd # PV 的参数。比如:type=pd-ssd,指的是这个 PV 的类型是“SSD 格式的 GCE 远程磁盘”

2).在PVC中指定StorageClass 名字

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim1
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: block-service #指定storageClass名字
  resources:
    requests:
      storage: 30Gi

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐