k8s 日志

容器场景

  • 输 出到标准输出和标准错误输出

    输出到标准输出 和标 准错误输出的日志通常由容器引擎接管,并保存在容器运行 的 Node 上,例如 Docker 会被保存在 /var/lib/docker/containers 目录下 。 在 Kubernetes 中,用 户可以通过 kubectl logs 命令查看容器输出到 stdout 和 stderr 的日志

  • 输出到某个日志文件

    输出到文件中的日志,其保存位置依赖千容器应用使用的存储类型。需要将 日志待久化存储时 ,容器可以选择使 用 Kubernetes 提供的某种存储卷 (Volume),例如 hostpath (保存在 Node 上)、 nfs (保存 在 NFS 服务器上)、 PVC (保存在某种网络共享存储上)。保存在共享存储卷中的日志要求 容楛应用确保文件名或子目录名称不冲突。

  • 输出到某个外部系统。

    例如通过一个消息队列(如 Kafka) 转发到一个后端日志存储中心 。 在这种情况下,外部系统的搭建方式和应用程序 如何将日志输出到外部系统,应由容器应用程序的运维人员负责,不应由 Kubemetes 负责 。

系统组件场景

系统组件的日志可以通过–log-dir 参数保存到指定的目录下(例如 /var/log),或者通 过–logtostderr参数输出到标准错误输出中 ( stderr)。 如果系统管理员将这些服务配萱为 systemd 的系统服务,日志则会被 journald 系统保存。

Kubernetes 从 1.19 版本开始,开始引入对结构化日志的支待,使日志格式统一,便于 日志中字段的提取、保存和后续处理。结构化日志以 JSON 格式保存 。 目前 kube-apiserver、

kube-contraIIer-manager、 kube-scheduler 和 kubelet 这 4 个服务都支待通过启动参数 –logging-format=json 设 置 JSON 格式的日志,需要注意的是, JSON 格式的日志在启用 systemd 的系统中将被保存到 journald 中,在未使用 systemd 的系统中将在 /var/log 目录下 生成*log文件 ,不能再通过–log-dir参数指定保存目录 。

Kubernetes 应用 程序在生成 JSON 格 式 日 志时,可以设置的字段如下 。

  • ts : UNIX 格式的浮点数类型的时间戳(必填项)。
  • v: 日志级别,默认为 0 (必填项)。
  • msg: 日志信息(必 填项)。
  • err: 错误信息,字符串类型(可选项) 。

image-20221011213822956

Kubemetes 的审计 日 志可通过 kube-apiserver 服务的 –audit-log-*相关参数进行设置

  • 对于输出到主 机 ( Node ) 上的日志,管理员可以考虑在每个 Node 上都启动一个 日志采集工具,将日志采集后汇总到统一日志中 心 ,以供日志查询和分析
    • 对于容器输出到 stdout 和 stderr 的 日 志:管理员应该配置容器引擎(例如 Docker ) 对 日 志的轮转 ( rotate ) 策略,以免文件无限增长 , 将主机磁盘空间耗尽 。
    • 对于系统组件输出到主机 目录上( 如/var/log) 的日志,管理员应该配置各系统组 件日志的轮转 ( rotate ) 策略,以免文件无限增长等将主机磁盘空间耗尽。
    • 对千容器应用使用 hostpath 输出到 Node 上的 日 志 : 管理员应合理分配主机目录, 在满足容器应用存储空间需求的同时,可以考虑使用采集工具将日志采集并汇总 到统 一 的日志中心 , 并定时清理 Node 的 磁盘空间 。
  • 对于输出到容器 内 的日志,容器应 用 可以将日志直接输出到容祥环境内的某个目 录下,这可以减轻应用程序在共享存储中管理不同文件名或子目录的复杂度。在这种情况 下,管理员可以为应用容器提供一个日志采集的 sidecar 容器,对容器的日志进行采集, 并将其汇总到某个日志中心,供业务运维人员查询和分析。

    对于容器应用输出到容器目录下的日志,可以为业务应用容器配置一个日志采集 sidecar容器,对业 务 容器 生 成的日志进行采集并汇总到某个日志中心,供业务运维人员查 询和分析,这通常用于业务日志的采集和汇总 。

在 Kubemetes生态中,推荐采用 Fluentd+Elasticsearch+Kibana完成对系统组件和容器 日志的采集 、汇 总和查询的统一管理机制 。 下面对系统的部署和应用进行说明 。

image-20221011220538712

这里假设将 Kubernetes 系统组件的日志输出到/var/log 巨录下,容器输出到 stdout和 stderr 的日志由 Docker Server 保存在 /var/lib/docker/containers 目录下 。 我们通过在每个 Node 上都部署 一个 Fluentd 容器来采集本节点在这 两个目录 下 的日志文件,然后将其汇总 到 Elasticsearch 库中保存,用户通过 Kibana 提供的 Web 页面查询日志 。

审计机制

从 1.4 版本开始引入审计机制,主 要体 现为审计日志 (Audit Log)。 审计日志按照时间顺序记录了与安全相关的各种事件,这些 事件有助于系统管理员快速、集中了解发生了什么事情、作用于什么对象、在什么时间发 生、谁(从哪儿)触发的、在哪儿观察到的、活动的后续处理行为是怎样的,等等 。

image-20221013222304263

API Server 把客户端的请求 ( Request) 的处理流程视为 一 个”链条”,这个链条上的 每个“节点”就是一个状态 ( Stage),从开始到结束的所有 Request Stage 如下 :

  • RequestReceived: 在 Audit Handler 收到请求后生成的状态 。
  • ResponseStarted: 响应 Header 已经发送但 Body 还没有发送的 状态,仅对长期运行的请求 ( Long-running Requests) 有效,例如 Watch。
  • ResponseComplete: Body 已经发送完成 。
  • Panic: 严重错误 (Panic) 发生时的状态 。

从 1.7 版本开始引入高级审计特性 (AdvancedAuditing),可以自定义审计策略(选择记录哪些事件)和审计后端存储(日志和 Webhook) 等,开启方法为增加 kube-apiserver 的启动参数–feature-gates=AdvancedAuditing=true 。 注意:在开启 AdvancedAuditing 后 , 日志的格式有一些修改,例如新增了上述 Stage 信息 ; 从 Kubernets1.8 版本开始,该参数默认为 true。

image-20221013222947133

第 1 个匹 配的规则会决 定宙计日志的级别 (Audit Level),目前定义的几种级别如下(按级别从低到高排列)

  • None: 不生成审计日志
  • Metadata: 只记录 Request 请求的元数据如 requesting user、 timestamp、 resource、verb 等,但不记录请求及响应的具体内容。
  • Request: 记录 Request请求的元数据及请求的具体内容 。
  • RequestResponse: 记录事件的元数据,以及请求与应答的 具体内容。