kubectl get pod|node|deploy|rs|ns [<source_name>] [-o wide|yaml|json] [-n defalt|kube-system] [|grep <filter_info>]
复制
Pod 异常是指数据库运行的容器实例(Pod)出现了不正常的状态或无法正常运行的情况。这些异常可能导致数据库服务的中断、数据不一致或性能下降等问题。下面主要就以下几个方面向您介绍 Pod 异常处理的相关内容:
-
Pod 生命周期:向您介绍 Pod 的整个生命周期中,一般都会存在哪些状态以及原因。
-
Pod 异常场景排查:Pod 在其生命周期中,一般都会出现哪些异常的场景及定位关键信息。
-
Pod 异常案例:整理部分 Pod 异常的故障排查及解决案例。
Pod 生命周期
查看 Pod 状态
除了必要的集群和应用监控,一般还需要通过 kubectl 命令搜集异常状态信息。
-
pod|node|deploy|rs|ns:需要查看的资源类型。该资源可以是 pod、node、deployment、replicaset、namespace 等。
-
<source_name>:资源(如 Pod)名称,不指定则输出集群中的所有知道类型资源。
-
-o:选择输出的格式,不指定则安装:
-
wide:以宽输出格式展示 Pod 的详细信息,包括资源(如 Pod)所在的节点 node 和 IP 地址等。
-
yaml|json:以 yaml 或 json 形式展示资源(如 Pod)的信息。
-
-
-n:选择命名空间,不指定则默认输出 default 中的资源(如 Pod)信息。
-
|grep:对输出信息进行筛选。

输出结果说明:
-
NAME:第一列展示了 Pod 的名称 ID。
-
READY:第二列表示一个 Pod 中有多少个容器被认为是就绪的。假设值为 m/n,若 m < n,Pod 中准备好的容器(m)将少于它们的总数(n),因此整个 Pod 不会被认为是就绪的。
-
STATUS:展示了 Pod 的状态,具体含义请参考 Pod 状态汇总。
-
RESTART:Pod 的重启次数。
-
AGE:该 Pod 距今创建了多长时间。
kubectl get pod <pod_name> -o yaml
复制
kubectl describe {pod|node|deploy|rs} <source_name>
复制
kubectl logs <pod_name> [<container_name>] [-f]
复制
-
<container_name>:当 Pod 中含有多个容器时,需要指定容器名称。
-
-f:表示实时动态展示指定 pod 的 pod 日志。
kubectl exec <pod_name> -n <name_space> -c <container_name> #<CMD> <ARGS>
复制
Pod 状态汇总
在整个生命周期中,Pod 会出现 5 种阶段(Phase),Pod 的 5 个阶段是 Pod 在其生命周期中所处位置的简单宏观概述,并不是对容器或 Pod 状态的综合汇总。下面向您介绍 Pod 和容器的生命周期以及基本状态:
在异常诊断过程中,容器的退出状态是至关重要的信息。 |
分类 | 状态 | 说明 |
---|---|---|
Pod 生命周期阶段(Phase) |
Pending |
Pod 被 K8s 创建出来后,起始于 Pending 阶段。在 Pending 阶段,Pod 将经过调度,被分配至目标节点开始拉取镜像、加载依赖项、创建容器。 |
Running |
当 Pod 所有容器都已被创建,且至少一个容器已经在运行中,Pod 将进入 Running 阶段。 |
|
Succeeded |
当 Pod 中的所有容器都执行完成后终止,并且不会再重启,Pod 将进入 Succeeded 阶段。 |
|
Failed |
若 Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止,也就是说容器以非 0 状态异常退出或被系统终止,Pod将进入Failed阶段。 |
|
Unkonwn |
因为某些原因无法取得 Pod 状态,这种情况 Pod 将被置为 Unkonwn 状态。 |
|
Pod 细分状态(PodConditions,用于描述造成 Pod 所处阶段的具体成因是什么) |
Ready/NotReady |
描述 Pod 是否准备好接收网络流量。Ready 表示 Pod 可以接收流量,NotReady 表示 Pod 尚未准备好接收流量。 |
Initialized |
描述 Pod 是否已完成初始化过程,包括创建容器、加载镜像等步骤。 |
|
PodScheduled |
表示 Pod 已经被调度到节点上运行。 |
|
Unschedulable |
表示 Pod 无法被调度到节点上运行。 |
|
容器生命周期状态(State) |
Waiting |
描述容器当前处于等待状态,可能是因为依赖其他资源、容器启动时间较长等待等原因。 |
Running |
描述容器正在正常运行中 |
|
Terminated |
描述容器已经终止或完成运行。 |
|
容器状态原因(Reason) |
ContainerCreating |
表示容器正在创建过程中。 |
Error |
表示容器发生错误,无法正常启动或运行。 |
|
OOMKilled |
表示容器因为内存不足被系统终止。 |
|
CrashLoopBackOff |
表示容器在启动后立即崩溃并持续重启。 |
|
Completed |
表示容器已经成功完成任务并终止。 |

