Kubernetes 是一个生产级的容器编排引擎,但是 Kubernetes 仍然存在系统复杂、故障诊断成本高等问题。网易内部在基于 Kubernetes 落地轻舟云原生体系时遇到了不少问题,主要包括以下几个维度:
Kubernetes 故障诊断恢复平台是基于 Kubernetes 云原生基础设施能力打造的框架,旨在解决云原生体系中故障诊断、运维恢复的自动化问题,帮助用户更加平滑地完成容器化落地。
Kubernetes 故障诊断恢复平台的设计目标包括:
故障诊断恢复平台 Agent 组件可以监听 APIServer 获取 Abnormal CRD 资源,Abnormal CRD 资源是对故障状态机的抽象。故障诊断恢复平台 Agent 组件可以通过 Event、Prometheus 报警、系统日志中的关键条目产生相对应的 Abnormal CRD 并送入故障诊断恢复的流水线。故障诊断恢复平台 Agent 组件使用 DaemonSet 部署在集群中:
---------------------
Watch (Event, CRD) | |
--------------------->| APIServer |
| | |
| |-------------------|
| | |
-------------- --------- | Etcd |
| | Monitor | | Monitor | |
| Prometheus |<----------------| Agent |---------------->|-------------------|
| | | | | |
-------------- --------- | ControllerManager |
| | |
| |-------------------|
| | |
| | Scheduler |
| | |
| ---------------------
\|/
---------------------
| |
| Kernel |
| Docker |
| Kubelet |
| Cgroup |
| ...... |
| |
---------------------
故障诊断恢复平台 Agent 组件由下列部分组成:
------------------ ---------------------- ------------------ ------------------
| | Abnormal | | Abnormal | | Abnormal | |
| AbnormalSource |------------>| InformationManager |------------>| DiagnoserChain |------------>| RecovererChain |
| | | | | | | |
------------------ ---------------------- ------------------ ------------------
| | |
| | |
| | |
\|/ \|/ \|/
-------------------------- --------------- ---------------
| | | | | |
| InformationCollector 1 | | Diagnoser 1 | | Recoverer 1 |
| | | | | |
-------------------------- --------------- ---------------
| | |
| | |
| | |
\|/ \|/ \|/
-------------------------- --------------- ---------------
| | | | | |
| InformationCollector 2 | | Diagnoser 2 | | Recoverer 2 |
| | | | | |
-------------------------- --------------- ---------------
| | |
| | |
| | |
\|/ \|/ \|/
....... ....... .......
故障诊断恢复平台 Agent 组件功能如下:
故障诊断恢复平台中 Abnormal 的状态迁移流程如下:
故障诊断恢复平台中 Abnormal 的状态迁移图如下:
----------
| |
----------------------------------------------------------->| Failed |
/|\ /|\ | |
| | ----------
Failed | Failed |
| |
----------- ------------------------- -------------- -------------- -------------
| | | | | | | | | |
| Created |------------------>| InformationCollecting |------------------>| Diagnosing |------------------>| Recovering |------------------>| Succeeded |
| | | | /|\ | | /|\ | | /|\ | |
----------- ------------------------- | -------------- | -------------- | -------------
| | | | | |
Successfully | | Successfully | | Successfully | |
| | | | | |
\|/ | \|/ | \|/ |
------------------------ | -------------- | ------------- |
| | | | | | | | |
| InformationCollected |--------- | Identified |--------- | Recovered |---------
| | | | | |
------------------------ -------------- -------------
Abnormal 是故障诊断恢复平台中故障事件源、故障分析链、故障恢复链之间通信的接口。故障事件的详情记录在 Spec 中,故障事件源、故障分析链和故障恢复链对 Abnormal 进行处理并通过变更 Status 字段进行通信。故障诊断恢复平台通过 Abnormal 提供以下功能:
Abnormal 是故障诊断恢复平台中故障事件源、故障分析链、故障恢复链之间通信的接口,用于描述故障。
Field | Description | Scheme | Required |
---|---|---|---|
metadata | API 资源元数据。 | metav1.ObjectMeta | false |
spec | 故障的来源和现象说明。支持用户自定义字段。 | AbnormalSpec | true |
status | 故障当前的状态。由故障事件源、故障分析链、故障恢复链维护,用户无法自行修改。 | AbnormalStatus | true |
Field | Description | Scheme | Required |
---|---|---|---|
source | 故障的来源。该字段支持 Log、KubernetesEvent、PrometheusAlert、Probe 和 Custom。 | string | true |
log | 表示故障的日志详细信息,对应 source 字段的 Log。 | Log | false |
kubernetesEvent | 表示故障的 Kubernetes Event 详细信息,对应 source 字段的 KubernetesEvent。 | corev1.Event | false |
prometheusAlert | 表示故障的 Prometheus Alert 详细信息,对应 source 字段的 PrometheusAlert。 | PrometheusAlert | false |
nodeProbe | 用户自定义的节点故障探测 Probe,支持 Probe 类型故障。 | NodeProbe | false |
podProbe | 用户自定义的容器故障探测 Probe,支持 Probe 类型故障。 | PodProbe | false |
skipDiagnosis | 跳过故障分析步骤。 | bool | false |
skipRecovery | 跳过故障恢复步骤。 | bool | false |
nodeName | Abnormal 所在节点名。 | string | false |
assignedDiagnosers | 指定进行诊断的故障诊断器列表。 | []NamespacedName | false |
assignedRecoverers | 指定进行恢复的故障恢复器列表。 | []NamespacedName | false |
assignedInformationCollectors | 指定进行信息采集的信息采集器列表。 | []NamespacedName | false |
context | 用于扩展的上下文信息,支持 Custom 类型故障。 | runtime.RawExtension | false |
Field | Description | Scheme | Required |
---|---|---|---|
filePath | 日志文件的绝对路径。 | string | true |
logEntry | 日志中表示故障的条目。 | string | true |
Field | Description | Scheme | Required |
---|---|---|---|
labels | Alert 的标签。 | labels.Labels | true |
annotations | Alert 的注解。 | labels.Labels | true |
startsAt | 告警的开始时间 | metav1.Time | false |
endsAt | 告警的结束时间 | metav1.Time | false |
generatorURL | 告警生成者的 URL | string | false |
Field | Description | Scheme | Required |
---|---|---|---|
name | 执行 Probe 的 Node。 | string | true |
timeoutSeconds | Probe 执行超时时间。 | int32 | false |
exec | Exec 命令。 | corev1.ExecAction | false |
httpGet | HTTP 请求。 | corev1.HTTPGetAction | false |
tcpSocket | TCP 探活。 | corev1.TCPSocketAction | false |
Field | Description | Scheme | Required |
---|---|---|---|
namespace | 执行 Probe 的 Pod 命名空间。 | string | true |
name | 执行 Probe 的 Pod。 | string | true |
container | 执行 Probe 的容器。 | string | true |
timeoutSeconds | Probe 执行超时时间。 | int32 | false |
exec | Exec 命令。 | corev1.ExecAction | false |
httpGet | HTTP 请求。 | corev1.HTTPGetAction | false |
tcpSocket | TCP 探活。 | corev1.TCPSocketAction | false |
Field | Description | Scheme | Required |
---|---|---|---|
identifiable | 表示该故障为可以被故障分析器识别的故障。 | bool | true |
recoverable | 表示该故障为可以被故障恢复器恢复的故障。 | bool | true |
conditions | 描述故障恢复流程中关键点的状况。 | []AbnormalCondition | false |
phase | 故障的当前阶段。该字段支持 InformationCollecting、Diagnosing、Recovering、Succeeded、Failed、Unknown。 | string | false |
message | 表示当前故障恢复阶段的可读信息。用于输出故障原因、故障恢复建议等。 | string | false |
reason | 表示当前故障恢复阶段的简短信息。 | string | false |
output | Exec 命令、HTTP 请求、TCP 探活的输出。 | string | false |
startTime | 表示当前故障开始被诊断的时间。 | metav1.Time | false |
diagnoser | 成功执行的故障诊断器。 | NamespacedName | false |
recoverer | 成功执行的故障恢复器。 | NamespacedName | false |
context | 用于扩展的上下文信息,支持 Custom 类型故障。 | runtime.RawExtension | false |
Field | Description | Scheme | Required |
---|---|---|---|
type | 故障状况的类型。 | string | true |
status | 故障状况的状态。该字段支持 True、False、Unknown。 | string | true |
lastTransitionTime | 上一次状况的状态变化时间。 | metav1.Time | false |
message | 表示当前状况的状态变化原因的可读信息。 | string | false |
reason | 表示当前状况的状态变化原因的简短信息。 | string | false |
Field | Description | Scheme | Required |
---|---|---|---|
namespace | API 资源的命名空间。 | string | false |
name | API 资源的名称。 | string | true |
故障事件源是获取故障事件的接口,大致可分为以下几类,每一类都需要实现故障事件源接口:
故障事件源在消费日志、Prometheus 报警和 Event 后会生成 Abnormal 故障事件并发往故障分析链。用户也可以直接通过 CRD 来创建故障事件。
故障分析链是一个调用链框架,本身并不包含故障分析的逻辑,用户需要实现故障分析的具体逻辑并注册到故障分析链中。故障分析链从故障事件源接收故障事件并将故障事件逐一传入被注册的故障分析器中,当故障事件能够被某个故障分析器识别则中止调用并交由该逻辑进行处理。如果故障无法被任何故障分析器识别则直接获取相关排障信息并报警。故障分析器一般是一个 HTTP 服务器。用户可以将自定义故障诊断分析的脚本放入特定路径,故障分析链会动态的获取自定义故障诊断分析文件。
故障分析器在无法识别 Abnormal 故障事件时返回错误,故障分析器在成功识别 Abnormal 故障事件后变更 Status 字段。故障分析链在某个故障分析器成功识别 Abnormal 故障事件后将 Abnormal 故障事件发往故障恢复链。故障分析器在执行诊断时可以通过调用信息采集器获取更多信息。
当故障分析或恢复流程较复杂时,需要从其他接口获取更多信息用于故障的诊断和确认。此时故障分析器或故障恢复器可以调用信息采集器获取更多信息。常用的信息采集器包括 eBPF、Golang 剖析文件、Java 虚拟机工具等。信息采集器一般是一个 HTTP 服务器。故障分析器或故障恢复器需要保证能够正确处理从信息采集器获取的信息。信息管理器用于管理多个信息采集器,用户通过请求信息管理器获取额外信息,信息管理器在接收到请求后会转发到相应的信息采集器中。
和故障分析链相似,故障恢复链也是一个调用链框架,本身并不包含故障恢复的逻辑,用户需要实现故障恢复的具体逻辑并注册到故障恢复链中。故障恢复链从故障分析链接收故障事件并将故障事件逐一传入被注册的故障恢复器中,当故障能够被某个故障恢复器识别则中止调用并交由该逻辑进行处理。如果故障无法被任何故障恢复器识别则报错中止。故障恢复器一般是一个 HTTP 服务器。用户可以将自定义故障恢复的脚本放入特定路径,故障恢复链会动态的获取自定义故障恢复文件。
社区 Issue 3529 中记录的 Bug 会导致 Docker 18.06 及以下版本因为 Shim 的死锁而无法正常终止容器。当该故障出现时可以通过以下步骤实现该故障的诊断恢复:
.spec.nodeName
字段为该 Pod 所处节点。reaper.go
相关函数以确定问题原因。 作者简介:
黄久远,网易杭州研究院轻舟云原生资深研发工程师。专注于云原生以及分布式系统等领域,作为核心成员参与了网易集团内部容器化落地以及网易轻舟容器平台产品化。目前主要负责网易轻舟云原生故障自动诊断系统的设计、开发以及商业化产品输出等工作。