「Kubernetes」- PersistentVolume, PersistentVolumeClaim

  CREATED BY JENKINSBOT

解决方案

PV + PVC 是我们早期最常用的方法,也是我们入门时学习使用的数据持久化方法。

使用步骤如下:
1)PV 非命名空间资源,因此需要集群管理员定义 PV 资源,它是对存储的抽象。
2)然后,开发者通过 PVC 资源来引用该 PV 资源,
3)最后,在 Pod 的 Volumes 中引用 PVC 资源。

注意事项:
1)如果使用 PVC 资源,则必须定义 PV 资源。
2)PVC 与 PV 是对应绑定的。如果已经有 PVC 绑定到 PV 对象,则其他 PVC 对象不能再绑定到该 PV 对象。
3)虽然 PV 不能共享,但是多个 POD 能够绑定到同个 PVC 以实现存储空间共享。

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

---
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

问题:重新使用 PV(已使用且释放)

A private cloud – all for myself » How to reuse a PersistentVolume/PV in Kubernetes

如果 PV 已经使用(已被 PVC 引用),即使删除 PVC 以后,也无法再继续使用该 PV 资源。

解决方法:
1)首先,修改 PV/persistentVolumeReclaimPolicy 为 Retain 以保存数据;
2)然后,删除 PVC/POD 资源,查看 PV 状态,应为 Released 状态;
3)最后,删除 PV/claimRef 属性,此时 PV 状态应为 Avaiable 状态;

问题:将 PVC 资源绑定特定 PV 资源

kubernetes – Can a PVC be bound to a specific PV? – Stack Overflow
Using Persistent Volumes | Developer Guide | OpenShift Container Platform 3.11

通常 PVC 所使用的 PV 是按需绑定的,由调度器负责分配。

但是,我们可以配置 PVC 资源绑定到特定 PV 资源,这需要我们同时设置 pvc/volumeName 以及 pv/claimRef 属性:
1)单纯设置 PVC/volumeName 不能防止 PV 被其他 PVC“抢占”;
2)单纯设置 PV/claimRef 不能防止 PVC 被绑定到其他 PV 资源;

如下示例 YAML 配置文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-storage-share
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  claimRef:
    name: nfs-storage-share
    namespace: default
  nfs:
    server: "ip address of the nfs server"
    path: "/"
---
apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
  name: "nfs-storage-share"
  namespace: default
spec:
  accessModes:
    - "ReadWriteOnce"
  resources:
    requests:
      storage: "50Gi"
  volumeName: "nfs-storage-share"

with Minikube

持久化数据存储:Persistent Volume

创建hostPath类型的PV,并以挂载普通卷的方式将PV挂载到容器的文件系统内。分为两步:

	(1)管理员创建PV对象;
	(2)开发者创建PVC对象;

(1)管理员创建PV对象:

kind: PersistentVolume
apiVerion: v1
metadatda:
  name: hostpathpv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp/data"

# 当然,前提是这个目录是存在的。

(2)开发者创建PVC对象,来使用空间:

# 如果要使用PV,则要先进行PVC定义,声明要使用某个持久卷
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resource:
    request:
      # 申请200Mi空间
      strage: 200Mi

kubectl create -f pvc.yaml
kubectl get pv # 来查看状态

(3)在容器中使用该卷:

# ...
volume:
  - name: pvc-claim
    persistentVolumeClaim:
      claimName: mypvc

!!!这个案例中使用了hostPath类型的PV,生成环境中不建议使用。应该定义NFS或者Amazon ElasticBlockStore支持的网络卷。

!!!PV是集群内的资源,没有命名空间。而PVC则是命名空间内的资源。

接下来,要掌握Minikube上的数据存储。部署一个有状态的应用程序,例如MySQL集群。

使用PVC申请空间:

# data.yaml
kind: PersistentVolumnClaim
apiVersion: v1
metadata:
  name: data
spec:
  accessModes:
    - ReadWriteOnce
  resource:
    requests:
      storage: 1Gi

然后创建该PVC:kubctl create -f data.yaml
查看状态:kubectl get pv

接下来就是在Pod中使用该PVC:

kind: Pod
apiVersion: v1
metadata:
  name: db
spec:
  container:
    - name: mysql
      image: mysql:5.5
      volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
      env:
        - name: MySQL_ROOT_PATH
          value: root
  volumns:
    - name: data
      persistentVolumeClaim:
        claimName: data

参考文献

Configure a Pod to Use a PersistentVolume for Storage | Kubernetes