Kubernetes 高级调度 01:InitContainer、Ephemeral Containers 与 HPA 知识大全

本文是 Kubernetes 高级调度系列的第一篇,全面讲解 InitContainer、Ephemeral Containers 和 HPA 三大调度特性,包含所有代码示例、补充知识点、实战技巧和常见问题,适合作为博客知识库使用。


一、初始化容器(InitContainer)

1.1 核心概念

InitContainer 是一种在 Pod 中优先于业务容器运行的容器,通常用于执行初始化任务,如:

  • 等待依赖服务(数据库、缓存等)就绪

  • 修改系统内核参数

  • 准备配置文件或目录

  • 执行数据库迁移脚本

补充知识点:
特性 InitContainer 普通容器
运行顺序 串行执行,一个完成才执行下一个 并行启动
生命周期钩子 不支持 postStart / preStop 支持
健康检查 不支持 livenessProbe / readinessProbe 支持
重启策略 失败后会重启 Pod(除非 restartPolicy: Never 按 Pod 重启策略
资源请求/限制 支持,但取所有 InitContainer 的最大值 各自独立

⚠️ 注意:InitContainer 的资源请求不会累加,而是取所有 InitContainer 中最大请求值作为 Pod 的调度依据。


1.2 示例 1:延迟启动

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: initc01
spec:
  containers:
  - name: n1
    image: nginx:1.7.9
  initContainers:
  - name: initc01
    image: nginx:1.7.9
    command: ["sh", "-c", "sleep 15"]
  restartPolicy: Never

观察状态变化:

bash

复制代码
kubectl get pod -w
# Init:0/1 → PodInitializing → Running

1.3 示例 2:修改内核参数(需要特权模式)

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: initc02
spec:
  containers:
  - name: n1
    image: nginx:1.7.9
  initContainers:
  - name: init02
    image: alpine
    command: ["sh", "-c", "/sbin/sysctl -w vm.swappiness=0"]
    securityContext:
      privileged: true
  restartPolicy: Never

验证:

bash

复制代码
# 在节点上执行
cat /proc/sys/vm/swappiness
# 输出应为 0

💡 补充:vm.swappiness=0 表示尽量少使用 swap,适合内存敏感型应用。


1.4 示例 3:等待依赖服务(DNS 解析)

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
  initContainers:
  - name: init-redis
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup redis-server; do echo waiting for redis; sleep 2; done;']
  - name: init-mysql
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mysql-server; do echo waiting for mysql; sleep 2; done;']

依赖服务示例(MySQL):

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        volumeMounts:
        - mountPath: /var/lib/mysql
          name: volv
      volumes:
      - name: volv
        hostPath:
          path: /root/k8s/mysql/var/lib/mysql
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-server
spec:
  ports:
  - port: 3306
  selector:
    app: mysql

二、临时容器(Ephemeral Containers)

2.1 概念与适用场景

临时容器是 Kubernetes 1.23+ 中引入的一种临时调试工具,适合:

  • 排查无法 exec 的容器(如 Distroless 镜像)

  • 查看崩溃容器的文件系统

  • 安装临时工具(curl、tcpdump 等)

补充知识点:
特性 说明
生命周期 不会自动重启,Pod 重启后消失
字段限制 不支持 portslivenessProberesources
创建方式 只能通过 kubectl debug 或 API 创建,不能直接写在 pod.spec
共享命名空间 可与目标容器共享进程、网络、文件系统

2.2 实战:为 Tomcat Pod 添加临时容器

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: tomcat-test
spec:
  containers:
  - name: tomcat-java
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080

bash

复制代码
kubectl apply -f pod-tomcat.yaml
kubectl debug -it tomcat-test --image=busybox:1.28 --target=tomcat-java

进入容器后可以执行:

bash

复制代码
ps -ef | grep tomcat
df -h
cat /etc/os-release

2.3 查看临时容器状态

bash

复制代码
kubectl describe pod tomcat-test

输出中会包含 Ephemeral Containers 字段,显示临时容器的状态(通常是 Terminated)。

💡 提示:临时容器退出后不会删除描述信息,可用于事后审计。


三、水平自动扩缩容(HPA)

3.1 什么是 HPA

HPA 根据 CPU、内存或自定义指标自动调整 Deployment、StatefulSet 等的副本数。

核心组件:
组件 作用
Metrics Server 采集 Pod/Node 的 CPU、内存等指标
HPA Controller 定期计算目标副本数并扩缩容
API Server 提供 HPA 对象的管理接口

3.2 工作流程

  1. 创建 HPA 对象,指定目标 CPU 利用率、最小/最大副本数

  2. Metrics Server 每 15 秒采集一次指标

  3. HPA 每 15 秒计算一次期望副本数:

    期望副本数=⌈当前指标总和目标值⌉期望副本数=⌈目标值当前指标总和⌉

  4. 更新 Deployment 的 replicas 字段

⚠️ 注意:HPA 默认有冷却时间(扩缩容稳定窗口),避免频繁震荡。


3.3 实战:Nginx 自动扩缩容

步骤 1:部署 Nginx Deployment

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        resources:
          requests:
            cpu: 10m

bash

复制代码
kubectl apply -f nginx-deployment.yaml
kubectl expose deployment nginx-server --port=80
步骤 2:创建 HPA

bash

复制代码
kubectl autoscale deployment nginx-server --cpu-percent=10 --min=1 --max=10
步骤 3:查看 HPA 状态

bash

复制代码
kubectl get hpa
# NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS
# nginx-server   Deployment/nginx-server   0%/10%    1         10        2
步骤 4:压测

bash

复制代码
while true; do wget -q -O- http://<CLUSTER-IP> > /dev/null; done
步骤 5:观察扩容

bash

复制代码
kubectl get hpa -w
# 显示 55%/10%,副本数逐渐增加到 10
kubectl get pod
# 看到多个 nginx-server-xxx 在运行
步骤 6:停止压测并观察缩容

bash

复制代码
# Ctrl+C 停止 while 循环
kubectl get hpa
# 2%/10% → 0%/10%
kubectl get pod
# 几分钟后副本数减少到 1 或 2

3.4 补充知识点:HPA 高级配置

支持多指标

yaml

复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-server
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-server
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: AverageValue
        averageValue: 200Mi
自定义指标(Prometheus + KEDA)

KEDA 是一个更强大的自动扩缩容组件,支持:

  • RabbitMQ 队列长度

  • Redis 列表长度

  • Cron 定时扩缩容


四、总结

特性 适用场景 关键限制
InitContainer 初始化、依赖检查、特权操作 不支持健康检查、生命周期钩子
Ephemeral Container 调试 Distroless 镜像、崩溃容器 不支持端口、资源限制、自动重启
HPA 应对流量波动、资源优化 需要 Metrics Server,有冷却时间

五、常见问题 FAQ

Q1:InitContainer 失败会怎样?

  • 如果 restartPolicy: Always(默认),Pod 会不断重启 InitContainer

  • 如果 restartPolicy: Never,Pod 会保持 Init:Error 状态

Q2:临时容器能否使用 kubectl exec

不能直接 exec,但可以通过 kubectl debug 创建并进入。

Q3:HPA 为什么不缩容?

  • 检查 --horizontal-pod-autoscaler-downscale-stabilization 窗口(默认 5 分钟)

  • 检查是否有其他 HPA 对象冲突

  • 检查 Metrics Server 是否正常


六、清理资源

bash

复制代码
kubectl delete -f init01.yml
kubectl delete -f init02.yml
kubectl delete -f myapp.yaml
kubectl delete -f mysql-deployment.yaml
kubectl delete -f redis-deployment.yaml
kubectl delete hpa nginx-server
kubectl delete deployment nginx-server
kubectl delete service nginx-server

📌 本文所有代码均已测试于 Kubernetes 1.28+,欢迎收藏、转发、评论交流。

相关推荐
阿里云云原生3 小时前
不改代码也能监控 AI Agent?揭秘 OBI 如何在内核层精准解析 GenAI 语义流量
云原生·agent
众人皆醒我独醉4 小时前
Pod 一直 Terminating,死活删不掉?三个凶手,每一个你都意想不到
面试·kubernetes
飞翔沫沫情5 小时前
K8s Alloy 采集 Pod 控制台日志
云原生·容器·kubernetes
潮起鲸落入海11 小时前
Kubernetes Metric Server, Quota and Limits
容器·kubernetes
梦想的颜色11 小时前
Docker 容器化本地部署 Claude Code 完整硬核教程|隔离沙盒 + 国产模型直连 + 持久化 Skill
运维·容器·ai 工程化·沙盒隔离·docker 本地部署·claude code硬核实战·国内国产模型接入
摇滚侠11 小时前
云原生 Java 架构师的第一课 K8s+Docker+KubeSphere+DevOps 19-25
java·云原生·kubernetes
渣渣盟11 小时前
Docker 运维常用命令手册(含扩容与实战)
运维·docker·容器
我叫张小白。13 小时前
一个微服务电商+社区项目(瓷韵app)的技术深度复盘
docker·微服务·云原生·架构
咕噜咕噜的猪大侠13 小时前
《K8s 核心知识梳理:Deployment 滚动更新、JobCronJob、DaemonSet 和 Service》
云原生·容器·kubernetes
虚心的百褶裙13 小时前
远程调用服务架构设计及zookeeper技术详解(下篇)
分布式·zookeeper·云原生