Kubernetes Pod 入门

前言

如果你刚接触 Kubernetes(简称 K8s),那一定绕不开 "Pod" 这个核心概念。Pod 是 K8s 集群里最小的部署单元,就像一个 "容器工具箱"------ 它不直接跑业务,而是把容器和集群的网络、存储资源打包在一起,让应用能在集群中稳定运行。不管是简单的 Nginx 服务,还是需要多个组件协作的复杂应用,都得靠 Pod 落地。今天这篇文章就用 "大白话 + 实战" 的方式,带你吃透 Pod 的核心知识,从概念到配置全搞懂。

一、Pod 基础详解

1.1 Pod 的基本概念

简单说,Pod 是 K8s 里 "最小的可部署单元",代表集群中的一个运行进程。你可以把它理解为 "容器的封装盒":里面能装一个或多个联系紧密的容器,这些容器共享 Pod 的网络、存储等资源,就像住在同一个房子里的室友,共用客厅和网络。

K8s 不会直接管理容器,所有的高级功能(比如自动重启、滚动升级)都是通过控制器(像 Deployment、StatefulSet 这些 "管理工具")围绕 Pod 实现的。所以搞懂 Pod,就是入门 K8s 的第一步。

1.2 Pod 的使用方式

根据里面装的容器数量,Pod 主要有两种用法,其中单容器 Pod 最常见。

1.2.1 单容器 Pod

这是最普遍的用法:一个 Pod 里只装一个容器。此时 Pod 就像给容器穿了件 "外套",K8s 管理的是这个 "外套",而不是里面的容器。比如部署一个 Nginx 服务,就可以用单容器 Pod。

简单配置示例(直接复制就能用):

yaml 复制代码
apiVersion: v1  # K8s 的 API 版本,Pod 用 v1 就行
kind: Pod       # 资源类型是 Pod
metadata:
  name: single-container-pod  # Pod 的名字,自己随便起
spec:
  containers:
  - name: nginx  # 容器的名字
    image: nginx:1.14  # 要使用的镜像(相当于容器的"安装包")
1.2.2 多容器 Pod

一个 Pod 里装多个容器,这些容器通常是 "工作搭档"------ 比如一个主应用容器(跑业务)和一个边车容器(收集日志、处理配置)。它们共享网络和存储,能通过 localhost 直接通信,不用走复杂的网络配置。

简单配置示例:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: app  # 主应用容器
    image: my-app:latest  # 自己的业务镜像
  - name: sidecar  # 边车容器(辅助作用)
    image: log-collector:latest  # 日志收集镜像

1.3 Pause 容器(基础容器)

每个 Pod 里都藏着一个 "隐形地基"------ Pause 容器(也叫基础容器)。它不用我们手动配置,K8s 会自动创建,主要做两件关键事:

  1. 提供 Pod 级别的 "基础环境"(Linux 命名空间),让里面的所有容器能共享网络和存储;
  2. 维护 Pod 的网络端点,让容器间通信更高效。

你可以在集群节点上执行 docker ps 命令,看到这个 "隐形容器",它的镜像通常是这样的:registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0,作用就是 "稳住" 整个 Pod 的基础资源。

1.4 Pod 中的共享资源

Pod 里的容器之所以能协作,核心是共享了两种关键资源:网络和存储。

1.4.1 网络共享
  • 每个 Pod 会分配一个唯一的 IP 地址(相当于这个 "房子" 的门牌号);
  • 所有容器共享这个 IP 和端口,就像室友共用一个门牌号,互相拜访(通信)直接喊 "localhost + 端口" 就行;
  • 要和集群外的服务通信,就得通过宿主机的端口映射(相当于给房子装个对外的大门)。
1.4.2 存储共享
  • Pod 可以创建多个 "共享文件夹"(叫 Volume),所有容器都能访问;
  • 这些 "文件夹" 支持持久化存储,就算容器重启,里面的数据也不会丢(比如数据库的存储卷,重启后数据还在)。

1.5 Pod 的使用场景

Pod 不是随便用的,主要适合两种场景:

  1. 单一进程应用:最常见,一个 Pod 跑一个业务容器(比如 Nginx、MySQL),简单直接;
  2. 多进程协作:多个容器一起完成任务(比如主应用 + 日志收集器 + 配置更新器),它们必须紧密配合,缺一不可。

1.6 Pod 的类型

