theboyaply

学,就硬学!

  • Home
  • Archives
  • Java
  • Maven
  • Docker
  • Kubernetes
  • JavaScript
  • ES6
  • Vue
  • 踩坑记录
  • noted

  • 搜索
element ui vue wsimport webservice npm mysql redis node nginx nfs ftp es6 开发工具 vscode 前端 javascript springboot 常见问题 tomcat oracle jenkins maven k8s Linux gitlab docker java

k8s PV和PVC

发表于 2020-04-01 | 分类于 Kubernetes | 2 | 阅读次数 587
  • 概述
  • 生命周期
  • PV 类型
  • PV 示例
    • capacity
    • volumeMode
    • accessModes
    • storageClassName
    • persistentVolumeReclaimPolicy
    • mountOptions
  • PVC 示例
    • accessModes
    • volumeMode
    • resources
    • selector
    • storageClassName
  • 示例 - NFS
    • 安装 NFS
    • 创建 PV
    • 创建 Pod 和 PVC

参考:

https://www.kubernetes.org.cn/pvpvcstorageclass

https://kubernetes.io/docs/concepts/storage/persistent-volumes/

概述

PersistentVolume(PV)和 PersistentVolumeClaim(PVC)提供了方便的持久化卷:PV 提供网络存储资源,而 PVC 请求存储资源。这样,设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建 PVC 来将 Pod 跟数据卷关联起来。PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。

生命周期

PV 是集群中的资源。PVC 是对这些资源的请求,也是对资源的索赔检查。PV 和 PVC 之间的相互作用遵循以下生命周期:

Provisioning ---> Binding ---> Using ---> Releasing ---> Recycling

  • Provisioning:创建 PV。

    • Static:集群管理员创建多个 PV。它们携带可供集群用户使用的真实存储的详细信息。它们存在于 Kubernetes API 中,可用于消费。
    • Dynamic:当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试为 PVC 动态配置卷。此配置基于 StorageClasses:PVC 必须请求一个类,并且管理员必须已创建并配置该类才能进行动态配置。要求该类的声明有效地为自己禁用动态配置。
  • Binding:将 PV 分配给 PVC。如果匹配的卷不存在,PVC 将保持无限期。 随着匹配卷变得可用,PVC 将被绑定。 例如,提供许多 50Gi PV 的集群将不匹配要求 100Gi的PVC。 当集群中添加 100Gi PV 时,可以绑定 PVC。

    值得注意的是,PV 与 PVC 是一对一绑定的。

  • Using:Pod 使用 PVC 作为卷。 集群检查声明以找到绑定的卷并挂载该卷的卷。 对于支持多种访问模式的卷,用户在将其声明用作 Pod 中的卷时指定所需的模式。

  • Releasing:Pod 释放 Volume 并删除 PVC。当用户完成卷时,他们可以从允许资源回收的 API 中删除 PVC 对象。 当 PVC 被删除时,PV 被认为是“释放的”,但是它不能被其它 PVC 使用。 Pod 数据仍然保留在 PV 中。

  • Reclaiming:回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除。删除 PV 将从集群中删除PV 对象,以及删除外部基础架构(如 AWS EBS,GCE PD,Azure Disk 或 Cinder 卷)中关联的存储资产。 动态配置的卷始终被删除。

PV 类型

PersistentVolume 类型作为插件实现。Kubernetes 当前支持以下插件:

  • GCEPersistentDisk、AWSElasticBlockStore、AzureFile、AzureDisk、CSI、FC (Fibre Channel)

  • FlexVolume、Flocker、NFS、iSCSI、RBD (Ceph Block Device)、CephFS、Cinder (OpenStack block storage)

  • Glusterfs、VsphereVolume、Quobyte Volumes、Portworx Volumes、ScaleIO Volumes、StorageOS

  • HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)

PV 示例

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

capacity

storage 指定了 PV 的容量大小。

当前,存储大小是可以设置或请求的唯一资源。 将来的属性可能包括IOPS,吞吐量等。

volumeMode

文件系统类型,有两种类型:Filesystem 和 Block。这是一个可选的参数,默认为 Filesystem。

