k8s 持久化存储卷

在 k8s 中为什么要做持久化存储?

在 k8s 中部署的应用都是以 pod 容器的形式运行的,假如我们部署 MySQL、Redis 等数据库,需

要对这些数据库产生的数据做备份。因为 Pod 是有生命周期的,如果 pod 不挂载数据卷,那 pod 被删 除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到 pod 数据持久化存储。


k8s 持久化存储方案:emptyDir


kubectl explain pods.spec.volumes

常用如下

emptyDir

hostPath

nfs persistentVolumeClaim glusterfs

cephfs configMap secret

我们想要使用存储卷,需要经历如下步骤

1、定义 pod 的 volume,这个 volume 指明它要关联到哪个存储上的 

2、在容器中要使用 volume mounts 挂载对应的存储

  经过以上两步才能正确的使用存储卷

emptyDir 类型的 Volume 是在 Pod 分配到 Node 上时被创建,Kubernetes 会在 Node 上自动 分配一个目录,因此无需指定宿主机 Node 上对应的目录文件。 这个目录的初始内容为空,当 Pod 从 Node 上移除时,emptyDir 中的数据会被永久删除。emptyDir Volume 主要用于某些应用程序无需永 久保存的临时目录,多个容器的共享目录等。


#创建一个 pod,挂载临时目录 emptyDir

cat emptydir.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-empty

spec:

  containers:

  - name: container-empty

    image: nginx

    volumeMounts:

    - mountPath: /cache

      name: cache-volume

  volumes:

  - emptyDir:

      {}

    name: cache-volume

kubectl apply -f emptydir.yaml

kubectl get pods -o wide | grep empty


#查看 pod 的 uid

kubectl get pods pod-empty -o yaml | grep uid

uid: ff865494-205a-4318-b8bc-072de1d8ea6f

工作节点看挂载目录


由上可知,临时目录在本地的/var/lib/kubelet/pods/ff865494-205a-4318-b8bc-072de1d8ea6f/volumes/kubernetes.io~empty-dir/cache-volume/下


k8s 持久化存储方案:hostPath

hostPath Volume 是指 Pod 挂载宿主机上的目录或文件。 hostPath Volume 使得容器可以使用 宿主机的文件系统进行存储,hostpath(宿主机路径):节点级别的存储卷,在 pod 被删除,这个存储 卷还是存在的,不会被删除,所以只要同一个 pod 被调度到同一个节点上来,在 pod 被删除重新被调度 到这个节点之后,对应的数据依然是存在的。

kubectl explain pods.spec.volumes.hostPath

FIELDS:

path -required-

type


tomcat.tar.gz  上传到工作节点

#创建一个 pod,挂载 hostPath 存储卷

如果文档里有#号注释复制的时候会乱.  vim打开的时候加:set paste就不会乱了


,

cat hostpath.yaml

 apiVersion: v1

kind: Pod

metadata:

  name: test-hostpath

spec:

  containers:

  - image: nginx

    name: test-nginx

    volumeMounts:

    - mountPath: /test-nginx

      name: test-volume

  - image: tomcat

    name: test-tomcat

    volumeMounts:

    - mountPath: /test-tomcat        #挂载到容器内目录

      name: test-volume

  volumes:

  - name: test-volume

    hostPath:

      path: /data1                        #挂载到节点目录

      type: DirectoryOrCreate    

# DirectoryOrCreate 表示本地有/data1 目录,就用本地的,本地没有就会在 pod 调度到的节点 自动创建一个

 kubectl apply -f hostpath.yaml

#查看 pod 调度到了哪个物理节点

kubectl get pods -o wide | grep hostpath

在 god62 上的/data1 下创建一个目录

# mkdir -p /data1/god

#测试存储卷是否可以正常使用,登录到 nginx 容器

kubectl exec -it test-hostpath -c test-nginx -- /bin/bash

