4、第一个Pod:编写YAML文件、创建Pod、查看Pod状态、进入Pod调试

好,咱们现在开始动手了。

前面聊了那么多理论,什么Pod是调度最小单元、什么容器化部署。说实话,光听不练容易飘。我自己的经验是,第一个Pod跑起来,你才算真正摸到了K8s的门

这一节,我们就来写一个YAML文件,把它扔到集群里,看看Pod怎么活过来,再钻进去看看里面到底长什么样。

4.1 为什么非得用YAML?

你可能会问:我能不能直接敲命令行创建Pod?

能。比如 kubectl run nginx --image=nginx 确实能跑起来。但我不建议你这么干。

为什么?因为不可复现。你想想看,生产环境里几十个Pod,每个都要手动敲参数?哪天集群挂了要重建,你还能记得当初敲了啥?

YAML文件就是你的“部署说明书”。它把Pod的规格、镜像、端口、环境变量全写死了。保存到Git里,团队里谁都能拉下来跑。这才是DevOps的玩法。

💡 我的习惯: 每个Pod、每个Deployment,我都先写YAML。哪怕只是一个测试用的hello-world。这个习惯帮我避免过至少三次“哎呀我忘了挂载卷”的尴尬。

4.2 编写第一个Pod的YAML文件

咱们的目标很简单:跑一个Nginx容器,暴露80端口,看看能不能访问。

新建一个文件,叫 my-first-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-demo
  labels:
    app: nginx
    env: test
spec:
  containers:
  - name: nginx-container
    image: nginx:1.25-alpine
    ports:
    - containerPort: 80
      protocol: TCP
    resources:
      requests:
        memory: "128Mi"
        cpu: "100m"
      limits:
        memory: "256Mi"
        cpu: "200m"

来,一行行拆开看:

  • apiVersion:K8s API的版本。Pod用 v1,这是最稳定的核心API。我刚开始学的时候老写错版本,后来记住一个口诀:核心资源用v1,其他资源看文档。
  • kind:资源类型。这里就是 Pod,大写P,别写成小写。
  • metadata:元数据。name是Pod的名字,labels是标签。标签这东西后面有大用,比如Service通过标签选择Pod。
  • spec:规格描述。里面定义容器。
  • containers:一个Pod可以跑多个容器,但咱们入门阶段先跑一个。
  • image:镜像地址。我选了 nginx:1.25-alpine,alpine版本体积小,只有20多MB,拉取快。
  • ports:声明容器要暴露的端口。注意这只是“声明”,不是“自动映射”。
  • resources:资源限制。requests是“最少要多少”,limits是“最多能用多少”。生产环境一定要加,不然一个Pod能把整个节点的内存吃光。
⚠️ 我曾经踩过的坑: 有一次没写resources.limits,结果一个测试Pod内存泄漏,把节点搞OOM了,上面其他Pod全被Kill。从那以后,我写YAML第一件事就是先把资源限制写好。

4.3 创建Pod

YAML写好了,怎么让它生效?

kubectl apply 命令:

kubectl apply -f my-first-pod.yaml

如果一切正常,你会看到:

pod/nginx-pod-demo created

嗯,就这么简单。K8s收到你的YAML后,会做几件事:

  1. API Server校验YAML格式是否正确
  2. 把Pod信息写入etcd(集群的数据库)
  3. Scheduler找到一个合适的节点
  4. 节点上的kubelet拉取镜像,启动容器

整个过程也就几秒钟。如果你用的是minikube,第一次拉取nginx镜像可能会慢一点,耐心等。

4.4 查看Pod状态

Pod创建完了,它现在是什么状态?用 kubectl get pods 看看:

kubectl get pods -o wide

输出大概长这样:

NAME            READY   STATUS    RESTARTS   AGE   IP            NODE
nginx-pod-demo   1/1     Running   0          45s   10.244.0.5    minikube

几个关键字段:

  • READY:1/1 表示Pod里有一个容器,并且已经就绪。
  • STATUS:Running表示正常运行。其他常见状态还有 Pending(等待调度)、CrashLoopBackOff(容器反复崩溃)、ImagePullBackOff(镜像拉取失败)。
  • IP:Pod的集群内IP。这个IP是K8s分配的,只能在集群内部访问。
  • NODE:Pod跑在哪个节点上。

如果你想看更详细的信息,用 kubectl describe pod nginx-pod-demo。这个命令会输出Pod的完整事件,包括镜像拉取日志、容器启动日志、挂载卷信息等。排错的时候特别好用。

💡 调试小技巧: 当Pod状态是Pending时,用 kubectl describe pod 看Events部分,通常能直接看到原因——比如节点资源不足、镜像不存在、PVC没绑定等。

4.5 进入Pod调试

Pod跑起来了,我想进去看看Nginx的默认页面长什么样,或者改个配置,怎么办?

kubectl exec 命令:

kubectl exec -it nginx-pod-demo -- /bin/sh

解释一下参数:

  • -i:交互模式
  • -t:分配一个伪终端
  • --:分隔符,后面跟要执行的命令
  • /bin/sh:启动一个shell。注意nginx的alpine镜像里没有bash,只有sh。

执行后,你会看到类似这样的提示符:

/ #

恭喜,你已经进入Pod内部了!现在你可以:

  • 查看Nginx默认页面:cat /usr/share/nginx/html/index.html
  • 查看进程:ps aux
  • 查看网络:ip addr(alpine里可能需要先安装iproute2)
  • 测试网络连通性:wget -O- http://localhost

退出Pod,输入 exit 或者按 Ctrl+D。

⚠️ 注意: 进入Pod后做的任何修改,Pod一旦重启就会丢失。因为容器是基于镜像启动的,文件系统是临时的。要持久化数据,得用Volume挂载,这个后面会讲。

4.6 核心逻辑流程图

下面这张图,把从YAML编写到进入Pod调试的完整流程串起来了。你可以把它当作本章的“知识地图”:

📋 第一个Pod:从YAML到调试的完整流程 ① 编写YAML my-first-pod.yaml ② kubectl apply 提交到API Server ③ Pod创建 Scheduler调度 → kubelet启动 ④ 查看状态 kubectl get pods ⑤ describe排错 kubectl describe pod ⑥ 进入Pod调试 kubectl exec -it 💡 核心要点 YAML是“部署说明书” → apply提交声明 → 查看状态确认运行 → exec进入容器调试 记住:Pod内修改不持久,生产环境一定要用Volume

4.7 本章小结

咱们这一节,把Pod的完整生命周期走了一遍:

  • 写了一个标准的YAML文件,定义了Pod的规格
  • kubectl apply 提交到集群
  • kubectl get podskubectl describe pod 查看状态
  • kubectl exec 进入容器内部调试

说实话,这几个命令你练熟了,K8s日常运维的60%工作就搞定了。剩下的无非是Deployment、Service、ConfigMap这些资源的组合。

嗯,第一个Pod跑起来的感觉,是不是还挺爽的?


专注资料整理