文章目录
- 前言
- 理论部分
- 实验部分
-
- 1_Pod配置与镜像策略测试
-
- 1.1_镜像拉取策略验证
-
- [① 创建测试配置文件](#① 创建测试配置文件)
- [② 创建与验证Pod](#② 创建与验证Pod)
- [③ 修改配置并验证](#③ 修改配置并验证)
- 2_资源限制与调度实验
-
- 2.1_配置多容器资源限制
-
- [① 创建测试Pod](#① 创建测试Pod)
- [② 部署与验证](#② 部署与验证)
- 3_健康检查实验
-
- 3.1_livenessProbe配置实验
-
- [① exec方式验证](#① exec方式验证)
- [② httpGet方式验证](#② httpGet方式验证)
- 3.2_readinessProbe联动验证
-
- [① 部署多副本应用](#① 部署多副本应用)
- [② 触发就绪失败](#② 触发就绪失败)
- 4_生命周期管理实验
-
- 4.1_Init容器与钩子验证
-
- [① 创建生命周期测试Pod](#① 创建生命周期测试Pod)
- [② 验证执行顺序](#② 验证执行顺序)
- 结语
前言
Pod是Kubernetes中最小部署单元,它代表集群中的一个运行进程。本笔记系统梳理了Pod的核心概念、实现机制及高级配置,涵盖基础特性、共享资源、容器分类、配置策略、资源限制和健康检查等内容,帮助读者掌握Pod的设计原理与实战应用。
- Pod核心概念与组成机制
- Pod资源管理与配置策略
- 健康检查与生命周期管理
理论部分
1_Pod核心概念与组成机制
- Pod 是 Kubernetes 中的最小部署单元,代表集群中的一个运行进程,由一个或多个紧密耦合的容器组成,这些容器共享网络和存储资源。在 Kubernetes 中,Deployment、StatefulSet 等控制器对象都围绕 Pod 进行扩展。
1.1_Pod的两种场景
- 单容器 Pod:最常见的用法,一个 Pod 仅包含一个容器,此时 Pod 相当于容器的封装。
- 多容器 Pod:一个 Pod 包含多个容器,适用于需要共享网络和存储资源的紧密耦合服务。
1.2_Pause容器(基础容器)
- 每个 Pod 中均包含特殊的 Pause 容器,它负责提供 Linux 命名空间基础,使所有容器共享同一网络和存储命名空间。镜像路径通常为:
registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0 - 进程ID为1的init容器
- 管理所有容器的守护进程容器
共享资源机制 :- 网络共享:每个 Pod 分配唯一 IP 地址,容器间通过 localhost 通信,与外界通信需通过宿主机端口映射。
- 存储共享 :Pod 可指定多个共享 Volume,确保容器重启后数据不丢失。

1.3_分类
- 自主式 Pod:不具备自我修复能力,节点故障即删除。
- 控制器管理的 Pod:通过 Deployment 等控制器管理,提供副本管理和自动修复功能。
1.4_容器角色划分
- 基础容器:即 Pause 容器,管理网络和存储命名空间。
- 初始化容器:Init 容器在应用容器启动前串行运行,必须顺序执行且全部成功后应用容器才启动。用于执行初始化任务,如依赖(jdk等)、配置文件等。
- 应用容器:即 Maincontainer,负责业务逻辑执行,多容器场景下并行启动。
初始化容器(init容器): 阻塞或者延迟应用容器的启动 ,可以为应用容器事先提供好运行环境和工具(JDK 配置文件 nginx.conf),
多个init容器时是串行启动,每个init容器都必须在下一个init容器启动完成才会退出
2_Pod资源管理与配置策略
2.1_镜像拉取策略
| 策略 | 解释 |
|---|---|
IfNotPresent |
默认策略,本地有镜像则不拉取 |
Always |
每次启动均强制拉取最新镜像 |
Never |
仅使用本地镜像,不进行拉取 |
image nginx 镜像的标签为latest或者无标签时,默认镜像拉取策略为always
nginx:1.20 镜像的标签为非latset,默认的镜像拉取策略为 IFNotPresent
2.2_重启策略
| 策略 | 解释 |
|---|---|
Always |
默认值,无论退出状态均重启 |
OnFailure |
仅非正常退出(退出码≠0)时重启 |
Never |
容器退出后永不重启,适合一次性任务 |
注意:Kubernetes 不支持直接重启 Pod,只能删除重建。
2.3_资源限制配置
- requests:容器启动时最少需要的资源,是调度器选择节点的依据。
- limits:容器运行时可使用的最大资源量,超出将被限流或终止。
- 未设置 requests 时自动套用 limits 值。
资源单位: - CPU :以 m(毫核)为单位,
500m = 0.5 CPU。 - 内存 :推荐使用二进制单位(
1Gi = 1024 Mi),避免与十进制单位混淆。
调度逻辑 :调度器根据所有容器 requests 总和选择节点,节点需预留足够资源。可通过kubectl describe nodes查看资源分配详情。
3_健康检查与生命周期管理
3.1_探针类型
| 探针类型 | 执行时机 | 失败后果 |
|---|---|---|
| livenessProbe | 判断容器是否存活 | 杀死容器并按 restartPolicy 重启 |
| readinessProbe | 判断容器是否就绪接收请求 | Service 从 Endpoints 剔除该 Pod |
| startupProbe | 判断应用是否启动完成(K8s 1.17+) | 重启容器 |
| 存活探针(liveness probe) |
- 判断容器时正常运行,如果探测失败会杀掉容器(不是pod)
- 容器会根据容器的策略决定是否重启
就绪探针(readiness probe) - 判断pod是否能进入ready状态,做好接受请求的准备。
- 探测失败会进入Notready状态,并从service资源会在endporint中去剔除pod,service将不会再把访问请求去转发给这个pod。
启动探针(startup probe) - 判断容器内应用是否启动成功
- 探测成功转到sucess之前,其他探针都会处于失效状态。
3.2_检测方法
| 方法 | 执行方式 | 成功条件 |
|---|---|---|
| exec | 在容器内执行命令 | 返回码为 0 |
| tcpSocket | 对容器 IP:Port 进行 TCP 三次握手检查 | 端口成功打开 |
| httpGet | 对容器 IP:Port/Path 执行 HTTP GET 请求 | 状态码 200≤code<400 |
| exec |
- 通command设置执行在容器内的linux命令来进行探测。
- 如果返回码为0,默认探测成功。
httpget
- 通过http get 请求访问指定的容器端口 url路劲 /path;
- 若果返回的状态码>=200且<400(2xx,3xx),则认为探测成功。
tcpsocket
- 通过对指定的端口发送tcp连接
- 如果端口无误且 三次握手成功(tcp连接成功),则认为探测成功。
3.3_生命周期钩子
- postStart:容器启动后立即执行,无法保证顺序。
- preStop:容器终止前执行,用于优雅关闭。
- 钩子失败可能导致容器终止或重启,具体行为取决于配置。
3.4_pod状态
pending
- pod已经被系统认可了,但是内部的container还没有创建出来。
- 这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。
Running - pod已经与node绑定了(调度成功)
- 而且pod中所有的container已经创建出来,至少有一个容器在运行中,
- 或者容器的进程正在启动或者重启状态。
这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。
Succeeded
- 这个状态很少出现,
- 表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。
Failed - pod中的所有容器都被terminated,至少一个container是非正常终止的。
退出的时候返回了一个非0的值或者是被系统直接终止
unknown
- 由于某些原因pod的状态获取不到,有可能是由于通信问题。
- 一般情况下pod最常见的就是前两种状态。
- 而且当Running的时候,需要进一步关注container的状态
Container生命周期
- Waiting:启动到运行中间的一个等待状态。
- Running:运行状态。
- Terminated:终止状态。
- 如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。
- 但如果长时间处于Waiting状态,container会有一个字段reason表明它所处的状态和原因。
- 如果这个原因很容易能标识这个容器再也无法启动起来时,例如ContainerCannotRun,整个服务启动就会迅速返
回。(这里是一个失败状态返回的特性,不详细阐述)
实验部分
1_Pod配置与镜像策略测试
1.1_镜像拉取策略验证
① 创建测试配置文件
shell
mkdir /opt/demo
cd /opt/demo
vim pod1.yaml
mkdir/cd:创建并进入测试目录
vim:编辑配置文件
- pod1.yaml 内容
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test1
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
imagePullPolicy: Always:强制每次拉取镜像
command:执行后立即退出的命令
② 创建与验证Pod
shell
kubectl create -f pod1.yaml
kubectl get pods -o wide
输出:
pod-test1 0/1 CrashLoopBackOff说明:容器退出触发重启,因 restartPolicy 默认 Always
shell
kubectl describe pod pod-test1
关键事件:
Warning BackOff: Back-off restarting failed container说明:每次重启都重新拉取镜像
③ 修改配置并验证
shell
vim pod1.yaml # 修改:image: nginx:1.14, 注释command
kubectl delete -f pod1.yaml && kubectl apply -f pod1.yaml
操作:固定镜像版本并移除退出命令
验证:
curl -I http://<Pod_IP>返回200 OK
2_资源限制与调度实验
2.1_配置多容器资源限制
① 创建测试Pod
shell
vim pod2.yaml
- pod2.yaml 内容
yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: web
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: db
image: mysql
resources:
requests:
memory: "512Mi"
cpu: "0.5"
limits:
memory: "1Gi"
cpu: "1"
配置:Web容器(0.25/0.5 CPU + 64/128Mi 内存)
配置:DB容器(0.5/1 CPU + 512/1Gi 内存)
总计:0.75/1.5 CPU + 576/1.128Gi 内存
② 部署与验证
shell
kubectl apply -f pod2.yaml
kubectl describe pod frontend
输出资源详情:
Requests: cpu=500m, memory=128Mi
Limits: cpu=1, memory=256Mi
shell
kubectl describe node node02
节点资源分配视图:
Namespace: default, Name: frontend, CPU Requests: 500m (25%), Memory Requests: 128Mi (3%)
3_健康检查实验
3.1_livenessProbe配置实验
① exec方式验证
- exec.yaml 配置
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
command: ["/bin/sh","-c","touch /tmp/live; sleep 30; rm -rf /tmp/live; sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
原理:30秒后删除检查文件触发探测失败
shell
kubectl create -f exec.yaml
kubectl get pods -w
输出:
liveness-exec ... Restarted 1...2说明:文件删除后每30秒触发重启
② httpGet方式验证
- httpget.yaml 配置
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
spec:
containers:
- name: nginx
image: soscscs/myapp:v1
livenessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
shell
kubectl create -f httpget.yaml
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
操作:删除首页文件
结果:容器3次探测失败后自动重启
3.2_readinessProbe联动验证
① 部署多副本应用
- readiness-myapp.yaml 配置
yaml
# 包含3个myapp Pod和1个Service
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 80
shell
kubectl create -f readiness-myapp.yaml
kubectl get endpoints # 显示3个健康Pod
② 触发就绪失败
shell
kubectl exec -it myapp1 -- rm -rf /usr/share/nginx/html/index.html
kubectl get endpoints # 仅显示2个健康Pod
说明:失败Pod的IP从Endpoints中剔除,不再接收流量
4_生命周期管理实验
4.1_Init容器与钩子验证
① 创建生命周期测试Pod
- post.yaml 配置
yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
initContainers:
- name: init-myservice
command: ["/bin/sh","-c","echo 'Hello initContainers' >> /var/log/nginx/message"]
containers:
- name: app
image: soscscs/myapp:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","echo Hello postStart >> /var/log/nginx/message"]
preStop:
exec:
command: ["/bin/sh","-c","echo Hello preStop >> /var/log/nginx/message"]
volumes:
- name: message-log
hostPath:
path: /data/volumes/nginx/log/
② 验证执行顺序
shell
kubectl create -f post.yaml
kubectl exec lifecycle-demo -- cat /var/log/nginx/message
输出顺序:
Hello initContainers
Hello postStart
shell
kubectl delete pod lifecycle-demo
cat /data/volumes/nginx/log/message # 节点查看
追加内容:
Hello preStop
结语
Pod是Kubernetes的核心调度单元,承载容器运行环境。关键要点:Pause容器提供命名空间基础;Init容器确保初始化顺序;资源请求/限制保障调度与运行;Liveness/Readiness/Startup探针实现智能自愈;生命周期钩子扩展容器行为控制。
Pod核心地位 :最小可部署单元,所有Workload基于此扩展。
资源限制意义 :requests用于调度,limits防资源耗尽,单位m(CPU)、Mi(内存)。
探针优先级:startupProbe成功后,其他探针才生效,避免误杀启动慢的应用。
面试题 pod中多个容器之间怎么通讯
答:localhost
为k8s pod内部容器是共享网络空间的,所以容器直接可以使用localhost访问其他容器。
k8s在启动容器的时候会先启动一个pause容器,这个容器就是实现这个功能的。
!question\] 请问Pause容器的核心作用是什么? 提供Pod的Linux命名空间基础,使所有容器共享网络和存储资源。 \[!question\] 请问Init容器与应用容器的启动顺序是什么? Init容器按顺序启动并成功退出后,所有应用容器并行启动。 \[!question\] 请问readinessProbe失败会触发什么后果? 端点控制器将Pod IP从Service的Endpoints中剔除,不再接收流量。 \[!question\] 请说明restartPolicy为Never时Init容器失败的处理逻辑。 Pod不会自动重启,卡在Pending状态等待人工干预。 \[!question\] 为什么建议内存配置使用二进制单位(如1Gi)? 避免二进制与十进制单位混淆(1GiB = 1.074GB),减少资源分配误差。