#测试存储卷是否可以正常使用,登录到 tomcat 容器

kubectl exec -it test-hostpath -c test-tomcat -- /bin/bash root@test-hostpath:/usr/local/tomcat# cd /test-tomcat/ #/test-tomcat/目录存在,说明已经把宿主机目录挂载到了容器里 root@test-hostpath:/test-tomcat# ls

#通过上面测试可以看到,同一个 pod 里的 test-nginx 和 test-tomcat 这两个容器是共享存储卷 的。

hostpath 存储卷缺点:

单节点

pod 删除之后重新创建必须调度到同一个 node 节点,数据才不会丢失

可以用分布式存储: nfs,cephfs,glusterfs


k8s 持久化存储方案:NFS


hostPath 存储,存在单点故障,pod 挂载 hostPath 时,只有调度到同一个节点,数据 才不会丢失。那可以使用 nfs 作为持久化存储。



1、搭建 nfs 服务

#以 k8s 的控制节点作为 NFS 服务端

yum install nfs-utils -y 

#在宿主机创建 NFS 需要的共享目录

 mkdir /data/volumes -pv 

mkdir: created directory ‘/data’

mkdir: created directory ‘/data/volumes’

#配置 nfs 共享服务器上的/data/volumes 目录 

# systemctl start nfs 

# vim /etc/exports 

/data/volumes  192.168.1.0/24(rw,no_root_squash) 

#no_root_squash: 用户具有根目录的完全管理访问权限 #使 NFS 配置生效

# exportfs -arv

exporting 192.168.172.0/24:/data/volumes

]# service nfs start

Redirecting to /bin/systemctl start nfs.service 

#设置成开机自启动

]# systemctl enable nfs

#查看 nfs 是否启动成功

systemctl status nfs Active: active

看到 nfs 是 active,说明 nfs 正常启动了 #god62 和 god64 上也安装 nfs 驱动 

yum install nfs-utils -y

service nfs start && systemctl enable nfs

在 god62 上手动挂载试试:

mount -t nfs 192.168.172.63:/data/volumes /data1

df -h 看一哈


#手动卸载:

 umount /data1/


#创建 Pod,挂载 NFS 共享出来的目录

cat nfs.yaml

apiVersion: v1

kind: Pod

metadata:

  name: test-nfs-volume

spec:

  containers:

  - name: test-nfs

    image: nginx

    ports:

    - containerPort: 80

      protocol: TCP

    volumeMounts:

    - mountPath: /usr/share/nginx/html

      name: nfs-volumes

  volumes:

  - name: nfs-volumes

    nfs:

      server: 192.168.172.163

      path:  /data/volumes

注:path: /data/volumes #nfs 的共享目录

server:192.168.172.63 是 god63 机器的 ip,这个是安装 nfs 服务的地址

kubectl get pods -o wide | grep nfs

test-nfs-volume        1/1    Running    0          59s    10.244.187.124  god62           

#登录到 nfs 服务器(master),在共享目录创建一个 index.html

cd /data/volumes/

echo "hello,welcome to pod" > inde.html


curl 10.244.187.124

hello,welcome to pod

#通过上面可以看到,在共享目录创建的 index.html 已经被 pod 挂载了

#登录到 pod 验证下

# kubectl exec -it test-nfs-volume -- /bin/bash root@test-nfs-volume:/# cat /usr/share/nginx/html/index.html

hello, Welcome to pod

 #上面说明挂载 nfs 存储卷成功了,nfs 支持多个客户端挂载,可以创建多个 pod,挂载同一个 nfs 服务器共享出来的目录;但是 nfs 如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分布 式存储有 glusterfs 和 cephfs


k8s 持久化存储方案: PVC


参考官网:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes


k8s PV 是什么? 

PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像 pod 是 k8s 集群资源一样。 PV 是容量插件,如 Volumes,其生命周期独立于使用 PV 的任何单个 pod。

k8s PVC 是什么?

PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建 pod 时可以定义这个类型的存储卷。 它类似于一个 pod。 Pod 消耗节点资源,PVC 消耗 PV 资源。 Pod 可以请求特定级别的资源 (CPU 和内存)。 pvc 在申请 pv 的时候也可以请求特定的大小和访问模式(例如,可以一次读写或多次 只读)。


k8s PVC 和 PV 工作原理

PV 是群集中的资源。 PVC 是对这些资源的请求。

 PV 和 PVC 之间的相互作用遵循以下生命周期:


(1)pv 的供应方式 可以通过两种方式配置 PV:静态或动态。

静态的:

集群管理员创建了许多 PV。它们包含可供群集用户使用的实际存储的详细信息。它们存在于Kubernetes API 中,可供使用。

动态的:

当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,群集可能会尝试为 PVC 专门动态配置卷。此配置基于 StorageClasses,PVC 必须请求存储类,管理员必须创建并配置该类,以便 进行动态配置。

2)绑定

用户创建 

pvc 并指定需要的资源和访问模式。在找到可用 pv 之前,pvc 会保持未绑定状态


3)使用

a)需要找一个存储服务器,把它划分成多个存储空间;

b)k8s 管理员可以把这些存储空间定义成多个 pv;

c)在 pod 中使用 pvc 类型的存储卷之前需要先创建 pvc,通过定义需要使用的 pv 的大小和对应 的访问模式,找到合适的 pv;

d)pvc 被创建之后,就可以当成存储卷来使用了,我们在定义 pod 时就可以使用这个 pvc 的存 储卷

e)pvc 和 pv 它们是一一对应的关系,pv 如果被 pvc 绑定了,就不能被其他 pvc 使用了; f)我们在创建 pvc 的时候,应该确保和底下的 pv 能绑定,如果没有合适的 pv,那么 pvc 就会 处于 pending 状态。


4)回收策略

当我们创建 pod 时如果使用 pvc 做为存储卷,那么它会和 pv 绑定,当删除 pod,pvc 和 pv 绑定

就会解除,解除之后和 pvc 绑定的 pv 卷里的数据需要怎么处理,目前,卷可以保留,回收或删除: Retain

Recycle (不推荐使用,1.15 可能被废弃了) Delete

1、Retain

当删除 pvc 的时候,pv 仍然存在,处于 released 状态,但是它不能被其他 pvc 绑定使用,里面的 数据还是存在的,当我们下次再使用的时候,数据还是存在的,这个是默认的回收策略

Delete

删除 pvc 时即会从 Kubernetes 中移除 PV,也会从相关的外部设施中删除存储资产


创建 pod,使用 pvc 作为持久化存储卷 

1、创建 nfs 共享目录

#在宿主机创建 NFS 需要的共享目录

# mkdir /data/volume_test/v{1,2,3,4,5,6,7,8,9,10} -p

#配置 nfs 共享宿主机上的/data/volume_test/v1..v10 目录

cat /etc/exports

/data/volumes 192.168.172.0/24(rw,no_root_squash)

/data/volumes 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v1 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v2 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v3 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v4 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v5 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v6 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v7 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v8 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v9 192.168.172.0/24(rw,no_root_squash)

/data/volume_test/v10 192.168.172.0/24(rw,no_root_squash)

# 冒号替换一下保存

:1,$s/192.168.1.0/192.168.172.0/g


#重新加载配置,使配置成效

exportfs -arv

systemctl restart nfs


#查看定义 pv 需要的字段

kubectl explain pv.spec.nfs

path -required-

readOnly

server -required-


3、创建 pv

存取模式

PersistentVolume可以通过资源提供者支持的任何方式安装在主机上。如下表所示,提供商将具有不同的功能,并且每个PV的访问模式都将设置为该特定卷支持的特定模式。例如,NFS可以支持多个读/写客户端,但是特定的NFS PV可能以只读方式在服务器上导出。每个PV都有自己的一组访问模式,用于描述该特定PV的功能。

