58 k8s之pod

文章目录

前言

Pod是Kubernetes中最小部署单元,它代表集群中的一个运行进程。本笔记系统梳理了Pod的核心概念、实现机制及高级配置,涵盖基础特性、共享资源、容器分类、配置策略、资源限制和健康检查等内容,帮助读者掌握Pod的设计原理与实战应用。

  1. Pod核心概念与组成机制
  2. Pod资源管理与配置策略
  3. 健康检查与生命周期管理

理论部分

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生命周期

  1. Waiting:启动到运行中间的一个等待状态。
  2. Running:运行状态。
  3. 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),减少资源分配误差。

相关推荐
可爱又迷人的反派角色“yang”2 小时前
k8s(五)
linux·运维·docker·云原生·容器·kubernetes
oMcLin2 小时前
如何在Ubuntu 22.10上通过配置K3s轻量级Kubernetes集群,提升边缘计算环境的资源管理能力?
ubuntu·kubernetes·边缘计算
optimistic_chen3 小时前
【Docker入门】容器技术
linux·运维·服务器·docker·容器
小明_GLC3 小时前
理解Docker、镜像Images、容器Container
docker·容器
努力搬砖的咸鱼3 小时前
用 Docker 部署你的第一个微服务
docker·微服务·云原生·容器
水上冰石3 小时前
如何查看k8s按照的jenkins插件的路径
容器·kubernetes·jenkins
鱼跃鹰飞3 小时前
经典面试题:K8S的自动缩扩容和崩溃恢复
java·容器·kubernetes
江湖有缘3 小时前
Fenrus + Docker 实战:构建简洁高效的浏览器新标签页
运维·docker·容器
Zsr10233 小时前
K8s核心组件pod:进阶篇
云原生·容器·kubernetes·pod