【云原生|K8S系列】不再迷茫!跟随这份攻略,10分钟了解K8S持久化存储!

Kubernetes(简称K8s)是一种强大的容器编排工具,能够自动化应用程序的部署、扩展和管理。在Kubernetes中,存储是一个关键组件,因为它允许状态化应用程序在容器中运行。本文将介绍Kubernetes存储的基础知识、不同的存储类型,以及如何配置和使用Kubernetes存储。

存储类型

Kubernetes支持多种类型的存储卷,可以将存储空间挂载到 Pod 中的容器中。以下是一些常见的 Kubernetes存储卷类型:

k8s存储类型
  • EmptyDir:这是一个临时目录,会在 Pod 创建时在节点上创建,并在 Pod 删除时自动删除。它是临时的,并且不能跨多个节点共享。

  • HostPath:此存储卷允许您将宿主机上的某个路径映射到容器中。它主要用于测试和开发目的,不建议在生产环境中使用。

  • PV&PVCPV是一种可在整个集群中共享的持久性存储资源,而 PVC 则是用户请求的一种持久性存储。PV 可以由管理员预先创建并定义其大小和访问模式,然后由用户通过 PVC 请求使用

  • ConfigMap&Secret:这两种特殊类型的存储卷允许您将配置文件和加密数据插入到容器中。它们可以通过存储卷来挂载,也可以通过环境变量或命令行参数来传递给容器。

  • StorageClass:这是一个Kubernetes对象,用于定义一组持久性存储参数和行为,以便用户可以根据需要创建和管理持久性存储卷。

在了解了k8s存储类型的基础, 我们可以通过具体案例进一步探讨 k8s的不同存储类型及其应用场景。以下示例将详细阐述如何在实际应用中使用这些存储类型,帮助您更好地掌握k8s存储的配置和管理。

EmptyDir

EmptyDirKubernetes中的一种Volume类型,用于在同一个Pod中的不同容器之间共享临时数据。以下是一个使用EmptyDir的完整示例:

EmptyDir案例

在这个示例中,我们创建了一个包含两个容器的Pod,并使用EmptyDir在这两个容器之间共享数据。具体配置如下:

  • 容器1
    • 使用 busybox 镜像。

    • 执行命令:在 /mnt/data/message 文件中写入Hello from Container 1

    • 挂载共享卷到 /mnt/data

  • 容器2
    • 使用 busybox 镜像。

    • 执行命令:读取并显示 /mnt/data/message 文件的内容。

    • 挂载共享卷到 /mnt/data

  • EmptyDir 卷
    • 定义一个名为 shared-dataEmptyDir卷。

    • 两个容器都挂载该卷,以共享数据。

EmptyDir卷在Pod生命周期内是持久的,但在Pod被删除后,数据将会丢失。这种卷类型非常适用于需要在同一个Pod内的多个容器之间共享临时数据的场景。

HostPath

HostPathKubernetes中的一种 Volume类型,允许将主机(节点)上的文件或目录挂载到Pod中。这使得容器可以直接访问主机的文件系统资源。以下是一个使用HostPath的完整示例:

HostPath

在这个示例中,我们创建了一个包含一个容器的 Pod,并使用 HostPath 将主机上的目录挂载到容器中。具体配置如下:

  • 容器
    • 使用 busybox 镜像。

    • 执行命令:每隔10秒读取并显示 /mnt/host/data.txt 文件的内容。

    • 挂载 HostPath 卷到 /mnt/host

  • HostPath 卷
    • 定义一个名为 host-data 的 HostPath 卷。

    • 将主机上的 /data 目录挂载到容器内的 /mnt/host 路径。

    • 如果 /data 目录不存在,会自动创建。

使用 HostPath可以方便地在容器中访问和操作主机上的文件系统资源,适用于需要直接使用主机文件系统的场景。然而,由于HostPath存在安全和隔离性问题,通常只建议在开发、测试环境中使用,不推荐在生产环境中使用。

PV&PVC

PV(Persistent Volume)

PV(Persistent Volume)是集群中的持久化存储卷,代表实际的存储资源。它是全局资源,不受命名空间的限制。PV 的生命周期独立于Pod,即使没有被Pod使用,PV仍然存在于集群中。这使得PV可以在不同的Pod之间共享和重用,从而提供稳定的存储解决方案。


apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv # PV 的名称
spec:
capacity:
storage: 2Gi # PV 的容量为 2GB
volumeMode: Filesystem # 指定 PV 的文件系统类型
accessModes:
- ReadWriteMany # 设置 PV 的访问模式为 ReadWriteMany,即多个节点可以同时读写
persistentVolumeReclaimPolicy: Retain # 设置 PV 的回收策略为 Retain,保留 PV 的数据
storageClassName: nfs-storage # 引用的 StorageClass 的名称
mountOptions:
- vers=4.1 # 挂载选项,指定 NFS 版本为 4.1
nfs:
path: /your/nfs/path # 指定 NFS 服务器上的共享路径
server: your.nfs.server.ip # 指定 NFS 服务器的 IP 地址

PVC(Persistent Volume Claim)

PVC(PersistentVolumeClaim)PodPV(PersistentVolume)的请求,用于声明存储需求,包括容量、访问模式等。通过PVCPod可以请求连接到PV提供的存储资源。Kubernetes会自动匹配符合条件的PV,并将PVCPV绑定。如何创建PVC呢?示例如下:


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc # PVC 的名称
namespace: middleware # PVC 所在的命名空间
spec:
accessModes:
- ReadWriteMany # 设置 PVC 的访问模式为 ReadWriteMany,与 PV 一致
storageClassName: nfs-storage # 引用的 StorageClass 的名称,与 PV 一致
resources:
requests:
storage: 2Gi # 申请的存储容量为 2GB

注意storageClassName部分,这个字段,PVC要与其想申请的PV保持一致。

PVC与PV的成功绑定,有两个条件:(1)PVspec信息满足PVC的要求(如存储容量、访问模式等)。(2)PV PVCstorageClassName字段的值需一致。

有了PVCPV的组合,我们可以在需要持久化存储时向Kubernetes申请 PV。然而,PV仍然需要运维人员提前创建。那么,有没有一种方法可以实现动态创建PV呢?答案就是使用StorageClass和存储插件。

StorageClass与存储插件

StorageClass和存储插件是实现动态创建PV的一种方式。StorageClass定义了动态分配存储的属性,如存储类型、访问模式等,并指定使用的存储插件,这些插件通常与外部存储系统(如 CephNFS 等)相关。当 PVC 请求动态分配存储时,由 StorageClass 指定的存储插件会负责创建 PVKuberneteskube-controller-manager 组件则会将 PVPVC 绑定在一起。

如何创建StorageClass 呢?示例如下:

apiVersion: storage.k8s.io/v1  # Kubernetes API 版本
kind: StorageClass # 定义资源类型为 StorageClass
metadata:
name: local-path # StorageClass 的名称
provisioner: rancher.io/local-path # 使用的存储插件
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

需要注意的是,存储插件需要我们提前安装到K8S集群中。这里使用的rancher.io/local-path是存储插件的一种。OpenEBS(Open Elastic Block Storage)是一个开源的容器化存储平台,旨在为 Kubernetes 提供动态和分布式的块存储。它允许用户通过 PVC在 Kubernetes 集群中动态创建和管理存储卷。

这样我们就可以通过以下方式创建PVC,存储插件会创建PV,之后K8S会将此PV与我们的PVC绑定。


apiVersion: v1 # Kubernetes API 版本
kind: PersistentVolumeClaim # 定义资源类型为 PersistentVolumeClaim
metadata:
name: mypvc # PVC 的名称
spec:
storageClassName: local-path # 指定使用的 StorageClass 为 openebs
accessModes:
- ReadWriteOnce # 访问模式为 ReadWriteOnce
resources:
requests:
storage: 1Gi # 请求存储容量为 1Gi

我们如何在应用中使用以上PVC呢?还是以创建nginx为例:

apiVersion: apps/v1  # 使用的 Kubernetes API 版本
kind: Deployment # 定义部署对象
metadata:
name: nginx # 部署的名称
spec:
replicas: 1 # 副本数为 1,即只运行一个 Pod
selector:
matchLabels:
app: nginx # 根据标签选择 Pod
template:
metadata:
labels:
app: nginx # Pod 的标签
spec:
containers:
- name: nginx # 容器名称
image: nginx:latest # 使用的 Docker 镜像
ports:
- containerPort: 80 # 容器监听的端口
volumeMounts:
- name: nginx-storage # 挂载名为 data 的 Volume
mountPath: /usr/share/nginx/html # 挂载到容器的路径
volumes:
- name: nginx-storage # 定义名为 data 的 Volume
persistentVolumeClaim:
claimName: mypvc # 指定使用的 PVC 名称

