1. Kubernetes中的卷是什么,ConfigMap和Secret是卷吗?
在 Kubernetes 中,卷(Volume) 是一种用于将数据持久化或共享到容器中的机制。与容器的生命周期不同,卷的生命周期独立于容器,即使容器被销毁或重启,卷中的数据仍然可以保留。
Kubernetes 支持多种类型的卷,例如:
emptyDir:容器临时目录,Pod 删除时数据会丢失。hostPath:将宿主机的文件或目录挂载到容器中。persistentVolumeClaim(PVC):绑定到持久化存储(如 NFS、云盘等)。configMap和secret:将配置数据或敏感信息注入到容器中。
ConfigMap 和 Secret 是卷吗?
是的,ConfigMap 和 Secret 都属于卷类型,它们可以作为特殊的卷挂载到容器中,用于传递配置信息或敏感数据。
2. 有哪些常用的本地存储卷
在 Kubernetes 中,本地存储卷(Local Volumes) 通常用于需要高性能或数据持久化需求的场景。以下是一些常用的本地存储卷类型及其用途:
1. emptyDir
用途:临时目录,Pod 被删除时数据也会被清除。
特点:
数据仅存在于 Pod 生命周期内。
可用于容器间共享数据。
适用于缓存、临时文件等场景。
2. hostPath
用途:将宿主机上的文件或目录挂载到容器中。
特点:
数据持久化在宿主机上。
适用于调试、日志收集等场景。
需要确保宿主机路径存在,并具有正确权限。
3. local
用途:基于节点本地磁盘的持久化存储。
特点:
与
PersistentVolume和PersistentVolumeClaim结合使用。适用于生产环境中的持久化需求。
需要在 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 的关键属性:
什么是 PVC?
PVC 是用户对存储资源的“申请”,它描述了用户对存储的需求(大小、访问模式等)。
Kubernetes 系统会根据 PVC 的需求自动绑定一个合适的 PV。
用户不需要关心底层存储实现,只需声明所需资源即可。
PVC 的关键属性:
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 应该如何处理底层存储资源。
支持的回收策略
二、PV 的访问模式(Access Mode)
访问模式定义了 Pod 对 PV 的访问权限,影响多个 Pod 是否可以同时读写该卷。
✅ 支持的访问模式
⚠️ 注意:不是所有存储类型都支持所有访问模式。例如:
hostPath只支持ReadWriteOncenfs同时支持ReadWriteOnce和ReadWriteMany云厂商磁盘(如 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 availablestorage class not foundcapacity request too large
2. 检查是否有匹配的 PV
kubectl get pv确保有可用的 PV,并且其状态为 Available。然后检查以下字段是否与 PVC 匹配:
3. 检查 PVC 是否指定了 StorageClass
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi如果 PVC 指定了 storageClassName,则 Kubernetes 只会查找该类别的 PV 或尝试动态创建。
检查是否存在对应的 StorageClass:
kubectl get storageclass4. 检查 StorageClass 是否设置为默认
如果你使用的是动态供给(如云厂商),请确认 StorageClass 是否设置了 is-default-class 注解:
kubectl get storageclass5. 检查 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常见问题与解决办法总结
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-data2. 创建 PVC 并绑定该 PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi3. 创建多个 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 实际挂载到了容器的哪个路径下
16. 什么是动态制备卷,对比静态有哪些特点
在 Kubernetes 中,动态制备卷(Dynamic Volume Provisioning) 是一种自动创建持久化存储卷的机制,允许用户根据需求自动创建 PV(PersistentVolume),而无需手动预先定义 PV。这是通过 StorageClass 和 Provisioner 插件 实现的。
动态卷工作原理简述
用户创建一个 PVC,并指定
storageClassName;Kubernetes 根据该 StorageClass 自动调用对应的 provisioner 插件;
provisioner 在底层存储系统中创建一个新的卷(如云盘);
自动生成 PV 并绑定到 PVC;
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: Immediate2. 创建 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),你需要完成以下步骤:
一、前提条件
Kubernetes 集群版本 ≥ v1.20
已安装 CSI 驱动支持(默认启用)
NFS Server 已部署并可访问
所有 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-nfs2. 部署 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.yamlkubectl 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-pvckubectl 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