访问方式为:

ReadWriteOnce-可以通过单个节点以读写方式安装该卷

ReadOnlyMany-该卷可以被许多节点只读挂载

ReadWriteMany-该卷可以被许多节点读写安装

在CLI中,访问模式缩写为:

RWO-ReadWriteOnce

ROX-ReadOnlyMany

RWX-ReadWriteMany

重要的!即使一次卷支持多个卷,也只能一次使用一种访问模式挂载该卷。例如,GCEPersistentDisk可以由单个节点安装为ReadWriteOnce,也可以由多个节点安装为ReadOnlyMany,但不能同时安装。

cat pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

  name: v1

spec:

  capacity:

    storage: 1Gi    #pv的存储空间容量 

  accessModes: ["ReadWriteOnce"]

  nfs:

    path: /data/volume_test/v1 #把nfs的存储空间创建成pv

    server: 192.168.172.163    #nfs服务器的地址

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v2

spec:

  capacity:

      storage: 2Gi

  accessModes: ["ReadWriteMany"]

  nfs:

    path: /data/volume_test/v2

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v3

spec:

  capacity:

      storage: 3Gi

  accessModes: ["ReadOnlyMany"]

  nfs:

    path: /data/volume_test/v3

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v4

spec:

  capacity:

      storage: 4Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v4

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v5

spec:

  capacity:

      storage: 5Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v5

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v6

spec:

  capacity:

      storage: 6Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v6

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v7

spec:

  capacity:

      storage: 7Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v7

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v8

spec:

  capacity:

      storage: 8Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v8

    server: 192.168.40.130

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v9

spec:

  capacity:

      storage: 9Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v9

    server: 192.168.172.163

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name:  v10

spec:

  capacity:    #pv的存储空间容量

      storage: 10Gi

  accessModes: ["ReadWriteOnce","ReadWriteMany"]

  nfs:

    path: /data/volume_test/v10  #把nfs的存储空间创建成pv

    server: 192.168.172.163

---


#更新资源清单文件

]# kubectl apply -f pv.yaml

#查看 pv 资源


#STATUS 是 Available,表示 pv 是可用的


创建 pvc,和符合条件的 pv 绑定

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: my-pvc

spec:

  accessModes: ["ReadWriteMany"]

  resources:

    requests:

      storage: 2Gi


kubectl apply -f pvc.yaml

#查看 pv 和 pvc

# kubectl get pv


#STATUS是Bound,表示这个pv已经被my-pvc绑定了

kubectl get pvc

NAME    STATUS  VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE

my-pvc  Bound         v2      2Gi        RWX                          2m25s

#. pvc 的名字-绑定到 pv-绑定的是 v2 这个 pv-pvc 可使用的容量是 2G#


5、创建 pod,挂载 pvc

cat pod_pvc.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-pvc

spec:   

  containers:

  - name: nginx

    image: nginx

    volumeMounts:

    - name: nginx-html

      mountPath: /usr/share/nginx/html

  volumes:

  - name: nginx-html

    persistentVolumeClaim:

      claimName: my-pvc


kubectl get pods | grep pod-pvc

pod-pvc                1/1    Running    0          71s

#通过上面可以看到 pod 处于 running 状态,正常运行

注:使用 pvc 和 pv 的注意事项

1、我们每次创建 pvc 的时候,需要事先有划分好的 pv,这样可能不方便,那么可以在创建 pvc 的 时候直接动态创建一个 pv 这个存储类,pv 事先是不存在的

2、pvc 和 pv 绑定,如果使用默认的回收策略 retain,那么删除 pvc 之后,pv 会处于 released 状 态,我们想要继续使用这个 pv,需要手动删除 pv,kubectl delete pv pv_name,删除 pv,不会删除 pv 里的数据,当我们重新创建 pvc 时还会和这个最匹配的 pv 绑定,数据还是原来数据,不会丢失。


