一、部署nfs服务端

1、需在 k8s-master 节点上搭建了一个 NFS 服务器,目录为 /nfsdata:

yum install -y nfs-utils rpcbind
vim /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)

2、保存配置文件后,执行如下操作:

  在服务端创建对应的目录和赋予权限:

 mkdir /nfsdata
chmod 777 /nfsdata

3、启动rpcbind和nfs服务:

systemctl start rpcbind && systemctl enable rpcbind
systemctl start nfs && systemctl enable nfs

4、每个node安装nfs工具

 yum install -y nfs-utils 

5、每个node查询NFS服务器

showmount -e nfs-ip

二、 NFS PersistentVolume

1、创建PV

(1)下面创建一个PV mypv1,配置文件nfs-pv1.yml如下:

[root@ren7 yaml]# cat nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1 #需要创建pv1目录,否则pod起不来
server: 192.168.11.7

  ① capacity 指定 PV 的容量为 1G。

  ② accessModes 指定访问模式为 ReadWriteOnce,支持的访问模式有:

  ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。

  ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。

  ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。

  ③ persistentVolumeReclaimPolicy 指定当 PV 的回收策略为 Recycle,支持的策略有:
  Retain – 需要管理员手工回收。
  Recycle – 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*
  Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

  ④ storageClassName 指定 PV 的 class 为 nfs。相当于为 PV 设置了一个分类,PVC 可以指定 class 申请相应 class 的 PV。

  ⑤ 指定 PV 在 NFS 服务器上对应的目录。

  注意要做storage-provider段要提前建好文件夹

[root@ren7 nfsdata]# pwd
/nfsdata
[root@ren7 nfsdata]# mkdir pv1
[root@ren7 nfsdata]# ls
pv1

(2)创建 mypv1:

[root@ren7 yaml]# kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 created
[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Recycle Available nfs 9s

  STATUS 为 Available,表示 mypv1 就绪,可以被 PVC 申请。

2、创建PVC

(1)接下来创建 PVC mypvc1,配置文件 nfs-pvc1.yml 如下:

  注意:

  1)storageClassName需要与上面定义的pv保持一致!

  2)各个节点都需要下载nfs-utils

[root@ren7 yaml]# cat nfs-pvc1.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs

  PVC 就很简单了,只需要指定 PV 的容量,访问模式和 class。

(2)创建 mypvc1:

