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 覆盖)

    • 作用:定义容器启动时主进程要执行的命令。

    • 生命周期:只会在容器启动时运行,并且它就是容器的主进程,如果它退出,容器就退出。

    • 默认值:取决于镜像里的 ENTRYPOINTCMD,如果你在 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 配置文件里字段的数据类型。

  1. <string>
    意思:该字段的值是 单个字符串。
    值类型:纯文本,不能直接是数组或对象。

  2. <[]string>
    意思:这是一个 字符串数组(list of strings)。
    值类型:一组字符串,用 - 表示数组元素。

  3. <object>
    意思:这是一个 对象(key-value 结构)。
    值类型:键值对(里面还可以嵌套其他类型)。

  4. <[]object>
    意思:这是一个 对象数组(list of objects)。
    值类型:多个对象,每个对象可以有不同的字段和值。

  • 对象(object)
    在 Kubernetes YAML 里,如果一个字段是对象类型(map / dict),它意味着这个字段下的内容必须是一组带名字的键值对,而且这些键的名字和结构必须符合 API 规范
    有时这个对象里还会引用到已经存在的其他资源(比如 configMapRef 需要指向已存在的 ConfigMap 名字),这种情况下就会出现“必须有对应已创建内容”的限制。
    但也有很多对象字段只是内部结构,并不要求引用现有资源,比如 resources.limits 就是直接写数值。

  • 字符串(string)
    字符串就是一段文本,它的内容一般是直接设定的,没有键值结构,但仍然可能有规则限制,比如:

    • 某些字段必须是合法的 DNS 名称(如 metadata.name
    • 某些字段必须是合法的镜像名(如 image
    • 有的字段是自由文本(如 args 里的参数)
      也就是说,字符串虽然比对象灵活,但仍然可能有格式限制。

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)

  1. livenessProbe

    • 判断容器内应用程序是否运行

    • 如果探测失败,Kubelet 会 杀死容器并重启

    • 语法示例

      livenessProbe:
        <检查方法配置>
        initialDelaySeconds: 10
        periodSeconds: 5
      

      两个字段分别为:

      • 容器启动后执行探针秒数
      • 探针执行间隔时间
  2. readinessProbe

    • 判断容器是否准备好接收流量

    • 探测失败时,K8s 不会重启容器,但会将该 Pod 从 Service 的 Endpoint 列表中移除 → 不再接收流量。

    • 语法示例

      readinessProbe:
        <检查方法配置>
        initialDelaySeconds: 5
        periodSeconds: 3
      

      两个字段分别为:

      • 容器启动后执行探针秒数
      • 探针执行间隔时间

Service服务依靠容器就绪探针的结果来确定是否转发流量,而不是单纯依靠容器状态决定.
如果就绪探针返回结果失败,service将会移除此pod对应的endpoints对象,根据设定的间隔时间再次运行就绪探针并判断.

  1. startupProbe

    与前两种探针不同,此探针是在"容器启动时"进行,而非"容器运行时"
    主要作用可分为两点:

    • 避免启动慢的容器频繁被存活探针误杀,导致反复重启

    • 检查依赖服务是否就绪(如数据库,消息队列等)

    • 用来判断容器 是否启动完成

    • 对于启动慢的应用很有用。

    • 在 startupProbe 成功之前,K8s 不会运行 livenessProbe 和 readinessProbe

    • 语法示例

      startupProbe:
        <检查方法配置>
        failureThreshold: 30
        periodSeconds: 10
      

      两个字段分别为:

      • 最大失败次数
      • 间隔时间

检查方法

以下方法在Lifecycle Hooks中也会用到

  1. httpGet

    • K8s 会对容器发起 HTTP GET 请求,例如:
      livenessProbe:
        httpGet:
          path: /health
          port: 8080
      
    • 如果返回 2xx 或 3xx 状态码 → 健康;否则认为失败。
    • 常用于 Web 服务。
  2. exec

    • 在容器内执行某条命令,如果退出码是 0 → 健康,否则失败:
      livenessProbe:
        exec:
          command: ["cat", "/tmp/healthy"]
      
    • 适合自定义检查,比如检查文件是否存在、进程是否在跑。
  3. 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 上线后,容器运行时可能会用多用少(只要不超过 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 中的 每个容器 都同时设置了 requestslimits,并且 两者相等

例子:

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 的作用与影响
  1. 调度阶段

    • 调度器只考虑 requests,不考虑 limits。

    • QoS 本身不影响调度,但 requests 的大小决定 Pod 是否能调度到某个节点。

  2. 运行阶段

    • 节点资源不足时,驱逐顺序:
      BestEffort → Burstable → Guaranteed

    • 即 QoS 越高,存活的优先级越高。

  3. 资源利用率

    • 通过 QoS,K8s 可以在保证关键服务稳定运行的同时,让非关键任务尽量利用闲置资源。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