在 Kubernetes(K8s)的实际运维中,我们经常会遇到 Pod 崩溃、容器无法启动或网络连接不稳定等问题。本文将通过一个真实的案例,详细分析如何从零开始排查和解决 CrashLoopBackOff 错误,并深入探讨 netshoot 容器的使用技巧。文章包含以下内容:
用户发现名为 zeroone-log-deployment-normal-7f795f8fdd-qczvb 的 Pod 处于 CrashLoopBackOff 状态,且其中一个容器 (net-tool) 未能启动。通过日志检查,发现以下关键错误:
/bin/bash: sleep 300: No such file or directorynet-tool 容器的启动命令格式错误,sleep 300 中的多余空格导致命令无法解析。bash 或 sleep)。通过 kubectl describe pod 获取详细信息:
kubectl describe pod zeroone-log-deployment-normal-7f795f8fdd-qczvb重点关注以下字段:
# 查看主容器日志
kubectl logs zeroone-log-deployment-normal-7f795f8fdd-qczvb -c main
# 查看 net-tool 容器日志
kubectl logs zeroone-log-deployment-normal-7f795f8fdd-qczvb -c net-tool --previous原因 | 检查方法 | 解决方案 |
|---|---|---|
镜像拉取失败 | kubectl describe pod 的 Events | 检查镜像名称或配置 imagePullSecret |
启动命令错误 | kubectl logs | 修正 command 或 args |
资源不足(OOMKilled) | kubectl describe pod | 调整 resources.limits |
健康检查失败 | 查看 livenessProbe 配置 | 优化探针参数或应用逻辑 |
原始错误的 net-tool 容器配置:
command:
- /bin/bash
- sleep 300 # 错误:多余空格修正方案:
command: ["sleep", "300"] # 直接调用 sleep 命令或通过 Shell 执行:
command: ["/bin/sh", "-c", "sleep 300"] # 使用 sh 代替 bash更新 Deployment 后观察 Pod 状态:
kubectl get pods -l app=zeroone-deployment
kubectl logs <new-pod-name> -c net-tool如果容器因 OOM 被终止,需调整资源:
resources:
limits:
memory: "512Mi"
requests:
memory: "256Mi"netshoot 是一个集成了网络诊断工具(如 ping、curl、tcpdump)的 Docker 镜像,常用于 K8s 网络问题排查。
原因:默认命令(如 sleep)执行完毕或会话超时。
修复:使用永久运行命令:
command: ["sleep", "infinity"]原因:镜像过于精简。
修复:换用功能完整的镜像:
image: nicolaka/netshoot修复:通过 port-forward 稳定连接:
kubectl port-forward pod/netshoot 8080:80apiVersion: v1
kind: Pod
metadata:
name: netshoot-debug
spec:
containers:
- name: netshoot
image: nicolaka/netshoot
command: ["sleep", "infinity"]在 Deployment 中启用 Java 远程调试:
env:
- name: JAVA_TOOL_OPTIONS
value: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
ports:
- containerPort: 5005
protocol: TCP通过 port-forward 连接调试器:
kubectl port-forward <pod-name> 5005:5005使用 Logback 或 Log4j2 动态调整日志级别:
// 示例:通过 HTTP 接口动态修改日志级别
@RestController
public class LogController {
@PostMapping("/loglevel")
public String setLogLevel(@RequestParam String level) {
LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory();
ctx.getLogger("ROOT").setLevel(Level.valueOf(level));
return "OK";
}
}livenessProbe:
httpGet:
path: /actuator/health
port: 8066
initialDelaySeconds: 30
periodSeconds: 10通过本文的实战案例,我们学习了如何从零开始排查 CrashLoopBackOff 错误,优化容器配置,并掌握 netshoot 的高级用法。同时,针对 Java 应用提供了调试和日志管理的最佳实践。Kubernetes 运维的核心在于精细化监控和快速定位根因,希望这篇指南能帮助你更高效地解决问题。
延伸阅读:
欢迎留言交流你在 K8s 调试中的实战经验! 🚀