1. Kubernetes中的卷是什么,ConfigMap和Secret是卷吗?

在 Kubernetes 中,卷(Volume) 是一种用于将数据持久化或共享到容器中的机制。与容器的生命周期不同,卷的生命周期独立于容器,即使容器被销毁或重启,卷中的数据仍然可以保留。

Kubernetes 支持多种类型的卷,例如:

  • emptyDir:容器临时目录,Pod 删除时数据会丢失。

  • hostPath:将宿主机的文件或目录挂载到容器中。

  • persistentVolumeClaim(PVC):绑定到持久化存储(如 NFS、云盘等)。

  • configMapsecret:将配置数据或敏感信息注入到容器中。

ConfigMap 和 Secret 是卷吗?

是的,ConfigMapSecret 都属于卷类型,它们可以作为特殊的卷挂载到容器中,用于传递配置信息或敏感数据。


2. 有哪些常用的本地存储卷

在 Kubernetes 中,本地存储卷(Local Volumes) 通常用于需要高性能或数据持久化需求的场景。以下是一些常用的本地存储卷类型及其用途:


1. emptyDir

  • 用途:临时目录,Pod 被删除时数据也会被清除。

  • 特点

    • 数据仅存在于 Pod 生命周期内。

    • 可用于容器间共享数据。

    • 适用于缓存、临时文件等场景。

2. hostPath

  • 用途:将宿主机上的文件或目录挂载到容器中。

  • 特点

    • 数据持久化在宿主机上。

    • 适用于调试、日志收集等场景。

    • 需要确保宿主机路径存在,并具有正确权限。

3. local

  • 用途:基于节点本地磁盘的持久化存储。

  • 特点

    • PersistentVolumePersistentVolumeClaim 结合使用。

    • 适用于生产环境中的持久化需求。

    • 需要在 Kubernetes 集群中手动创建 PersistentVolume

4. nfs

  • 用途:通过 NFS 挂载远程文件系统。

  • 特点

    • 多个 Pod 可以共享访问同一份数据。

    • 适用于分布式应用。

    • 需要配置 NFS 服务器。

5. persistentVolumeClaim (PVC)

  • 用途:动态分配和管理存储资源。

  • 特点

    • 与底层存储实现解耦。

    • 支持多种存储后端(如云盘、Ceph、GlusterFS 等)。

    • 是推荐的持久化存储方式。

6. csi (Container Storage Interface)

  • 用途:通过插件机制支持第三方存储系统。

  • 特点

    • 支持各种存储供应商(如 AWS EBS、Azure Disk、GCP PD 等)。

    • 提供灵活的存储扩展能力。

    • 需要安装相应的 CSI 驱动。


3. emptyDir 卷的生命周期是什么?有哪些使用场景

在 Kubernetes 中,emptyDir 是一种最简单的本地存储卷类型。它的生命周期与挂载它的 Pod 紧密相关。


emptyDir 卷的生命周期

  • 创建:当 Pod 被分配到某个节点上时,Kubernetes 会自动在该节点上创建一个空目录(即 emptyDir)。

  • 使用:该目录可以被 Pod 中的一个或多个容器挂载并读写数据。

  • 删除

    • 当 Pod 被删除时,emptyDir 中的数据也会被永久删除

    • 如果容器崩溃或重启,只要 Pod 没有被删除,数据仍然保留。

总结emptyDir 的生命周期 = Pod 的生命周期。Pod 删除 → 数据丢失。


4. hostPath 卷有哪些典型风险,应该在什么场景下使用

在 Kubernetes 中,hostPath 卷是一种将宿主机文件系统中的文件或目录挂载到 Pod 中的存储方式。虽然它提供了持久化数据的能力,但由于其与节点紧密耦合,存在一些典型风险


hostPath 卷的典型风险

1. 安全风险

  • 权限问题:Pod 可以访问宿主机上的任意文件,可能导致敏感信息泄露或被恶意修改。

  • 提权攻击:如果容器具有 root 权限,可能通过挂载的 hostPath 挂载 /proc/etc 等关键目录,进而实现对宿主机的控制。

2. 可移植性差

  • 节点绑定hostPath 是节点本地路径,Pod 被调度到其他节点时无法访问相同的数据,导致应用不可用。

  • 集群扩展困难:当节点数量增加或更换节点时,需要手动同步数据,维护成本高。

