Kubernetes 学习笔记之 PV 与 PVC 的建立引用

简介

PersistentVolume(PV)是 K8S 集群中由管理员配置的一段网络存储。 它是集群中的资源,就像节点是集群资源同样。 PV 是容量插件,如 Volumes,但其生命周期独立于使用 PV 的任何单个 Pod。 此 API 对象捕获存储实现的详细信息,包括 NFS,iSCSI 或特定于云提供程序的存储系统。
PersistentVolumeClaim(PVC)是 K8S 中由用户进行存储的请求。 它相似于 Pod。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 能够请求特定级别的资源(CPU和内存)。声明能够请求特定的大小和访问模式(例如,能够一次读/写或屡次只读)。
经过 storageClassName 参数来指定使用对应名字的 StorageClass,也就是 PVC 与 PV 具备相同的storageClassName,PVC 才能绑定到这个对应的 PV。PVC 能够不指定storageClassName,或者将该值设置为空,若是打开了准入控制插件,而且指定一个默认的 StorageClass,则 PVC 会使用默认的 StorageClass,不然就绑定到没有 StorageClass 的 PV 上。node

Kubernetes 学习笔记之 PV 与 PVC 的建立引用

生命周期

PV 是 K8S 群集中的资源。PVC 是对这些资源的请求,而且还充当对资源的检查。PV 和 PVC 之间的相互做用遵循如下生命周期:nginx

Provisioning ——> Binding ——> Using ——> Releasing ——> Recyclingdocker

  • 供应准备 Provisioning:经过集群外的存储系统或者云平台来提供存储持久化支持。
    • 静态提供 Static:集群管理员建立多个 PV。 它们携带可供集群用户使用的真实存储的详细信息。 它们存在于 Kubernetes API 中,可用于消费。
    • 动态提供 Dynamic:当管理员建立的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试动态地为 PVC 建立卷。此配置基于 StorageClasses:PVC 必须请求存储类,而且管理员必须建立并配置该类才能进行动态建立。声明该类为 “” 能够有效地禁用其动态配置。
  • 绑定 Binding:用户建立 PVC 并指定须要的资源和访问模式。在找到可用 PV 以前,PVC 会保持未绑定状态。
  • 使用 Using:用户可在 Pod 中像 Volume 同样使用 PVC。
  • 释放 Releasing:用户删除 PVC 来回收存储资源,PV 将变成 released 状态。因为还保留着以前的数据,这些数据须要根据不一样的策略来处理,不然这些存储资源没法被其余 PVC 使用。
  • 回收 Recycling—PV 能够设置三种回收策略:保留(Retain)、回收(Recycle)、删除(Delete)。
    • 保留策略:容许人工处理保留的数据。
    • 删除策略:将删除 PV 和外部关联的存储资源,须要插件支持。
    • 回收策略:将执行清除操做,以后能够被新的 PVC 使用,须要插件支持。

注:目前只有 NFS 和 HostPath 类型卷支持回收策略,AWS EBS、GCE PD、Azure Disk、Cinder 支持删除 (Delete) 策略。vim

环境信息

# kubectl get nodes -o wide
NAME     STATUS   ROLES    AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME
test01   Ready    master   17d   v1.14.0   192.168.127.133           CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://18.9.3
test02   Ready             17d   v1.14.0   192.168.127.135           CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://18.9.3

PV 支持的类型不少,好比:RBD、CephFS、Glusterfs、NFS 等,这里使用 nfs 类型的 PV,并使用 Job 对象来验证 PV 建立以及 PVC 资源的申请与绑定。api

实践操做

  1. 在 K8S master(192.168.127.133)上准备 nfs 服务器,用于提供存储。
    # yum install nfs-utils rpcbind -y
    # mkdir -p /data/nfs
    # vim /etc/exports
    /data/nfs *(rw,sync)
    # systemctl start nfs-server.service

并在 K8S node 上安装 nfs 客户端:
# yum install nfs-utils -y服务器

  1. 使用如下配置建立 PV 存储。
    编辑 PV 资源的配置文件:
    # cat pv_nfs.yml 
    apiVersion: v1
    kind: PersistentVolume
    metadata:
    name: nfspv1
    spec:
    # 指定 PV 的容量为1Gi
    capacity:
    storage: 1Gi
    # 指定访问模式
    accessModes:
    # PV 能以 readwrite 模式 mount 到单个节点
    - ReadWriteOnce
    # 指定 PV 的回收策略,即 PVC 资源释放后的事件,recycle (不建议,使用动态供给代替)删除 PVC 的全部文件
    persistentVolumeReclaimPolicy: Recycle
    # 指定 PV 的 class 为 mynfs,至关于为 PV 分类,PVC 将指定 class 申请 PV
    storageClassName: mynfs
    # 指定 PV 为 nfs 服务器上对应的目录
    nfs:
    path: /data/nfs
    server: 192.168.127.133

应用 PV 配置:网络

# kubectl apply -f pv_nfs.yml
persistentvolume/nfspv1 created

