文章目录
概述
在虚拟机的环境中,应用程序的数据通常存储在本地磁盘上,即使重启虚拟机也不会数据丢失。但是在 pod 中。pod 的特点就是 “临时性” ,随着 pod 的重建,容器中的数据也会消失,这将导致一些应用程序读不到之前的数据。因此 pod 引入了持久化这个概念,也就是 “卷”
卷
卷是 pod 中存储数据和共享数据的一个抽象概念。它提供了一种将存储设备挂载进容器的机制。
卷的常用类型
卷的分类 | 卷类型 | 说明 |
---|---|---|
临时存储 | emptyDir | 用于 pod 中,容器之间的共享 |
本地存储 | hostPath | 将节点文件系统上的文件或者目录挂载到 pod 中 |
对象存储 | ConfigMap,Secret | k8s 内置的存储对象,用于存储应用程序配置和敏感数据 |
自建存储系统 | NFS,Ceph,ISCSI | 将自建的存储系统挂载到 pod 中 |
存储对象 | persistentVolumesClaim(PVC) | 与 PV 持久卷配合使用 |
emptyDir
empytDir 用于在 pod 中实现容器之间的数据共享,与 pod 的生命周期一致,当 pod 被删除时,对应的目录也会销毁
[root@k8s-master ~]# cat emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
spec:
containers:
- image: docker.io/library/centos:latest
imagePullPolicy: IfNotPresent
name: app
command: ["/bin/sh","-c","for i in {1..10000};do echo $i >> /opt/file.txt;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /opt
- image: docker.io/library/centos:latest
imagePullPolicy: IfNotPresent
name: sidecar # 边车容器
command: ["/bin/sh","-c","tail -f /opt/file.txt"]
volumeMounts:
- name: data
mountPath: /opt
volumes:
- name: data
emptyDir: {}
[root@k8s-master ~]# kubectl apply -f emptyDir.yaml
pod/pod-emptydir created
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-emptydir 2/2 Running 0 3s
在上面的例子中,我们定义了两个容器和一个 emptyDir 卷,该卷被挂载到两个容器中的同一个目录下了,因此该目录中的文件可以被彼此访问
[root@k8s-master ~]# kubectl exec -it pod-emptydir --container app -- /bin/bash
Defaulted container "app" out of: app, sidecar
[root@pod-emptydir /]# cd opt/
[root@pod-emptydir opt]# ls
file.txt
[root@k8s-master ~]# kubectl exec -it pod-emptydir --container sidecar -- /bin/bash
[root@pod-emptydir /]# cd opt/
[root@pod-emptydir opt]# ls
file.txt
边车容器
边车容器(Sidecar Container)是与主应用容器在同一个Pod中运行的辅助容器。它们通过提供额外的服务或功能(如日志记录、监控、安全性或数据同步)来增强或扩展主应用容器的功能,而无需直接修改主应用代码。边车容器与主容器共享网络和存储命名空间,使得它们能够紧密交互并共享资源。
除了边车容器,Kubernetes还支持其他类型的容器,包括:
-
标准容器(Application Containers):这是最常见的容器类型,用于运行主要的应用逻辑。
-
Init 容器:这些容器在应用容器启动之前运行,用于执行一些初始化任务,比如设置配置文件或者等待外部服务就绪。Init 容器在Pod中的所有应用容器启动前完成执行并退出。
-
Ephemeral 容器:这是一种临时性的容器,它们缺少对资源或执行的保证,并且永远不会自动重启。Ephemeral 容器主要用于调试目的,允许用户加入一个临时容器到正在运行的Pod中,用于调试。
HostPath
hostpath 卷用来将宿主机的目录挂载进容器,这使得容器可以访问宿主机的数据,由于挂载的是宿主机的目录,因此在容器被销毁后,数据并不会丢失。
但是在 k8s 卷的分类中,我们还有一个专门做持久卷的,名叫 PV/PVC 。那这两种挂载方式到底差距在哪呢:
HostPath:
- 直接挂载宿主机本地路径到容器,适合单节点和开发环境。
- 不支持跨节点存储,数据与特定节点绑定。
- 无自动扩展功能,存储容量和管理完全依赖宿主机。
- 没有 Kubernetes 对存储的生命周期管理,容器删除后数据可能丢失。
PV/PVC:
- Kubernetes 管理的持久化存储,可以通过 PVC 请求动态存储资源。
- 支持跨节点、云存储等多种后端,具备高可用性和扩展性。
- 具备自动扩展、容量管理和存储生命周期管理功能。
- 支持不同存储策略(如保留、删除等),适用于生产环境。
那我们在 yaml 文件中如何挂载它呢?
[root@k8s-master ~]# cat hostPath.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: hostpath-container
image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: hostpath-volume
mountPath: /usr/share/nginx/html
volumes:
- name: hostpath-volume
hostPath:
path: /data # 这会挂载宿主机的 /data 目录到容器的 /usr/share/nginx/html 目录
type: DirectoryOrCreate
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
hostpath-pod 1/1 Running 0 4s
在该 yaml 文件中,我们将 /usr/share/nginx/html 挂载到容器里面的 data 目录下了
hostPath 所支持的卷的类型 (这些参数在 yaml 文件中有对应)
取值 | 作用 |
---|---|
”“ | 该字段为空或者未指定,默认是 DirectoryOrCreate |
DirectoryOrCreate | 如果指定的目录不存在,则会自动创建空目录并为其赋值 0755 |
Directory | 指定的目录必须存在 |
FileOrCreate | 和上面那个差不多,在空文件被创建出来之后默认赋权 0644 |
File | 指定文件必须存在 |
Socket | 指定套接字文件必须存在 |
CharDevice | 指定的字符设备必须存在 |
BlockDevice | 指定的块设备必须存在 |
k8s 在 pod 启动时会检查路径是否与期望类型所匹配,如果不匹配或者类型检查异常,pod 会呈现 ContainerCreateing 状态
hostpath 卷不支持存储容器限制,并且可使用的存储容量受主机文件系统限制
nfs
将 nfs 服务器挂载到 pod 中,实现 pod 之间的数据共享。我们在之前还提到过