我来对云原生可观测性应用场景进行简单梳理。
1.故障分析
故障分析是云原生可观测性的最基本的应用场景,也是可观测性技术的持续发展的重要驱动力。谷歌给出可观测性的核心价值快速排障(troubleshooting)。可观测性犹如整个 IT 系统的眼睛,它是运维人员发现问题、定位问题、解决问题的第一步,同时,也是运维监控的实现“先知、先觉、先行”的重要条件。随着云原生持续发展,业务对可靠性、稳定性的要求越来越高。提前发现故障、快速发现故障、快速定位故障原因是做好稳定性的核心要素,良好的可观测性能够帮助用户在故障分析上事半功倍,有效提高业务上线运行地稳定性。在故障分析领域,云原生可观测技术协助运维人员发现故障事件,分析故障发生原因,快速定位故障根因,可极大提升云原生领域运维效率。
2.事件预测
在安全运维领域,自动化成为技术发展的趋势。系统能够完成人类根本无法完成的任务,例如通过机器学习方法,在错误或事件发生之前进行预测。实现预测能力,需要通过在可观测性系统添加人工智能层。将人工智能的大数据分析能力及结果赋能于可观测性系统,使可观测性系统在问题发生之前提供预测能力。人工智能赋能的可观测性系统,除了提供预测能力,并且可对预测发生的问题提供解决方案。在安全运维领域提升对未发生事件、未知威胁的感知能力。
为使得可观测性系统具备更强的预测能力,需要更多的数据和更强大的算力支持,建立精确的模型和预测系统,提供更深刻的事件洞察能力。
3.日志审计
日志与审计对系统和应用行为的记录,对云原生可观测性的实现起到了重要的作用。通过日志系统获取系统以及应用的详细操作数据,是云原生可观测性重要的数据来源。 针对 Docker 和 Kubernetes,分别具有对应的日志采集机制,从安全审计的角度出发,可对日志数据进行存储、归类、查询等操作处理。
3.1 Docker
日志审计 Docker 支持多种日志记录机制,用以帮助用户从正在运行的容器和服务中获取信息,这种机制被称为日志驱动程序。Docker 从 1.6 版本开始支持日志驱动,用户可以将日志直接从容器输出到如 syslogd 这样的日志系统中。每个 Docker 守护进程都有一个默认的日志驱动程序,通常这个默认的日志驱动是 json-file,也就是以 JSON 文件的形式保存日志信息。同时Docker 还支持其他的日志驱动,比如 none、json-file、syslog 和 fluentd 等。下表2 展示了当前Docker 支持的日志驱动格式。
CIS Benchmark 对 Docker 的日志审计也提出了安全建议和要求,例如,在CISDocker Benchmark v1.6.0 版本中,2.13 小节要求需要配置集中和远程的日志记录,以确保所有的日志记录都是安全的,进而满足容灾的需要,而具体的日志驱动程序,则可以根据自身情况进行选择。 除了对容器的日志审计外,CIS Benchmark还针对 Docker 主机,提出了相关的安全审计建议。对Docker 主机的安全审计,一方面包括了常规的对 Linux 文件系统以及系统调用等进行审计。另一方面,也包括针对 Docker 守护进程等相关内容的安全审计。例如CIS Docker Benchmarkv1.12.0 版本中,1.1.3 小节要求,需要审计所有活动的Docker 守护进程,可以通过 auditctl -l | grep /usr/bin/docker 命令,列出当前的审计规则,默认情况下,没有针对 Docker 守护进程的审计规则。 CIS Benchmark 中除了对 Docker 守护进程提出了安全审计的建议外,还对Docker 相关的文件和目录提出了安全审计建议,例如:需要审计Docker 文件和/var/lib/docker 目录、需要审计 Docker 文件和/etc/docker 目录、需要审计Docker 文件和 docker.socket 目录等。更多针对 Docker 详细的安全审计建议,可参考CISDocker Benchmark 标准。
3.2 Kubernetes 日志审计
应用程序日志
应用程序的日志记录可以更好的了解应用内部的运行状况,同时对调试问题、监控集群活动以及对应用程序运行过程的安全性分析有着非常大的作用。当前,大部分应用程序都有某种日志记录机制,前文已经介绍过,以Docker 为代表的容器引擎也被设计成支持日志记录的方式。针对容器化应用,最简单且最广泛采用的日志记录方式就是写入标准输出(stdout)和标准错误流(stderr)。但是,由容器引擎或运行时提供的原生日志功能,通常不足以构成完整的日志审计方案。例如,当发生容器崩溃或者节点宕机等情况时,我们通常会想访问应用的日志,这时可能就会出现问题。在集群中,日志应该具有独立的存储和生命周期,与节点、Pod 或容器的生命周期相独立。这里通常会称为集群级的日志。
系统组件日志
在 Kubernetes 中,除了 Pod 中应用程序的日志外,Kubernetes 系统组件的日志同样需要有一定的方案来记录和存储。系统组件的日志主要记录了集群中发生的事件,这对于调试以及安全审计有着重要的作用。系统组件日志可以根据需要配置日志的粒度,灵活调整日志记录的细节程度。日志可以是只显示组件内错误这种粗粒度的,也可以是更加细粒度的,例如记录事件的每一个追踪步骤(HTTP 访问日志、Pod 状态更新、控制器操作、调度器决策等)。
在 Kubernetes 中,系统组件根据部署运行方式的不同,可以分为两种类型:其中一种是运行在容器中的,比如,kube-scheduler、kube-proxy 等;另一种是不在容器中运行的,比如 kubelet、以及容器运行时等。在使用systemd 机制的服务器上,kubelet 和容器运行时将日志写入到 journald 中。如果没有systemd,它们会将日志写入到/var/log 目录下的.log 文件中。容器中的系统组件通常将日志写到/var/log 目录,绕过默认的日志机制。 Kubernetes 默认使用的日志库是 klog,专门用来做日志初始化的相关操作,klog 是 glog 的 fork 版本,由于 glog 不再开发、在容器中运行有不易测试等一系列问题,所以 Kubenetes 自己维护了一个 klog, 由于 Kubernetes 近期版本一直持续不断在精简系统日志组件的,因此在 Kubernetes v1.23.0 开始,klog 的一些命令行参数已经被废弃。
CIS Benchmark 对 Kubernetes 的日志审计也提出了安全建议和要求,例如,在 CIS Kubernetes Benchmark v1.6.0 版本中,1.2.22 小结要求需要配置—audit-log-path 路径,启动 Kubernetes API Server 的审计功能,设置合适的日志路径,进而可以获取 API Server 一系列按时间排序的与安全相关的记录。更多针对Kubernetes 详细的安全审计建议,可参考 CIS kubernetes Benchmark 标准。虽然 Kubernetes 没有为集群级日志记录提供原生的解决方案,但是Kubernetes 官方给出了几种常见的参考设计方法(Logging Architecture)
日志工具
目前支持 Kubernetes 的日志管理工具种类也比较多,例如Zebrium、ElasticStack、CloudWatch、Fluentd 等,这些日志管理工具都有着一个共同的目标,那就是可以尽可能高效、快速的进行日志监控、记录以及分析处理。这里我们以CNCF 项目 Fluentd 为例简单进行介绍。 Fluentd 由 Sadayuki “Sada” Furuhashi 于 2011 年提出,是一个跨平台的开源数据收集器,提供了统一的日志记录层,以便更好的使用和理解数据,不过它并不是一个独立的日志管理器。 这是一个非常流行的工具,有着数十个贡献者、数百个社区贡献的插件、有超过 5000 多名用户以及数以万计的事件被收集、过滤和存储,其用户包括Atlassian、Microsoft 和 Amazon 等。 从架构上来看,Fluentd 创建了一个统一的日志记录层,可以更有效的使用数据,并在软件上对数据进行快速的迭代,可以每秒处理12 万条记录。可扩展性方面,当前最大的用户集群可以从 5 万多个服务器中收集日志。因此,有着高可靠性、高可扩展性和良好的性能。