k8s 存储类:storageclass


上面介绍的 PV 和 PVC 模式都是需要先创建好 PV,然后定义好 PVC 和 pv 进行一对一的 Bond, 但是如果 PVC 请求成千上万,那么就需要创建成千上万的 PV,对于运维人员来说维护成本很高, Kubernetes 提供一种自动创建 PV 的机制,叫 StorageClass,它的作用就是创建 PV 的模板。k8s 集 群管理员通过创建 storageclass 可以动态生成一个存储卷 pv 供 k8s pvc 使用。

每个 StorageClass 都包含字段 provisioner,parameters 和 reclaimPolicy。

具体来说,StorageClass 会定义以下两部分:

1、PV 的属性 ,比如存储的大小、类型等;

2、创建这种 PV 需要使用到的存储插件,比如 Ceph、NFS 等

有了这两部分信息,Kubernetes 就能够根据用户提交的 PVC,找到对应的 StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,创建出需要的 PV。

kubectl explain storageclass

allowVolumeExpansion

allowedTopologies <[]Object>

mountOptions <[]string>

parameters

provisioner -required-

reclaimPolicy

volumeBindingMode

provisioner:供应商,storageclass 需要有一个供应者,用来确定我们使用什么样的存储来创 建 pv,常见的 provisioner 如下

