在上一篇文章里,我们一起完成了 minikube 与 kubeadm 的集群部署,跑通了一个最小的 Kubernetes 环境。很多刚接触 K8s 的朋友会有一种感觉:集群是起来了,可里面那一堆抽象对象到底是怎么回事?为什么一个应用不是直接”跑容器”,而是要先写 Pod?为什么还要给资源贴 Label,再用 Selector 去选?命名空间又是用来隔离什么的?
今天这篇文章,我们就聚焦 Kubernetes 最基础、也最核心的几个对象——Pod、Label、Selector 与命名空间。理解它们之间的关系,是后面学习 Deployment、Service、ConfigMap 等一切高级对象的前提。可以说,K8s 的学习是否扎实,很大程度取决于你有没有真正吃透今天这四个概念。

核心概念:四个对象分别解决什么问题
在正式进入实战之前,我们先把这四个概念在脑中”对号入座”,搞清楚它们各自在集群中扮演的角色。
Pod:Kubernetes 的最小调度单位
Pod 是 Kubernetes 中最小的、可以创建和调度的计算单元。一个 Pod 内部可以包含一个或多个容器,这些容器共享同一个网络命名空间(也就是共享同一个 IP 和端口空间)以及存储卷。日常最常用的场景是”一个 Pod 一个容器”,即 Pod 作为单个应用实例的载体。
需要特别强调的是:在 Docker 时代,我们习惯直接管理容器;但在 K8s 里,你永远不直接运行容器,而是通过 Pod 间接管理。Pod 是 K8s 与容器运行时之间的”唯一接口”。
Label:给资源贴标签
Label 是一组键值对,可以附加在 Pod、Service、Deployment 等几乎所有 K8s 对象上。它本身不参与任何系统行为,纯粹是用来给资源做”标记”的元数据。比如你可以给一个 Pod 打上 app=nginx、env=prod、tier=frontend 这样的标签。
Selector:根据标签筛选资源
有了 Label,就需要一种机制把它们”用起来”,这就是 Selector。Selector 通过标签的键值匹配规则,从一堆资源里筛出符合条件的目标。最常见的用法是 Service 通过 Selector 找到它要代理的那组 Pod。
命名空间:逻辑隔离的边界
Namespace(命名空间)提供了一种在单个集群内划分资源组的机制。不同团队、不同项目可以各自拥有独立的命名空间,彼此之间的资源名称互不冲突,也可以配合 RBAC 做权限隔离。默认集群里会有 default、kube-system、kube-public、kube-node-lease 这几个系统命名空间。
实战步骤:亲手创建并管理 Pod
光说不练假把式,下面我们直接上手,从写一个最简单的 Pod 清单开始。
第一步:编写 Pod 的 YAML 清单
K8s 的资源几乎都是用 YAML 声明的。下面是一个运行 Nginx 的 Pod 定义:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
env: dev
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
把上面的内容保存为 nginx-pod.yaml,然后执行创建命令:
kubectl apply -f nginx-pod.yaml
第二步:查看 Pod 状态
创建之后,用下面的命令确认 Pod 是否正常运行:
kubectl get pods
kubectl get pods -o wide
kubectl describe pod nginx-pod
get pods -o wide 可以看到 Pod 被调度到了哪个节点、分配到了哪个 IP;describe 则能看到更详细的 Events,方便排障。
第三步:验证 Label 与 Selector 的配合
Label 的真正价值在于被 Selector 使用。我们创建一个 Service,让它通过 Selector 选中上面打了 app=nginx 标签的 Pod:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
保存为 nginx-svc.yaml 并应用:
kubectl apply -f nginx-svc.yaml
kubectl get svc nginx-svc
kubectl get endpoints nginx-svc
执行 get endpoints 后,你会看到 Service 自动把 app=nginx 的 Pod IP 挂载到了 Endpoints 上。这就是 Label + Selector 最经典的协作方式:Pod 贴标签,Service 用选择器找到它。
第四步:用命名空间做资源分组
下面我们创建一个名为 dev 的命名空间,并把资源创建到其中:
kubectl create namespace dev
kubectl get namespaces
如果希望把 Pod 建到 dev 命名空间,只需要在 metadata 里加上 namespace 字段:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: dev
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
或者直接使用命令行指定:
kubectl apply -f nginx-pod.yaml -n dev
kubectl get pods -n dev
常见问题:新手最容易踩的坑
为什么 Pod 一直处于 Pending 状态?
Pending 意味着 Pod 已经被 API Server 接受,但还没有被成功调度到节点上。常见原因包括:集群资源不足、节点不可用、或者 Pod 声明的资源请求超过了节点剩余容量。用 kubectl describe pod 查看 Events,通常能直接看到具体原因。
Label 和 Annotation 有什么区别?
Label 用于标识和筛选资源,会被 Selector 使用,因此有长度和字符集限制;Annotation 则用来存放非标识性的元数据(比如构建信息、联系方式、运维说明),不会被 Selector 用来选择资源,可以存更长的自由文本。
一个 Pod 里放多个容器有什么好处?
当多个容器需要紧密共享网络和存储、且生命周期一致时,可以把它们放进同一个 Pod。典型场景是”边车(Sidecar)”模式:比如主容器跑业务,边车容器负责日志采集或配置刷新。但要注意,同一 Pod 内的容器是”共进退”的,一个失败可能拖累整体。
命名空间能实现真正的隔离吗?
命名空间提供的是”逻辑隔离”,不是像虚拟机那样的强隔离。它隔离的是资源名称和部分权限,不同命名空间的 Pod 默认仍然可以互相通信(除非用 NetworkPolicy 限制)。真正要做强隔离,还需要配合网络策略、资源配额(ResourceQuota)和 RBAC。
总结
今天我们讲清楚了 Kubernetes 的四个核心对象:Pod 是最小调度单位,Label 是贴在资源上的标签,Selector 是根据标签筛选资源的机制,Namespace 则是逻辑隔离的边界。它们之间的关系可以浓缩成一句话:Pod 承载应用,Label 标记资源,Selector 连接资源,Namespace 划分空间。
掌握这四个概念之后,你已经能够独立地”声明”并运行一个最简单的应用了。但从运维角度看,直接手动管理裸 Pod 是远远不够的——Pod 一旦挂了不会自动重建,扩容缩容也得靠人肉操作。这就需要我们引入工作负载控制器。下一篇文章,我们将进入 Deployment、ReplicaSet 与滚动更新,看看 K8s 是如何让应用”自愈”和”滚动升级”的。
下期预告
下一篇《K8s 运维系列 | 第 4 天:工作负载——Deployment、ReplicaSet 与滚动更新》将带你理解控制器模式,学会如何让应用实现自动修复、水平扩容和无损滚动发布,敬请期待。


















暂无评论内容