k8s-高级调度(一)
目录
初始化容器Init Container
Init Container基本概念
核心定义
核心特性
串行执行
共享存储卷
资源隔离
设计目的
解耦初始化逻辑
增强安全性
提高可靠性
与普通容器的对比
典型应用场景
Pause容器
命名空间共享与隔离
共享存储与资源管理
Pod 生命周期管理
网络初始化与代理
轻量级与高效性
典型应用场景
与 Init 容器的区别
临时容器 Ephemeral Containers
核心特性
典型应用场景
与常规容器的对比
HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩器)
HPA 的核心功能
HPA 的工作原理
HPA 的配置与使用
HPA 的应用场景
HPA 的注意事项
初始化容器Init Container
初始化容器(Init Container)是 Kubernetes 中一种在应用容器启动前运行的特殊容器,用于完成应用所需的预置条件或初始化任务。
Init Container基本概念
初始化容器(Init Container)是 Kubernetes 中一种在应用容器(主容器)启动前运行的特殊容器,用于完成 Pod 启动前的初始化任务。它的核心设计目标是将初始化逻辑与应用逻辑解耦,确保应用容器在满足所有前置条件后安全、可靠地运行。
核心定义
-
生命周期位置:
Init Container 在 Pod 的生命周期中位于“调度完成”和“应用容器启动”之间。只有所有 Init Container 成功执行完毕,Kubernetes 才会启动应用容器。 -
与普通容器的区别:
- 执行时机:仅在应用容器启动前运行一次。
- 执行次数:不持续运行,任务完成后即退出。
- 设计目的:专注初始化任务,而非业务逻辑。
核心特性
- 顺序执行
- 一个 Pod 中可定义多个 Init Container,它们会按声明顺序串行执行,只有前一个容器成功退出(状态码为 0),才会启动下一个。
- 例如:先检查数据库服务是否就绪,再生成配置文件,最后下载依赖包。
- 生命周期隔离
- Init Container 与应用容器独立运行,不共享进程空间,但可共享存储卷(如 ConfigMap、Secret、EmptyDir 等),实现数据预加载。
- 例如:Init Container 从远程下载机器学习模型文件到 EmptyDir,应用容器直接使用该文件。
- 资源限制与调度
- Init Container 可设置资源请求(requests)和限制(limits),调度器会基于 Pod 的有效资源请求值(取所有应用容器资源之和与 Init Container 最大资源请求中的较大值)进行资源分配。
- 例如:Init Container 需下载 1GB 数据,可设置
memory: "1Gi"
避免被低内存节点调度。
- 状态与重启策略
- Init Container 的状态通过
status.initContainerStatuses
字段返回,Pod 状态会显示初始化进度(如Init:0/2
表示 2 个 Init Container 中 0 个已完成)。 - 若 Init Container 失败,Pod 会根据
restartPolicy
决定是否重启(通常设为OnFailure
或Always
)。
- Init Container 的状态通过
关键特性
串行执行
- 顺序性:
一个 Pod 中可定义多个 Init Container,它们按声明顺序依次执行。前一个容器必须成功退出(返回状态码0
),下一个容器才会启动。
共享存储卷
- 数据传递:
Init Container 和应用容器可通过共享存储卷(如EmptyDir
、ConfigMap
、Secret
)交换数据。- 典型场景:
- Init Container 从远程下载文件到
EmptyDir
,应用容器直接使用该文件。 - Init Container 从
Secret
读取密码并写入共享卷,应用容器无需直接访问Secret
。
- Init Container 从远程下载文件到
- 典型场景:
资源隔离
- 资源请求与限制:
Init Container 可单独设置resources.requests
和resources.limits
,调度器会基于 Pod 的有效资源请求值(取所有应用容器资源之和与 Init Container 最大资源请求中的较大值)分配资源。
状态与故障处理
- 状态跟踪:
Init Container 的状态通过status.initContainerStatuses
字段返回,Pod 状态会显示初始化进度(如Init:0/2
表示 2 个 Init Container 中 0 个已完成)。 - 失败行为:
- 若 Init Container 失败,Pod 会根据
restartPolicy
决定是否重启(通常设为OnFailure
或Always
)。 - 频繁失败的 Init Container 可能导致 Pod 进入
CrashLoopBackOff
状态。
- 若 Init Container 失败,Pod 会根据
设计目的
解耦初始化逻辑
- 分离关注点:
将初始化任务(如依赖检查、配置生成)与应用逻辑分离,避免应用镜像臃肿或复杂化。- 对比:
- 传统方式:应用容器启动时执行初始化脚本,可能导致镜像庞大或启动时间过长。
- Init Container 方式:初始化脚本放在轻量级 Init Container 中,应用容器只需关注业务逻辑。
- 对比:
增强安全性
- 最小权限原则:
Init Container 可使用不同权限或文件系统视图执行敏感操作(如读取Secret
),而应用容器无需直接访问敏感资源。- 示例:
- Init Container 从
Secret
读取数据库密码并写入共享卷,应用容器通过卷读取密码,无需挂载Secret
。
- Init Container 从
- 示例:
提高可靠性
- 前置条件验证:
确保应用依赖的服务(如数据库、API 服务)已就绪后再启动应用,避免因依赖未就绪导致的启动失败。
与普通容器的对比
特性 | Init Container | 普通容器(应用容器) |
---|---|---|
执行时机 | 应用容器启动前 | 初始化完成后启动 |
执行次数 | 仅运行一次 | 持续运行(除非崩溃或被终止) |
资源限制 | 可单独设置,调度基于有效资源请求值 | 可单独设置 |
探针支持 | 不支持 readinessProbe /livenessProbe | 支持 |
典型用途 | 初始化、依赖检查、配置生成 | 运行应用业务逻辑 |
典型应用场景
- 依赖服务检查
- 等待数据库、消息队列等依赖服务可用后再启动应用。
- 配置文件生成
- 基于环境变量或模板动态生成配置文件。
- 数据预加载
- 下载大型文件(如机器学习模型)到共享卷。
- 权限预处理
- 使用
chown
/chmod
修改文件权限,供应用容器使用。
- 使用
- 注册中心注册
- 在服务启动前向注册中心(如 Consul、Eureka)注册实例。
Pause容器
在 Kubernetes 中,Pause 容器(又称 Infra 容器)是每个 Pod 的核心基础设施组件,它不运行任何业务逻辑,但通过创建和管理共享资源环境,为 Pod 内其他容器提供稳定运行的基础。
命名空间共享与隔离
- 网络命名空间:
Pause 容器启动时创建独立的网络命名空间,Pod 内其他容器(如应用容器、Sidecar 容器)加入该命名空间,共享同一 IP 地址和端口范围。这使得容器间可通过localhost
直接通信,无需额外网络配置,同时通过命名空间隔离实现 Pod 间的网络独立性。 - IPC 命名空间:
共享 SystemV IPC 或 POSIX 消息队列,允许容器间通过共享内存段、信号量等高效通信,适用于需要紧密协作的场景(如日志收集器与主应用容器)。 - UTS 命名空间:
Pod 内所有容器共享同一主机名,简化服务发现和配置管理。 - PID 命名空间(可选):
早期版本中 Pause 容器曾作为 PID 1 进程管理僵尸进程,但后续更新中该功能被移除,现主要依赖 Kubernetes 自身机制处理进程生命周期。
共享存储与资源管理
- 存储卷挂载:
Pause 容器负责挂载 Pod 级别的存储卷(如emptyDir
、configMap
、secret
),其他容器通过共享挂载点访问相同数据,实现容器间文件共享。例如,Sidecar 容器可修改配置文件,主应用容器实时读取更新。 - 资源聚合:
作为 Pod 内所有容器的父进程,Pause 容器的资源请求(CPU/Memory)和限制会聚合到 Pod 级别,影响调度和 QoS 分类(如Guaranteed
、Burstable
)。
Pod 生命周期管理
- 状态同步:
Pause 容器的生命周期与 Pod 完全绑定。若 Pause 容器退出,Kubernetes 会认为整个 Pod 失效,终止所有容器并重新调度。这确保了 Pod 网络和命名空间的完整性。 - 优雅终止:
Pod 终止时,Kubelet 先向 Pause 容器发送SIGTERM
,确保所有子容器有序退出,避免数据丢失或状态不一致。
网络初始化与代理
- CNI 插件集成:
Kubernetes 通过 CNI 插件为 Pause 容器配置网络(如分配 IP、设置路由),其他容器复用该配置,无需重复初始化网络环境。 - Sidecar 模式支持:
在服务网格(如 Istio)中,Sidecar 代理容器(如 Envoy)与主应用容器共享 Pause 容器的网络命名空间,可透明拦截和处理所有网络流量,无需修改应用代码。
轻量级与高效性
- 极简资源占用:
Pause 容器通常基于极简镜像(如k8s.gcr.io/pause
),仅运行一个无限休眠进程(如while true; do sleep 3600; done
),几乎不消耗 CPU 或内存资源。 - 高可靠性:
作为常驻容器,Pause 确保 Pod 运行期间网络和命名空间稳定,避免因业务容器重启导致的通信中断。
典型应用场景
- 多容器协作:
主应用容器与日志收集器(如 Fluentd)、监控代理(如 Prometheus Node Exporter)共享网络和存储,实现高效协作。 - 服务网格:
Sidecar 代理容器通过共享 Pause 容器的网络命名空间,拦截并处理所有进出 Pod 的流量。 - 共享配置:
通过共享configMap
或secret
挂载点,实现容器间配置动态更新。
与 Init 容器的区别
特性 | Pause 容器 | Init 容器 |
---|---|---|
执行时机 | Pod 启动时最先运行,持续运行 | 应用容器启动前运行,完成后退出 |
核心作用 | 提供共享资源环境(网络、存储等) | 执行初始化任务(依赖检查、配置生成) |
资源占用 | 极轻量级,几乎不消耗资源 | 可设置资源请求/限制 |
用户可见性 | 隐藏(通过 kubectl 默认不可见) | 显式定义在 Pod 配置中 |
临时容器 Ephemeral Containers
临时容器(Ephemeral Containers)是 Kubernetes 中一种用于临时运行任务的特殊容器,主要用于故障排查、调试、日志收集等场景,而非构建应用程序或提供持续服务
核心特性
- 动态注入
- 通过 API 的
ephemeralcontainers
处理器创建,而非直接修改pod.spec
,因此无法用kubectl edit
添加。
- 通过 API 的
- 资源共享
- 可共享目标容器的进程命名空间、文件系统等,便于检查进程状态或文件内容。
- 例如,通过
ps aux
查看其他容器的进程,或直接访问/proc/<PID>/root
检查文件系统。
- 生命周期短暂
- 仅在调试期间存在,任务完成后自动销毁,避免长期占用资源。
- Pod 终止时,临时容器随之销毁。
- 无资源保证
- 不支持端口、存活探针(
livenessProbe
)或就绪探针(readinessProbe
)配置。 - 资源占用取决于临时任务需求,但需注意避免影响主容器性能。
- 不支持端口、存活探针(
典型应用场景
- 故障排查
- 崩溃容器分析:当主容器崩溃时,注入临时容器检查日志或运行调试工具(如
strace
、gdb
)。 - 网络问题诊断:使用
netshoot
镜像(含tcpdump
、netstat
等工具)排查网络连通性问题。
- 崩溃容器分析:当主容器崩溃时,注入临时容器检查日志或运行调试工具(如
- 文件系统检查
- 检查被污染的业务容器文件系统,例如验证配置文件是否被错误修改。
- 示例:通过共享文件系统访问主容器的
/etc/nginx/nginx.conf
。
- 动态日志收集
- 临时挂载日志分析工具(如
logrotate
、fluentd
)收集实时日志。
- 临时挂载日志分析工具(如
与常规容器的对比
特性 | 临时容器 | 常规容器 |
---|---|---|
执行时机 | 动态注入到现有 Pod | 随 Pod 启动时创建 |
生命周期 | 临时运行,任务完成后销毁 | 持续运行(除非崩溃或被终止) |
资源保证 | 无资源分配保证 | 可设置资源请求/限制 |
探针支持 | 不支持 livenessProbe /readinessProbe | 支持 |
典型用途 | 调试、故障排查 | 运行应用程序业务逻辑 |
HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩器)
HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩器)是 Kubernetes 中的一种自动扩缩容机制,用于根据应用程序的负载动态调整 Pod 的副本数量,以确保应用程序在不同负载条件下保持良好的性能和响应能力。
HPA 的核心功能
-
动态调整 Pod 数量:
- HPA 通过监控 Pod 的资源使用情况(如 CPU 利用率、内存使用量)或其他自定义指标,自动增加或减少 Pod 副本数量。
- 当负载升高时,HPA 会自动创建更多的 Pod 来处理增加的请求;当负载降低时,它会自动减少 Pod 的数量,以实现资源的高效利用。
-
提高集群弹性和自动化水平:
- HPA 使得 Kubernetes 集群能够根据实际的业务需求自动扩展或收缩应用程序,提高了集群的弹性和自动化水平。
- 这有助于保障应用的高可用性和稳定性,同时降低人工管理的成本和复杂性。
HPA 的工作原理
-
监控指标:
- HPA 可以监控多种类型的指标,包括资源指标(如 CPU、内存使用率)、对象指标(如 Ingress 的请求速率)、Pod 指标(如每个 Pod 的网络流量)以及外部指标(如来自第三方服务的指标)。
- 在 Kubernetes 的稳定版本
autoscaling/v1
中,HPA 主要支持 CPU 指标的动态伸缩;而在测试版本autoscaling/v2beta2
中,则支持内存和自定义指标的动态伸缩。
-
计算目标副本数:
- HPA 控制器会定期(默认间隔为 15 秒)检查每个 HPA 对象中监控的指标。
- 它将这些指标的当前值与预设的目标值进行比较,然后根据比较结果计算出需要调整的 Pod 副本数量。
- 计算过程中,HPA 会考虑当前副本数、最小副本数和最大副本数的限制,以确保调整后的副本数在合理范围内。
-
执行扩缩容操作:
- 一旦计算出目标副本数,HPA 控制器会向 Kubernetes API Server 发送请求,修改伸缩对象(如 Deployment、ReplicaSet)的
scale
子对象中的replicas
字段。 - 这将触发 Kubernetes 集群执行扩缩容操作,以调整 Pod 的副本数量。
- 一旦计算出目标副本数,HPA 控制器会向 Kubernetes API Server 发送请求,修改伸缩对象(如 Deployment、ReplicaSet)的
HPA 的配置与使用
-
创建 Deployment 或 StatefulSet:
- 首先,需要创建一个 Deployment 或 StatefulSet 等资源对象,并定义工作负载的基础配置。
-
创建 HPA 配置对象:
- 然后,创建一个 HPA 配置对象,指定目标资源对象(如 Deployment 的名称)、期望的指标(如 CPU 使用率)以及最小副本数和最大副本数限制等参数。
-
部署 HPA 配置对象:
- 将 HPA 配置对象与应用资源对象一起部署到 Kubernetes 集群中。
- HPA 会自动监视目标 Pod 的资源使用情况,并根据预设的指标计算出需要调整的副本数量,自动调整资源的副本数量。
HPA 的应用场景
-
Web 服务场景:
- 在 Web 服务场景中,HPA 可以监控 Deployment 或 StatefulSet 的 CPU 和内存使用情况,根据请求量和响应时间等指标自动地对 Pod 的数量进行调整。
- 这有助于保证服务的稳定性和可用性,特别是在高并发场景下。
-
大数据处理场景:
- 在大数据处理场景中,HPA 可以根据数据处理任务的负载情况自动调整 Pod 的副本数量。
- 这有助于提高数据处理效率,缩短任务完成时间。
-
消息队列场景:
- 在消息队列场景中,HPA 可以监控消息队列的长度或消费者的处理速度等指标,自动调整消费者的 Pod 副本数量。
- 这有助于确保消息能够及时被处理,避免消息堆积或丢失。
HPA 的注意事项
-
合理设置指标和阈值:
- 在使用 HPA 时,需要根据实际应用场景选择合适的资源指标(如 CPU 使用率或内存使用率)和自定义指标。
- 同时,需要合理设置指标的阈值,以确保 HPA 能够在负载变化时及时触发扩缩容操作。
-
考虑资源的可用性:
- 在配置 HPA 时,需要考虑资源的可用性,合理设置最小副本数和最大副本数限制。
- 这有助于避免在极端情况下资源的过度使用或不足。
-
监控和日志记录:
- 需要监控 HPA 的工作状态和资源使用情况,以便及时发现和解决问题。
- 同时,记录相关的日志信息以便分析和排查问题。
-
测试和验证:
- 在实际部署之前,建议在测试环境中进行 HPA 的测试和验证,确保其按预期工作。