ConfigMap&Secret

Kubernetes 中的 ConfigMapSecret 是两种特殊类型的存储卷,用于在容器中注入配置信息和敏感数据。

ConfigMap

ConfigMap允许您将配置文件、环境变量或命令行参数传递给容器。它通过将非敏感的配置信息以键值对的形式存储,使得应用程序配置与容器镜像分离,从而更容易管理和更新。以下是一个使用 ConfigMap 的示例:

apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
data:
app.properties: |
database_url=jdbc:mysql://localhost:3306/mydb
database_user=root
database_password=password

然后在Pod中使用 ConfigMap

apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- mountPath: /etc/config
name: config-volume
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: example-config # 该字段是对应ConfigMap中的metadata.name
key: database_url
volumes:
- name: config-volume
configMap:
name: example-config ## 该字段是对应ConfigMap中的metadata.name

Secret

Secret 用于存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。Secret 通过 Base64 编码存储数据,提供了更高的安全性。以下是一个使用 Secret 的示例:

apiVersion: v1
kind: Secret
metadata:
name: example-secret
type: Opaque
data:
password: cGFzc3dvcmQ=

然后在Pod中使用 Secret

apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- mountPath: /etc/secret
name: secret-volume # 这个字段与volumes.name是一致
env:
- name: PASSWORD
valueFrom:
secretKeyRef:
name: example-secret # 这个字段与secretName是一致
key: password
volumes:
- name: secret-volume
secret:
secretName: example-secret

总结

Kubernetes 提供了多种存储解决方案,以满足不同的应用需求。持久化存储方面,通过 PVPVC,我们可以实现存储资源的动态分配和管理,而 StorageClass 结合存储插件则进一步简化了 PV 的动态创建。对于临时和本地存储,Kubernetes 提供了 emptyDirHostPath,分别用于 Pod 内部容器间的临时数据共享和直接访问主机文件系统。此外,特殊类型的存储卷如 ConfigMapSecret,帮助我们更安全、便捷地管理应用配置和敏感数据。通过这些灵活多样的存储机制,Kubernetes 有效支持了应用的持久化和高可用性需求。

推荐文章


相关推荐

  • 最高贴息1000万!杭州14条重磅AI新政发布,每年发2.5亿元算力券
  • 扎克伯格深度专访:中美AI竞争完全错误,美国别想长期领先中国
  • 云巨头大暴走,自研CPU落地200万张!新一轮芯片洗牌开始了
  • 基于大模型 + 知识库的 Code Review 实践
  • AI编程哪家强?一次对比4大编程助手
  • “开源模型是智商税” v.s. “开源AI是前进的道路”
  • 苹果iPhone 15 Pro跑起精简版Win11
  • 成都最硬核的公司,陆奇投了
  • 美团后端日常实习面试,轻松拿捏了!
  • 深入分析 C++ 错误处理:哪种策略的性能最强?
  • “Llama 会成为 AI 界的 Linux”,扎克伯格最新访谈出炉!最强模型 Llama 3.1 来了
  • 在 iPad 上「复活」WinXP!耗时 2.5 小时后,用户直呼:“这就是我一直想要的”
  • Java新闻汇总:JDK 24更新、Spring Framework、Piranha Cloud、Gradle 8.9
  • Rich Harris 承诺:使用 Svelte 5.0 你将编写更少的代码
  • 人工智能如何助力书写“数字金融”大文章
  • 业技融合难、ROI 不划算:金融大模型落地的两大困境有解吗?
  • 新晋开源顶流模型 Llama 3.1 被开发者赞爆!小扎拿苹果“开刀”反对闭源厂商:AI 不要“苹果税”!
  • 复旦大学:没钱标数据的有福了!利用合成数据就能大幅提升大模型归纳推理能力
  • ICML 2024十篇最佳论文开奖!贾扬清十年经典之作获时间检验奖
  • 开源Llama 3.1一夜成最强大模型!超越闭源GPT-4o,OpenAI坐不住了