如果使用的是 Filesystem,那么在创建 Pod 时会将挂载的卷嵌入到 Pod 的文件目录中。

如果使用的是 Block,此模式对于为 Pod 提供最快的访问卷的方式很有用,而 Pod 和卷之间没有任何文件系统层。

accessModes

主机挂载 PV 的关系,这是一个集合属性,即可以在一个 PV 里面声明多个。PVC 的 accessModes 必须和 PV 的 accessModes 一样或者是 PV 的子集才能够绑定到。

  • ReadWriteOnce – 只能在一个节点中挂载,能够读写。
  • ReadOnlyMany – 能够在多个节点挂载,只能读。
  • ReadWriteMany – 能够在多个节点挂载,能够读写。

storageClassName

为 PV 声明一个类名。PVC 的 storageClassName 必须和这个一致。但是 PV 和 PVC 都可以不设置这个值而使用默认的类名。

persistentVolumeReclaimPolicy

回收策略。Retain、Delete 和 Recycle。默认为 Delete。

  • Retain:保留。删除 PVC 后,PV 仍然存在,并且该 PV 被视为”已释放“。这时 PV 不能再被其它对象绑定,并且数据以然存在该 PV 中。

    通常删除一个 PV 的步骤如下:

    1. 删除 PV,但是与之关联的外部基础架构(如 AWS EBS,GCE PD,Azure Disk 或 Cinder 卷)数据仍然存在。
    2. 手动清理外部基础架构数据。
    3. 手动删除外部基础架构。如果要重复使用这个 PV,请重新创建一个。
  • Delete:删除(rm -rf /thevolume/*)。

    从集群中删除 PV 对象以及外部基础架构中的关联存储资产,例如 AWS EBS,GCE PD,Azure Disk 或Cinder 卷。动态预配置的卷将继承其 StorageClass 的回收策略。管理员应根据用户的期望配置 StorageClass。否则,PV 必须在创建后进行编辑或打补丁。

  • Recycle:回收。不推荐使用此策略。相反,推荐的方法是使用动态配置。

mountOptions

安装选项。安装选项是一个字符串,在将卷安装到磁盘时将被累积地连接和使用。当 PV 被创建在某一节点时,管理可以指定额外的安装选项。

值得注意的是并非所有的 PV 类型都支持这个。

如果该选项没有经过验证,那么挂载将会失败。

PVC 示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

accessModes

必须和 PV 的 accessModes 一样或者是 PV 的子集。

volumeMode

必须和 PV 的 volumeMode 一样。

resources

声明(如pod)可以请求的资源大小。 PVC 会自动去寻找合适大小的 PV 进行匹配。

selector

可以指定标签选择器以进一步过滤 PV。 只有标签与选择器匹配的 PV 才能绑定到 PVC。 选择器可以由两个字段组成:

  • matchLabels:PV 必须带有这个标签和值。
  • matchExpressions:通过指定关键字和值的关键字,值列表和运算符所做的要求列表。 有效运算符包括 In,NotIn,Exists 和 DoesNotExist。

storageClassName

必须和 PV 的 storageClassName 一样。PV 与 PVC 都没有这个属性。

示例 - NFS

安装 NFS

我们在 harbor 私有仓库这个机器上安装 nfs 服务,IP 地址为:192.168.19.170:

# 安装 nfs 服务及相关工具
[root@hub ~]# yum install -y nfs-common nfs-utils rpcbind
已加载插件:fastestmirror
Determining fastest mirrors
 * base: mirrors.nju.edu.cn
 * extras: mirrors.njupt.edu.cn
 * updates: mirrors.njupt.edu.cn
 ......
完毕!

# 创建4个共享文件夹
[root@hub ~]# mkdir /nfs1 /nfs2 /nfs3 /nfs4
[root@hub ~]# chmod 777 /nfs1 /nfs2 /nfs3 /nfs4
[root@hub ~]# chown nfsnobody /nfs1 /nfs2 /nfs3 /nfs4

[root@hub ~]# vim /etc/exports
/nfs1 *(rw,no_root_squash,no_all_squash,sync)
/nfs2 *(rw,no_root_squash,no_all_squash,sync)
/nfs3 *(rw,no_root_squash,no_all_squash,sync)
/nfs4 *(rw,no_root_squash,no_all_squash,sync)

[root@hub ~]# systemctl start rpcbind
[root@hub ~]# systemctl start nfs

在集群中所有节点安装 nfs 客户端:

yum install -y nfs-utils rpcbind

安装完成后在集群任一节点测试挂载 nfs 文件系统:

# 测试连接 nfs,结果显示了 nfs 服务器的可挂载目录
[root@k8s-master01 testnfs]# showmount -e 192.168.19.170
Export list for 192.168.19.170:
/nfs4 *
/nfs3 *
/nfs2 *
/nfs1 *

[root@k8s-master01 ~]# pwd
/root
[root@k8s-master01 ~]# mkdir nfs2

# 将本地 /root/nfs2/ 目录挂载到 nfs2 服务器目录
[root@k8s-master01 testnfs]# mount -t nfs 192.168.19.170:/nfs2 /root/nfs2/
[root@k8s-master01 ~]# cd nfs2/
[root@k8s-master01 testnfs]# touch test.txt
[root@k8s-master01 testnfs]# ls
test.txt

# 此时 192.168.19.170 机器上的 /nfs2 目录可以看到 test.txt 这个文件

# 退出连接
[root@k8s-master01 testnfs]# umount -l /root/nfs2/

错误排查:

如果执行命令 showmount -e 192.168.19.170 提示: clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host),可以关掉 nfs 服务器的防火墙(systemctl status firewalld),或者开启某些端口(自行网上搜索下)。

创建 PV

编写资源清单 nfs1-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs1-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: "nfs"
  nfs:
    path: /nfs1
    server: 192.168.19.170

然后再依此编写 nfs2-pv.yaml、nfs3-pv.yaml、nfs4-pv.yaml,基本信息一致,除了以下几点:

  • nfs2-pv.yaml
    • metadata.name: nfs2-pv
    • spec.capacity: 4Gi
    • spec.nfs.path: /nfs2
  • nfs3-pv.yaml
    • metadata.name: nfs3-pv
    • spec.capacity: 7Gi
    • spec.nfs.path: /nfs3
  • nfs4-pv.yaml
    • metadata.name: nfs4-pv
    • spec.capacity: 10Gi
    • spec.nfs.path: /nfs4

这里创建多个 PV 的目的是为了验证 PVC 可以根据容量大小自动选择合适的 PV。

创建 PV:

[root@k8s-master01 pv]# kubectl apply -f nfs1-pv.yaml 
persistentvolume/nfs1-pv created

[root@k8s-master01 pv]# kubectl apply -f nfs2-pv.yaml 
persistentvolume/nfs2-pv created

[root@k8s-master01 pv]# kubectl apply -f nfs3-pv.yaml 
persistentvolume/nfs3-pv created

[root@k8s-master01 pv]# kubectl apply -f nfs4-pv.yaml 
persistentvolume/nfs4-pv created

[root@k8s-master01 pv]# kubectl get pv -o wide
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
nfs1-pv   1Gi        RWO            Recycle          Available           nfs                     51s   Filesystem
nfs2-pv   4Gi        RWO            Recycle          Available           nfs                     47s   Filesystem
nfs3-pv   7Gi        RWO            Recycle          Available           nfs                     43s   Filesystem
nfs4-pv   10Gi       RWO            Recycle          Available           nfs                     40s   Filesystem

加上 -o wide 参数,会多显示 VOLUMEMODE 字段,你会发现,默认的 VOLUMEMODE 是 Filesystem。

上面显示所有 PV 都是 Available 的,即未绑定状态。

创建 Pod 和 PVC

编写资源清单 nfs-pvc-pod.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx-app
spec:
  ports:
  - port: 80
    name: web
  clusterIP: "None"
  selector:
    app: nginx-app
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  replicas: 1
  serviceName: "nginx-app"
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx-container
        image: hub.xixihaha.com/library/mynginx:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: pvc-volume
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: pvc-volume
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 6Gi

上面是使用 volumeClaimTemplates 创建的 PVC,这种方式会每次都创建一个新的 pvc,即有几个 Pod 就会有几个 pvc。

因此个人建议,将 PVC 单独拿出来创建。这样的话,创建的这个 pvc 能够同时被多个 Pod 绑定:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-volume
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: "nfs"
  resources:
    requests:
      storage: 6Gi

如果是单独创建的 PVC,那么我们可以在 Pod 里这样配置它:

# 部分配置
metadata:
  labels:
    app: nginx-app
spec:
  containers:
  - name: nginx-container
    image: hub.xixihaha.com/library/mynginx:v1
    ports:
    - containerPort: 80
      name: web
    volumeMounts:
    - name: pvc-volume
       mountPath: /usr/share/nginx/html
  volumes:
  - name: pvc-volume
    persistentVolumeClaim:
      claimName: pvc-volume

创建 Pod 及 PVC(pvc 使用 volumeClaimTemplates 一并创建):

[root@k8s-master01 pv]# kubectl apply -f nfs-pvc-pod.yaml 
service/nginx-svc created
statefulset.apps/web created

查看此时的 pvc、pv 以及 pod:

[root@k8s-master01 pv]# kubectl get pvc
NAME               STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-volume-web-0   Bound    nfs3-pv   7Gi        RWO            nfs            8s

[root@k8s-master01 pv]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                      STORAGECLASS   REASON   AGE
nfs1-pv   1Gi        RWO            Recycle          Available                              nfs                     88s
nfs2-pv   4Gi        RWO            Recycle          Available                              nfs                     84s
nfs3-pv   7Gi        RWO            Recycle          Bound       default/pvc-volume-web-0   nfs                     80s
nfs4-pv   10Gi       RWO            Recycle          Available                              nfs                     77s

[root@k8s-master01 pv]# kubectl get pod
NAME                   READY   STATUS      RESTARTS   AGE
web-0                  1/1     Running     0          3m13s

从结果看到,pvc 绑定到了 nfs3-pv 上面。因为它的大小 7Gi 更适合 pvc 的 6Gi。

因为指定了 pvc 的 accessModes 为 ReadWriteOnce,即一个 pvc 只能被一个 pod 绑定,所以现在我们验证一下。

我们将 statefulSet 扩容到 2 个 Pod,然后查看 pvc 的绑定情况:

[root@k8s-master01 pv]# kubectl scale statefulSet web --replicas 2
statefulset.apps/web scaled

[root@k8s-master01 pv]# kubectl get statefulSet
NAME   READY   AGE
web    2/2     10m

[root@k8s-master01 pv]# kubectl get pod
NAME                   READY   STATUS      RESTARTS   AGE
web-0                  1/1     Running     0          10m
web-1                  1/1     Running     0          12s

[root@k8s-master01 pv]# kubectl get pvc
NAME               STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-volume-web-0   Bound    nfs3-pv   7Gi        RWO            nfs            10m
pvc-volume-web-1   Bound    nfs4-pv   10Gi       RWO            nfs            18s

[root@k8s-master01 pv]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                      STORAGECLASS   REASON   AGE
nfs1-pv   1Gi        RWO            Recycle          Available                              nfs                     12m
nfs2-pv   4Gi        RWO            Recycle          Available                              nfs                     12m
nfs3-pv   7Gi        RWO            Recycle          Bound       default/pvc-volume-web-0   nfs                     11m
nfs4-pv   10Gi       RWO            Recycle          Bound       default/pvc-volume-web-1   nfs                     11m

因为 nfs3-pv 已经被绑定了,所以扩容的 Pod 只能绑定在除了 nfs3-pv 之外的合适的 nfs4-pv 上面。

-- end --

# k8s
1-maven 介绍
Linux和Windows下安装 jdk
  • 文章目录
  • 站点概览
theboyaply

theboyaply

好记性不如烂笔头

184 日志
13 分类
27 标签
Github E-mail
Creative Commons
0%
© 2019 — 2023 theboyaply
由 Halo 强力驱动
|
主题 - NexT.Gemini
湘ICP备19009291号

湘公网安备 43312402001034号