Pod 详解
pod存货,越来越忙了,昨天还没睡好,晚上硬顶一下把任务都完成吧
Pod 详解
主容器的辅助:init容器,sidecar容器
init 容器
Init 容器是一种特殊容器,它在 Pod 内的应用容器启动之前运行,用来在主容器启动之前执行一些初始化任务以及操作,以满足环境. 可以不止一个,必须显式指定,没有默认的init容器
一般可以用来:数据库初始化,准备文件(通过pod内共享卷),检查依赖服务等
例子:
apiVersion: v1
kind: Pod
metadata:
name: pod-init
labels:
app: nginx
spec:
# 初始化容器
initContainers:
- name: clone
image: bitnami/git
command: ['/bin/sh', '-c', "git clone <目标内容>"]
volumeMounts:
- name: data
mountPath: /data
# 主容器
containers:
- name: web
image: nginx:1.23
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
emptyDir: {}
此例中,init容器使用git拷贝代码平台上的程序,并通过共享目录和主容器共享,完成后退出,供nginx容器提供网站服务
Static Pod
Container Lifecycle Hooks
本节参考: 健康检查-检查方法指定
所谓的"容器生命周期回调",感觉这个翻译及其误导人,又不是类似"快照"那种机制,还"回调"呢.我认为就是一些准备的初始化动作,"hook"可以当成抛锚收锚
-
lifecycle hooks(容器生命周期回调)
-
作用:在容器生命周期的特定阶段执行一些 额外动作,而不是主进程。
-
两个 hook:
-
postStart:容器启动后立即执行(但不保证在容器主进程前/后)。 -
preStop:在容器被终止之前执行(例如 Pod 删除、缩容时)。
-
-
它们只是“附加动作”,不会替代容器主进程。
-
-
command(相当于 Docker 的
ENTRYPOINT/CMD覆盖)-
作用:定义容器启动时主进程要执行的命令。
-
生命周期:只会在容器启动时运行,并且它就是容器的主进程,如果它退出,容器就退出。
-
默认值:取决于镜像里的
ENTRYPOINT和CMD,如果你在 Deployment 里没写command,K8s 就用镜像自带的。
-
定义字段
apiversion: v1 # API版本
kind: Pod # 资源类型
metadata: <Object> # 资源元数据
labels: # Pod标签
key: value
name: <string> # Pod名称
namespace: <string> # 指定命名空间
spec: # Pod规模
containers: <[]Object> # Pod中的容器列表
- image: <string> # 镜像地址
imagePullPolicy: <string> # 镜像下载策略
name: <string> # 容器名称
args: <[]string> # entrypoint参数
command: <[]string> # 执行命令
ports: <[]Object> # 容器公开的端口
env: <[]Object> # 环境变量
resources: <Object> # 容器资源请求
livenessProbe: <Object> # 存活探针
readinessProbe: <Object> # 就绪探针
startupProbe: <Object> # 启动探针
volumeMounts: <[]Object> # 卷挂载
securityContext: <Object> # 安全上下文
lifecycle: <Object> # 容器生命周期回调(PostStart、PreStop)
volumes: <[]Object> # 卷来源
<string>, <[]string>, <object>, <[]object> ,用来表示 YAML/JSON 配置文件里字段的数据类型。
-
<string>
意思:该字段的值是 单个字符串。
值类型:纯文本,不能直接是数组或对象。 -
<[]string>
意思:这是一个 字符串数组(list of strings)。
值类型:一组字符串,用 - 表示数组元素。 -
<object>
意思:这是一个 对象(key-value 结构)。
值类型:键值对(里面还可以嵌套其他类型)。 -
<[]object>
意思:这是一个 对象数组(list of objects)。
值类型:多个对象,每个对象可以有不同的字段和值。
-
对象(object)
在 Kubernetes YAML 里,如果一个字段是对象类型(map/dict),它意味着这个字段下的内容必须是一组带名字的键值对,而且这些键的名字和结构必须符合 API 规范。
有时这个对象里还会引用到已经存在的其他资源(比如configMapRef需要指向已存在的 ConfigMap 名字),这种情况下就会出现“必须有对应已创建内容”的限制。
但也有很多对象字段只是内部结构,并不要求引用现有资源,比如resources.limits就是直接写数值。 -
字符串(string)
字符串就是一段文本,它的内容一般是直接设定的,没有键值结构,但仍然可能有规则限制,比如:- 某些字段必须是合法的 DNS 名称(如
metadata.name) - 某些字段必须是合法的镜像名(如
image) - 有的字段是自由文本(如
args里的参数)
也就是说,字符串虽然比对象灵活,但仍然可能有格式限制。
- 某些字段必须是合法的 DNS 名称(如
imagePullPolicy
设置镜像拉取策略,可选值为:
- Always
- IfNotPresent
- Never
区分依据为节点上的镜像与镜像仓库中的镜像
ports
定义容器公开端口,其值为对象列表类型
- name :仅定义一个端口时该字段可选
- containerPort :容器内应用程序监听的端口
- protocol :TCP,UDP,SCTP
SCTP协议
一、SCTP
全称:Stream Control Transmission Protocol(流控制传输协议)。
位置:位于 传输层,和 TCP、UDP 同级。
最初用途:最早是为电话信令(SS7 over IP)设计的协议。
标准:由 IETF 定义,见 RFC 4960。
二、SCTP 的主要特点
可以理解为 结合了 TCP 的可靠性 + UDP 的多流特性:
面向连接,可靠传输,像 TCP 一样,SCTP 提供可靠的、有序的数据传输,确保丢包重传。
- 多流(Multi-streaming)
TCP:一个连接里,所有数据是一个字节流,必须严格按顺序到达。一个包丢了,后面的都要等(称为“队头阻塞”)。
SCTP:一个连接里可以有多个“流(Stream)”,互相独立。
举例:你的视频和文字消息可以走同一个 SCTP 连接里的不同流,视频丢帧不影响文字消息。
- 多宿主(Multi-homing)
TCP:一个连接绑定在一个源 IP 和一个目标 IP 上。
SCTP:可以同时绑定多个 IP 地址 → 在一条物理链路断掉时,可以自动切换到另一条链路,增强容错性。
- 四次握手(Four-way Handshake)
TCP 是三次握手,容易受到 SYN Flood 攻击。
SCTP 引入 四次握手,并使用 Cookie 机制 来防御这种攻击。
- 消息边界(Message-Oriented)
TCP 是字节流,没有消息边界,应用层需要自己分包。
SCTP 是消息导向,天然支持“报文”概念,应用层不用自己做粘包/拆包处理,更像 UDP。
三、应用场景
虽然不如 TCP/UDP 普及,但 SCTP 在一些特定领域很有用:
电信领域:最初用于 SS7 over IP。
WebRTC / VoIP:常用 SCTP 作为数据通道传输协议(例如 WebRTC 的 DataChannel 底层就是 SCTP)。
高可用服务:利用多宿主特性,实现网络冗余。
军用/航空:对可靠性和实时性要求高的通信。
四、类比总结
TCP:可靠、面向字节流、但只有一条流,可能阻塞。
UDP:不可靠、无连接、无序,但快,支持消息边界。
SCTP:可靠 + 面向消息 + 多流 + 多宿主,是二者的折中和增强。
env
在 Pod 的容器定义里,env 用来为容器 注入环境变量。
原理:
K8s 在创建容器时,会把 env 字段定义的键值对写入容器的 环境变量表(等同于 Linux export VAR=value)。
应用在容器内运行时,可以像平时读取系统环境变量一样,获取这些值
作用:
解耦应用与配置 → 不需要把配置写死在镜像中。
配合 ConfigMap、Secret → 实现 配置集中化管理 和 安全性。
env 字段语法示例
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: APP_MODE
value: "production" # 直接写死
- name: DB_HOST
valueFrom: # 从 ConfigMap 里取值
configMapKeyRef:
name: myapp-config
key: database_host
- name: DB_PASSWORD
valueFrom: # 从 Secret 里取值
secretKeyRef:
name: myapp-secret
key: db_password
当一个 Pod 被调度到某个 Node 上时,Kubelet 会在容器启动时自动注入与 Service 相关的环境变量,这些环境变量包括 Service 的 ClusterIP、端口号等信息。
由于此方法静态,可扩展性差,现在主流是使用dns服务发现
健康检查
在 Kubernetes 中,容器健康检查主要是为了判断容器是否处于正常工作状态,方便自动恢复、负载均衡和流量分发。
健康检查主要是为了避免容器中应用程序启动慢,应用程序假死而不能精确提供服务.
三种探针(Probe)
-
livenessProbe
-
判断容器内应用程序是否运行
-
如果探测失败,Kubelet 会 杀死容器并重启。
-
语法示例:
livenessProbe: <检查方法配置> initialDelaySeconds: 10 periodSeconds: 5两个字段分别为:
- 容器启动后执行探针秒数
- 探针执行间隔时间
-
-
readinessProbe
-
判断容器是否准备好接收流量
-
探测失败时,K8s 不会重启容器,但会将该 Pod 从 Service 的 Endpoint 列表中移除 → 不再接收流量。
-
语法示例:
readinessProbe: <检查方法配置> initialDelaySeconds: 5 periodSeconds: 3两个字段分别为:
- 容器启动后执行探针秒数
- 探针执行间隔时间
-
Service服务依靠容器就绪探针的结果来确定是否转发流量,而不是单纯依靠容器状态决定.
如果就绪探针返回结果失败,service将会移除此pod对应的endpoints对象,根据设定的间隔时间再次运行就绪探针并判断.
-
startupProbe
与前两种探针不同,此探针是在"容器启动时"进行,而非"容器运行时"
其主要作用可分为两点:-
避免启动慢的容器频繁被存活探针误杀,导致反复重启
-
检查依赖服务是否就绪(如数据库,消息队列等)
-
用来判断容器 是否启动完成。
-
对于启动慢的应用很有用。
-
在 startupProbe 成功之前,K8s 不会运行 livenessProbe 和 readinessProbe。
-
语法示例:
startupProbe: <检查方法配置> failureThreshold: 30 periodSeconds: 10两个字段分别为:
- 最大失败次数
- 间隔时间
-
检查方法
以下方法在Lifecycle Hooks中也会用到
-
httpGet
- K8s 会对容器发起 HTTP GET 请求,例如:
livenessProbe: httpGet: path: /health port: 8080 - 如果返回 2xx 或 3xx 状态码 → 健康;否则认为失败。
- 常用于 Web 服务。
- K8s 会对容器发起 HTTP GET 请求,例如:
-
exec
- 在容器内执行某条命令,如果退出码是 0 → 健康,否则失败:
livenessProbe: exec: command: ["cat", "/tmp/healthy"] - 适合自定义检查,比如检查文件是否存在、进程是否在跑。
- 在容器内执行某条命令,如果退出码是 0 → 健康,否则失败:
-
sleep
-
不是 Linux
sleep命令,而是 K8s 内置的延迟动作。 -
例如在
PreStop里:sleep: seconds: 10表示 Pod 终止时等 10 秒,让负载均衡摘除流量。
老大你不要走:
tcpSocket
检查某个端口是否能成功建立 TCP 连接,例如:
readinessProbe:
tcpSocket:
port: 3306
适合数据库、非 HTTP 的服务(比如 Redis、MySQL)。
grpc(K8s 1.23+ 引入的新方法,补充说明):使用 gRPC 协议的健康检查。
总结表
| 探针类型 | 作用 | 失败后动作 |
|---|---|---|
| livenessProbe | 检查容器是否存活 | 杀死容器并重启 |
| readinessProbe | 检查容器是否就绪可接收请求 | 从 Service 流量转发中移除,不重启 |
| startupProbe | 检查容器是否完成启动 | 成功前不执行其他探针 |
| 检查方法 | 用途描述 | 示例关键字段 |
|---|---|---|
| httpGet | 通过 HTTP 响应检查 | path, port |
| exec | 执行容器内命令检查 | command |
| tcpSocket | 尝试 TCP 连接检查(逐渐弃用) | port |
| sleep | 延时等待检查(K8s 1.29+ 新增) | seconds |
资源配额 QOS
默认情况,容器可以无限制使用节点上所有资源;为了避免一些pod无限制请求资源,导致其他pod无可用资源,需要有一些措施.
资源请求 (Resource Requests)
定义:
-
Requests 是 Pod/容器声明运行时需要的 最少资源保证。
-
它告诉调度器:运行这个容器至少需要这么多资源,调度器会基于这个值选择合适的 Node。
配置字段:写在 Pod 规格的 resources.requests 下,例如:
resources:
requests:
cpu: "500m" # 请求 0.5 CPU
memory: "256Mi" # 请求 256 MiB 内存
单位解释:
-
CPU:以 core(核)为单位。
-
1= 1 核 -
500m= 0.5 核(m = milli CPU,即千分之一核)
-
-
内存:以字节为单位,可以用:
-
Mi(Mebibyte, 2^20 bytes),Gi(Gibibyte, 2^30 bytes) -
例如:
256Mi≈ 268 MB,1Gi≈ 1.07 GB
-
是否真正申请资源?
-
❌ 不会真的去“划分”或“预留”资源(CPU 和内存不会被锁死)。
-
✅ 只是写入 etcd → 调度器参考。
-
实际运行时,容器可能用少于 requests,也可能用超过 requests( limits 限制)。
Requests 对 Pod 调度的影响
kubernetes调度会结合 资源请求 考虑 均衡负载 以及 资源规划 ;
还会结合其他因素:节点资源利用率,污点,亲和性规则等
-
核心作用:调度器只会把 Pod 调度到能满足 Requests 的 Node 上。
- 例如,Pod
requests.cpu=2,调度器不会把它放到只有 1 核可分配资源的 Node。
- 例如,Pod
-
不会真正锁定/预留物理资源:
-
Pod 上线后,容器运行时可能会用多用少(只要不超过 limits)。
-
所以 requests 是 调度约束,而不是硬性分配。
-
资源限制 (Resource Limits)
和 Requests 常常一起配置:
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
-
limits.cpu:容器最多能用多少 CPU,超出后会被 cgroup 限速(不会杀掉)。
-
limits.memory:容器最多能用多少内存,超过会 OOMKilled。
-
requests ≤ limits:通常这样配置。
资源配额 (Resource Quotas)
定义:
-
ResourceQuota 是对 Namespace 级别 的资源使用总量限制。
-
防止某个团队或应用独占集群资源。
配置示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "4" # 该 namespace 内 Pod 的总 requests CPU 不超过 4 核
requests.memory: "8Gi" # 请求内存总量 ≤ 8Gi
limits.cpu: "10"
limits.memory: "16Gi"
pods: "20" # Pod 数量最多 20
单位同上:CPU 用 core/milliCPU,内存用 Mi/Gi。
服务质量 QoS
1. QoS 的概念
QoS (Quality of Service)是 Kubernetes 根据 Pod 中 资源请求(requests)和限制(limits) 的配置情况,为 Pod 分配的优先级类别。
当节点资源紧张(例如内存不足需要驱逐 Pod)时,QoS 类别会影响 Pod 被驱逐的顺序。
K8s 把 Pod 分为三类 QoS:
-
Guaranteed(保证级别)
-
Burstable(可突发级别)
-
BestEffort(尽力而为级别)
2. QoS 分类规则
(1) Guaranteed
条件:
- Pod 中的 每个容器 都同时设置了
requests和limits,并且 两者相等。
例子:
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "500m"
特点:
-
最稳定,最不容易被驱逐。
-
当资源不足时,除非节点不可用,否则 Guaranteed Pod 几乎不会被杀掉。
(2) Burstable
条件:
-
Pod 至少有一个容器设置了
requests,但 并非所有容器的 requests == limits。 -
或者部分容器设置了 requests,部分没设置。
例子:
resources:
requests:
memory: "128Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "1"
特点:
-
具有基本保障(requests),但仍可突发使用更高资源(直到 limits)。
-
被驱逐时优先级低于 Guaranteed,但高于 BestEffort。
(3) BestEffort
条件:
- Pod 中的所有容器都 没有设置 requests 和 limits。
例子:
resources: {}
特点:
-
没有任何资源保证,完全依赖节点的空闲资源运行。
-
最容易被驱逐。
3. QoS 的作用与影响
-
调度阶段
-
调度器只考虑
requests,不考虑 limits。 -
QoS 本身不影响调度,但
requests的大小决定 Pod 是否能调度到某个节点。
-
-
运行阶段
-
节点资源不足时,驱逐顺序:
BestEffort → Burstable → Guaranteed -
即 QoS 越高,存活的优先级越高。
-
-
资源利用率
- 通过 QoS,K8s 可以在保证关键服务稳定运行的同时,让非关键任务尽量利用闲置资源。
更多推荐

所有评论(0)