存储
- pod运行存储,删除pod的时候,pod里面写入的数据就没有了
一、本地存储
1、emptydir类型
-
在pod所在的物理主机上生成的一个随机目录,也就是临时目录
-
pod容器删除后,临时目录也会被删除
bash
[root@k-master volume]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources: {}
volumeMounts:
- name: v1 # 挂载v1的目录
mountPath: /data1 # 挂载到容器里面的/data1目录,不存在,会自动创建
volumes:
- name: v1 # 临时目录的名字为v1
emptyDir: {} # 创建一个临时目录
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
# 创建pod之后,查看pod调度在哪一个节点上面了
[root@k-master volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 4m50s 10.244.82.181 k-node1 <none> <none>
# 然后在node1上面查看pod1容器的详细信息
[root@k-node1 v1]# crictl inspect 1a04aed59dd91 |grep -i mount -C3
"io.kubernetes.container.terminationMessagePolicy": "File",
"io.kubernetes.pod.terminationGracePeriod": "30"
},
"mounts": [
{
"containerPath": "/data1",
"hostPath": "/var/lib/kubelet/pods/99036af5-21a9-4af9-ac1c-f04e9c23dbed/volumes/kubernetes.io~empty-dir/v1", # node1上面创建的临时目录
--
"value": "443"
}
],
"mounts": [
{
"container_path": "/data1",
"host_path": "/var/lib/kubelet/pods/99036af5-21a9-4af9-ac1c-f04e9c23dbed/volumes/kubernetes.io~empty-dir/v1"
--
"root": {
"path": "rootfs"
},
"mounts": [
{
"destination": "/proc",
"type": "proc",
--
"path": "/proc/13150/ns/uts"
},
{
"type": "mount"
},
{
"type": "network",
# 进入这个临时目录即可
[root@k-node1 v1]# pwd
/var/lib/kubelet/pods/99036af5-21a9-4af9-ac1c-f04e9c23dbed/volumes/kubernetes.io~empty-dir/v1
[root@k-node1 v1]# ls
test
# pod删除后,临时目录也就被删除了
2、hostPath
-
有一个缺点,当删除了node1上面的pod后,node1上面有一个挂载目录,当再次创建pod后,调度在node2上面,因此就不行了,不能实现挂载,因为挂载目录在node1上面
-
就是不能在各个节点上面进行同步
bash
[root@k-master volume]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources: {}
volumeMounts:
- name: v1
mountPath: /data1
volumes:
- name: v1
hostPath:
path: /d1 # 宿主机上不存在的话,会自动创建
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@k-master volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 4m2s 10.244.82.182 k-node1 <none> <none>
# 这个宿主机目录是在节点上面创建,删除了pod这个目录依然存在
[root@k-node1 /]# ls -d d1
d1
二、网络存储
1、NFS
- 就是不管我的pod在哪一个节点上面运行,都能存储数据,因此NFS服务就可以实现了
1、搭建一个nfs服务器
- 我是在master机器上面搭建的
bash
[root@k-master nfsdata]# systemctl enable nfs-server --now
Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.
[root@k-master ~]# mkdir /nfsdata
mkdir /test
chmod o+w /test # 需要加上权限,才能写入进去
# 编写一个配置文件
[root@k-master nfsdata]# cat /etc/exports
/nfsdata *(rw)
# 重启服务
2、客户端挂载nfs
bash
# 测试NFS服务器是否正常了
[root@k-master ~]# mount 192.168.50.100:/nfsdata /test
[root@k-master ~]# df -hT /test
Filesystem Type Size Used Avail Use% Mounted on
192.168.50.100:/nfsdata nfs4 50G 5.7G 44G 12% /test
3、编写一个pod
bash
[root@k-master volume]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources: {}
volumeMounts:
- name: v1
mountPath: /data1
volumes:
- name: v1
nfs:
path: /nfsdata # nfs服务器挂载的目录,将这个目录挂载到容器里面了,
server: 192.168.50.100 # nfs服务器地址
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4、查看nfs挂载目录
bash
[root@k-master ~]# ls /nfsdata/
1.txt 2.txt 4.txt
2、isccsi存储
-
分一个区20G
-
防火墙要关闭
bash
[root@k-master ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 12.8G 0 rom
nvme0n1 259:0 0 50G 0 disk
├─nvme0n1p1 259:1 0 500M 0 part /boot
└─nvme0n1p2 259:2 0 49.5G 0 part
└─cs_docker-root 253:0 0 49.5G 0 lvm /
nvme0n2 259:3 0 20G 0 disk
└─nvme0n2p1 259:4 0 20G 0 part
2、安装target包
bash
[root@k-master ~]# yum -y install target*
[root@k-master ~]# systemctl enable target --now
Created symlink /etc/systemd/system/multi-user.target.wants/target.service → /usr/lib/systemd/system/target.service.
3、配置iscsi
bash
# 刚分区的盘不需要做格式化
[root@k-master ~]# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.
/> ls /
o- / ......................................................... [...]
o- backstores .............................................. [...]
| o- block .................................. [Storage Objects: 0]
| o- fileio ................................. [Storage Objects: 0]
| o- pscsi .................................. [Storage Objects: 0]
| o- ramdisk ................................ [Storage Objects: 0]
o- iscsi ............................................ [Targets: 0]
o- loopback ......................................... [Targets: 0]
# 创建一个block1
/> /backstores/block create block1 /dev/nvme0n2p1
Created block storage object block1 using /dev/nvme0n2p1.
/> ls /
o- / ......................................................... [...]
o- backstores .............................................. [...]
| o- block .................................. [Storage Objects: 1]
| | o- block1 .. [/dev/nvme0n2p1 (20.0GiB) write-thru deactivated]
| | o- alua ................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ....... [ALUA state: Active/optimized]
| o- fileio ................................. [Storage Objects: 0]
| o- pscsi .................................. [Storage Objects: 0]
| o- ramdisk ................................ [Storage Objects: 0]
o- iscsi ............................................ [Targets: 0]
o- loopback ......................................... [Targets: 0]
/>
# 添加一个iscsi驱动器,有严格的格式要求
/> /iscsi create iqn.2023-03.com.memeda:memeda
Created target iqn.2023-03.com.memeda:memeda.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
/>
/> cd iscsi/iqn.2023-03.com.memeda:memeda/tpg1/
/iscsi/iqn.20...a:memeda/tpg1> ls
o- tpg1 ..................................... [no-gen-acls, no-auth]
o- acls ................................................ [ACLs: 0]
o- luns ................................................ [LUNs: 0]
o- portals .......................................... [Portals: 1]
o- 0.0.0.0:3260 ........................................... [OK]
/iscsi/iqn.20...a:memeda/tpg1>
/iscsi/iqn.20...a:memeda/tpg1> luns/ create /backstores/block/block1
Created LUN 0.
/iscsi/iqn.20...a:memeda/tpg1> ls
o- tpg1 ..................................... [no-gen-acls, no-auth]
o- acls ................................................ [ACLs: 0]
o- luns ................................................ [LUNs: 1]
| o- lun0 ..... [block/block1 (/dev/nvme0n2p1) (default_tg_pt_gp)]
o- portals .......................................... [Portals: 1]
o- 0.0.0.0:3260 ........................................... [OK]
/iscsi/iqn.20...a:memeda/tpg1>
/iscsi/iqn.20...a:memeda/tpg1> acls/ create iqn.2023-03.com.memeda:acl
Created Node ACL for iqn.2023-03.com.memeda:acl
Created mapped LUN 0.
/iscsi/iqn.20...a:memeda/tpg1> ls
o- tpg1 ..................................... [no-gen-acls, no-auth]
o- acls ................................................ [ACLs: 1]
| o- iqn.2023-03.com.memeda:acl ................. [Mapped LUNs: 1]
| o- mapped_lun0 ...................... [lun0 block/block1 (rw)]
o- luns ................................................ [LUNs: 1]
| o- lun0 ..... [block/block1 (/dev/nvme0n2p1) (default_tg_pt_gp)]
o- portals .......................................... [Portals: 1]
o- 0.0.0.0:3260 ........................................... [OK]
/iscsi/iqn.20...a:memeda/tpg1>
/iscsi/iqn.20...a:memeda/tpg1> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json
4、客户端安装iscsi客户端
bash
[root@k-node1 ~]# yum -y install iscsi*
[root@k-node1 ~]# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1994-05.com.redhat:56a1ef745c4e
# 修改这个iscsi号
[root@k-node2 ~]# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2023-03.com.memeda:acl
# 重启iscsid服务
5、编写pod配置文件
bash
[root@k-master volume]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources: {}
volumeMounts:
- name: v1
mountPath: /data
volumes:
- name: v1
iscsi:
lun: 0
targetPortal: 192.168.50.100:3260
iqn: iqn.2023-03.com.memeda:memeda
readOnly: false
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
# lun映射到node1上面的sad,然后映射到容器里面
[root@k-node1 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk /var/lib/kubelet/pods/0a64972c-
sr0 11:0 1 12.8G 0 rom
nvme0n1 259:0 0 50G 0 disk
├─nvme0n1p1 259:1 0 500M 0 part /boot
└─nvme0n1p2 259:2 0 49.5G 0 part
└─cs_docker-root
253:0 0 49.5G 0 lvm /
三、持久化存储
-
pv和pvc
-
底层用的还是传统存储
-
pv就是一个一个块,pvc就是使用这个块的
-
pvc与pv进行绑定
1、pv和pvc
-
pv底层还是使用的存储,nfs或者iscsi存储,或者其他的,把他做成了一个pv
-
pv做成了之后,是公共的,所有名称空间下都能看到,全局可见的
-
在一个名称空间下面创建一个pvc绑定pv
-
在一个名称空间下面创建一个pod绑定pvc就能使用了
2、pv和pvc实验(静态创建)
-
nfs充当底层存储
-
首先搭建一个nfs服务
1、创建pv
bash
[root@k-master volume]# cat pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
spec:
capacity: # 指定这个pv的大小
storage: 5Gi
accessModes: # 模式
- ReadWriteOnce
nfs:
server: 192.168.50.100 # 这个pv使用的就是nfs的存储
path: /nfsdata
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Retain Available 2m19s
# Retain 是回收的策略
# Available 可用的
# RWO 权限
# claim为空的,表示pvc还没有绑定
1、pv的策略
-
persistentVolumeReclaimPolicy 字段控制
-
retain策略,保留策略
-
删除pod,pvc,里面的数据是保留的,pv也是保留的
-
静态的创建pv和pvc的话,策略默认是reatin
bash
# 首先删除pod,然后删除pvc,pv状态就变成了released状态了
# 如果在创建一个pvc的话,就不能绑定了,因为状态必须是available
# 如果还要再次使用这个pv的话,就删除这个pv,在创建一个pv,绑定底层的nfs数据
-
delete策略
-
删除了pod,pvc的话,pv也会被删除掉
-
里面的数据也会被删除掉
-
delete策略,只能用动态配置,静态配置不能
-
-
recycle策略被弃用了
2、pv的状态
状态名 | 含义 | 常见触发场景 |
---|---|---|
Available | 尚未被任何 PVC 绑定,可被申领 | 刚创建出来,或回收策略为 Retain 且已被解除绑定 |
Bound | 已与某条 PVC 成功绑定 | kubectl get pv 最常见的状态 |
Released | 绑定的 PVC 已被删除,但 PV 尚未被回收 | ReclaimPolicy=Retain 时,PVC 删除后 PV 进入此状态 |
Failed | 自动回收(Recycle/Delete)操作失败 | 例如底层存储删除卷时返回错误 |
3、pv的访问模式
-
ReadWriteOnce RWO 单节点读写
-
ReadOnlyMany ROX 多节点只读
-
ReadWriteMany RWX 多节点读写
-
ReadWriteOncePod 单节点pod读写
访问模式 | 全称 | 含义 | 典型场景 |
---|---|---|---|
ReadWriteOnce | RWO | 单节点读写 | 大多数块存储(EBS、Ceph RBD、iSCSI);一个节点挂载,可读写。 |
ReadOnlyMany | ROX | 多节点只读 | 共享文件存储(NFS、CephFS、GlusterFS);多个节点可同时挂载读取。 |
ReadWriteMany | RWX | 多节点读写 | 分布式文件系统(NFS、CephFS、Portworx);多个节点同时挂载读写。 |
ReadWriteOncePod | RWOP | 单节点单 Pod 读写 | 1.22+ 引入,针对 CSI 卷;同一节点上只允许一个 Pod 挂载读写,适合 StatefulSet 精细化调度。 |
2、创建pvc
- 一个pv只能与一个pvc进行绑定
bash
[root@k-master volume]# cat pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-1
spec:
accessModes:
- ReadWriteOnce # 权限
resources:
requests: # 需要的大小
storage: 5Gi
# 通过权限和大小进行匹配pv
# 多个相同的pvc的话,就是随机匹配pvc
# 一个pv只能被一个pvc进行绑定
# pvc的容量小于等于pv的容量才能匹配到
# 如果有多个pvc的话,那就需要看谁创建的快,就先匹配
[root@k-master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-1 Bound pv01 5Gi RWO 52s
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Retain Bound default/pvc-1 7m14s
1、pvc的状态
状态名 | 含义 | 常见触发场景 |
---|---|---|
Pending | 尚未找到/绑定到合适的 PV | 集群里没有匹配容量、AccessMode、StorageClass 的 PV;或动态供给未就绪 |
Bound | 已成功绑定到一个 PV | 正常使用的常态 |
Lost | 所绑定的 PV 意外消失(对象被删除或后端存储不可用) | 手动删除 PV 或底层存储故障 |
Terminating | PVC 正在删除中(对象处于 metadata.deletionTimestamp 非空) |
执行 kubectl delete pvc 后,等待回收或 finalizer 完成 |
3、pv和pvc绑定
-
受到权限和大小和storagename(存储类名称,标识)这个三个参数的影响
-
storagename是优先级最高的,即使满足权限和大小,pvc没有这个storageClassName的话,就不能绑定,只有pvc有这个storageClassName的才能绑定
bash
[root@k-master volume]# cat pv2.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02
spec:
storageClassName: abc # 存储卷的名称为abc
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
server: 192.168.50.100
path: /nfsdata
[root@k-master volume]# cat pvc2.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv02 5Gi RWO Retain Available abc 49s
[root@k-master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-2 Pending 25s
# 只有这个pvc有storageClassName才能匹配到
4、pod使用pvc
bash
[root@k-master volume]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: pod2
name: pod2
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod2
resources: {}
volumeMounts:
- name: mypv
mountPath: /var/www/html # 挂载到容器里面的/var/www/html目录下
restartPolicy: Always
volumes:
- name: mypv # 卷的名字
persistentVolumeClaim: # 用pvc来做这个卷
claimName: pvc-1 # pvc的名字
status: {}
[root@k-master volume]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod2 1/1 Running 0 2m22s
[root@k-master ~]# kubectl exec -ti pod2 -- /bin/bash
# 查看挂载点
root@pod2:/var/www/html# df -hT /var/www/html/
Filesystem Type Size Used Avail Use% Mounted on
192.168.50.100:/nfsdata nfs4 50G 5.7G 44G 12% /var/www/html
# 写入数据
root@pod2:/var/www/html# echo 1 > 1.txt
# 发现,最底层的作为pv的nfs存储里面也有数据
[root@k-master volume]# ls /nfsdata/
1.txt
# 这个pod调度在node1节点上,也可以查看到挂载的情况
# 这个pod的挂载目录也会创建出来的
[root@k-node1 pv01]# df -hT | grep -i nfs
192.168.50.100:/nfsdata nfs4 50G 5.7G 44G 12% /var/lib/kubelet/pods/2ce30dc7-4076-482f-9d78-d5af92d03967/volumes/kubernetes.io~nfs/pv01
[root@k-node1 pv01]# cd /var/lib/kubelet/pods/2ce30dc7-4076-482f-9d78-d5af92d03967/volumes/kubernetes.io~nfs/pv01
[root@k-node1 pv01]# ls
1.txt 2.txt
5、删除pod,pv的状态
- 怎么处理
bash
[root@k-master volume]# kubectl delete -f pod2.yaml
pod "pod2" deleted
[root@k-master volume]# kubectl delete -f pvc1.yaml
persistentvolumeclaim "pvc-1" deleted
# pv的状态为released
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Retain Released default/pvc-1 81s
# 删除relf下面的字段,就能重新变成available了
[root@k-master volume]# kubectl edit pv pv01
persistentvolume/pv01 edited
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Retain Available 2m26s
# 或者删除pv,然后重新创建即可
3、pv和pvc和pod
-
首先pv是一个块,底层使用的是一个存储,用来做成pv,使用nfs也可以,或者其他的
-
pvc用来绑定一个pv,一个pv只能绑定一个pvc
-
pod的持久化存储的话,就是使用的pvc来实现的,pvc挂载到容器的目录下
-
在这个目录下面写入数据的话,就写入到了最底层的存储里面了
-
其实pv和pvc都是虚拟出来的,最底层的还是一个存储
-
pv和pvc方便集中管理
-
最底层的nfs或者其他的也可以管理,也就是分权管理
-
也就是多级映射关系,抽象出来的
-
最底层的nfs,映射到pv,pv映射到pvc,最后以卷的形式挂载到pod里面即可
3、nfs配置动态卷的供应流程
-
就是在定义pvc的时候,自动的创建出pv
-
依靠的就是nfs驱动器
-
默认的pv策略是delete,可以修改的为retain
-
创建一个存储类,映射到nfs存储,然后创建一个pvc就会自动的创建一个pv
1、配置nfs服务器
bash
[root@k-master ~]# cat /etc/exports
/nfsdata *(rw)
2、配置nfs驱动
bash
# 先git clone 一些这个文件
[root@k-master nfs-deploy]# git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
# 进入到deploy目录下
[root@k-master deploy]# pwd
/root/volume/nfs-deploy/nfs-subdir-external-provisioner/deploy
# 如果名称空间不是默认的default的话,需要修改名称空间,如果是默认的则无需操作
[root@k-master deploy]# ls
class.yaml kustomization.yaml rbac.yaml test-pod.yaml
deployment.yaml objects test-claim.yaml
[root@k-master deploy]# kubectl apply -f rbac.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
# 修改了deployment.yaml
- name: nfs-client-provisioner
image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
# 如果可以拉取到这个镜像,就无需修改,不行的话,就需要更换镜像
registry.cn-hangzhou.aliyuncs.com/cloudcs/nfs-subdir-external-provisioner:v4.0.2
# 这个是别人的网络仓库
# 修改驱动文件中的nfs的一些配置,修改deployment.yaml
- name: NFS_SERVER
value: 192.168.50.100
- name: NFS_PATH
value: /nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 192.168.50.100
path: /nfsdata
[root@k-master deploy]# kubectl apply -f deployment.yaml
deployment.apps/nfs-client-provisioner created
[root@k-master deploy]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-9f74c968-2lm9k 1/1 Running 0 15s
# 这个pod就跟nfs存储做了一个映射,当创建一个pvc(使用的存储类是nfs-client)的时候,就会自动的创建一个pv
3、创建一个存储类
bash
[root@k-master ~]# cat class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiverOnDelete: "false"
[root@k-master ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 37s
[root@k-master ~]#
4、创建一个pvc
- 创建一个pvc就会自动的创建一个pv
bash
[root@k-master volume]# cat pvc3.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc3
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-client # 使用的存储类是nfs-client,就会自动的创建pv
resources:
requests:
storage: 5Gi
[root@k-master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-37889731-cc0f-4485-8647-0bc46a435faf 5Gi RWO Delete Bound default/pvc3 nfs-client 9s
[root@k-master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc3 Bound pvc-37889731-cc0f-4485-8647-0bc46a435faf 5Gi RWO nfs-client 13s
5、创建一个pod
bash
[root@k-master volume]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: pod2
name: pod2
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod2
resources: {}
volumeMounts:
- name: mypv
mountPath: /var/www/html
restartPolicy: Always
volumes:
- name: mypv
persistentVolumeClaim:
claimName: pvc3
status: {}
[root@k-master volume]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-9f74c968-2lm9k 1/1 Running 0 20m
pod2 1/1 Running 0 70s
# 就会在nfsdata这个目录创建一个目录用来存储数据
[root@k-master volume]# ls /nfsdata/
1.txt 2.txt default-pvc3-pvc-37889731-cc0f-4485-8647-0bc46a435faf
# 写入一些数据
[root@k-master volume]# ls /nfsdata/default-pvc3-pvc-37889731-cc0f-4485-8647-0bc46a435faf/
11 22
# 删除pod和pvc
[root@k-master volume]# kubectl delete -f pod2.yaml
pod "pod2" deleted
[root@k-master volume]# kubectl delete -f pvc3.yaml
persistentvolumeclaim "pvc3" deleted
# 这个nfs的目录的名字就会修改
[root@k-master volume]# ls /nfsdata/
archived-default-pvc3-pvc-3cd12cad-47a5-43f3-93a0-8e9a9d4a490c
# 因为这个是delete策略导致的,防止数据立即丢失
四、总结
-
本地存储的话,比较笨重
-
静态逻辑
-
先有一个最底层的nfs服务器,可以让别人挂载这个目录
-
然后创建一个pv,pvc之间进行绑定
-
创建一个pod绑定pvc,从而写数据,写的数据存储在nfs这个目录下
-
-
动态的逻辑
-
创建一个nfs服务器
-
创建一个nfs的驱动器,映射到nfs存储,使用的还是nfs存储
-
然后创建一个存储类,驱动器使用的是上面创建的
-
创建一个pvc,存储类使用的nfs-client,这个驱动器就会自动的创建一个pv,也就是在nfs存储目录里面划分一个目录用于存储
-
创建一个pod进行绑定pvc即可
-