根据管理方式,Pod 分两种,生产环境里几乎都用第二种。

1.6.1 自主式 Pod

直接手动创建的 Pod,就像 "没人管的孩子":如果它所在的节点出故障(比如宕机),这个 Pod 会被删除,而且不会自动重建,适合临时测试。

1.6.2 控制器管理的 Pod

由 K8s 的 "管理工具"(控制器,比如 Deployment)创建的 Pod,就像 "有监护人的孩子":

  • 支持自动修复(节点故障了,会在其他节点重建 Pod);
  • 能管理多个副本(比如同时跑 3 个 Nginx Pod,负载均衡);
  • 支持滚动升级(更新应用时不中断服务),是生产环境的首选。

1.7 Pod 容器的分类

一个 Pod 里的容器分工明确,主要分三类:

1.7.1 基础容器(Infrastructure Container)

就是前面说的 Pause 容器,K8s 自动创建,维护基础资源,对我们透明(不用管它)。

1.7.2 初始化容器(Init Containers)

"准备工作专员",必须在应用容器启动前跑完,而且要按顺序执行(第一个做完,第二个才开始)。主要做这些事:

  • 等待依赖服务就绪(比如先等数据库启动,再启动应用);
  • 生成配置文件、设置权限等初始化操作;
  • 如果初始化失败,K8s 会根据重启策略重试,直到成功。
1.7.3 应用容器(Main Containers)

我们真正要部署的业务容器,比如 Nginx、MySQL,是 Pod 的核心。只有所有初始化容器都成功后,应用容器才会并行启动。

1.7.4 示例:等待 myservicemydb 服务就绪的初始化容器

下面用一个实战例子,带你看懂初始化容器的作用:我们要启动一个应用,但它必须等 myservicemydb 两个服务启动后才能运行。

步骤 1:创建带初始化容器的 Pod

新建文件 myapp-pod.yaml,内容如下:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod  # Pod 名字
  labels:
    app: myapp
spec:
  # 应用容器(要等初始化完成才启动)
  containers:
  - name: myapp-container
    image: busybox:1.28  # 轻量级工具镜像
    command: ['sh', '-c', 'echo 应用启动成功! && sleep 3600']  # 模拟应用运行

  # 初始化容器(按顺序执行)
  initContainers:
  # 第一个:等 myservice 服务就绪
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo 等 myservice...; sleep 2; done;']
  # 第二个:等 mydb 服务就绪
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mydb; do echo 等 mydb...; sleep 2; done;']
步骤 2:查看 Pod 状态(初始化阻塞)

执行命令创建 Pod:kubectl apply -f myapp-pod.yaml,然后查看状态:

bash 复制代码
kubectl get pods

会看到 Pod 状态是 Init:0/2(两个初始化容器都没完成),因为 myservicemydb 还没创建,初始化容器一直在等。

步骤 3:创建依赖服务,让初始化完成

分别创建 myservicemydb 服务(模拟依赖就绪):

  1. 新建 myservice.yaml
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

执行:kubectl apply -f myservice.yaml

  1. 新建 mydb.yaml
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

执行:kubectl apply -f mydb.yaml

步骤 4:验证应用启动

再查看 Pod 状态:kubectl get pods,会发现状态变成 Running(应用启动成功)。执行命令查看日志:

bash 复制代码
kubectl logs myapp-pod -c myapp-container

会输出 应用启动成功!,说明初始化容器完成了依赖检查。

二、Pod 的核心配置

Pod 的稳定运行,关键靠两个核心配置:镜像拉取策略和重启策略。

2.1 镜像拉取策略(imagePullPolicy)

容器是基于 "镜像" 启动的(镜像相当于容器的 "安装包"),这个策略决定了 K8s 怎么获取镜像,有三种选择:

策略 作用 适用场景
IfNotPresent 本地有镜像就用,没有才从网上拉(默认) 生产环境(高效)
Always 每次启动都重新从网上拉镜像 开发环境(实时更)
Never 只用地本地镜像,绝不从网上拉 离线环境

配置示例(给 Nginx 容器设置 Always 策略):

yaml 复制代码
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    imagePullPolicy: Always  # 每次启动都拉新镜像
2.1.1 镜像拉取策略案例

我们用一个实战案例,看看策略配置错了会怎么样:

步骤 1:创建一个有问题的 Pod

新建 pod1.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: Always
    command: [ "echo", "SUCCESS" ]  # 问题所在:执行完就退出