3.监控
监控(Metrics)在生产系统中,是必不可少的一部分,是系统稳定运行的重要基础,尤其是在云原生环境下,良好的监控系统,对于云原生应用的高效平稳运行,起到了重要的作用。 监控与日志有所不同,日志是对应用程序行为操作的一种记录,提供的是显式的数据。而监控更多的是通过数据的聚合,来对一个程序在特定时间内的行为进行衡量。 监控数据是可累加的,他们具有原子性,每个都是一个逻辑计量单元,或者一个时间段内的综合数据。监控的结果可以很好的观察系统的状态和趋势,但相比较于日志和追踪,监控结果对于问题的定位缺乏细节展示。作为云原生架构的重要支撑技术平台,我们以 Kubernetes 的监控为例,来介绍云原生环境下的主要监控指标。Kubernetes 的监控一方面需要包括对整个基础架构平台的监控,另一方面包括对正在运行的工作负载的监控。具体的监控指标,根据集群的特性不同而有所差异。
3.1 集群状态指标
集群状态可以说是一个基本的,也是关键的监控指标,我们需要知道集群中所有的聚合资源当前的状态以及使用情况,比如节点的状态、可用的Pod、不可用 Pod 等。通过对集群状态进行监控,进而对监控数据进行评估,以及由此产生的监控指标,可以让我们看到集群总体运行状况的概要视图。还可以了解到节点、Pod、Service 等相关联的问题。根据状态指标,可以判断集群的运行是否正常,是否存在相应的风险。 通过监控集群状态指标,我们还可以对节点正在使用的资源数量进行评估,包括共有多少节点、有多少节点可用等信息,从而可以根据需要调整所使用节点的数量和大小。
3.2 资源状态指标
CPU 利用率。清晰准确地知道节点 CPU 资源的使用情况,对于保障系统以及应用的平稳、安全运行有着至关重要的作用。如果微服务应用或主机节点已分配的 CPU 资源被耗尽,那么就需要考虑增加 CPU 配额或者增加处理节点,以满足业务的正常运行。同时,针对 CPU 资源使用情况的监控,还可以通过分析资源使用行为,发现挖矿、拒绝服务攻击等针对计算资源的恶意攻击行为。内存压力。这个监控指标展示了一个节点正在使用的内存量,通过监控数据,我们可以实时的了解整个节点内存的使用状态,防止节点因内存耗尽而对应用运行产生影响。同时,还可以通过对每个组件、应用的内存分配情况进行分析,发现内存分配异常问题,比如,哪些应用的内存分配过度、不必要地增加了节点的开销,同时高内存压力还可以初步的判断应用程序是否存在内存泄露等问题
磁盘压力。磁盘在使用过程中,通常会设置相应的使用阈值,通过对磁盘使用情况的监控,结合既定的使用阈值,来判断节点磁盘空间的使用情况,进而确定是否需要增加额外的磁盘空间、当前应用程序的磁盘使用是否正常、是否需要对应用程序的磁盘使用进行调整等。
3.3 网络状态指标
对网络状态相关指标的监控,无论对于应用程序的通信还是安全,都有着重要的指示意义。 基于微服务架构的云原生应用,服务间的网络通信异常频繁,只有确保通信的正常,才能保证业务系统的顺畅运行。通过监控网络状态指标(比如,带宽、速率、连接状态等),及时的发现网络出现的问题,进而对问题进行定位、处置。另外,对网络状态的监控,除了能够发现并解决网络故障问题,还可以通过对网络状态数据进行分析,判断是否存在网络层的攻击发生,比如拒绝服务攻击的检测,再比如异常网络行为的检测等。
3.4 作业运行指标
除了对基本的基础设施资源进行监控外,我们还需要对正在运行的作业任务进行监控,保证任务的准确运行。Kubernetes 中,使用了Job 和CronJob 两个资源,来提供一次性任务和定时任务的特性,这两种资源使用控制器模型来实现资源的管理。Kubernetes 的 Job 可以创建并且保证一定数量Pod 的成功停止,当Job 持有的一个 Pod 对象成功完成任务之后,Job 就会记录这一次Pod 的成功运行。当一定数量的 Pod 任务执行结束之后,当前的 Job 就会将它自己的状态标记成结束。 基于这种机制,可以有效地对 Pod 进行管理和控制,同时对这些内容进行监控,也可以发现相关的问题,比如作业失败、崩溃循环、资源耗尽等。作业失败并不一定意味着应用程序变得不可访问,但是忽略作业失败可能会导致后续部署出现更严重的问题。密切监控作业失败可以帮助及时恢复,并在未来避免这些问题。 崩溃循环通常指,应用程序在 Pod 启动时崩溃,并在不断的崩溃和重新启动中循环。出现崩溃循环可能会有很多原因,通常很难确定根本原因。因此,实时对其进行监控,在发生崩溃循环时,可以快速告警,快速缩小原因列表,并采取紧急措施使应用程序处于正常状态。