date: 2021-04-20title: k8s之pod、service、ingress常见错误排查 #标题
tags: k8s错误排查 #标签
categories: k8s # 分类
常见pod错误
Pod可能会出现启动和运行时错误。
启动错误包括:
- ImagePullBackoff
- ImageInspectError
- ErrImagePull
- ErrImageNeverPull
- RegistryUnavailable
- InvalidImageName
运行时错误包括:
- CrashLoopBackOff
- RunContainerError
- KillContainerError
- VerifyNonRootError
- RunInitContainerError
- CreatePodSandboxError
- ConfigPodSandboxError
- KillPodSandboxError
- SetupNetworkError
- TeardownNetworkError
有些错误比其他错误更常见。
状态 | 描述 |
---|---|
CrashLoopBackOff | 容器退出,kubelet正在将它重启 |
InvalidImageName | 无法解析镜像名称 |
ImageInspectError | 无法校验镜像 |
ErrImageNeverPull | 策略禁止拉取镜像 |
ImagePullBackOff | 正在重试拉取 |
RegistryUnavailable | 连接不到镜像中心 |
ErrImagePull | 通用的拉取镜像出错 |
CreateContainerConfigError | 不能创建kubelet使用的容器配置 |
CreateContainerError | 创建容器失败 |
m.internalLifecycle.PreStartContainer | 执行hook报错 |
RunContainerError | 启动容器失败 |
PostStartHookError | 执行hook报错 |
ContainersNotInitialized | 容器没有初始化完毕 |
ContainersNotRead | 容器没有准备完毕 |
ContainerCreating | 容器创建中 |
PodInitializing | pod 初始化中 |
DockerDaemonNotReady | docker还没有完全启动 |
NetworkPluginNotReady | 网络插件还没有完全启动 |
以下是最常见的错误列表以及如何修复它们的方法。
ImagePullBackOff
当Kubernetes无法获取到Pod中某个容器的镜像时,将出现此错误。
共有三个可能的原因:
- 镜像名称无效,例如拼错了名称,或者image不存在
- 为image指定了不存在的标签
- 尝试检索的image属于一个私有registry,而Kubernetes没有凭据可以访问它
CrashLoopBackOff
如果容器无法启动,则Kubernetes将显示错误状态为:CrashLoopBackOff。
通常,以下情况下容器无法启动:
- 应用程序中存在错误,导致无法启动
- 未正确配置容器
- Liveness探针失败太多次
如果由于容器重新启动太快而看不到日志,则可以使用以下命令:
# --previous 对应的短选项为 “-p”
$ kubectl logs <pod-name> --previous # 打印前一个容器的错误消息。
RunContainerError
当容器无法启动时,出现此错误。
甚至在容器内的应用程序启动之前。
该问题通常是由于配置错误,例如:
- 挂载不存在的卷,例如ConfigMap或Secrets
- 将只读卷安装为可读写
应该使用 kubectl describe pod 命令收集和分析错误。
处于Pending状态的Pod
当创建Pod时,该Pod保持Pending状态。
为什么?
假设调度程序组件运行良好,可能的原因如下:
- 集群没有足够的资源(例如CPU和内存)来运行Pod
- 当前的命名空间具有ResourceQuota对象,创建Pod将使命名空间超过配额
- 该Pod绑定到一个处于pending状态的 PersistentVolumeClaim
最好的选择是检查kubectl describe命令输出的“事件”部分内容:
$ kubectl describe pod <pod name>
对于因ResourceQuotas而导致的错误,可以使用以下方法检查集群的日志:
$ kubectl get events --sort-by=.metadata.creationTimestamp
处于未就绪状态的Pod
如果Pod正在运行但未就绪(not ready),则表示readiness就绪探针失败。
当“就绪”探针失败时,Pod未连接到服务,并且没有流量转发到该实例。
就绪探针失败是应用程序的特定错误,因此应检查 kubectl describe 中的 Events 部分以识别错误。
service的故障排除
如果Pod正在运行并处于就绪状态,但仍无法收到应用程序的响应,则应检查服务的配置是否正确。
service旨在根据流量的标签将流量路由到Pod。
因此,应该检查的第一件事是服务关联了多少个Pod。
可以通过检查服务中的端点(endpoint)来做到这一点:
$ kubectl describe service <service-name> | grep Endpoints
端点是一对,并且在服务(至少)以Pod为目标时,应该至少有一个端点。
如果“端点”部分为空,则有两种解释:
- 没有运行带有正确标签的Pod(提示:应检查自己是否在正确的命名空间中)
- service的 selector 标签上有拼写错误
如果看到端点列表,但仍然无法访问应用程序,则 targetPort 可能是服务中的罪魁祸首。
如何测试服务?
无论服务类型如何,都可以使用 kubectl port-forward 来连接它:
$ kubectl port-forward service/<service-name> 3000:80
# <service-name> 是服务的名称
# 3000 是你希望在计算机上打开的端口
# 80 是服务公开的端口
查看pod日志的几种姿势
# 追踪名称空间 nsA 下容器组 pod1 的日志
kubectl logs -f pod1 -n nsA
# 追踪名称空间 nsA 下容器组 pod1 中容器 container1 的日志
kubectl logs -f pod1 -c container1 -n nsA
# 查看容器组 nginx 下所有容器的日志
kubectl logs nginx --all-containers=true
# 查看带有 app=nginx 标签的所有容器组所有容器的日志
kubectl logs -lapp=nginx --all-containers=true
# 查看容器组 nginx 最近20行日志
kubectl logs --tail=20 nginx
# 查看容器组 nginx 过去1个小时的日志
kubectl logs --since=1h nginx