|
Pod 异常排查
Pod 在其生命周期的许多时间点可能发生不同的异常,按照 Pod 容器是否运行为标志点,我们将异常场景大致分为两类:
-
在 Pod 进行调度并创建容器过程中发生异常,此时 Pod 将卡 在 Pending 阶段。
-
Pod 容器运行中发生异常,此时 Pod 按照具体场景处在不同阶段。

对于不同的异常场景,Pod 会有不同的错误状态,您可以根据相关报错信息中的状态关键词快速锁定 Pod 异常原因:
异常场景 | 常见错误状态 |
---|---|
Unschedulable |
|
ImagePullBackOff |
|
Error |
|
Error |
|
CrashLoopBackOff |
|
FailedPostStartHook 或 FailedPreStopHook 事件 |
|
容器已经全部启动,但是 Pod 处于 NotReady 状态,服务流量无法从 Service 达到 Pod |
|
CrashLoopBackOff |
|
CrashLoopBackOff |
|
OOMKilled |
|
Pod Evicted |
|
Unkonwn |
|
卡在Terminating |
调度失败
Pod 被创建后进入调度阶段,K8s 调度器依据 Pod 声明的资源请求量和调度规则,为 Pod 挑选一个适合运行的节点。当集群节点均不满足 Pod 调度需求时,Pod 将会处于 Pending 状态。造成调度失败的典型原因如下:
节点资源不足
K8s 将节点资源(CPU、内存、磁盘等)进行数值量化,定义出节点资源容量(Capacity)和节点资源可分配额(Allocatable)。
-
资源容量是指 Kubelet 获取的计算节点当前的资源信息,
-
资源可分配额是 Pod 可用的资源。
Pod 容器有两种资源额度概念:请求值 Request 和限制值 Limit,容器至少能获取请求值大小、至多能获取限制值的资源量。
-
Pod 的资源请求量是 Pod 中所有容器的资源请求之和;
-
Pod 的资源限制量是 Pod 中所有容器的资源限制之和。
K8s 默认调度器按照较小的请求值作为调度依据,保障可调度节点的资源可分配额一定不小于 Pod 资源请求值。当集群没有一个节点满足 Pod 的资源请求量,则 Pod 将卡在 Pending 状态。
-
Pod 因为无法满足资源需求而被 Pending,可能是因为集群资源不足,需要进行扩容,也有可能是集群碎片导致。
以一个典型场景为例,用户集群有十几个 4 核 8GB 内存的节点,整个集群资源使用率在 60% 左右,每个节点都有碎片,但因为碎片太小导致扩不出来一个 2c4g(2 核 4G 内存)的 Pod。
一般来说,小节点集群会更容易产生资源碎片,而碎片资源无法供 Pod 调度使用。如果想最大限度地减少资源浪费,使用更大的节点可能会带来更好的结果。
超过 Namespace 资源配额
K8s 用户可以通过资源配额(Resource Quota)对 Namespace 进行资源使用量限制,包括两个维度:
-
限定某个对象类型(如 Pod)可创建对象的总数。
-
限定某个对象类型可消耗的资源总数。
如果在创建或更新 Pod 时申请的资源超过了资源配额,则 Pod 将调度失败。此时需要检查 Namespace 资源配额状态,做出适当调整。
不满足 NodeSelector 节点选择器
Pod 通过 NodeSelector 节点选择器指定调度到带有特定 Label 的节点,若不存在满足 NodeSelector 的可用节点,Pod 将无法被调度,需要对 NodeSelector 或节点 Label 进行合理调整。
不满足亲和性
节点亲和性(Affinity)和反亲和性(Anti-Affinity)用于约束 Pod 调度到哪些节点,而亲和性又细分为软亲和(Preferred)和硬亲和(Required)。对于软亲和规则,K8s 调度器会尝试寻找满足对应规则的节点,如果找不到匹配的节点,调度器仍然会调度该 Pod。而当硬亲和规则不被满足时,Pod 将无法被调度,需要检查 Pod 调度规则和目标节点状态,对调度规则或节点进行合理调整。
节点存在污点
K8s 提供污点(Taints)和容忍(Tolerations)机制,用于避免 Pod 被分配到不合适的节点上。假如节点上存在污点,而 Pod 没有设置相应的容忍,Pod 将不会调度到该节点。此时需要确认节点是否有携带污点的必要,如果不必要的话可以移除污点;若 Pod 可以分配到带有污点的节点,则可以给 Pod 增加污点容忍。
没有可用节点
节点可能会因为资源不足、网络不通、Kubelet 未就绪等原因导致不可用(NotReady)。当集群中没有可调度的节点,也会导致 Pod 卡在 Pending 状态。此时需要查看节点状态,排查不可用节点问题并修复,或进行集群扩容。
镜像拉取失败
Pod 经过调度后分配到目标节点,节点需要拉取 Pod 所需的镜像为创建容器做准备。拉取镜像阶段可能存在以下几种原因导致失败:
镜像名字拼写错误或配置了错误的镜像
出现镜像拉取失败后首先要确认镜像地址是否配置错误。
私有仓库的免密配置错误
集群需要进行免密配置才能拉取私有镜像。自建镜像仓库时需要在集群创建免密凭证 Secret,在 Pod 指定 ImagePullSecrets,或者将 Secret 嵌入 ServiceAccount,让 Pod 使用对应的 ServiceAccount。而对于 ACR 等镜像服务云产品一般会提供免密插件,需要在集群中正确安装免密插件才能拉取仓库内的镜像。免密插件的异常包括:集群免密插件未安装、免密插件 Pod 异常、免密插件配置错误,需要查看相关信息进行进一步排查。
网络不通
网络不通的常见场景有三个:
-
集群通过公网访问镜像仓库,而镜像仓库未配置公网的访问策略。
-
对于自建仓库,可能是端口未开放,或是镜像服务未监听公网 IP;
-
对于 ACR 等镜像服务云产品,需要确认开启公网的访问入口,配置白名单等访问控制策略。
-
-
集群位于专有网络,需要为镜像服务配置专有网络的访问控制,才能建立
镜像拉取超时
常见于带宽不足或镜像体积太大,导致拉取超时。可以尝试在节点上手动拉取镜像,观察传输速率和传输时间,必要时可以对集群带宽进行升配,或者适当调整 Kubelet 的 --image-pull-progress-deadline 和 --runtime-request-timeout
同时拉取多个镜像,触发并行度控制
常见于用户弹性扩容出一个节点,大量待调度 Pod 被同时调度上去,导致一个节点同时有大量 Pod 启动,同时从镜像仓库拉取多个镜像。而受限于集群带宽、镜像仓库服务稳定性、容器运行时镜像拉取并行度控制等因素,镜像拉取并不支持大量并行。这种情况可以手动打断一些镜像的拉取,按照优先级让镜像分批拉取。
依赖项错误
在 Pod 启动之前,Kubelet 将尝试检查与其他 K8s 元素的所有依赖关系。主要存在的依赖项有三种:PersistentVolume、ConfigMap 和 Secret。
当这些依赖项不存在或者无法读取时,Pod 容器将无法正常创建,Pod 会处于 Pending 状态直到满足依赖性。当这些依赖项能被正确读取,但出现配置错误时,也会出现无法创建容器的情况。比如将一个只读的持久化存储卷 PersistentVolume 以可读写的形式挂载到容器,或者将存储卷挂载到 /proc 等非法路径,也会导致容器创建失败。
容器创建失败
Pod容器创建过程中出现了错误。常见原因包括:
-
违反集群的安全策略,比如违反了 PodSecurityPolicy 等。
-
容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定。
-
缺少启动命令,Pod 描述文件和镜像 Dockerfile 中均未指定启动命令。
-
启动命令配置错误。Pod 配置文件可以通过 command 字段定义命令行,通过 args 字段给命令行定义参数。启动命令配置错误的情况非常多见,要格外注意命令及参数的格式。
初始化失败
K8s 提供 Init Container 特性,用于在启动应用容器之前启动一个或多个初始化容器,完成应用程序所需的预置条件。Init container 与应用容器本质上是一样的,但它们是仅运行一次就结束的任务,并且必须在执行完成后,系统才能继续执行下一个容器。如果 Pod 的 Init Container 执行失败,将会 block 业务容器的启动。通过查看 Pod 状态和事件定位到 Init Container 故障后,需要查看 Init Container 日志进一步排查故障点。
回调失败
K8s 提供 PostStart 和 PreStop 两种容器生命周期回调,分别在容器中的进程启动前或者容器中的进程终止之前运行。PostStart 在容器创建之后立即执行,但由于是异步执行,无法保证和容器启动命令的执行顺序相关联。PreStop 在容器终止之前被同步阻塞调用,常用于在容器结束前优雅地释放资源。如果 PostStart 或者 PreStop 回调程序执行失败,容器将被终止,按照重启策略决定是否重启。当出现回调失败,会出现 FailedPostStartHook 或 FailedPreStopHook 事件,进一步结合容器打出的日志进行故障排查。
就绪探针失败
K8s 使用 Readiness Probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当 Pod 中的容器都处于就绪状态时,K8s 才认定该Pod 处于就绪状态,才会将服务流量转发到该容器。
一般就绪探针失败分为几种情况:
-
容器内应用原因:健康检查所配置规则对应的端口或者脚本,无法成功探测,如容器内应用没正常启动等。
-
针配置不当:写错检查端口导致探测失败;
检测间隔和失败阈值设置不合理,例如每次检查间隔 1 秒,一次不通过即失败;
启动延迟设置太短,例如应用正常启动需要 15 秒,而设置容器启动10s后启用探针。
-
系统层问题:节点负载高,导致容器进程异常。
-
CPU 资源不足:CPU 资源限制值过低,导致容器进程响应慢。
存活探针失败
K8s 使用 Liveness Probe(存活探针)来确定容器是否正在运行。
-
如果存活态探测失败,则容器会被杀死,随之按照重启策略决定是否重启。存活探针失败的原因与就绪探针类似,然而存活探针失败后容器会被 kill 消失。
一个典型的用户场景是,用户在压测期间通过 HPA 弹性扩容出多个新 Pod,然而新 Pod 一启动就被大流量阻塞,无法响应存活探针,导致 Pod 被 kill。kill 后又重启,重启完又挂掉,一直在 Running 和 CrashLoopBackOff 状态中振荡。
-
微服务场景下可以使用延迟注册和服务预热等手段,避免瞬时流量打挂容器。
-
如果是程序本身问题导致运行阻塞,建议先将 Liveness 探针移除,通过 Pod 启动后的监控和进程堆栈信息,找出流量涌入后进程阻塞的根因。
容器退出
容器退出分为两种场景:
-
启动后立即退出,可能原因是:
-
启动命令的路径未包含在环境变量PATH中。
-
启动命令引用了不存在的文件或目录。
-
启动命令执行失败,可能因为运行环境缺少依赖,也可能是程序本身原因。
-
启动命令没有执行权限。
-
容器中没有前台进程。容器应该至少包含一个long-running的前台进程,不能后台运行,比如通过nohup这种方式去启动进程,或是用tomcat的startup.sh脚本。
对于容器启动后立即退出的情况,通常因为容器直接消失,无法获取其输出流日志,很难直接通过现场定位问题。一个简易的排查方式是,通过设置特殊的启动命令卡住容器(比如使用tail -f /dev/null),然后进到容器中手动执行命令看看结果,确认问题原因。
-
-
运行一段时间后退出: 这种情况一般是容器内 1 进程 Crash 或者被系统终止导致退出。此时首先查看容器退出状态码,然后进一步查看上下文信息进行错误定位。这种情况发生时容器已经删除消失,无法进入容器中查看日志和堆栈等现场信息,所以一般推荐用户对日志、错误记录等文件配置持久化存储,留存更多现场信息。几种常见的状态码如下:
表 6.3.3:容器退出状态码 状态码 含义 分析 0
正常退出
容器的启动程序不是一个 long-running 的程序。如果正常退出不符合预期,需要检查容器日志,对程序的执行逻辑进行调整。
137
外部终止
137 表示容器已收到来自主机操作系统的 SIGKILL 信号。该信号指示进程立即终止,没有宽限期。可能原因包含:容器运行时将容器 kill,例如 docker kill 命令;Linux 用户向进程发送 kill -9 命令触发;K8s尝试终止容器,超过优雅下线窗口期后直接 kill 容器;由节点系统触发,比如遭遇了 OOM。
139
段错误
139 表示容器收到了来自操作系统的 SIGSEGV 信号。这表示分段错误——内存违规,由容器试图访问它无权访问的内存位置引起。
143
优雅终止
143 表示容器收到来自操作系统的 SIGTERM 信号,该信号要求容器正常终止。该退出码可能的原因是:容器引擎停止容器,例如使用 docker stop 停止了容器;K8s 终止了容器,比如缩容行为将 Pod 删除。
OOMKilled
K8s 中有两种资源概念:可压缩资源(CPU)和不可压缩资源(内存,磁盘 )。当 CPU 这种可压缩资源不足时,Pod 不会退出;而当内存和磁盘 IO 这种不可压缩资源不足时,Pod 会被 kill 或者驱逐。因为内存资源不足/超限所导致的 Pod 异常退出的现象被称为 Pod OOMKilled。
K8s存在两种导致 Pod OOMKilled 的场景:
-
Container Limit Reached,容器内存用量超限
Pod 内的每一个容器都可以配置其内存资源限额,当容器实际占用的内存超额,该容器将被 OOMKilled 并以状态码 137 退出。OOMKilled 往往发生在 Pod 已经正常运行一段时间后,可能是由于流量增加或是长期运行累积的内存逐渐增加。这种情况需要查看程序日志以了解为什么 Pod 使用的内存超出了预期,是否出现异常行为。如果发现程序只是按照预期运行就发生了 OOM,就需要适当提高 Pod 内存限制值。
例如 JAVA 容器设置了内存资源限制值 Limit,然而 JVM 堆大小限制值比内存 Limit 更大,导致进程在运行期间堆空间越开越大,最终因为 OOM 被终止。对于JAVA容器来说,一般建议容器内存限制值 Limit 需要比 JVM 最大堆内存稍大一些。
-
Limit Overcommit,节点内存耗尽
K8s 有两种资源额度概念:请求值 Request 和限制值 Limit,默认调度器按照较小的请求值作为调度依据,保障节点的所有 Pod 资源请求值总和不超过节点容量,而限制值总和允许超过节点容量,这就是 K8s 资源设计中的 Overcommit(超卖)现象。超卖设计在一定程度上能提高吞吐量和资源利用率,但会出现节点资源被耗尽的情况。当节点上的 Pod 实际使用的内存总和超过某个阈值,K8s 将会终止其中的一个或多个 Pod。
为避免这种情况,建议在创建 Pod 时选择大小相等或相近的内存请求值和限制值,也可以利用调度规则将内存敏感型 Pod 打散到不同节点。
Pod 驱逐
当节点内存、磁盘这种不可压缩资源不足时,K8s 会按照 QoS 等级对节点上的某些 Pod 进行驱逐,释放资源保证节点可用性。当 Pod 发生驱逐后,上层控制器例如 Deployment 会新建 Pod 以维持副本数,新 Pod 会经过调度分配到其他节点创建运行。对于内存资源,前文已经分析过可以通过设置合理的请求值和限制值,避免节点内存耗尽。而对于磁盘资源,Pod 在运行期间会产生临时文件、日志,所以必须对 Pod 磁盘容量进行限制,否则某些 Pod 可能很快将磁盘写满。类似限制内存、CPU 用量的方式,在创建 Pod 时可以对本地临时存储用量(ephemeral-storage)进行限制。同时,Kubelet 驱逐条件默认磁盘可用空间在 10% 以下,可以调整云监控磁盘告警阈值以提前告警。
Pod 失联
Pod处于 Unkonwn 状态,无法获取其详细信息,一般是因为所在节点 Kubelet 异常,无法向 APIServer 上报 Pod 信息。首先检查节点状态,通过 Kubelet 和容器运行时的日志信息定位错误,进行修复。如果无法及时修复节点,可以先将该节点从集群中删除。
无法被删除
当一个 Pod 被执行删除操作后,却长时间处于 Terminating 状态,这种情况的原因有几种:
-
Pod关联的 finalizer 未完成。首先查看 Pod 的 metadata 字段是否包含 finalizer,通过一些特定上下文信息确认 finalizer 任务具体是什么,通常 finalizer 的任务未完成可能是因为与 Volume 相关。如果 finalizer 已经无法被完成,可以通过 patch 操作移除对应的 Pod 上的 finalizer 完成删除操作。
-
Pod 对中断信号没有响应。Pod 没有被终止可能是进程对信号没有响应,可以尝试强制删除Pod。
-
节点故障。通过查看相同节点上的其他 Pod 状态确认是否节点故障,尝试重启 Kubelet 和容器运行时。如果无法修复,先将该节点从集群中删除。
Pod 异常案例
Pod Pending
问题描述
TOS 集群中的 Pod 长期处于 Pending 状态。
问题分析
此问题一般是由于 TOS 集群的某种类似的资源不足或是不符合调度规则导致。
排查思路
引发此问题的原因可能是:调度器自身问题,调度节点资源问题及 pod 的亲和性污点(taint)问题。
-
查看 TOS 或 K8s 集群的 kube-scheduler 组件是否正常运行(running):
kubectl get po -n kube-system | grep scheduler
复制若是这个 pod 状态不是 Running,可以执行以下命令重启 scheduler 尝试恢复:
kubectl delete po tos-scheduler-tos-xxx ##其中“xxx”一般为节点的 hostname
复制scheduler 恢复后查看 pending pod 状态是否正常。
-
查看 pending pod 的 describe 日志:
kubectl describe pods <pending_pod_name>
复制在最后的 Events 会有 pod 调度失败的原因。
解决方案
集群中节点的 CPU/内存/GPU 资源不够
-
添加更多节点到集群,或者终止不需要的 pod 为 pending 中的 pod 提供空间。
-
检查该 pod 请求的资源是否小于节点(node)可申请的资源:查看 node 资源使用情况
kubectl get nodes ##查看集群节点 kubectl describe node <node1> ##查看节点描述
复制-
Allocatable 为此节点能够申请的资源总和;
-
Allocated resources 为此节点已经分配的资源;
-
前者与后者相减,为剩余可以申请的资源。
-
若是 describe pod 的 FailedScheduling 的报错中含有 MatchNodeSelector,pod affinity,pod anti-affinity 或是 node affinity 等字眼的报错,可以通过如下命令查看 pod 或是 node affinity 相关定义部分:
kubectl get po <pod_name> -oyaml | grep 'nodeSelector:' ## nodeSelector 相关部分 kubectl get po <pod_name> -oyaml | grep -A 20 'affinity:' ## affinity 相关部分
复制
如果节点上存在污点(Taints),而 Pod 没有相应的容忍(Tolerations),Pod 将无法调度成功。
-
通过 describe node 可以看下 Node 有哪些 Taints:
kubectl describe nodes <node> | grep Taints:
复制 -
若是有污点,即输出内容不是 <none>,解决方法有如下 2 个:
-
删除污点:
kubectl taint nodes <node1> <key>-
复制 -
(推荐)给 Pod 加上这个污点的容忍:
-
进入 Pod 编辑页面(谨慎操作,建议联系星环科技工程师确认):
kubectl edit pod <pod_name>
复制 -
找到 tolerations,并添加如下信息
tolerations: - key: "master" ##根据 key 的值自行修改 operator: "Equal" ##根据 key 的值自行修改 value: "true" effect: "NoSchedule"
复制
-
-
Pod 健康状态与 Manager 页面不一致
问题描述
Manager 页面上服务角色报黄提示 running with problem,后台查看的 pod 状态,都是 0/1 running
问题分析
Manager的health 包括两部分: DAEMON_CHECK和VITAL_SIGN_CHECK。前者检查 pod 状态,后者检查服务状态,出现上述情况时候基本可以确定是后者检查问题。
解决方案
如果 Manager 开启了高可用(HA),那么需要重启所有 Manager 节点
如果 Manager 开启了高可用,当节点上数据不同步时候也可能导致该问题。
解决方案:停掉所有的 Manager,然后只启动最初始的那个 Manager 节点,观察服务状态是否正常。
可以清理浏览器缓存、尝试使用无痕模式、更换其他浏览器(谷歌/火狐)
此时需要了解各个组件的 health check 原理才行 |
-
如果检查结果同样报错了,说明服务确实有问题,需要去对应组件的日志中寻找错误原因;
-
如果检查结果中服务是健康的,说明可能是 health check 的误报,是 Manager 有问题。
在业务场景以及客户允许的情况下,尝试重启该服务。
网络环境做过一些特殊的限制等,影响了 health check 的探查。
扩容节点 Pod 无法查看日志
问题描述
集群做过扩容节点操作,扩容后新添加的节点中的所有 Pos 均无法查看日志信息。
问题分析
出现该情况的原因是 apiserver 所对应容器里的 /etc/hosts 信息记录不完全。
解决方案
-
确认 apiserver 所在的 server 信息,查看 TOS 角色信息能得知部署了 apiserver 的 pod 的对应节点:
kubectl get pods -owide -n kube-system | grep apiserver
复制 -
分别 ssh 登录每个节点服务器,执行以下命令查看 apiserver 容器信息:
#分别登录部署了 apiserver 的节点 ssh <user_name>@<server_ip> # 然后输入 yes 确认连接操作之后,输入用户密码即可 # 列出所有在运行的 apiserver 容器信息,输出结果第一列为 container_id docker ps | grep apiserver
复制图 6.3.4:查看 apiserver 容器 -
分别进入相关的 container 内,查看 /etc/hosts 信息
docker exec -it <container_id> bash cat /etc/hosts
复制 -
对比正常的 /etc/hosts 信息可以看出 apiserver 的 container 内 /etc/hosts 信息有很多缺失,且缺失部分所在节点均无法正常查看 pod 日志。
-
在 apiserver 的 container 内直接修改 hosts 信息:
docker exec -it <container_id> bash vi /etc/hosts
复制/etc/hosts 文件添加缺失节点的 ip 和 hostname 映射
-
经过验证,在 container 内修改后,即使重启该 container,/etc/hosts 信息仍然会保留。