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 和调试工具)。

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

相关推荐
汪碧康20 分钟前
一文掌握k8s的升级更新策略
云原生·容器·kubernetes·k8s·亲和性·xkube
汪碧康6 小时前
一文掌握k8s的健康检查探针
云原生·容器·kubernetes·k8s·xkube·k8s管理平台
汪碧康1 天前
一文掌握k8s容器的资源限制
docker·云原生·容器·golang·kubernetes·k8s·xkube
会飞的土拨鼠呀2 天前
kubectl 常用命令
k8s
岁岁种桃花儿4 天前
【K8s实战】从Ingress到Pod:微服务完整部署架构全解析
k8s
fanruitian6 天前
使用harbor搭建私有仓库
k8s·harbor
潞哥的博客6 天前
Ingress nginx退役,该怎么换,gateway api 上线
运维·gateway·k8s
Y.O.U..11 天前
Kubernetes-控制器介绍
k8s
大都督老师11 天前
配置 containerd 使用镜像加速器拉取 Docker Hub 镜像
容器·kubernetes·k8s