查看 PV 资源:app

# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
nfspv1   1Gi        RWO            Recycle          Available
  1. 使用如下配置建立 PVC,经过指定 storageClassName 名称与指定 PV 进行绑定。
    编辑 PVC 资源配置文件:
    # cat pvc_nfs.yml 
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: nfspvc1
    spec:
    accessModes:
    - ReadWriteOnce
    resources:
    requests:
      storage: 1Gi
    storageClassName: mynfs

应用 PVC 配置:ide

# kubectl apply -f pvc_nfs.yml
persistentvolumeclaim/nfspvc1 created

查看 PVC 资源,经过下面的结果能够看到 nfspvc1 已经与 PV 为 nfspv1 绑定:学习

# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nfspvc1   Bound    nfspv1   1Gi        RWO            mynfs          25s
</pre>
  1. 使用如下配置建立 Job,使用 PVC 存储。
    编辑应用资源配置文件:
    # cat pvjob.yml
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: pvjob
    spec:
    template:
    spec:
      containers:
      - name: bbox1
        image: busybox
        command: ["/bin/sh","-c","echo 'hello pv' > /mydata/hello"]
        volumeMounts:
        - mountPath: "/mydata"
          name: mydata
      restartPolicy: Never
      volumes:
      - name: mydata
        persistentVolumeClaim:
          claimName: nfspvc1

    该 job 将在 nfs 的 volume 建立一个 hello 文件,打印 hello pv 字符串。

应用该 Job 配置文件:

# kubectl apply -f pvjob.yml
job.batch/pvjob created

确认容器状态是 Completed 状态:

# kubectl get pod -o wide
NAME                            READY   STATUS      RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
deploy-nginx-684b85cd79-kv5sg   1/1     Running     2          10d   10.244.1.14   test02              
pvjob-gljl7                     0/1     Completed   0          39s   10.244.1.33   test02

确认 master 上 nfs 的 /data/nfs 目录,检查实验结果:

# cat /data/nfs/hello 
hello pv

排错

在此次实验中出现了几个错误:

  1. 使用 PVC 存储的 Pod 一直处于 pending 状态,没法启动,经过命令 kubectl describe pod podname 查看对应报错的 Pod 的信息,部分报错信息以下:

    # dmesg | tail or so.
    Warning  FailedMount  118s  kubelet, test02  MountVolume.SetUp failed for volume "nfspv1" : mount failed: exit status 32
    Mounting command: systemd-run
    Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/d25895f2-8220-11e9-820c-000c295ab742/volumes/kubernetes.io~nfs/nfspv1 --scope -- mount -t nfs 192.168.127.133:/data/nfs /var/lib/kubelet/pods/d25895f2-8220-11e9-820c-000c295ab742/volumes/kubernetes.io~nfs/nfspv1
    Output: Running scope as unit run-15184.scope.
    mount: wrong fs type, bad option, bad superblock on 192.168.127.133:/data/nfs,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount. helper program

    注意到报错信息:wrong fs type, bad option, bad superblock on 192.168.127.133:/data/nfs,若是没有安装 nfs-utils 软件包,没法识别 nfs 类型的文件系统,也没法做为 nfs 的客户端使用。
    解决方案:
    安装 nfs-utils 软件包,删除以前建立失败的 Job 资源并从新建立。

  2. 若是 Pod 状态是 Error 的:
    # kubectl get pod -o wide
    NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
    deploy-nginx-684b85cd79-kv5sg   1/1     Running   2          10d     10.244.1.14   test02              
    pvjob-4dp29                     0/1     Error     0          3m10s   10.244.1.35   test02              
    pvjob-f6lpp                     0/1     Error     0          2m33s   10.244.1.37   test02              
    pvjob-l8q6z                     0/1     Error     0          2m13s   10.244.1.38   test02              
    pvjob-qbxx6                     0/1     Error     0          53s     10.244.1.39   test02              
    pvjob-zcx6l                     0/1     Error     0          2m56s   10.244.1.36   test02

    经过查看执行失败 Pod 的 log 日志,发现是容器没有权限写文件到挂载的 nfs 目录中:

    # kubectl logs pvjob-4dp29
    /bin/sh: can't create /mydata/hello: Permission denied

    解决方案:
    Permission denied 多见于普通用户执行高权限命令失败,不过 busybox 容器自己使用的就是 root 用户,所以不存在这个问题。在 nfs 中,nfs 服务端没有权限访问挂载的目录也会致使这个问题。

更改目录属主为 nfsnobody:
# chown nfsnobody /data/nfs

删除原来 Job 并从新建立后,Job 就能执行成功:

# kubectl delete -f pvjob.yml
# kubectl apply -f pvjob.yml
# kubectl get pod -o wide
NAME                            READY   STATUS      RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
deploy-nginx-684b85cd79-kv5sg   1/1     Running     2          10d   10.244.1.14   test02              
pvjob-gljl7                     0/1     Completed   0          39s   10.244.1.33   test02
相关文章
相关标签/搜索