[root@ren7 yaml]# kubectl apply -f nfs-pvc1.yml
persistentvolumeclaim/mypvc1 created
[root@ren7 yaml]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc1 Bound mypv1 1Gi RWO nfs 10s
[root@ren7 yaml]#
[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Recycle Bound default/mypvc1 nfs 161m

  从 kubectl get pvc 和 kubectl get pv 的输出可以看到 mypvc1 已经 Bound 到 mypv1,申请成功。

3、pod使用PVC

(1)接下来就可以在 Pod 中使用存储了,Pod 配置文件 pod1.yml 如下:

[root@ren7 yaml]# cat pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod1
spec:
containers:
- name: mypod1
image: reg.yunwei.com/learn/busybox:latest
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/mydata"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc1

  与使用普通 Volume 的格式类似,在 volumes 中通过 persistentVolumeClaim 指定使用 mypvc1 申请的 Volume。

(2)创建 mypod1:

[root@ren7 yaml]# kubectl apply -f pod1.yml
pod/mypod1 created
[root@ren7 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mypod1 1/1 Running 0 12s 172.20.72.157 192.168.11.5 <none> <none>

(3)验证 pv 是否可用:

[root@ren7 yaml]# kubectl exec mypod1 touch /mydata/hello
[root@ren7 yaml]# cd /nfsdata/
[root@ren7 nfsdata]# ls
pv1
[root@ren7 nfsdata]# ls pv1/
hello

  可见,在 Pod 中创建的文件 /mydata/hello 确实已经保存到了 NFS 服务器目录 /nfsdata/pv1 中。

  如果不再需要使用 pv,可用删除PVC 回收 pv。

三、回收 PV:

1、当 PV 不再需要时,可通过删除 PVC 回收。

[root@ren7 yaml]# kubectl delete -f nfs-pvc1.yml
persistentvolumeclaim "mypvc1" deleted
[root@ren7 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mypod1 1/1 Running 0 3h46m 172.20.72.157 192.168.11.5 <none> <none>

  当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod这个 Pod 的作用就是清除 PV mypv1 的数据。这个时候我们再看 NFS 服务器目录 /nfsdata/pv1 中已经没有数据了。

[root@ren7 nfsdata]# ls
pv1
[root@ren7 nfsdata]# ls pv1/
[root@ren7 nfsdata]#
[root@ren7 nfsdata]#

2、当数据清除完毕,mypv1 的状态重新变为 Available,此时则可以被新的 PVC 申请。

[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Recycle Available nfs 3h52m

3、因为 PV 的回收策略设置为 Recycle,所以数据会被清除,但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为 Retain。

apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.11.7

4、通过kubectl apply 更新PV:

[root@ren7 yaml]# kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 configured
[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Retain Available nfs 14s

5、回收策略已经变为 Retain,通过下面步骤验证其效果:

[root@ren7 yaml]# kubectl apply -f nfs-pvc1.yml
persistentvolumeclaim/mypvc1 created
[root@ren7 yaml]#
[root@ren7 yaml]# kubectl get pod
No resources found.
[root@ren7 yaml]# kubectl apply -f pod1.yml
pod/mypod1 created
[root@ren7 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mypod1 1/1 Running 0 10s 172.20.72.159 192.168.11.5 <none> <none>
[root@ren7 yaml]# kubectl exec mypod1 touch /mydata/nihao
[root@ren7 yaml]# kubectl delete pod mypod1
pod "mypod1" deleted
[root@ren7 yaml]# kubectl delete pvc mypvc1
persistentvolumeclaim "mypvc1" deleted
[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Retain Released default/mypvc1 nfs 6m51s

[root@ren7 yaml]# kubectl get pvc
  No resources found.
  [root@ren7 yaml]# kubectl get pod
  No resources found.

  ① 重新创建 mypvc1。

  ② 在 mypv1 中创建文件 nihao。

  ③ mypv1 状态变为 Released。

  ④ Kubernetes 并没有启动 Pod recycler-for-mypv1。

  ⑤ PV 中的数据被完整保留。

(6)我们再看 NFS 服务器目录 /nfsdata/pv1 中数据还保留。

[root@ren7 nfsdata]# ls
pv1
[root@ren7 nfsdata]# ls pv1/
nihao

(7)虽然 mypv1 中的数据得到了保留,但其 PV 状态会一直处于 Released,不能被其他 PVC 申请。

[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Retain Released default/mypvc1 nfs 10m

(8)为了重新使用存储资源,可以删除并重新创建 mypv1。删除操作只是删除了 PV 对象,存储空间中的数据并不会被删除。

  新建的 mypv1 状态为 Available,已经可以被 PVC 申请。

[root@ren7 yaml]# kubectl delete pv mypv1
persistentvolume "mypv1" deleted
[root@ren7 yaml]# kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 created
[root@ren7 yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Retain Available nfs 6s

  PV 还支持 Delete 的回收策略,会删除 PV 在 Storage Provider 上对应存储空间。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

四、PV的动态供给

1、pv的供给方式

  前面的例子中,我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision)。

  与之对应的是动态供给(Dynamical Provision),即如果没有满足 PVC 条件的 PV,会动态创建 PV。相比静态供给,动态供给有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高。

  动态供给是通过 StorageClass 实现的,StorageClass 定义了如何创建 PV

2、pv动态供给举例

  StorageClass standard:

  StorageClass slow:

  这两个 StorageClass 都会动态创建 AWS EBS,不同在于 standard 创建的是 gp2 类型的 EBS,而 slow 创建的是 io1 类型的 EBS。不同类型的 EBS 支持的参数可参考 AWS 官方文档。

  StorageClass 支持 Delete 和 Retain 两种 reclaimPolicy,默认是 Delete。

  与之前一样,PVC 在申请 PV 时,只需要指定 StorageClass 和容量以及访问模式,比如:

  除了 AWS EBS,Kubernetes 支持其他多种动态供给 PV 的 Provisioner,完整列表请参考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

五、pv、pvc无法删除问题

   一般的删除步骤为:先删除pod再删除pvc最后删除pv。

  但是遇到pv始终处于“Terminating”状态,而且delete不掉。

解决办法:

  直接删除k8s中的记录:

kubectl patch pv xxx -p '{"metadata":{"finalizers":null}}'

  参考信息:

This happens when persistent volume is protected. You should be able to cross verify this:
Command:
kubectl describe pvc PVC_NAME | grep Finalizers
Output:
Finalizers: [kubernetes.io/pvc-protection]
You can fix this by setting finalizers to null using kubectl patch:
kubectl patch pvc PVC_NAME -p '{"metadata":{"finalizers": []}}' --type=merge

NFS PersistentVolume(11)的更多相关文章

  1. NFS PersistentVolume(8)

    一.部署nfs服务端: k8s-master 节点上搭建了 NFS 服务器 (1)安装nfs服务: yum install -y nfs-utils rpcbind vim /etc/exports ...

  2. Netruon 理解(11):使用 NAT 将 Linux network namespace 连接外网

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  3. 基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码

    在Web开发的时候,我们很多时候,需要引用很多CSS文件.JS文件,随着使用更多的插件或者独立样式文件,可能我们的Web界面代码会越来越臃肿,看起来也很累赘,在MVC里面提供了一个Bundle的对象, ...

  4. Python的平凡之路(11)

    一. rabbitmq 1 进程Queue:  父进程与子进程进行交互,或者同属于同一父进程下多个子进程进行交互 2 队列通信:   send1.py #!/usr/bin/env python#Au ...

  5. spring 第一篇(1-1):让java开发变得更简单(下)转

    spring 第一篇(1-1):让java开发变得更简单(下) 这个波主虽然只发了几篇,但是写的很好 上面一篇文章写的很好,其中提及到了Spring的jdbcTemplate,templet方式我之前 ...

  6. Web 在线文件管理器学习笔记与总结(11)获取文件夹信息 (12)返回上一级操作

    (11)获取文件夹信息 文件夹没有修改操作. index.php: <?php require 'dir.func.php'; require 'file.func.php'; require ...

  7. MS CRM 2011的自定义和开发(11)——插件(plugin)开发(三)

    http://www.cnblogs.com/StoneGarden/archive/2012/02/06/2340661.html MS CRM 2011的自定义和开发(11)——插件(plugin ...

  8. MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四)

    http://www.cnblogs.com/StoneGarden/archive/2012/02/08/2343294.html MS CRM 2011的自定义和开发(11)——插件(plugin ...

  9. MS CRM 2011的自定义和开发(11)——插件(plugin)开发(一)

    http://www.cnblogs.com/StoneGarden/archive/2012/02/02/2336147.html MS CRM 2011的自定义和开发(11)——插件(plugin ...

随机推荐

  1. 关于C语言解决汉诺塔(hanoi)问题

    C语言解决汉诺塔问题 汉诺塔是典型的递归调用问题: hanoi简介:印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣 ...

  2. linux 更新python3.8

    1 下载源码 地址 选版本下载即可,目前最新为3.8.2版本. 2 解压 tar -zxvf Python-3.8.2.tgz cd Python-3.8.2 3 新建安装目录 安装目录在/usr/l ...

  3. 2. IntelliJ Idea 常用快捷键列表

    Ctrl+E,最近的文件 Ctrl+Shift+E,最近更改的文件 Shift+Click,可以关闭文件 Ctrl+[ OR ],可以跑到大括号的开头与结尾 Ctrl+F12,可以显示当前文件的结构 ...

  4. Python:读写文件(I/O) | 组织文件

    1. I/O 概述  程序与用户交互涉及到程序的输入输出(I/O) 一种类型是字符串,通过input() 和 print() 函数以及数据类型转换类函数如(int()),实现数据的输入输出. 另一种类 ...

  5. pc/shouji/weixin判断跳转

    pc 和 手机端 判断 function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android&q ...

  6. 【原创】Centos8使用ansible

    目录 使用ansible发布公钥 ansible基本命令 ansbile配置文件详解 一.使用ansible发布公钥 1.0 生成秘钥对 1.生成命令 ssh-keygen -t rsa# 推送单个公 ...

  7. Sqli 注入点解析

    目录 Less-1: 字符型注入 Less-2: 数字型注入 Less-3: 单引号字符型+括号 Less-4: 双引号字符型+括号 Less-5: 单引号字符型+固定输出信息 (floor报错注入& ...

  8. Linux中的DHCP服务

    目录 DHCP DHCP的报文类型 DHCP的部署 DHCP中继(DHCP代理) DHCP DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局 ...

  9. androguard安装和体验

    安装步骤按照官方教程https://code.google.com/p/androguard/wiki/Installation,下面记录下无法在ubuntu下apt-get的模块: python模块 ...

  10. 【maven和jdk】报错:系统找不到指定的文件

    创建一个maven项目出错 问题描述 在idea.log出现如下错误(系统找不到指定的文件,但是不知道指定文件是什么) com.intellij.execution.process.ProcessNo ...