Kubernetes中的PV和PVC是啥

K8S引入了一组叫做Persistent Volume Claim(PVC)和Persistent Volume(PV)的API对象,大大下降了用户声明和使用持久化Volume的门槛。
在Pod的Volumes中,只要声明类型是persistentVolumeClaim,指定PVC的名字,当建立这个PVC对象,k8s就自动为它绑定一个符合条件的Volume,这个Volume,从PV来html

PVC和PV的设计,相似“接口”和“实现”的思想,开发者只知道使用“接口”PVC,运维人员负责给“接口”绑定具体的实现PV,说白了PVC就是一种特殊的Volumenode

PVC和PV的实现原理
PVC:描述 Pod想要使用的持久化属性,好比存储大小、读写权限等
PV:描述一个具体的Volume属性,好比Volume的类型、挂载目录、远程存储服务器地址等
StorageClass:充当PV的模板,自动为PVC建立PV
nginx

1、关于PV建立的流程

大多数状况,持久化Volume的实现,依赖于远程存储服务,如远程文件存储(NFS、GlusterFS)、远程块存储(公有云提供的远程磁盘)等。
K8s须要使用这些存储服务,来为容器准备一个持久化的宿主机目录,以供之后挂载使用,建立这个目录分为两阶段:ubuntu

1.建立一个远程块存储,至关于建立了一个磁盘,称为Attach

由Volume Controller负责维护,不断地检查 每一个Pod对应的PV和所在的宿主机的挂载状况。能够理解为建立了一块NFS磁盘,至关于执行api

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

为了使用这块磁盘,还须要挂载操做服务器

2.将这个磁盘设备挂载到宿主机的挂载点,称为Mount

将远程磁盘挂载到宿主机上,发生在Pod对应的宿主机上,是kubelet组件一部分,利用goroutine执行,不会阻塞主我看一下
至关于执行运维

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

经过这个挂载操做,Volume的宿主机目录就成为了一个远程NFS目录的挂载点,之后写入的全部文件,都会被保存在NFS服务器上
若是是已经有NFS磁盘,第一步能够省略.ui

一样,删除PV的时候,也须要Umount和Dettach两个阶段处理spa

2、PV、PVC使用示例

1.建立PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: cqh
  labels:
    cqh: chenqionghe
spec:
  capacity:
    storage: 100Mi
  volumeMode: Filesystem
  accessModes: ["ReadWriteMany"]
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /data/pv
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: cqh
          operator: In
          values:
          - chenqionghe

建立后查看设计

root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM         STORAGECLASS    REASON    AGE
cqh       100Mi      RWX            Delete           Bound     default/cqh   local-storage             4m

2.建立PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: cqh
spec:
  storageClassName: local-storage
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 100Mi
  selector:
    matchLabels:
      cqh: chenqionghe

AccessModes为ReadWriteMany,表示这个Volume是可读写的,而且能挂载在多个节点上(官方支持的AccessMode)

执行建立后查看

root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS    AGE
cqh       Bound     cqh       100Mi      RWX            local-storage   4m

3.建立Pod,使用PVC

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

建立后查看

NAME                    READY     STATUS    RESTARTS   AGE       IP            NODE            NOMINATED NODE
cqh                     1/1       Running   0          4m        10.244.0.46   vm-0-8-ubuntu   <none>
root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl describe po cqh
Name:               cqh
Namespace:          default
...
Volumes:
  pv-storage:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  cqh
    ReadOnly:   false
  default-token-gqfrx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-gqfrx
    Optional:    false
...
Events:
  Type    Reason     Age   From                    Message
  ----    ------     ----  ----                    -------
  Normal  Scheduled  4m    default-scheduler       Successfully assigned default/cqh to vm-0-8-ubuntu
  Normal  Pulling    4m    kubelet, vm-0-8-ubuntu  pulling image "nginx"
  Normal  Pulled     4m    kubelet, vm-0-8-ubuntu  Successfully pulled image "nginx"
  Normal  Created    4m    kubelet, vm-0-8-ubuntu  Created container
  Normal  Started    4m    kubelet, vm-0-8-ubuntu  Started container

总结

  1. PVC和PV至关于面向对象的接口和实现
  2. 用户建立的Pod声明了PVC,K8S会找一个PV配对,若是没有PV,就去找对应的StorageClass,帮它建立一个PV,而后和PVC完成绑定
  3. 新建立的PV,要通过Master节点Attach为宿主机建立远程磁盘,再通过每一个节点kubelet组件把Attach的远程磁盘Mount到宿主机目录
相关文章
相关标签/搜索