(https://kubernetes.io/zh/docs/concepts/storage/storage-classes/):


provisioner 既可以由内部供应商提供,也可以由外部供应商提供,如果是外部供应商可以参考 https://github.com/kubernetes-incubator/external-storage/下提供的方法创建。

以 NFS 为例,要想使用 NFS,我们需要一个 nfs-client 的自动装载程序,称之为 provisioner,这 个程序会使用我们已经配置好的 NFS 服务器自动创建持久卷,也就是自动帮我们创建 PV。

reclaimPolicy:回收策略

allowVolumeExpansion:允许卷扩展,PersistentVolume 可以配置成可扩展。将此功能设置为

true 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。当基础存储类的 allowVolumeExpansion 字段设置为 true 时,以下类型的卷支持卷扩展。


注意:此功能仅用于扩容卷,不能用于缩小卷。


安装 nfs provisioner,用于配合存储类动态生成 pv

#把 nfs-provisioner-v1.tar.gz 工作节点上上,手动解压

1、创建运行 nfs-provisioner 需要的 sa 账号

cat serviceaccount.yaml

apiVersion: v1

kind: ServiceAccount

metadata:

  name: nfs-provisioner

kubectl apply -f serviceaccount.yaml


what.   sa?

sa 的全称是 serviceaccount。

serviceaccount 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。指定了 serviceaccount 之后,我们把 pod 创建出来了,我们在使用这个 pod 时,这个 pod 就 有了我们指定的账户的权限了。

2、对 sa 授权

#kubectl create clusterrolebinding nfs-provisioner --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner

3、k8s1.20 版本通过 nfs provisioner 动态生成 pv 会报错

Unexpected error getting claim reference to claim "default/test-claim1": selfLink was empty, can't make reference,报错原因是 1.20 版本仅用了 selfLink,解决方法如下;

vim /etc/kubernetes/manifests/kube-apiserver.yaml

在这里:

spec:

containers: - command:

- kube-apiserver 添加这一行:

- --feature-gates=RemoveSelfLink=false


然后应用它,即可:

kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml

二进制安装的 k8s,按如下修改:

vi /etc/systemd/system/kube-apiserver.service

--feature-gates=RemoveSelfLink=false \

--v=2

systemctl datemon-reload

systemctl restart apiserver

4、安装 nfs-provisioner 程序

# mkdir /data/nfs_pro -p

#把/data/nfs_pro 变成 nfs 共享的目录

cat /etc/exports

/data/nfs_pro 192.168.172.0/24(rw,no_root_squash)


#exportfs -arv

systemctl restart nfs

cat nfs-deployment.yaml

kind: Deployment

apiVersion: apps/v1

metadata:

  name: nfs-provisioner

spec:

  selector:

    matchLabels:

      app: nfs-provisioner

  replicas: 1

  strategy:

    type: Recreate

  template:

    metadata:

      labels:

        app: nfs-provisioner

    spec:

      serviceAccount: nfs-provisioner

      containers:

        - name: nfs-provisioner

          image: registry.cn-hangzhou.aliyuncs.com/god/nfs-client-provisioner:v1

          volumeMounts:

            - name: nfs-client-root

              mountPath: /persistentvolumes

          env:

            - name: PROVISIONER_NAME

              value: example.com/nfs           #提供人表示提供人的类型。

            - name: NFS_SERVER

              value: 192.168.172.163

            - name: NFS_PATH

              value: /data/nfs_pro/

      volumes:

        - name: nfs-client-root

          nfs:

            server: 192.168.172.163

            path: /data/nfs_pro/

kubectl apply -f nfs-deployment.yaml

1,$s/文档内容/替换内容/g

#查看 nfs-provisioner 是否正常运行

kubectl get pods | grep nfs

nfs-provisioner-6cb84f5d49-nwvtj  1/1    Running    0          22s


创建 storageclass,动态供给 pv


cat nfs-storageclass.yaml

apiVersion: storage.k8s.io/v1

kind:  StorageClass

metadata:

  name: nfs

provisioner: example.com/nfs

kubectl apply -f nfs-storageclass.yaml

#查看 storageclass 是否创建成功

kubectl get storageclass

NAME  PROVISIONER      RECLAIMPOLICY  VOLUMEBINDINGMODE  ALLOWVOLUMEEXPANSION  AGE

nfs    example.com/nfs  Delete          Immediate          false                  2s

注意:provisioner 处写的 example.com/nfs 应该跟安装 nfs provisioner 时候的 env 下的 PROVISIONER_NAME 的 value 值保持一致,如下:

env:

- name: PROVISIONER_NAME 

   value: example.com/nfs


创建 pvc,通过 storageclass 动态生成 pv

cat claim.yaml

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: test-claim1

  annotations:

    volume.beta.kubernetes.io/storage-class: "nfs"

spec:

  accessModes:  ["ReadWriteMany"]

  resources:

    requests:

      storage: 1Gi

  storageClassName:  nfs


kubectl apply -f claim.yaml

#查看是否动态生成了 pv,pvc 是否创建成功,并和 pv 绑定

kubectl get pvc

NAME          STATUS  VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE

my-pvc        Bound    v2                                        2Gi        RWX                          22h

test-claim1  Bound    pvc-b03288b7-13f8-4e6d-aba7-ff6d23a5c500  1Gi        RWX            nfs            7m16s

#通过上面可以看到 test-claim1 的 pvc 已经成功创建了,绑定的 pv 是 pvc-b03288b7-13f8-4e6d-aba7-ff6d23a5c500,这个 pv 是由 storageclass 调用 nfs provisioner 自动生成的。

总结:

1、供应商:创建一个 nfs provisioner

2、创建 storageclass,storageclass 指定刚才创建的供应商 

3、创建 pvc,这个 pvc 指定 storageclass

创建 pod,挂载 storageclass 动态生成的 pvc:test-claim1

cat read-pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: read-pod

spec:

  containers:

  - name: read-pod

    image: nginx

    volumeMounts:

      - name: nfs-pvc

        mountPath: /usr/share/nginx/html

  restartPolicy:

  volumes:

    - name: nfs-pvc

      persistentVolumeClaim:

        claimName: test-claim1


#查看 pod 是否创建成功

kubectl get pods | grep read

read-pod                          1/1    Running    0          29s

你可能感兴趣的:(k8s 持久化存储卷)