容器内的目录和宿主机的目录进行挂载。
容器的生命状态是短站的,delete删除,k8s用控制创建的pod,delete相当于重启,容器的状态也会回复到初始状态。
一旦回到初始状态,所有的后天编辑的文件都会消失。
容器和节点之间创建一个可以持久化保存容器内文件的存储卷。即使容器被销毁,删除,重启,节点上的存储卷的数据依然存在,后续也可以进行继续使用。可以继续将容器内目录和宿主机挂载,保存的数据继续使用。
存储卷的方式
-
emptyDir 容器内
-
hostPath 本地本地
-
NFS 远程
emptyDir
容器内部共享储存卷,k8s系统中,是一个pod当中的多个容器共享一个存储卷目录。
emptvDir卷可以是pod当中容器在这个存储卷上读取和写入
emptyDir是不能挂载到节点的。随着pod的生命周期结束,emptvDir也会结束,数据也不会保留
容器内部共享。
实验
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#第一个个name,存储的名称,可以自定义,mountPath,定义容器内的挂载目录点,和节点或者
- image: nginx:1.22
name: nginx2
volumeMounts:
- name: html
mountPath: /data
#引用上一个挂载的名称,表示我将和/usr/share/nginx/html/这个目录挂载,由data目录和它挂载
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
emptyDir: {}
进入指定容器内查看挂载的文件
kubectl exec -it nginx2-96b45c96c-jvvg9 -c nginx2 bash
hostPath
将容器内的挂载点,和节点上的目录进行挂载,hostPath可以实现数据的持久。node节点被销毁,数据也会丢失。
实验
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#第一个个name,存储的名称,可以自定义,mountPath,定义容器内的挂载目录点,和节点或者
- image: nginx:1.22
name: nginx2
volumeMounts:
- name: html
mountPath: /data
#引用上一个挂载的名称,表示我将和/usr/share/nginx/html/这个目录挂载,由data目录和它挂载
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
hostPath:
path: /opt/test
type: DirectoryOrCreate
NFS
所有pod内的目录都和节点上的nfs共享目录形成数据卷。所有的数据文件都保存在共享目录当中。集中方便管理。
nfs共享的工作流程图:
实验
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#第一个个name,存储的名称,可以自定义,mountPath,定义容器内的挂载目录点,和节点或者
- image: nginx:1.22
name: nginx2
volumeMounts:
- name: html
mountPath: /data
#引用上一个挂载的名称,表示我将和/usr/share/nginx/html/这个目录挂载,由data目录和它挂载
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
nfs:
path: /data/volumes
server: 192.168.10.40
#这里的server可以是IP地址和主机名(需要做映射)
PVC和pv静态
pv:全称:persistent Volume 持久化存储卷,描述和定义一个存储卷,pv是由运维人员来定的。
pvc:全称:persist Volume Claim 持久化储存的请求。pvc实际上用来描述或者声明我希望使用声明什么样的pv来进行储存
pvc-pv是一一对应的关系(描述,储存(大小))
pvc-pv都是虚拟化的概念,是k8s的抽象的虚拟的储存资源。
pvc---pv-----nfs
pv是集群当中的储存资源,pvc来请求存储资源,也是对储存资源的一个检索(检查索引),选择一个最合适的pv来存储资源。
pvc--pv是由生命周期管理的:
Provisioning(配置)--------pvc请求request----------检索(找一个合适的pv)-----------------pvc和pv(binding绑定)-----------使用-----------pod被删除-------------pv的releasing(释放)------------recycling(回收) |
配置:静态,动态
绑定:就是把pv分配给pvc
使用:就是pod通过pvc使用储存资源
释放:pod解除volume的关系,删除pvc
回收:保留pv,让下一个pvc使用。
pv的四种状态:
状态 | 文字描述 | 表示 |
Avialable | 可以 | 没有任何pvc绑定 |
Bound | 绑定 | pv已经绑定了pvc,绑定即使用 |
released | 释放 | pvc已经被删除了,但是pv的存储资源还没有被集群回收 |
Failed | 资源回收失败 | pv为不可用状态 |
pv的三种类型
类型 | 缩写 | 说明 |
ReadWriteOnce | RWO | 储存pv可读可写,但只能被单个pod挂载。 |
ReadOnlyMany | ROX | 储存的pv可以以只读的方式被多个pod挂载 |
ReadWriteMany | RWX | 储存可以支持读写的方式被多个pod共享 |
hostPath 支持ReadWriteOnce的方式
nfs可支持以上三种方式
有ISCSI不支持ReadOnlyMany方式
iscsiadm -m session -P 3
iscsiadm 查看服务器是否有iscsi设备
-m session 指定操作的会话模块,管理iscsi的会话
-P 3 显示详细信息的级别。级别是3 共0-3
集群回收pv资源的方式:
类型 | 文字描述 | 说明 |
Retain(默认) | 保留 | pod和挂载点的数据不会被删除 |
Recysle | 回收 | pv上的数据被删除,挂载点的数据也被删除 |
Delete | 淡出 | 解绑时,自动删除PV上的数据。(本地硬盘不能使用,AWS,EBS GCE) 支持动态卷的可以使用,pv不再可用 (云平台自己处理)。 |
补充:当pod运行之后通过pvc请求到了pv,除非pod被销毁,否则无法删除pvc |
实验
master01 192.168.10.10
node01 192.168.10.20
node02 192.168.10.30
nfs4 192.168.10.40
nfs4 ---192.168.10.40
mkdir v{1,2,3,4,5}
vim /etc/exports
/data/v1 20.0.0.0/24(rw,no_root_squash)
/data/v2 20.0.0.0/24(rw,no_root_squash)
/data/v3 20.0.0.0/24(rw,no_root_squash)
/data/v4 20.0.0.0/24(rw,no_root_squash)
/data/v5 20.0.0.0/24(rw,no_root_squash)
exportfs -arv
#发布出去
showmount -e 192.168.10.40
#在每个节点上查看
master01主节点上创建PV.yaml文件
vim pv.yaml
apiVersion: v1
kind: PersistentVolume
#PersistentVolume就是PV但是yaml文件中要用全称
metadata:
name: pv001
labels:
name: pv001
spec:
#设定pv的参数
nfs:
path: /data/v1
#定义pv的挂载位置
server: 192.168.10.40
#声明pv来自哪个IP地址
accessModes: ["ReadWriteMany", "ReadWriteOnce"]
#ReadWriteMany表示支持多个pod挂载
#ReadWriteOnly表示只支持单个pod挂载
#支持多种挂载方式
capacity:
storage: 1Gi
#定义pv的大小
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /data/v2
server: 192.168.10.40
accessModes: ["ReadWriteOnce","ReadOnlyMany"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /data/v3
server: 192.168.10.40
accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
labels:
name: pv004
spec:
nfs:
path: /data/v4
server: 192.168.10.40
accessModes: ["ReadWriteMany","ReadOnlyMany"]
persistentVolumeReclaimPolicy: Recycle
capacity:
storage: 3Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /data/v5
server: 192.168.10.40
accessModes: ["ReadOnlyMany"]
capacity:
storage: 5Gi
执行
kubectl apply -f pv.yaml
#创建PV
kubectl get pv
#查看PV状态
master01定义一个请求向PV发起请求
vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes: ["ReadWriteMany"]
#pvc期望请求的pv的读写挂载类型是什么
resources:
requests:
storage: 2Gi
#pvc期望请求pv的储存大小是2G
#期望的pv类型:ReadWriteMany 大小2G
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc
#定义pvc的名称.由mypc获取PV
执行
kubectl get pv
#查看PV状态
表示请求成功
到k8s
kubectl get pv
cd v3
echo 123 > index.html
回到master01主机
kubectl get pod -o wide
curl nginx副本IP测试
彻底的删除
删除pod
kubectl delete deployments.apps nginx2
kubectl delete deployments.apps nginx1
删除(pod存在,无发删除)
kubectl delete pvc mypvc
去k8s4查看共享文件是否存在
在Retain下,让pvc的状态由released手动转为Available(可用)
kubectl edit pv pv004
修改策略Recycle,让pv的状态released自动转变为Available(可用)
vim pv.yaml
persistentVolumeReclaimPolicy: Recycle
PVC发起请求选择使用哪个PV的存储
PV通过挂载的方式和物理存储做映射
最终由物理设备提供存储卷
若是Recycle回收策略
总结:
存储卷的三种模式:
- emptvDir: 容器内存储卷,随着pod被销毁,也会被销毁,数据不保留
- hostPath: 节点目录的存储卷,可以实现持久化存储。数据在每个节点上都有
- nfs:共享目录储存卷,可以实现持久化,数据集中在一个目录,方便管理
pv和pvc
- pvc请求-------------》pv的存储资源--------》nfs硬盘空间
- nfs支持pvc的所有挂载方式和读写模式
- hostPath仅支持ReadWriteOnce 方式
- pvc是以检索的方式找到匹配的pv资源
检索:挂载方式和读写模式 和 pv提供检索资源的大小
谁适合就用谁
资源回收方式:
- 保留:默认方式
- 回收:自动回收,节点上的数据将会被删除
- 删除: pv会变成failed模式,不可用,数据也会被删除。
PVC和PV之间静态请求。一旦成百个PVC负载能力将会下降,这就需要使用动态PVC
静态比较麻烦,自动的匹配pv资源