执行创建命令:kubectl create -f pod1.yaml

步骤 2:观察异常状态

查看 Pod 状态:kubectl get pods -o wide,会发现状态是 CrashLoopBackOff(崩溃循环重启)。

原因:echo "SUCCESS" 执行完就结束了,容器生命周期结束,但重启策略是默认的 Always(一直重启),而且镜像拉取策略是 Always,所以每次重启都要重新拉镜像,反复循环。

步骤 3:修复配置

修改 pod1.yaml,删除错误命令,修改拉取策略:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    imagePullPolicy: IfNotPresent  # 本地有就不用拉

执行更新:kubectl apply -f pod1.yaml

步骤 4:验证结果

再查看状态:kubectl get pods -o wide,会显示 Running(正常运行)。在集群节点上执行 curl -I Pod的IP,会返回 HTTP/1.1 200 OK,说明 Nginx 正常工作。

2.2 重启策略(restartPolicy)

这个策略决定了容器退出后,K8s 要不要重启它,也有三种选择:

策略 作用 适用场景
Always 不管退出码是什么,都重启(默认) 长期服务(如 Nginx)
OnFailure 只有容器非正常退出(退出码非 0)才重启 重要任务(怕意外崩溃)
Never 退出后绝不重启 一次性任务(如数据备份)

注意:K8s 不能直接重启 Pod,只能删除后重建,这个策略只针对容器。

配置示例(设置 OnFailure 策略):

yaml 复制代码
spec:
  containers:
  - name: busybox
    image: busybox
    args: ['sh', '-c', 'sleep 30; exit 3']  # 30 秒后非正常退出
  restartPolicy: OnFailure  # 非正常退出才重启
2.2.1 重启策略案例
步骤 1:创建默认策略的 Pod

新建 pod3.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args: ['sh', '-c', 'sleep 10; exit 3']  # 10 秒后非正常退出

执行创建:kubectl apply -f pod3.yaml

步骤 2:观察重启情况

10 秒后查看状态:kubectl get pods,会发现 RESTARTS(重启次数)变成 1,说明默认的 Always 策略生效了,一直在重启。

步骤 3:修改为 Never 策略

修改 pod3.yaml,添加重启策略:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: busybox
    image: busybox
    args: ['sh', '-c', 'sleep 10; exit 3']
  restartPolicy: Never  # 绝不重启

执行更新:kubectl delete -f pod3.yaml && kubectl apply -f pod3.yaml

步骤 4:验证结果

实时监控状态:kubectl get pods -w,10 秒后容器退出,状态变成 Error,但 RESTARTS 一直是 0,说明不再重启,策略生效。

总结

Pod 是 K8s 的 "基础积木",核心要点其实很简单:

  1. 本质是 "容器封装盒",里面有基础容器(Pause)、初始化容器(做准备)、应用容器(跑业务);
  2. 容器共享网络和存储,适合单一进程或紧密协作的多进程场景;
  3. 生产环境用 "控制器管理的 Pod",配合 IfNotPresent 镜像拉取策略和 Always 重启策略,稳定又高效;
  4. 遇到问题用 kubectl get pods(看状态)、kubectl describe pod 名字(查原因)、kubectl logs 名字 -c 容器名(看日志),基本能解决大部分问题。
相关推荐
java_logo2 小时前
Dify 开源 LLM 应用开发平台企业级 Docker Compose 部署手册
docker·容器·开源·dify部署·dify部署文档·dify部署方案·dify部署教程
jarreyer3 小时前
【docker的gpu加速相关问题解决记录】
运维·docker·容器
韭菜钟3 小时前
制作自定义Docker镜像并部署使用
运维·docker·容器
椰汁菠萝3 小时前
docker部署gitlab
docker·容器·gitlab
Gold Steps.4 小时前
K8s Gateway-API 标准化流量治理
容器·kubernetes·gateway
oMcLin4 小时前
如何在Ubuntu 20.04上配置并调优Kubernetes集群,确保在多租户环境下的高可用性与资源分配?
linux·ubuntu·kubernetes
牛奔5 小时前
Docker Compose 解决服务间 DNS 解析失败问题
运维·docker·容器
L1624766 小时前
Docker 安装部署全流程使用指南(Linux 通用版)
linux·docker·容器
Mr. Cao code6 小时前
MySQL数据卷实战:持久化存储秘籍
数据库·mysql·docker·容器