3. 运维复杂度高

  • 数据清理困难:Pod 删除后,hostPath 中的数据不会自动清理,需人工干预。

  • 版本不一致:不同节点上挂载路径的内容可能不一致,容易引发环境差异问题。

4. 资源冲突

  • 多个 Pod 同时使用:如果多个 Pod 挂载相同的 hostPath 目录,可能会造成写入冲突或数据损坏。

推荐使用场景

尽管存在上述风险,但在某些特定场景下,hostPath 仍然是一个有用的工具:

1. 调试用途

  • 临时查看日志或配置文件:例如挂载 /var/log/etc/kubernetes 用于调试。

  • 快速验证功能:开发测试阶段用于快速验证挂载逻辑。

2. 节点级服务

  • DaemonSet 类型的服务:如日志收集器(Fluentd)、监控组件(Prometheus Node Exporter)等,通常每个节点只需运行一个实例,并且依赖于本机资源。

3. Kubernetes 组件自身需求

  • kube-proxy、kubelet 等核心组件:它们通常需要访问节点本地的资源(如 /lib/modules/sys),因此会使用 hostPath 挂载。


5. 什么是PV,什么是PVC,两者有什么关系

在 Kubernetes 中,PV(PersistentVolume) 和 PVC(PersistentVolumeClaim) 是用于管理持久化存储的核心资源对象。它们共同构成了 Kubernetes 的声明式存储模型。

什么是 PV?

  • PV 是集群中的一块网络存储资源,由管理员预先配置或通过 StorageClass 动态创建。

  • 它独立于 Pod 生命周期存在,提供持久化的数据存储能力。

  • 支持多种后端存储类型,如 NFS、Ceph、云厂商磁盘(AWS EBS、GCP PD、阿里云云盘等)、本地磁盘等。

PV 的关键属性:

属性

说明

capacity

存储容量大小,例如 storage: 10Gi

accessModes

访问模式,如 ReadWriteOnceReadWriteManyReadOnlyMany

reclaimPolicy

回收策略,如 RetainRecycleDelete

storageClassName

关联的 StorageClass 名称

volumeMode

卷模式,支持 FilesystemBlock

什么是 PVC?

  • PVC 是用户对存储资源的“申请”,它描述了用户对存储的需求(大小、访问模式等)。

  • Kubernetes 系统会根据 PVC 的需求自动绑定一个合适的 PV。

  • 用户不需要关心底层存储实现,只需声明所需资源即可。

PVC 的关键属性:

属性

说明

resources.requests.storage

请求的存储空间大小

accessModes

请求的访问模式

storageClassName

指定要使用的 StorageClass 名称(可选)

volumeName

可选字段,指定具体 PV 名字进行绑定


6. 找一台集群外的,同局域网集群搭建一个NFS服务,如果不具备条件,可以使用K8s集群内的机器进行搭建

在NFSserver上安装NFS服务

sudo apt update
sudo apt install -y nfs-kernel-server

创建共享服务

sudo mkdir -p /srv/nfs/k8s-data

设置共享权限

在/etc/exports下设置

/srv/nfs/k8s-data 192.168.75.0/24(rw,sync,no_subtree_check,no_root_squash)

应用并重启服务

sudo exportfs -a
sudo systemctl restart nfs-kernel-server


7. 创建Pod直接挂载上面创建的NFS

创建一个以下yaml:

apiVersion: v1
kind: Pod
metadata:
  name: direct-nfs-pod
spec:
  containers:
    - name: app-container
      image: nginx
      volumeMounts:
        - name: nfs-volume
          mountPath: /mnt/nfs
  volumes:
    - name: nfs-volume
      nfs:
        server: 192.168.75.130 //此处输入nfsserverip
        path: /srv/nfs/k8s-data


8. 使用上面的NFS创建静态PV和PVC,并使用pod挂载创建好的PVC

静态pvyaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  volumeMode: Filesystem
  nfs:
    server: 192.168.75.130
    path: /srv/nfs/k8s-data

静态pvc yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

创建一个使用nginx镜像,挂在pvc的yaml:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-nfs-pod
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - name: nfs-volume
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs-volume
      persistentVolumeClaim:
        claimName: nfs-pvc


9. 正常的删除PV流程是什么样的,删除上面创建的Pod、PVC和PV

一般流程如下:

