目录
一、初始化容器(InitContainer):主容器的 "开机预备员"
三、临时容器(Ephemeral Containers):运行中 Pod 的 "急诊医生"
在 Kubernetes 集群中常会遇到这些问题:主容器启动前要做初始化准备?
运行中的容器出问题没法调试?流量突增时 Pod 不够用?下面带你了解k8s的 4 个核心功能。
一、初始化容器(InitContainer):主容器的 "开机预备员"
1. 什么是 InitContainer?
InitContainer 是在 Pod 内主容器启动前运行的特殊容器,专门负责初始化工作(比如等待依赖服务、修改系统配置)。它就像手机开机前的 "插 SIM 卡、连 WiFi",必须完成后,主程序才能启动。
2. 核心特点
- 顺序执行:多个 Init 容器按定义顺序逐个运行,上一个完成后下一个才启动。
- 必须成功:所有 Init 容器运行完成后,主容器才启动;若失败,K8s 会重试(
restartPolicy=Never
时不重试)。 - 无健康检查:不支持
livenessProbe
(存活检查)等,因为它必须在 Pod 就绪前跑完。
3. 典型案例
场景 1:延迟主容器启动(模拟等待依赖)
需求:让主容器延迟 15 秒启动,给依赖服务留准备时间。
# init-delay.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-delay-pod
spec:
containers: # 主容器
- name: main-nginx
image: nginx:1.7.9 # 主应用镜像
initContainers: # 初始化容器
- name: delay-init
image: nginx:1.7.9 # 用nginx镜像(含sh命令)
command: ["sh", "-c", "sleep 15"] # 休眠15秒
restartPolicy: Never # 失败不重试
代码解析:
initContainers
:定义初始化容器delay-init
,优先级高于主容器。command
:通过sleep 15
实现延迟,确保 15 秒后才启动主容器。- 部署后观察:前 15 秒 Pod 状态为
Init:0/1
,完成后变为Running
。
验证:
kubectl apply -f init-delay.yaml
# 前15秒查看Pod状态,会显示"Init:0/1"(表示1个Init容器正在运行)
kubectl get pod init-delay-pod
# 15秒后状态变为"Running",主容器启动
场景 2:修改内核参数(需高权限操作)
需求:启动前将宿主机内核参数vm.swappiness
设为 0(减少 swap 使用,提升性能)。
# init-sysctl.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-sysctl-pod
spec:
containers:
- name: main-nginx
image: nginx:1.7.9
initContainers:
- name: sysctl-init
image: alpine # 轻量镜像,自带sysctl工具
command: ["sh", "-c", "/sbin/sysctl -w vm.swappiness=0"] # 修改参数
securityContext:
privileged: true # 必须开启特权模式,否则无权修改内核
restartPolicy: Never
代码解析:
securityContext: privileged: true
:获取宿主机 root 权限,允许修改内核参数。image: alpine
:选择轻量镜像(≈5MB),比 nginx 更高效,适合临时操作。- 验证:部署后在宿主机执行
cat /proc/sys/vm/swappiness
,输出应为 0。
验证:
kubectl apply -f init-sysctl.yaml
# 查看Pod运行的节点
kubectl get pod init-sysctl-pod -o wide
# 登录节点验证参数已修改
ssh 节点IP "cat /proc/sys/vm/swappiness" # 输出应为0
场景 3:等待依赖服务启动(如 Redis/MySQL)
需求:主容器(Nginx)必须在 Redis 和 MySQL 服务启动后才运行。
# init-wait.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-wait-pod
spec:
containers:
- name: main-nginx
image: nginx:1.7.9
initContainers:
# 等待Redis服务
- name: wait-redis
image: busybox:1.28 # 含nslookup工具(用于解析服务)
command: ["sh", "-c", "until nslookup redis-service; do echo waiting for redis; sleep 2; done"]
# 等待MySQL服务
- name: wait-mysql
image: busybox:1.28
command: ["sh", "-c", "until nslookup mysql-service; do echo waiting for mysql; sleep 2; done"]
restartPolicy: Never
代码解析:
nslookup redis-service
:检查名为redis-service
的服务是否存在(K8s 中服务名可直接解析)。until ...; do ...; done
:循环检查,直到服务可用(nslookup
成功),每 2 秒重试一次。- 部署后:若 Redis/MySQL 服务未创建,Init 容器会一直等待;创建服务后,主容器才启动。
验证:
# 部署Pod(此时Redis和MySQL服务未创建)
kubectl apply -f init-wait.yaml
kubectl get pod init-wait-pod # 状态为"Init:0/2"(等待第一个Init容器)
# 创建redis-service和mysql-service后再次查看
kubectl get pod init-wait-pod # 状态变为"Running"(主容器启动)
4. 为什么要用 InitContainer?
- 主容器镜像可以更干净(不用装初始化工具),减少安全风险。
- 初始化操作(如高权限命令)仅执行一次,完成后退出,不影响主容器。
二、pause 容器:Pod 的 "网络底座"
1. 什么是 pause 容器?
pause 容器是每个 Pod 的第一个容器,它不跑业务逻辑,仅作为 Pod 内所有容器的 "网络基石"—— 提供共享的网络命名空间,让 Pod 内所有容器共享同一 IP 和端口。
2. 核心作用
-
共享网络:Pod 内所有容器通过 pause 容器共享 IP 和端口,可直接用
localhost
通信(比如 Nginx 和 MySQL 在同一 Pod 内,可通过localhost:3306
访问)。 -
稳定网络配置:即使主容器停止,pause 容器运行时,Pod 的 IP 和网络配置仍保留(避免 Pod 重建导致 IP 变化)。
-
极简设计:镜像仅 700KB,仅执行
/pause
命令(无限循环),几乎不占资源。
3. 关键特点
- 每个 Pod 必含一个 pause 容器,是 Pod 启动的第一个容器。
- 生命周期与 Pod 一致:Pod 存在则 pause 容器运行,Pod 删除则 pause 容器终止。
- 不执行任何业务逻辑,仅作为网络基础设施。
4. 举个例子
当一个 Pod 包含 Nginx 和 MySQL 两个容器时:
- pause 容器先启动,创建网络命名空间(分配 IP:如
10.244.85.195
)。 - Nginx 和 MySQL 通过 "加入"pause 的网络命名空间,共享 IP
10.244.85.195
。 - 两容器可通过
localhost:80
(Nginx)和localhost:3306
(MySQL)直接通信。
三、临时容器(Ephemeral Containers):运行中 Pod 的 "急诊医生"
1. 什么是临时容器?
临时容器是临时添加到运行中 Pod的容器,专门用于调试(比如主容器没装ps
、netstat
等工具时)。就像给运行中的设备 "临时插个调试器",用完就扔,不影响主程序。
2. 核心特点
-
临时存在:随 Pod 重启消失,不会被自动重启。
-
无业务配置:不支持端口、健康检查、资源限制(仅用于调试)。
-
快速添加:通过
kubectl debug
命令添加,无需修改 Pod 原始配置。
3. 实战:调试运行中的 Tomcat 容器
需求:Tomcat 容器没装ps
工具,需临时添加容器查看进程。
步骤 1:部署目标 Pod
# pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcat-test
spec:
containers:
- name: tomcat-java # 主容器名(后续调试需指定)
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
部署:kubectl apply -f pod-tomcat.yaml
步骤 2:添加临时容器
kubectl debug -it tomcat-test --image=busybox:1.28 --target=tomcat-java
命令解析:
-it
:进入交互模式(类似kubectl exec
)。--image=busybox:1.28
:临时容器使用的镜像(含ps
等调试工具)。--target=tomcat-java
:指定关联的主容器(共享其进程空间,可查看主容器进程)。
步骤 3:调试操作
进入临时容器后,执行ps -ef | grep tomcat
,可看到主容器的 Tomcat 进程:
/# ps -ef | grep tomcat
1 root ... org.apache.catalina.startup.Bootstrap start # Tomcat主进程
步骤 4:验证临时容器
kubectl describe pod tomcat-test | grep "Ephemeral Containers" -A 10
可看到临时容器信息(如debugger-czh68
),Pod 重启后会自动消失。
四、自动扩缩容(HPA):Pod 的 "弹性伸缩器"
1. 什么是 HPA?
HPA(Horizontal Pod Autoscaler)是根据CPU / 内存使用率自动调整 Pod 副本数的工具。就像超市自动增减收银台:人多了加台,人少了减台,保证服务稳定又不浪费资源。
2. 核心依赖与原理
-
依赖:需部署
Metrics Server
组件,用于采集 Pod 和节点的 CPU、内存等指标。 -
原理:HPA 控制器定期对比当前指标(如 CPU 使用率)与目标值,若当前值高于目标则扩容(增加副本),低于目标则缩容(减少副本),副本数在
min
和max
之间波动。
3. 实战:Nginx 自动扩缩容
需求:当 Nginx 的平均 CPU 使用率超过 10% 时自动扩容(最多 10 个副本),低于 10% 时自动缩容(最少 1 个副本)。
步骤 1:部署 Nginx(需配置资源请求)
# 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 # 必须配置,HPA基于此计算使用率
ports:
- containerPort: 80
部署:kubectl create -f nginx-deployment.yaml
步骤 2:暴露 Service(用于访问)
kubectl expose deployment nginx-server --port=80 # 创建ClusterIP服务
步骤 3:创建 HPA
kubectl autoscale deployment nginx-server --cpu-percent=10 --min=1 --max=10
命令解析:
--cpu-percent=10
:目标 CPU 使用率为 10%(超过则扩容,低于则缩容)。--min=1
:最小副本数 1(再闲也至少留 1 个)。--max=10
:最大副本数 10(再忙也不超过 10 个)。
步骤 4:压力测试(触发扩容)
新开终端,用循环请求模拟高负载:
while true; do wget -q -O- http://<nginx-service-ip> >/dev/null; done
(nginx-service-ip
可通过kubectl get svc nginx-server
获取)
步骤 5:观察扩缩容效果
# 查看HPA状态(1分钟左右更新)
kubectl get hpa
# 输出示例:CPU使用率55%/10%,副本数从2增至10
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
nginx-server Deployment/nginx-server 55%/10% 1 10 10
# 查看Pod副本数
kubectl get pod | grep nginx-server # 可见10个运行中的Pod
步骤 6:停止测试(触发缩容)
按Ctrl+C
终止压力测试,1 分钟后观察:
kubectl get hpa # 输出示例:CPU使用率0%/10%,副本数从10减至1
总结
Kubernetes 高级调度的 4 个核心功能各有侧重:
- InitContainer:主容器启动前的 "预备工作",解决依赖和初始化问题。
- pause 容器:Pod 的 "网络底座",保障容器间网络共享。
- 临时容器:运行中 Pod 的 "急诊医生",快速调试不影响主容器。
- HPA:Pod 的 "弹性伸缩器",自动应对流量波动,优化资源利用。