前言
Kubernetes 中的存储卷(Volume)是一种持久化存储,用于在Pod内部共享数据或将数据持久化存储。存储卷允许将容器中的数据存储到持久化的存储介质上,以便数据在容器之间共享、在容器重启后保留,并且不受容器生命周期的影响。储卷可以挂载到 Pod的一个或多个容器中,容器可以读取、写入存储卷中的数据。存储卷通常用于存储应用程序的配置文件、日志、数据库文件等数据。
常见的存储卷:
1. EmptyDir:临时存储卷,生命周期与 Pod 相同,当 Pod 被删除时,数据也会被清除。
2. HostPath:使用节点上的文件系统路径作为存储卷,可以用于共享文件给同一节点上的多个Pod。
3. PersistentVolumeClaim(PVC):持久化存储卷声明,用于与持久卷(如 NFS、iSCSI、AWS EBS 等)建立关联。PVC 允许 Pod 与持久卷进行动态绑定和解绑,使得持久化存储的管理更加灵活。
4. ConfigMap:用于将配置文件注入到 Pod 中,可以直接作为存储卷使用。
5. Secret:用于将敏感数据注入到 Pod 中,也可以直接作为存储卷使用。
6. CSI Volume:Container Storage Interface 的存储卷,允许第三方存储插件提供存储卷功能。
通过kubectl explain pods.spec.volumes命令可以查看k8s都支持那些后端存储。要使用存储卷,都要经历两个步骤:
1)定义pod的volume,这个volume指明它要关联到哪个存储上的。2)挂载存储,在容器中挂载要使用volume mounts。
#EmptyDir Volume #
EmptyDir是Kubernetes中一种临时存储卷类型,它将在Pod生命周期内保持存在,但与Pod具有相同的生命周期。EmptyDir通常用于在容器之间共享临时数据,或者在容器重启时保留某些状态。当Pod被删除时,EmptyDir中的数据也会被清除。主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。
简单的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dy
labels:
web: nginx
namespace: default
annotations:
dac: " image version to v1.0"
spec:
minReadySeconds: 10
#新创建的Pod成为就绪状态之前,Deployment控制器等待的最短时间(秒数)。确保Pod中的业务程序能正常工作之前有做狗的时候完成初始化和准备工作。
paused: false
progressDeadlineSeconds: 60
#该字段用于指定部署操作的进度检查的超时时间(以秒为单位)。这个字段的作用是为了确保部署操作能够在指定的时间内完成,并在超时后进行相应的处理。
replicas: 4
revisionHistoryLimit: 5
#该用于指定要保留的 Deployment 版本历史记录的最大数量。Deployment 版本历史记录包含了过去创建的每个 Deployment 的详细信息,包括创建时间、更新时间、副本数量等。
#如果设置为 0,则不会保留任何历史记录;如果设置为负值,则表示将保留所有历史记录。
selector:
matchLabels:
ser: nginx-test
strategy:
#定义滚动更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: nginx
#namespeace
labels:
ser: nginx-test
spec:
nodeSelector:
app: to
hostname: nginx-dy
containers:
- image: docker.io/library/nginx:v1
name: nginx-dy
imagePullPolicy: IfNotPresent
ports:
- name: nginx-post
containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d
readOnly: false
#为true为只读方式挂载
volumes:
- emptyDir: {}
name: nginx-conf
运行后Pod在node01上已经正常运行()我们查看被挂载的nginx目录,进入容器查看/etc/nginx/conf.d,在没有挂载此目录时conf.d目录下会有default.conf文件现在已经消失。
kubectl exec nginx-dy-d7f78576f-4pqg5 -it -- /bin/bash
在此文件下创建一个文件bwk.txt。在宿主机查询此文件路径在:
[root@node01 home]# find / -name bwk.txt
/var/lib/kubelet/pods/7e062d73-7c10-4404-9b00-d08bb88c728c/volumes/kubernetes.io~empty-dir/nginx-conf/bwk.txt
临时存储的EmptyDir创建后K8s会在宿主机分配硬件资源,存储的目录名称为spec.volumes.name的name字段值,它在Pod被释放后释放。
HostPath Volume
HostPath 是 Kubernetes 中用于挂载主机文件系统目录的一种卷类型。它允许Pod中的容器访问主机上的特定目录,这对于需要与主机系统交互的应用程序非常有用。
我们进行容器的镜像编译的时时候在Dockerfile文件中FROM的基础镜像时间有时候不是上海时区,这对与后期进行项目部署程序获取时间出现错误的情况,这时我们要么在Dockerfile编译的时候测试好再使用镜像,要么就是在部署Pod的时候把本地的时间文件挂载到容器中去。
root@node01 home]# ll /etc/ | grep localtime
rwxrwxrwx. 1 root root 35 3月 10 15:47 localtime -> ../usr/share/zoneinfo/Asia/Shanghai
简单的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dy
labels:
web: nginx
namespace: default
annotations:
dac: " image version to v1.0"
spec:
minReadySeconds: 10
#新创建的Pod成为就绪状态之前,Deployment控制器等待的最短时间(秒数)。确保Pod中的业务程序能正常工作之前有做狗的时候完成初始化和准备工作。
paused: false
progressDeadlineSeconds: 60
#该字段用于指定部署操作的进度检查的超时时间(以秒为单位)。这个字段的作用是为了确保部署操作能够在指定的时间内完成,并在超时后进行相应的处理。
replicas: 4
revisionHistoryLimit: 5
#该用于指定要保留的 Deployment 版本历史记录的最大数量。Deployment 版本历史记录包含了过去创建的每个 Deployment 的详细信息,包括创建时间、更新时间、副本数量等。
#如果设置为 0,则不会保留任何历史记录;如果设置为负值,则表示将保留所有历史记录。
selector:
matchLabels:
ser: nginx-test
strategy:
#定义滚动更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: nginx
#namespeace
labels:
ser: nginx-test
spec:
nodeSelector:
app: to
hostname: nginx-dy
containers:
- image: docker.io/library/nginx:v1
name: nginx-dy
imagePullPolicy: IfNotPresent
ports:
- name: nginx-post
containerPort: 80
volumeMounts:
- name: nginx-time
mountPath: /etc/localtime
readOnly: true
#为true为只读方式挂载
volumes:
- name: nginx-time
hostPath:
path: /etc/localtime
type: File
未同步时间的Pod
[root@master bak]# date
2024年 03月 26日 星期二 22:48:53 CST
[root@master bak]# kubectl exec nginx-dy-d7f78576f-7vkrd -it -- /bin/bash
root@nginx-dy:/# date
Tue Mar 26 14:48:59 UTC 2024
同步时间后的Pod
[root@master yaml]# kubectl exec nginx-dy-74f79c4f5c-2lshp -it -- /bin/bash
root@nginx-dy:/# date
Tue Mar 26 23:05:23 CST 2024
root@nginx-dy:/# exit
exit
[root@master yaml]# date
2024年 03月 26日 星期二 23:05:28 CST
像yaml中的这种方式即替换Pod中的文件,需要文件的绝对路径。
hostPath的几种类型:
1. FileOrCreate:如果指定的路径不存在,则创建一个文件。
2. File:文件必须存在。如果不存在,则容器将无法启动。
3. DirectoryOrCreate:如果指定的目录不存在,则创建一个目录。
4. Directory:目录必须存在。如果不存在,则容器将无法启动。
nfs volume
在Kubernetes中,NFS(Network File System)是一种常见的存储解决方案,用于在集群中共享文件系统。
- 存储共享:NFS 允许将文件系统挂载到多个节点上,因此多个 Pod 可以同时访问共享的存储卷。这对于需要多个 Pod 之间共享数据的应用程序非常有用。
- 动态和静态配置:你可以在 Kubernetes 中静态或动态地配置 NFS 卷。静态配置涉及手动创建 PersistentVolume 和 PersistentVolumeClaim 对象,而动态配置则使用存储类(StorageClass)来自动创建这些对象。
- PersistentVolume和PersistentVolumeClaim:在使用 NFS 之前,你需要创建一个 PersistentVolume 对象来表示 NFS 服务器上的共享卷,并创建一个PersistentVolumeClaim对象来请求该卷。这两个对象会在 Pod 中进行挂载。
- 跨节点访问:NFS 提供了一种简单的跨节点访问机制,允许 Pod 在集群中的不同节点上运行,但仍然可以访问相同的存储卷。
- 数据持久性:NFS 存储卷的数据是持久的,即使 Pod 被重新调度到不同的节点上,数据仍然保持不变。这使得 NFS 成为存储应用程序数据和状态的理想选择。
- 部署和管理:Kubernetes 提供了丰富的资源类型和控制器,可用于管理 NFS 卷的生命周期。你可以使用 Deployment、StatefulSet、DaemonSet 等控制器来部署和管理使用 NFS 存储的应用程序。
安装nfs服务
yum -y install nfs-utils
配置服务:
[root@localhost nginx]# cat /etc/exports
/mnt/k8s 192.168.0.0/24(rw,no_root_squash)
配置生效重启nfs服务
exportfs -arv
systemctl restart nfs
在应用服务器查看共享目录
showmount -e 192.168.0.108
简单的yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dy
labels:
web: nginx
namespace: default
annotations:
dac: " image version to v1.0"
spec:
minReadySeconds: 10
#新创建的Pod成为就绪状态之前,Deployment控制器等待的最短时间(秒数)。确保Pod中的业务程序能正常工作之前有做狗的时候完成初始化和准备工作。
paused: false
progressDeadlineSeconds: 60
#该字段用于指定部署操作的进度检查的超时时间(以秒为单位)。这个字段的作用是为了确保部署操作能够在指定的时间内完成,并在超时后进行相应的处理。
replicas: 4
revisionHistoryLimit: 5
#该用于指定要保留的 Deployment 版本历史记录的最大数量。Deployment 版本历史记录包含了过去创建的每个 Deployment 的详细信息,包括创建时间、更新时间、副本数量等。
#如果设置为 0,则不会保留任何历史记录;如果设置为负值,则表示将保留所有历史记录。
selector:
matchLabels:
ser: nginx-test
strategy:
#定义滚动更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: nginx
#namespeace
labels:
ser: nginx-test
spec:
nodeSelector:
app: to
hostname: nginx-dy
containers:
- image: docker.io/library/nginx:v1
name: nginx-dy
imagePullPolicy: IfNotPresent
ports:
- name: nginx-post
containerPort: 80
volumeMounts:
- name: nginx-nfs
mountPath: /home
readOnly: false
#为true为只读方式挂载
volumes:
- name: nginx-nfs
nfs:
path: /mnt/k8s/nginx
readOnly: false
server: 192.168.0.108
此种方式配置的Deployment下所有的Pod共享/mnt/k8s/nginx目录。
PV和PVC
PV:PersistentVolume是Kubernetes中的资源对象,是集群中的持久化存储卷(NFS、iSCSI、AWS EBS、Azure Disk等类型的存储卷)是集群中的资源,由管理员配置或使用存储类动态配置。它独立于Pod而存在,PV有自己的生命周期,它可以手动创建、删除、调整容量等操作。PV一旦被创建,可以被多个PVC绑定并在Pod中使用。
PVC:PersistentVolumeClaim也是Kubernetes中的资源对象,用于申请集群中的持久化存储(PV),K8S管理员创建的对象,用于请求集群中预先配置的PV。Pod消耗节点资源,PVC消耗PV资源。PVC描述了对存储的需求,包括容量大小、访问模式等。PVC绑定到PV上,使得PV的存储资源可以被Pod使用。PVC可以被多个Pod共享,但一个PVC只能绑定到一个PV上。
PV的使用法方式
静态的:集群管理员创建了许多PV。它们包含可供群集用户使用的实际存储的详细信息。它们存在于Kubernetes API中,可供使用。
动态的:当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,群集可能会尝试为PVC专门动态配置卷。此配置基于StorageClasses:PVC必须请求存储类,管理员必须已创建并配置该类,以便进行动态配置。
PV的回收策略
- Retain(默认):使用Retain策略时,当PVC解绑时,PV中的数据不会被删除,而是保留下来。管理员需要手动处理PV中的数据,通常是通过将PV重新绑定到新的 PVC 或手动清理PV中的数据。这种策略适用于需要手动审查和处理数据的情况,以确保数据不会意外丢失。
- Delete(删除):使用Delete策略时,当PVC解绑时,PV中的数据将被删除。Kubernetes将自动删除PV中的数据,并将PV标记为“Released”状态。这种策略适用于可以安全删除数据的情况,例如PV中存储的数据可以被应用程序重新生成,或者数据不再需要保留。
- Dynamic Provisioning(动态分配):Dynamic Provisioning不是一种回收策略,而是一种动态创建PV的方法。当PVC 请求的存储资源找不到对应的PV时,Kubernetes可以根据定义的存储类(StorageClass)自动创建PV,并将其绑定到PVC。这种方式下,PV的生命周期由动态创建的时间开始,因此释放时将按照指定的回收策略进行处理。
简单的yaml文件
- 创建pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: ng-ng1
labels:
web: nginx
namespace: default
spec:
capacity:
storage: 3Gi
accessModes: ["ReadWriteMany"]
nfs:
path: /mnt/k8s/ng1
readOnly: false
#用于指定PV是否以只读方式挂载 NFS 卷。
server: 192.168.0.108
persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: ng-ng2
labels:
web: nginx
namespace: default
spec:
capacity:
storage: 6Gi
accessModes: ["ReadWriteMany"]
nfs:
path: /mnt/k8s/ng2
readOnly: false
server: 192.168.0.108
persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: ng-ng3
labels:
web: nginx
namespace: default
spec:
capacity:
storage: 2Gi
accessModes: ["ReadWriteMany"]
nfs:
path: /mnt/k8s/ng3
readOnly: false
server: 192.168.0.108
persistentVolumeReclaimPolicy: Delete
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: ng-ng4
labels:
web: nginx
namespace: default
spec:
capacity:
storage: 4Gi
accessModes: ["ReadWriteMany"]
nfs:
path: /mnt/k8s/ng4
readOnly: false
server: 192.168.0.108
persistentVolumeReclaimPolicy: Delete
PV的访问模式pv.spec.accessModes
RWO - ReadWriteOnce:可读科写,但支持被单个node挂载,一个PV可以被单个Pod以读写方式挂载。
ROX - ReadOnlyMany:可以只读的方式被多个node挂载,意味着PV可以同时被多个Pod挂载,并且这些Pod只读不可写入PV中的数据
RWX - ReadWriteMany:可以以读写的方式被多个node挂载,意味着PV可以同时被多个Pod挂载,并且这些Pod可以读取和写入PV中的数据。
PV回收的时候先删除pvc再删除pv,重建pv不会重建已经之前创建的pv。
- 创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nginx
labels:
web: pvc-ng
namespace: default
spec:
accessModes: ["ReadWriteMany"]
resources:
limits:
storage: 8Gi
requests:
storage: 2Gi
# storage:
pvc匹配pv的时候:根据大小(storage: 1G),访问方式(accessModes: [“ReadWriteOnce”])进行匹配
- 挂载pvc
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dy
labels:
web: nginx
namespace: default
annotations:
dac: " image version to v1.0"
spec:
minReadySeconds: 10
#新创建的Pod成为就绪状态之前,Deployment控制器等待的最短时间(秒数)。确保Pod中的业务程序能正常工作之前有做狗的时候完成初始化和准备工作。
paused: false
progressDeadlineSeconds: 60
#该字段用于指定部署操作的进度检查的超时时间(以秒为单位)。这个字段的作用是为了确保部署操作能够在指定的时间内完成,并在超时后进行相应的处理。
replicas: 4
revisionHistoryLimit: 5
#该用于指定要保留的 Deployment 版本历史记录的最大数量。Deployment 版本历史记录包含了过去创建的每个 Deployment 的详细信息,包括创建时间、更新时间、副本数量等。
#如果设置为 0,则不会保留任何历史记录;如果设置为负值,则表示将保留所有历史记录。
selector:
matchLabels:
ser: nginx-test
strategy:
#定义滚动更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
name: nginx
#namespeace
labels:
ser: nginx-test
spec:
nodeSelector:
app: to
hostname: nginx-dy
containers:
- image: docker.io/library/nginx:v1
name: nginx-dy
imagePullPolicy: IfNotPresent
ports:
- name: nginx-post
containerPort: 80
volumeMounts:
- name: nginx-pvc
mountPath: /home
readOnly: false
#为true为只读方式挂载
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: pvc-nginx
PV简单操作
导出废弃PV:
kubectl get pv -o custom-columns=STATUS:.status.phase,PATH:.spec.nfs.path |grep Released |awk '{print $2}' > 156.txt
清理废弃PV:
#!/bin/bash
whiteList=`kubectl get pv |grep Released |awk '{print $1}'`
echo "${whiteList}" | while read line
do
kubectl patch pv ${line} -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}'
done