# Step 1: 查看 PVC 绑定信息
kubectl describe pvc nfs-pvc

# Step 2: 删除引用该 PVC 的 Pod/Deployment
kubectl delete pod nfs-pod

# Step 3: 删除 PVC
kubectl delete pvc nfs-pvc

# Step 4: 查看 PV 状态(应为 Released)
kubectl get pv

# Step 5: 手动清理 NFS 数据(若必要)
ssh user@nfs-server "rm -rf /srv/nfs/k8s-data/*"

# Step 6: 删除 PV
kubectl delete pv nfs-pv


10. PV有哪些回收策略和访问模式,各有什么区别

在 Kubernetes 中,PersistentVolume(PV) 有两种关键属性:回收策略(Reclaim Policy) 和 访问模式(Access Mode)。它们分别决定了 PV 的生命周期管理和访问方式。

一、PV 的回收策略(Reclaim Policy)

回收策略定义了当 PVC 被删除后,PV 应该如何处理底层存储资源。

支持的回收策略

回收策略

描述

使用场景

Retain

手动回收,PVC 删除后 PV 进入 Released 状态,数据保留在底层存储中

生产环境推荐,防止误删数据

Recycle

自动清空 PV 数据(已弃用)

旧版本测试环境使用

Delete

自动删除 PV 及其对应的底层存储资源(如云盘)

动态供给的云存储环境

二、PV 的访问模式(Access Mode)

访问模式定义了 Pod 对 PV 的访问权限,影响多个 Pod 是否可以同时读写该卷。

✅ 支持的访问模式

访问模式

描述

是否支持多 Pod 共享

ReadWriteOnce (RWO)

卷可以被单个节点以读写方式挂载

不支持共享

ReadWriteMany (RWX)

卷可以被多个节点以读写方式挂载

支持共享

ReadOnlyMany (ROX)

卷可以被多个节点以只读方式挂载

支持共享

⚠️ 注意:不是所有存储类型都支持所有访问模式。例如:

  • hostPath 只支持 ReadWriteOnce

  • nfs 同时支持 ReadWriteOnceReadWriteMany

  • 云厂商磁盘(如 AWS EBS)通常仅支持 ReadWriteOnce


11. 如果 PVC 的状态为 Pending,常见的排查步骤有哪些

当 PVC(PersistentVolumeClaim)的状态为 Pending 时,说明它尚未成功绑定到一个合适的 PV(PersistentVolume)。

1. 查看 PVC 的状态和事件信息

kubectl describe pvc <pvc-name>

重点关注输出中的 Events 部分,例如:

Events:
  Type     Reason              Age                From                         Message
  ----     ------              ----               ----                         -------
  Warning  ProvisioningFailed  30s                persistentvolume-controller  no persistent volumes available for this claim and no storage class is set

常见错误信息包括:

  • no persistent volumes available

  • storage class not found

  • capacity request too large


2. 检查是否有匹配的 PV

kubectl get pv

确保有可用的 PV,并且其状态为 Available。然后检查以下字段是否与 PVC 匹配:

字段

是否匹配

spec.capacity.storage

PVC 请求的容量不能大于 PV 容量

spec.accessModes

PVC 的访问模式必须是 PV 支持的一个子集

spec.storageClassName

必须一致(或都为空)

spec.volumeMode

必须一致(Filesystem/Block)

3. 检查 PVC 是否指定了 StorageClass

spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

如果 PVC 指定了 storageClassName,则 Kubernetes 只会查找该类别的 PV 或尝试动态创建。

检查是否存在对应的 StorageClass:

kubectl get storageclass

4. 检查 StorageClass 是否设置为默认

如果你使用的是动态供给(如云厂商),请确认 StorageClass 是否设置了 is-default-class 注解:

kubectl get storageclass

5. 检查 PV 的状态和 reclaimPolicy

kubectl describe pv <pv-name>
  • 如果 PV 已被其他 PVC 占用(Bound),则当前 PVC 无法绑定。

  • 如果 PV 处于 Released 状态(即之前绑定的 PVC 被删除),你可以手动清理数据并将其恢复为 Available

6. 检查 NFS、hostPath 等后端存储是否正常

如果是 NFS 类型的 PV,需要确保:

  • NFS Server 正常运行;

  • 所有 Worker Node 可以访问 NFS;

  • 目录权限设置正确(如 no_root_squash);

  • nfs-common 已安装在所有节点上。

