Kubernetes 持久化存储与特殊容器

在 Kubernetes 集群中,容器的生命周期是短暂的,当 Pod 被删除或重启时,容器内的数据会随之丢失。对于 MySQL、Redis 等需要持久化数据的应用来说,持久化存储至关重要。同时,Kubernetes 还提供了特殊容器来应对特定场景的需求,本文将详细介绍这些内容。

一、Kubernetes 持久化存储

1. hostPath 存储

hostPath Volume 允许 Pod 挂载宿主机上的目录或文件,使得容器可以使用宿主机的文件系统进行存储。其生命周期独立于 Pod,只要 Pod 被调度到同一个节点,数据就不会丢失。

创建使用 hostPath 的 Pod

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  nodeName: k8s-node2  # 指定调度  containers:
  - image: nginx
    name: test-nginx
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data
      type: DirectoryOrCreate  # 目录存在则使用,不存在则创建

缺点:存在单点故障,Pod 重新创建必须调度到同一个节点才能保证数据不丢失。

2. NFS 存储

为解决 hostPath 的单点故障问题,可以使用 NFS 作为持久化存储,NFS 支持多个客户端挂载。

搭建 NFS 服务

  1. 在服务端安装 nfs-utils 并创建共享目录

shell

复制代码
yum install -y nfs-utils
mkdir /data -pv
  1. 配置共享目录

shell

复制代码
vim /etc/exports
/data 192.168.166.0/24(rw,sync,no_root_squash,no_subtree_check)
systemctl enable --now nfs
exportfs -avr  # 使配置生效
  1. 在所有 worker 节点安装 nfs-utils

shell

复制代码
yum install nfs-utils -y
systemctl enable --now nfs

创建使用 NFS 的 Pod

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-nfs
spec:
  containers:
  - name: test-nfs
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      protocol: TCP
    volumeMounts:
    - name: nfs-volumes
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nfs-volumes
    nfs:
      path: /data  # 共享目录
      server: 192.168.166.7  # NFS 服务器地址

3. PV 与 PVC

  • PV(PersistentVolume):集群中的一块存储,由管理员配置,是集群资源,生命周期独立于使用它的 Pod。
  • PVC(PersistentVolumeClaim):用户对存储资源的请求,类似于 Pod 请求节点资源,PVC 可以请求特定大小和访问模式的存储。

PV 和 PVC 的工作原理

  1. 供应:静态(管理员创建 PV)或动态(基于 StorageClass 自动创建)
  2. 绑定:用户创建 PVC 后,Kubernetes 会寻找匹配的 PV 进行绑定,未找到则 PVC 处于未绑定状态
  3. 使用:Pod 通过 PVC 使用存储资源,PVC 和 PV 一一对应
  4. 回收
    • Retain:删除 PVC 后,PV 仍存在且处于 released 状态,数据保留,需手动处理才能再次使用
    • Delete:删除 PVC 时,PV 会从 Kubernetes 中移除,相关存储资产也会被删除

创建 PV 和 PVC

  1. 先创建 NFS 共享目录

shell

复制代码
mkdir /data/v{1..10} -p
  1. 创建 PVC

yaml

复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
  1. 应用 PVC 配置

shell

复制代码
kubectl apply -f my-pvc.yaml
  1. 查看 PV 和 PVC 状态,STATUS 为 Bound 表示绑定成功

shell

复制代码
kubectl get pv

创建使用 PVC 的 Pod

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-pvc
spec:
  containers:
  - name: pod-pvc
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: nginx-html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nginx-html
    persistentVolumeClaim:
      claimName: my-pvc

4. StorageClass

当 PVC 数量众多时,手动创建 PV 维护成本高,Kubernetes 提供 StorageClass 机制实现 PV 的自动创建,它相当于创建 PV 的模板。

StorageClass 运行原理

  • 包含 provisioner(供应商)、parameters 和 reclaimPolicy 等字段
  • provisioner 决定使用哪种存储创建 PV,可由内部或外部供应商提供
  • 支持卷扩展(allowVolumeExpansion),但仅支持扩容

搭建 StorageClass + NFS 步骤

  1. 创建可用的 NFS Server
  2. 创建 Service Account,用于管控 NFS provisioner 在集群中的运行权限
  3. 创建 StorageClass,负责建立 PVC 并调用 NFS provisioner
  4. 创建 NFS provisioner,其功能是在 NFS 共享目录下创建挂载点并建立 PV 与挂载点的关联

创建使用 StorageClass 的 PVC 和 Pod:通过 StorageClass 动态生成 PV,创建 PVC 后,Kubernetes 会自动创建对应的 PV,Pod 挂载该 PVC 即可使用存储。

二、Kubernetes 特殊容器

1. Init 初始化容器

Init 容器在主容器启动之前运行,用于解决服务依赖问题、进行初始化配置等。

应用场景

  • 等待其他模块 Ready,如 Web 服务等待数据库启动
  • 做初始化配置,如为主容器准备集群配置信息
  • 将 Pod 注册到中央数据库、配置中心等

使用案例

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: init-demo
  labels:
    demo: init-demo
spec:
  containers:
  - name: init-demo
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-demo1
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice;sleep 2; done;']
  - name: init-demo2
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2;done;']
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - port: 5566
    targetPort: 6655
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 8899
    targetPort: 9988
    protocol: TCP

2. 临时容器(Ephemeral Containers)

临时容器用于交互式故障排查,当容器崩溃或镜像不包含调试工具时特别有用,例如 Distroless 镜像(轻量级镜像,不含 Shell 和调试工具)。

使用时启用进程名称空间共享有助于查看其他容器中的进程

相关推荐
退役小学生呀3 天前
二十六、K8s集群备份恢复
linux·云原生·容器·kubernetes·k8s
悬弧6 天前
第2章:工作负载管理 - 可视化应用部署
kubernetes·k8s
fushan20126 天前
Windows 虚拟机配置与驱动安装记录
windows·k8s·vm·kubevirt
一只栖枝6 天前
K8s 认证级别怎么选?适配不同运维场景
云原生·容器·kubernetes·k8s·cka
虚伪的空想家6 天前
首发:TDengine3.3.6版本使用K8S部署
java·docker·容器·kubernetes·k8s·时序数据库·tdengine
新手小白*6 天前
K8S-Ingress资源对象
k8s
阿拉斯攀登6 天前
Kubernetes(K8s)全面解析:核心概念、架构与实践
docker·云原生·容器·kubernetes·k8s
小坏讲微服务7 天前
K8S 部署 Spring Cloud Alibaba 微服务企业实战完整使用
spring cloud·docker·微服务·云原生·容器·kubernetes·k8s
新手小白*7 天前
K8S-Statefulset控制器
k8s