Kubernetes核心概念详解:Namespace、Pod、Deployment、PV和PVC原创
# Kubernetes中的Namespace、Pod、Deployment、PV和PVC详解
# Namespace
Namespace(命名空间)用于在同一个Kubernetes集群中将资源进行逻辑上的隔离。它类似于Linux中的命名空间,可以在一个集群中创建多个命名空间,每个命名空间下可以有一组独立的资源。
- 创建命名空间
kubectl create namespace <namespace-name>1 - 查看所有命名空间
kubectl get namespaces1 - 删除命名空间
kubectl delete namespace <namespace-name>1
命名空间通常用于不同环境(如开发、测试、生产)或不同项目之间的资源隔离。
版本说明
本文写于 2023-06,2026-08 复核。
文中涉及的 v1(Pod / Service / PV / PVC)与 apps/v1(Deployment)资源,其 API 版本与字段结构自 1.16 起稳定,到 1.31 未变,命令与 YAML 可直接使用。
唯一需要替换的是 PV 示例中的 hostPath——见下文「坑与边界」第 3 条。
# Pod
Pod是Kubernetes中最小的部署单元,包含一个或多个容器(通常是Docker容器)。Pod中的容器共享网络和存储,并且始终在同一个Node上调度和运行。
- 创建Pod(YAML文件)
apiVersion: v1 kind: Pod metadata: name: my-pod namespace: default spec: containers: - name: my-container image: nginx1
2
3
4
5
6
7
8
9kubectl apply -f pod.yaml1 - 查看所有Pod
kubectl get pods1 - 描述Pod
kubectl describe pod <pod-name>1 - 删除Pod
kubectl delete pod <pod-name>1
# Deployment
Deployment是Kubernetes中用于管理Pod的声明式定义。它可以确保集群中始终有指定数量的Pod副本在运行,并且可以实现滚动更新和回滚。
为什么不直接创建 Pod:直接 kubectl apply 一个 Pod,它就是一个孤儿——节点宕机、进程崩溃、被驱逐,Pod 就永远消失了,没有任何东西负责把它拉起来。Deployment 背后是一条控制链:Deployment 管 ReplicaSet,ReplicaSet 管 Pod,控制器持续对比「期望副本数」与「实际副本数」并把差值补上。这就是 Kubernetes 的声明式模型——你描述想要的状态,控制器负责让现实收敛过去。滚动更新也是这条链的产物:改镜像时 Deployment 新建一个 ReplicaSet 并逐步扩容、同时缩容旧的,回滚就是把两者调换回来(kubectl rollout undo)。
创建Deployment(YAML文件)
apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: default spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: nginx1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18kubectl apply -f deployment.yaml1spec.selector.matchLabels与spec.template.metadata.labels必须完全一致,否则 API Server 会直接拒绝并返回selector does not match template labels。原因是 Deployment 靠标签选择器找自己管的 Pod,如果模板打的标签不在选择器范围内,它创建出来的 Pod 立刻就「不认识」了,会陷入无限创建的循环——所以 Kubernetes 干脆在提交时就拦住。另外selector在 Deployment 创建后不可修改,需要改就只能删了重建。查看所有Deployments
kubectl get deployments1描述Deployment
kubectl describe deployment <deployment-name>1更新Deployment
kubectl apply -f deployment.yaml1删除Deployment
kubectl delete deployment <deployment-name>1
# PV(Persistent Volume)
Persistent Volume(持久卷)是Kubernetes集群中的一块存储,可以由管理员预先配置,也可以通过动态供应器自动创建。PV是一个集群资源,与Pod独立。
- 创建PV(YAML文件)
apiVersion: v1 kind: PersistentVolume metadata: name: my-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"1
2
3
4
5
6
7
8
9
10
11kubectl apply -f pv.yaml1 - 查看所有PVs
kubectl get pv1 - 描述PV
kubectl describe pv <pv-name>1 - 删除PV
kubectl delete pv <pv-name>1
# PVC(Persistent Volume Claim)
Persistent Volume Claim(持久卷声明)是用户请求PV资源的方式。PVC可以请求特定大小和访问模式的存储,Kubernetes会找到满足要求的PV并将其绑定到PVC上。
- 创建PVC(YAML文件)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi1
2
3
4
5
6
7
8
9
10kubectl apply -f pvc.yaml1 - 查看所有PVCs
kubectl get pvc1 - 描述PVC
kubectl describe pvc <pvc-name>1 - 删除PVC
kubectl delete pvc <pvc-name>1
# 怎么确认部署真的成功了
kubectl apply 返回 created 只代表 API Server 收下了这份 YAML,不代表东西跑起来了。逐层确认:
# 1. Deployment 层:期望副本是否都已就绪
kubectl get deployment my-deployment
2
期望 READY 列是 3/3。若是 0/3 且长时间不动,问题在 Pod 层。
# 2. Pod 层:卡在哪个阶段
kubectl get pods -l app=my-app
2
STATUS 的含义各不相同,对应的排查方向也不同:
| STATUS | 含义 | 下一步 |
|---|---|---|
Pending | 调度器找不到合适节点 | kubectl describe pod <name>,看 Events 里是资源不足、污点、还是 PVC 没绑上 |
ContainerCreating | 已调度,正在拉镜像或挂卷 | 同上看 Events;卡很久通常是挂卷失败 |
ImagePullBackOff | 镜像拉不下来 | 镜像名/tag 写错,或私有仓库缺 imagePullSecrets |
CrashLoopBackOff | 容器起来后反复退出 | kubectl logs <name> --previous 看上一次崩溃前的输出 |
Running 但 READY 0/1 | 进程在跑,readinessProbe 没过 | 探针路径/端口写错,或应用启动比探针慢 |
# 3. 事件层:所有异常最终都会落在这里
kubectl get events -n default --sort-by=.lastTimestamp | tail -20
2
这条命令是 Kubernetes 排障的起点,比一个个 describe 快得多。注意事件默认只保留 1 小时。
# 4. PVC 层
kubectl get pvc my-pvc
2
期望 STATUS 为 Bound、VOLUME 列有具体 PV 名。停在 Pending 就 kubectl describe pvc my-pvc | tail -20 看事件。
# 坑与边界
1. kubectl delete namespace 是级联删除,且没有二次确认。 它会删掉该命名空间下的全部资源——Deployment、Service、PVC、Secret,一个不留。生产集群上这条命令的破坏力接近 rm -rf,执行前先 kubectl get all -n <ns> 看一眼里面有什么。
2. Namespace 卡在 Terminating 删不掉,几乎总是 finalizer 的问题。 某个资源(常见于 CRD 或已卸载的 Operator 留下的对象)带着 finalizer,而负责清理它的控制器已经不在了,于是删除流程永远等不到确认。先用 kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 kubectl get -n <ns> --ignore-not-found 找出残留对象,逐个清掉 finalizer。不要直接去改 Namespace 对象的 finalizer 强推——那会留下一堆无人回收的孤儿资源。
3. hostPath PV 在多节点集群上会静默丢数据。 上文 PV 示例用的 hostPath: /mnt/data 指的是「Pod 恰好被调度到的那个节点上的路径」。Pod 一旦漂移到别的节点,挂上来的是一个空目录——数据库会以为自己是全新实例并重新初始化,问题在故障恢复时才暴露。多节点环境请改用 local 类型的 PV 并配 nodeAffinity 把 PV 钉在特定节点上,或直接用网络存储 / CSI StorageClass。
4. kubectl delete pod 删不掉由控制器管理的 Pod。 Deployment 下的 Pod 删掉后会立刻被 ReplicaSet 重建(这正是它该有的行为)。要真正停掉,得删 Deployment,或 kubectl scale deployment my-deployment --replicas=0。想强制重启一组 Pod 用 kubectl rollout restart deployment/my-deployment,比手工删 Pod 更可控——它走的是滚动更新,不会一次性全断。
5. 不是所有资源都属于某个 Namespace。 Node、PersistentVolume、ClusterRole、StorageClass 都是集群级资源,加 -n 参数对它们无效。上文的 PV 是集群级、PVC 是命名空间级,两者能绑定但归属层级不同——这也是 PVC 删了 PV 还在(Released 状态)的原因。用 kubectl api-resources --namespaced=false 可以列出全部集群级资源。
6. 默认没有资源配额,一个命名空间能吃光整个集群。 Namespace 只提供命名隔离,不提供资源隔离,也不提供网络隔离。要限制用量得额外建 ResourceQuota 和 LimitRange;要禁止跨命名空间访问得配 NetworkPolicy(且需要 CNI 插件支持,Flannel 默认不支持)。把 Namespace 当成安全边界是常见的误解。
# 总结
- Namespace:用于逻辑上隔离资源。
- Pod:Kubernetes中最小的部署单元,包含一个或多个容器。
- Deployment:用于管理Pod的声明式定义,支持滚动更新和回滚。
- PV(Persistent Volume):集群中的存储资源,管理员预先配置或动态供应。
- PVC(Persistent Volume Claim):用户请求PV资源的方式。