K8s系列第三篇:K8s 核心对象:Pod 从入门到实战(yaml 详解+常用命令)
前言:在上一篇文章中,我们已经用kubeadm成功搭建了K8s集群,并且通过部署Nginx测试了集群的可用性。从这一篇开始,我们正式深入学习K8s的核心对象——今天的主角是Pod。
很多小白刚接触K8s时,会把Pod和容器混淆,觉得“部署Pod就是部署容器”,其实不然。Pod是K8s中最小的部署单元,也是K8s调度、网络、存储的基础,后续学习的Deployment、Service等对象,本质上都是围绕Pod展开的。
本文专门针对小白,从“什么是Pod、Pod的生命周期、Pod的核心配置(yaml)、常用操作命令”四个维度,手把手教你掌握Pod,全程实操、命令可复制、yaml可直接复用,还会补充常见问题和注意事项,帮你彻底搞懂Pod的核心用法,为后续实战打下基础。
前置要求:已搭建好K8s集群(参考第二篇教程),熟悉kubectl基本使用(后续会详细讲),无需额外准备其他环境。
一、先搞懂:什么是Pod?
1.1 Pod的核心定义
官方定义:Pod是Kubernetes中最小的可部署计算单元,它代表了集群中一个独立的运行实例。一个Pod可以包含一个或多个容器(通常是紧密关联的容器),这些容器共享Pod的网络命名空间、存储卷和运行环境。
小白通俗理解:Pod就像一个“容器的集合包”,里面可以装一个或多个容器,这些容器是“绑定在一起”的——它们共享网络(比如容器A可以直接通过localhost访问容器B)、共享存储,并且会被同时调度到同一个Node节点上运行、同时启动、同时停止。
1.2 Pod和容器的区别(重点区分)
很多小白会混淆Pod和容器,这里用一张表格清晰区分,记住3个核心差异即可:
| 对比维度 | Pod | 容器(Docker) |
|---|---|---|
| K8s地位 | 最小部署单元,K8s直接操作的对象 | Pod内部的运行单元,K8s不直接操作容器 |
| 包含关系 | 一个Pod可包含1个或多个容器 | 独立运行,可被Pod包含 |
| 资源共享 | Pod内所有容器共享网络、存储 | 容器之间独立,默认不共享资源 |
| 生命周期 | Pod有自己的生命周期(Pending、Running等),容器生命周期依赖Pod | 容器生命周期由Docker管理,受Pod控制 |
1.3 Pod的核心作用
Pod的核心作用是“封装紧密关联的容器”,解决“容器之间的协同问题”。举2个实际场景,帮你理解:
场景1:Nginx容器 + 日志收集容器。Nginx容器负责提供Web服务,日志收集容器负责收集Nginx的访问日志,这两个容器紧密关联,需要共享日志文件(存储),就可以放在同一个Pod中,日志容器直接读取Nginx的日志文件,无需复杂的网络通信。
场景2:应用容器 + 配置更新容器。应用容器需要加载配置文件,配置更新容器负责定期从配置中心拉取最新配置,更新到共享存储中,应用容器从共享存储读取配置,两者协同工作,放在同一个Pod中最便捷。
注意:通常情况下,一个Pod只部署一个容器(这种Pod称为“单容器Pod”),只有当多个容器紧密关联、无法独立运行时,才会部署在同一个Pod中(“多容器Pod”),小白入门先重点掌握单容器Pod。
二、Pod的生命周期(小白必懂)
Pod从创建到删除,会经历一系列状态变化,了解这些状态,能帮你快速排查Pod异常(比如Pod一直处于Pending状态,说明启动失败)。Pod的核心生命周期状态如下(按执行顺序排列):
Pending(挂起):Pod已被K8s接收,但还未完成容器启动(比如正在拉取镜像、分配资源)。如果Pod长时间处于Pending状态,大概率是镜像下载失败或资源不足。
Running(运行中):Pod内所有容器都已启动,且至少有一个容器处于运行状态(不是暂停或退出状态)。这是Pod正常运行的状态。
Succeeded(成功):Pod内所有容器都已成功退出(退出码为0),且不会再重启。通常用于一次性任务(比如Job任务),任务执行完成后,Pod会处于这个状态。
Failed(失败):Pod内所有容器都已退出,但至少有一个容器是异常退出的(退出码非0)。说明Pod运行失败,需要排查容器日志。
Unknown(未知):K8s无法获取Pod的状态(比如Node节点故障、网络中断),这种状态较少见,通常是集群网络或Node节点异常导致。
2.1 Pod的重启策略(关键)
Pod的重启策略(restartPolicy)决定了当Pod内的容器退出时,K8s是否会重启该容器,这是Pod的核心配置之一,小白必须掌握。重启策略有3种:
Always(默认):无论容器是正常退出(退出码0)还是异常退出(退出码非0),K8s都会自动重启容器。适合长期运行的应用(比如Nginx、MySQL)。
OnFailure:只有当容器异常退出(退出码非0)时,K8s才会重启容器;正常退出时,不会重启。适合一次性任务(比如数据备份),任务完成后正常退出,无需重启。
Never:无论容器是正常退出还是异常退出,K8s都不会重启容器。适合不需要重启的一次性任务,退出后Pod状态变为Succeeded或Failed。
注意:重启策略是配置在Pod上的,作用于Pod内的所有容器,后续yaml配置中会详细演示。
2.2 特殊Pod:静态Pod(Static Pod)
静态Pod是一种特殊的Pod,由Node节点上的kubelet直接管理,不经过K8s的API服务器,无法通过kubectl命令直接操作(比如删除、更新)。
核心特点:静态Pod会被kubelet自动重启(即使删除容器,kubelet也会重新启动),通常用于部署K8s核心组件(比如etcd、kube-apiserver),小白入门阶段了解即可,无需深入实操。
2.3 特殊容器:InitContainer(初始化容器)
InitContainer是Pod启动时先执行的容器,用于完成“初始化任务”(比如等待其他服务启动、拉取配置文件、创建目录),只有所有InitContainer执行完成(成功退出),Pod内的主容器才会启动。
举个例子:如果主容器需要连接MySQL服务,就可以用InitContainer一直ping MySQL,直到MySQL启动成功,再启动主容器,避免主容器因MySQL未启动而报错。后续yaml配置中会给出实操示例。
三、Pod的核心配置:yaml详解(重中之重)
在K8s中,部署Pod有两种方式:命令行方式(简单快捷,适合测试)和yaml配置文件方式(规范、可复用,适合生产环境)。小白入门先掌握命令行方式,再深入学习yaml配置(生产环境必用)。
yaml是一种标记语言,语法简洁,核心是“键值对”,注意yaml文件中缩进必须用空格(不能用Tab),否则会报错。下面先给出一个完整的Pod yaml模板,再逐字段详解。
3.1 单容器Pod yaml完整模板(可直接复制复用)
apiVersion: v1# API版本,Pod的API版本固定为v1kind: Pod# 资源类型,这里是Podmetadata:# 元数据,用于描述Pod的基本信息name: nginx-pod# Pod的名称(必须唯一,不能重复)labels:# 标签,用于标识Pod,后续Service、Deployment会通过标签选择Podapp: nginx# 标签键值对,可自定义(比如app: nginx、env: test)spec:# 规格,用于定义Pod的核心配置(容器、重启策略等)containers:# 容器列表,一个Pod可包含多个容器- name: nginx# 容器名称(Pod内唯一)image: nginx:1.24# 容器镜像(仓库地址+镜像名+版本,版本不要省略)ports:# 端口配置,用于暴露容器端口- containerPort:80# 容器内部的端口(Nginx默认端口是80)protocol: TCP# 协议(TCP/UDP,默认TCP)restartPolicy: Always# 重启策略(Always/OnFailure/Never,默认Always)3.2 yaml核心字段详解(小白必记)
上面的yaml模板是最基础、最常用的,下面逐字段讲解,重点记“必配字段”,可选字段了解即可:
apiVersion: v1必配字段,指定K8s的API版本。Pod属于“核心资源”,API版本固定为v1,不需要修改。
kind: Pod必配字段,指定资源类型。这里我们要创建的是Pod,所以值为Pod;如果是Deployment,值为Deployment(后续会讲)。
metadata(元数据)必配字段,用于描述Pod的基本信息,核心子字段:
name:Pod的名称,必须在当前命名空间内唯一(默认命名空间是default),比如nginx-pod、tomcat-pod。
labels:标签,键值对形式,可自定义,用于标识Pod。比如给Pod打标签app: nginx,后续可以通过标签筛选出所有app为nginx的Pod。
namespace:可选字段,指定Pod所属的命名空间(默认是default),用于隔离资源(比如测试环境和生产环境用不同命名空间)。
- spec(规格)必配字段,Pod的核心配置,核心子字段:
containers:容器列表,必配字段,一个Pod可包含多个容器(数组形式,用-开头),每个容器的核心配置:
name:容器名称,必须在当前Pod内唯一,比如nginx、log-collector。
image:容器镜像,必配字段,格式为“仓库地址+镜像名+版本”,比如nginx:1.24、mysql:8.0。建议指定具体版本(不要用latest),避免镜像更新导致Pod异常。
ports:可选字段,用于暴露容器端口,方便Pod内部或外部访问,核心子字段containerPort(容器内部端口)必配,protocol(协议)可选(默认TCP)。
imagePullPolicy:可选字段,镜像拉取策略,有3种:Always(每次都拉取镜像)、IfNotPresent(本地有镜像则不用拉取,默认)、Never(只使用本地镜像,不拉取)。
restartPolicy:必配字段,重启策略,默认是Always,前面已经详细讲解。
initContainers:可选字段,初始化容器列表,格式和containers一致,会在主容器启动前执行。
3.3 多容器Pod yaml示例(可选)
下面给出一个多容器Pod的yaml示例(Nginx容器+日志收集容器),供参考,小白可先不实操,了解即可:
apiVersion: v1 kind: Pod metadata: name: nginx-log-pod labels: app: nginx-log spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort:80volumeMounts:# 挂载存储卷(共享日志文件)- name: log-volume mountPath: /var/log/nginx# 容器内挂载路径- name: log-collector image: busybox:1.35# 日志收集容器(用busybox模拟)command:["/bin/sh","-c","tail -f /var/log/nginx/access.log"]# 实时查看日志volumeMounts: - name: log-volume mountPath: /var/log/nginx# 和Nginx容器挂载同一个存储卷volumes:# 定义存储卷(共享存储)- name: log-volume emptyDir:{}# 临时存储卷,Pod删除后数据丢失3.4 InitContainer yaml示例(可选)
下面给出一个包含InitContainer的Pod yaml示例(初始化容器等待MySQL启动),供参考:
apiVersion: v1 kind: Pod metadata: name: app-with-init labels: app: app-init spec: initContainers:# 初始化容器- name: wait-mysql image: busybox:1.35 command:["sh","-c","until ping -c 1 mysql-service; do sleep 2; done"]# 等待mysql-service启动containers:# 主容器- name: app image: tomcat:8.5 ports: - containerPort:8080restartPolicy: Always四、Pod常用操作命令(实操重点,可直接复制)
掌握以下命令,就能完成Pod的日常操作(创建、查看、删除、进入容器等),所有命令均在Master节点执行,全程实操演示。
4.1 命令行创建Pod(适合测试)
用kubectl create命令直接创建Pod,无需编写yaml文件,简单快捷:
# 创建一个Nginx Pod(指定镜像和名称)kubectl create pod nginx-test--image=nginx:1.24# 查看Pod是否创建成功kubectl get pods输出结果中,STATUS为Running,说明Pod创建成功并正常运行。
4.2 用yaml文件创建Pod(适合生产)
- 先创建yaml文件(比如nginx-pod.yaml),复制前面的单容器Pod模板:
vinginx-pod.yaml# 粘贴yaml模板内容,保存退出(按Esc,输入:wq)2. 用kubectl apply命令创建Pod:
# 用yaml文件创建Podkubectl apply-fnginx-pod.yaml# 查看Pod状态kubectl get pods注意:kubectl apply -f 文件名 是K8s中部署资源的标准命令,后续部署Deployment、Service也会用到,优点是“可重复执行”(修改yaml后重新执行,会更新Pod配置)。
4.3 查看Pod相关信息(高频命令)
# 1. 查看所有Pod的状态(简洁版)kubectl get pods# 2. 查看所有Pod的状态(详细版,包含IP、Node节点等)kubectl get pods-owide# 3. 查看指定Pod的详细信息(排查异常必备)kubectl describe pod Pod名称# 比如kubectl describe pod nginx-pod# 4. 查看Pod的日志(排查容器运行异常)kubectl logs Pod名称# 比如kubectl logs nginx-pod# 5. 实时查看Pod日志(类似tail -f)kubectl logs-fPod名称# 6. 查看Pod的yaml配置(查看当前Pod的实际配置)kubectl get pod Pod名称-oyaml4.4 进入Pod的容器(实操必备)
当Pod内的容器出现异常时,我们可以进入容器内部,查看文件、执行命令,排查问题:
# 进入Pod的容器(单容器Pod,直接进入)kubectlexec-itPod名称 -- /bin/bash# 比如kubectl exec -it nginx-pod -- /bin/bash# 进入Pod的指定容器(多容器Pod,需指定容器名称)kubectlexec-itPod名称-c容器名称 -- /bin/bash# 比如kubectl exec -it nginx-log-pod -c nginx -- /bin/bash说明:-it 表示“交互式终端”,-- 后面是容器内要执行的命令(/bin/bash表示进入容器的命令行);进入容器后,执行exit命令即可退出。
4.5 更新Pod配置(yaml方式)
如果需要修改Pod的配置(比如更换镜像、修改端口),直接修改yaml文件,然后执行以下命令:
# 修改yaml文件(比如修改镜像版本为nginx:1.25)vinginx-pod.yaml# 更新Pod配置kubectl apply-fnginx-pod.yaml# 查看更新后的Pod状态kubectl get pods注意:Pod是“不可变的”,更新配置后,K8s会删除旧的Pod,重新创建一个新的Pod(旧Pod的状态会变为Terminating,新Pod会重新启动)。
4.6 删除Pod
# 方式1:删除指定Pod(按名称删除)kubectl delete pod Pod名称# 比如kubectl delete pod nginx-pod# 方式2:通过yaml文件删除Pod(创建时用yaml,删除时也可以用yaml)kubectl delete-fnginx-pod.yaml# 方式3:删除所有Pod(谨慎使用,会删除当前命名空间所有Pod)kubectl delete pods--all五、实战:部署一个Nginx Pod(全程实操)
结合前面的知识点,我们实战部署一个Nginx Pod,全程步骤可复制,确保小白能跟着完成:
步骤1:创建yaml文件vi nginx-pod.yaml粘贴以下yaml内容(可直接复制):apiVersion: v1
kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort:80restartPolicy: Always保存退出(按Esc,输入:wq)。
步骤2:创建Podkubectl apply -f nginx-pod.yaml输出“pod/nginx-pod created”,说明Pod创建成功。
步骤3:查看Pod状态kubectl get pods如果STATUS为Running,说明Pod正常运行;如果是Pending,等待1-2分钟(镜像正在下载),再次查看。
步骤4:查看Pod详细信息kubectl describe pod nginx-pod查看Pod的Node节点、容器状态、镜像信息等,确认没有异常。
步骤5:进入容器内部kubectl exec -it nginx-pod – /bin/bash进入容器后,执行以下命令,查看Nginx配置文件:cat /etc/nginx/nginx.conf执行exit命令退出容器。
步骤6:删除Pod(测试完成后)kubectl delete pod nginx-pod
完成以上步骤,就成功实战了Pod的创建、查看、进入容器、删除等操作,小白可以多练习几遍,熟悉命令。
六、常见问题排错(小白必看)
问题1:Pod创建后,状态一直为Pending原因:大概率是镜像下载失败(国外镜像源访问不畅),或Node节点资源不足(CPU/内存不够)。解决:1. 配置Docker镜像加速(参考第二篇2.3步骤);2. 手动拉取镜像(比如docker pull nginx:1.24);3. 检查Node节点资源(kubectl get nodes -o wide,查看CPU、内存使用情况)。
**问题2:Pod状态为CrashLoopBackOff(容器反复重启)**原因:容器启动失败(比如镜像错误、容器内命令错误、端口冲突)。解决:查看Pod日志(kubectl logs -f Pod名称),根据日志提示排查问题(比如镜像名称错误,将nginx:1.24改为nginx:latest)。
问题3:无法进入Pod容器,提示“exec: “/bin/bash”: stat /bin/bash: no such file or directory”原因:容器内没有/bin/bash命令(比如部分精简版镜像,只有/sh)。解决:用/sh代替/bin/bash,命令改为:kubectl exec -it Pod名称 – /bin/sh。
**问题4:yaml文件报错,提示“error: error parsing nginx-pod.yaml: error converting YAML to JSON: yaml: line x: did not find expected key”**原因:yaml文件缩进错误(用了Tab,或缩进不一致)。解决:检查yaml文件,确保所有缩进都用空格,且同一层级的缩进一致(比如metadata和spec缩进一致,containers下的子字段缩进比containers多2个空格)。
问题5:删除Pod后,Pod又自动重建原因:Pod被Deployment、StatefulSet等控制器管理(后续会讲),控制器会自动重建Pod。解决:先删除对应的控制器(比如kubectl delete deployment 控制器名称),再删除Pod。
七、总结
本文详细讲解了Pod的核心知识点,从定义、生命周期,到yaml配置、常用命令,再到实战操作和排错,全程围绕小白的学习节奏,确保每个知识点都能理解、每个命令都能实操。
重点记住3点:
Pod是K8s最小的部署单元,一个Pod可包含1个或多个容器,容器共享Pod的网络和存储;
yaml是部署Pod的标准方式,核心字段(apiVersion、kind、metadata、spec)必须掌握,缩进是yaml的关键,不能用Tab;
kubectl常用命令(create、apply、get、describe、logs、exec、delete)是操作Pod的核心,多练习就能熟练掌握。
下一篇文章,我们将学习K8s的工作负载控制器——《K8s 工作负载:Deployment 完整实战(滚动更新+回滚)》,带你了解如何用Deployment管理Pod,实现Pod的扩缩容、滚动更新,敬请关注!
最后,如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注,后续会持续更新K8s系列实战文章,从入门到精通,带你轻松搞定K8s!