7. 检查 Pod 是否引用了正确的 PVC

如果你已经绑定了 PVC,但在 Pod 中仍然无法挂载,可能是:

  • PVC 名称拼写错误;

  • PVC 和 Pod 不在同一命名空间;

  • 使用了 subPath 但路径不存在;

  • 容器镜像不支持挂载路径(如只读文件系统)。

完整流程:

# 查看 PVC 详细信息
kubectl describe pvc my-pvc

# 查看 PV 列表及状态
kubectl get pv

# 查看 StorageClass
kubectl get storageclass

# 查看 PVC 所属 Pod 的状态
kubectl describe pod my-pod

# 查看 PVC 绑定的事件日志
kubectl describe pvc my-pvc | grep -A 10 Events

常见问题与解决办法总结

问题现象

原因

解决方案

PVC 一直 Pending

没有可用 PV

创建符合要求的 PV

PVC 报错 storage class not found

StorageClass 不存在

创建或指定存在的 StorageClass

PVC 报错 exceeded quota

资源配额不足

修改配额或调整 PVC 请求值

PVC 报错 no volume plugin matched

存储插件未就绪

安装所需插件或检查节点网络

PVC 成功 Bound 但 Pod 启动失败

挂载失败或权限问题

检查容器日志、NFS 权限、SELinux 设置等



12. 如果一个 Pod 无法挂载 PVC,如何通过 events 或日志排查原因

1. 查看 Pod 的 Events 信息

kubectl describe pod <pod-name>

2. 查看 PVC 状态和事件

kubectl describe pvc <pvc-name>

3. 查看 PV 的详细状态

kubectl describe pv <pv-name>

4. 登录到节点并查看 kubelet 日志

journalctl -u kubelet -n 100 | grep 'Mount failed'


13. 如何通过 PVC 挂载持久卷后,在多个 Pod 之间实现数据共享

1. 创建 PV 并设置 accessModes: ReadWriteMany

apiVersion: v1
kind: PersistentVolume
metadata:
  name: shared-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.1.100
    path: /srv/nfs/shared-data

2. 创建 PVC 并绑定该 PV

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

3. 创建多个 Pod 共享该 PVC

apiVersion: v1
kind: Pod
metadata:
  name: pod-a
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - name: shared-volume
          mountPath: /usr/share/nginx/html
  volumes:
    - name: shared-volume
      persistentVolumeClaim:
        claimName: shared-pvc


14. 如果删除了 PVC,绑定的 PV 会立刻被删除吗?什么时候会被保留

在 Kubernetes 中,删除 PVC(PersistentVolumeClaim)后,绑定的 PV(PersistentVolume)并不会立刻被删除,具体行为取决于 PV 的 persistentVolumeReclaimPolicy(回收策略)。


15. 如何验证 PVC 实际挂载到了容器的哪个路径下

方法

命令

适用场景

kubectl describe pod

kubectl describe pod <name>

快速查看挂载路径

进入容器执行命令

kubectl exec -it <pod> -- sh

验证实际读写能力

YAML 文件检查

cat pod.yaml

开发调试阶段确认配置

jsonpath 提取字段

kubectl get pod -o jsonpath=...

自动化脚本提取路径

crictl 查看挂载详情

crictl inspect <container-id>

排查底层挂载问题


16. 什么是动态制备卷,对比静态有哪些特点

在 Kubernetes 中,动态制备卷(Dynamic Volume Provisioning) 是一种自动创建持久化存储卷的机制,允许用户根据需求自动创建 PV(PersistentVolume),而无需手动预先定义 PV。这是通过 StorageClass 和 Provisioner 插件 实现的。

特性

静态卷(Static Volumes)

动态卷(Dynamic Volumes)

PV 创建方式

手动创建 PV

自动创建 PV(由 StorageClass 控制)

PVC 使用方式

PVC 绑定到已有 PV

PVC 触发动态创建 PV

灵活性

低(需提前准备 PV)

高(按需创建)

可扩展性

有限(需要手动维护 PV)

强(支持大规模集群自动化管理)

适用场景

小规模测试环境、NFS 等共享存储

生产环境、云厂商存储(如 AWS EBS、GCP PD、阿里云盘等)

StorageClass 使用

可选

必须配置

