1. 为什么第一个对象一定是 Pod?
在 Kubernetes 中,Pod 是最小的可部署单元。无论你后面使用 Deployment、StatefulSet 还是 Job,本质上最终落地运行的,依然是 Pod。官方 Pod 生命周期文档也围绕 Pod 的创建、运行、状态变化与终止来描述工作负载的基本生命周期::cite[189].
所以,学习 Kubernetes 的第一步,不是先上复杂控制器,而是亲手把一个 Pod 跑起来,观察它从 YAML 变成真实运行实例的全过程。
2. 编写第一个 Pod 清单文件
我们先写一个最简单的 Nginx Pod。请新建文件 first-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: first-nginx-pod
labels:
app: first-nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
这个文件虽然短,但已经包含了最核心的几个字段:
| 字段 | 作用 |
|---|---|
apiVersion |
指定资源使用的 API 版本 |
kind |
说明资源类型,这里是 Pod |
metadata.name |
资源名称 |
metadata.labels |
标签,便于后续筛选和关联 |
spec |
期望状态定义 |
containers |
Pod 中要运行的容器列表 |
这里也顺便理解一个关键点:YAML 不是脚本,而是声明。你不是在命令 Kubernetes“现在立刻执行第 1 行到第 8 行”,而是在描述:我想要这样一个 Pod::cite[147].
3. 创建 Pod
创建非常简单,直接执行:
kubectl apply -f first-pod.yaml
如果一切正常,你会看到类似输出:
pod/first-nginx-pod created
这一步完成后,只能说明“对象已经成功提交给 API Server”,还不能说明容器一定已经运行成功。真正学会 Kubernetes,关键就在于:创建之后一定要观察状态。
4. 查看 Pod 是否真的跑起来
4.1 查看 Pod 列表
kubectl get pods
你可能会看到这样的输出:
NAME READY STATUS RESTARTS AGE
first-nginx-pod 1/1 Running 0 10s
这里的 STATUS 是最常被关注的字段之一。如果它已经进入 Running,说明至少有一个主容器成功启动并在运行::cite[189].
4.2 查看更详细的信息
kubectl get pod first-nginx-pod -o wide
这个命令会额外展示节点、Pod IP 等信息,方便你理解“这个 Pod 被调度到了哪台节点上”。
4.3 查看 YAML 视图
kubectl get pod first-nginx-pod -o yaml
这一步很有价值,因为你会看到:除了你自己写的配置外,Kubernetes 还补充了很多状态字段,例如 status、调度结果、容器状态等。它能帮助你逐渐区分:
- spec:你想要什么;
- status:系统现在实际怎么样。
5. 用 describe 看清 Pod 到底发生了什么
初学者最应该尽快养成的习惯,就是对象有问题时先看 describe:
kubectl describe pod first-nginx-pod
describe 会展示:
- 基本元信息;
- 当前在哪个节点;
- 容器镜像与端口;
- Conditions;
- Events(事件)。
尤其是 Events 非常重要。比如镜像拉取失败、调度失败、端口冲突等问题,通常都能从这里快速看出线索。很多时候,get 只能告诉你“坏了”,但 describe 能告诉你“为什么坏了”。
6. 用 logs 查看容器输出
Kubernetes 日志体系中,一个最常用的入口就是 kubectl logs。官方日志架构文档明确提到,因为 stdout 和 stderr 由 kubelet 处理,所以你可以直接使用 kubectl logs 查看容器日志::cite[193].
对这个 Pod 执行:
kubectl logs first-nginx-pod
如果容器持续输出日志,你会看到标准输出内容;如果是像 Nginx 这种刚启动的镜像,日志可能不多,但命令本身依然是排查应用问题的重要工具。
如果一个 Pod 中有多个容器,则需要显式指定容器名:
kubectl logs first-nginx-pod -c nginx
7. 用 exec 进入容器内部
当你不仅想“看日志”,还想“到容器里面看看”时,就要用 kubectl exec。Kubernetes 官方调试文档说明,kubectl exec 可以用来进入运行中的容器获取 shell,例如:kubectl exec --stdin --tty <pod> -- /bin/bash::cite[500].
你可以试试:
kubectl exec -it first-nginx-pod -- /bin/sh
进入之后,可以继续执行:
ls /
ps aux
如果镜像中有 Bash,也可以改为:
kubectl exec --stdin --tty first-nginx-pod -- /bin/bash
当一个 Pod 中有多个容器时,可以通过 --container 或 -c 指定目标容器,这也是官方文档给出的标准用法::cite[500].
8. 删除 Pod
练习完成后,把它删掉也很重要:
kubectl delete -f first-pod.yaml
或者:
kubectl delete pod first-nginx-pod
你会发现,删除并不是把某个进程“强行杀掉”这么简单,而是向 API Server 提交一个删除请求,随后 Kubernetes 进入对象终止流程。后面学习控制器时你会进一步看到:如果这个 Pod 是由 Deployment 创建的,那么你手动删掉后,控制器还可能再补一个新的出来。
9. 理解 Pod 生命周期的基本状态
官方文档指出,Pod 会经历一组定义好的生命周期阶段:通常从 Pending 开始,进入 Running,最终在结束后进入 Succeeded 或 Failed。这些 phase 是对 Pod 生命周期的高层摘要,而不是全部细节::cite[189].
9.1 Pending
Pending 表示 Pod 已被 Kubernetes 接收,但还有一个或多个容器尚未完成创建。常见原因包括:
- 还在调度;
- 还在拉取镜像;
- 挂载卷或初始化步骤尚未完成。
9.2 Running
Running 表示 Pod 已经绑定到节点,至少一个主容器已经成功启动并正在运行,或者正在启动/重启过程中::cite[189].
9.3 Succeeded
Succeeded 通常出现在“一次性任务”型 Pod,例如容器正常执行完并退出,且不会再重启。入门阶段你在 Job 场景里更容易遇到它。
9.4 Failed
Failed 表示 Pod 中至少有一个容器以失败状态结束,并且根据当前策略不会再继续恢复。常见原因可能是命令异常退出、镜像错误、应用启动失败等::cite[189].
9.5 Unknown
Unknown 比较少见,通常是因为控制平面暂时无法获得 Pod 的最新状态,例如节点通信异常。这更偏向集群层面问题。
9.6 关于 Terminating 的理解
你经常会在 kubectl get pods 里看到 Terminating,但要注意:它更像是删除过程中的显示状态,而不是 Pod phase 的正式取值。Pod 真正的 phase 文档重点仍然是 Pending、Running、Succeeded、Failed、Unknown 这几个::cite[189].
10. 一次完整的实操回放
把本章所有动作串起来,你会得到这样一条最小实践链路:
第 1 步:准备 YAML
vim first-pod.yaml
第 2 步:创建 Pod
kubectl apply -f first-pod.yaml
第 3 步:观察运行状态
kubectl get pods
kubectl get pod first-nginx-pod -o wide
kubectl describe pod first-nginx-pod
第 4 步:查看日志和进入容器
kubectl logs first-nginx-pod
kubectl exec -it first-nginx-pod -- /bin/sh
第 5 步:清理资源
kubectl delete -f first-pod.yaml
这套流程其实就是之后学习更复杂对象时的通用模板:
写 YAML → apply → get → describe → logs / exec → delete
只要这条路径熟练了,你就已经具备继续学习 Deployment、Service、ConfigMap 的基础操作能力。
11. 本章小结
本章你完成了 Kubernetes 学习里非常关键的第一步:从零编写一个 Pod 清单文件,把它提交到集群中,观察它的运行状态,并通过 logs、exec、describe 理解它的行为。
请一定记住:Kubernetes 学习不是“会写 YAML”就够了,而是“写完之后会观察、会验证、会排查”。真正的实战能力,往往就藏在 describe、logs 和 exec 这三个最基础的命令里::cite[193].
📝 版权声明:本文为原创技术博客,转载请注明出处。
如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!