动态卷工作原理简述

  1. 用户创建一个 PVC,并指定 storageClassName

  2. Kubernetes 根据该 StorageClass 自动调用对应的 provisioner 插件;

  3. provisioner 在底层存储系统中创建一个新的卷(如云盘);

  4. 自动生成 PV 并绑定到 PVC;

  5. Pod 可以使用该 PVC 挂载新创建的卷。

1. 定义 StorageClass(例如 AWS EBS)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp2
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Delete
volumeBindingMode: Immediate

2. 创建 PVC 并引用该 StorageClass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: gp2
  resources:
    requests:
      storage: 10Gi


17. 尝试使用csi-driver-nfs实现动态制备卷

要在 Kubernetes 中使用 csi-driver-nfs 实现 动态制备卷(Dynamic Volume Provisioning),你需要完成以下步骤:

一、前提条件

  1. Kubernetes 集群版本 ≥ v1.20

  2. 已安装 CSI 驱动支持(默认启用)

  3. NFS Server 已部署并可访问

  4. 所有 Worker Node 安装了 NFS 客户端工具(如 nfs-common

二、部署 csi-driver-nfs

你可以通过 Helm 或 YAML 文件部署 csi-driver-nfs。以下是使用官方 YAML 的方式:

1. 克隆仓库(可选)

git clone https://github.com/kubernetes-csi/csi-driver-nfs.git
cd csi-driver-nfs

2. 部署 CSI Driver for NFS

kubectl apply -f deploy/

这将创建以下资源:

  • ServiceAccount、Role、RoleBinding

  • DaemonSet(部署在每个节点上)

  • Deployment(控制器组件)

确保 Pod 正常运行:

kubectl get pods -n kube-system | grep nfs-csi

三、创建 StorageClass

创建一个名为 nfs-csi 的 StorageClass,用于触发动态卷制备。

storageclass-nfs-csi.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
  server: 192.168.1.100       # 替换为你的 NFS Server 地址
  share: /srv/nfs/k8s-data    # 替换为你的 NFS 共享路径
reclaimPolicy: Retain         # 可选 Delete
volumeBindingMode: Immediate
mountOptions:
  - hard
  - nfsvers=4.1               # 根据你的 NFS 版本调整
kubectl apply -f storageclass-nfs-csi.yaml

四、创建 PVC 并验证动态制备

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-csi
  resources:
    requests:
      storage: 5Gi

应用 PVC:

kubectl apply -f pvc-dynamic.yaml
kubectl get pvc

五、创建 Pod 挂载 PVC

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - name: nfs-volume
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs-volume
      persistentVolumeClaim:
        claimName: dynamic-nfs-pvc
kubectl apply -f pod-nfs-dynamic.yaml


18. 如果一个pod无法启动,要如何进行排查

# Step 1: 查看 Pod 状态
kubectl get pod

# Step 2: 查看 Pod 详细信息
kubectl describe pod <pod-name>

# Step 3: 查看容器日志(含 previous)
kubectl logs <pod-name>
kubectl logs <pod-name> --previous

# Step 4: 进入容器调试
kubectl exec -it <pod-name> -- sh

# Step 5: 查看 PVC 状态
kubectl get pvc

# Step 6: 查看 PVC 详细信息
kubectl describe pvc <pvc-name>

# Step 7: 查看节点资源
kubectl describe node

# Step 8: 查看节点污点
kubectl describe node <node-name> | grep Taints

# Step 9: 查看 kubelet 日志(需登录节点)
journalctl -u kubelet -n 100


19. Pod可能会有哪些状态,这些状态表示的含义是什么

问题类型

表现

排查命令

解决方案

镜像拉取失败

ImagePullBackOff

kubectl describe pod

检查镜像名、Secret、网络

容器崩溃重启

CrashLoopBackOff

kubectl logs --previous

查看日志、修改启动命令

资源不足

Pending + Insufficient

kubectl describe node

调整 requests/limits

卷挂载失败

ContainerCreating

kubectl describe pod

检查 PVC、PV、NFS

探针失败

Running but NotReady

kubectl logs

调整 initialDelaySeconds

节点污点

Pending + Taint

kubectl describe node

添加 Tolerations

节点不可达

NodeNotReady

kubectl get nodes

登录节点检查 kubelet


以他人的幸福为幸福,以他人的享乐为享乐。