乔克视界 乔克视界
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • Kubernetes
  • Prometheus
  • ELK
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档

乔克

云原生爱好者
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • Kubernetes
  • Prometheus
  • ELK
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档
  • Docker

  • Golang

  • AIOps

  • Python

  • DevOps

  • Kubernetes

  • Prometheus

  • ELK

    • 日志收集方案
      • 一、在 Node 上部署 logging agent
      • 二、sidecar 收集日志
      • 三、以 sidecar 运行 logging-agent
    • 日志系统搭建
    • 完整搭建
    • 部署 ECK(Elastic Cloud on Kubernetes)
    • 部署 log-pilot
    • elastic stack 搭建
    • 使用 helm 安装 es 和 kibana
    • elastic 账户认证 401 问题
  • 专栏
  • ELK
乔克
2025-07-20
目录

日志收集方案

在 kubernetes 中对日志的处理方式叫做 cluster-level-logging,即这个日志处理系统跟容器,Pod,Node 的生命周期无关,也就是无论是容器挂了,Pod 被删除了还是 Node 宕机了,应用的日志应该被正常获取到。

对于容器来说,当应用把日志输出到 stdout 和 stderr 中时,容器默认情况下就会把这些日志输出到宿主机上的一个 JSON 文件之中,同样我们也可以通过 docker logs 或者 kubectl logs 来查看到对应的日志信息。

但是 kubernetes 本身并不提供日志收集工作,但是它提供了三种方案。

# 一、在 Node 上部署 logging agent

这种方案的架构如下:

0bf89a2f3ceb48bb7e0295e7296d68eb MD5

这种架构的核心点就在 logging-agent,通常情况下它会一 DS 的方式运行在节点上,然后将宿主机的容器日志目录挂载进去,然后由 logging-agent 将日志收集转发出去。常用的方案有 EFK,即用 fluentd 作为上面的 logging-agent,然后将日志转发到远端的 ElasticSearch 中,然后由 kibana 进行展示。

这种方案的优点是只需要在节点部署一个 logging-agent,而且不会对应用和 Pod 有任何侵入性,但是其缺点就是必须要应用的日志输出必须输出到 stdout 和 stderr 中去。

# 二、sidecar 收集日志

由于第一种方式无法收集一些没有标准输出到 stdout 和 stderr 中,所以就有了第二种方式对这种特殊情况进行处理:当容器的日志只能输出到某些文件的时候,就可以通过一个 sidecar 容器把这些日志重新输出到 sidecar 的 stdout 和 stderr 中去,这样就可以继续使用第一种方案进行日志再处理。

其架构如下:

95f4633e33dd9b3780d502fa13d20e53 MD5

比如我有一个 pod,它会把日志输出到 1.log 和 2.log 的文件中,这个 Pod 的 YAML 文件如下:


apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

这种情况下,用 kubectl logs 是看不到任何日志的,所以第一种方法就没办法使用,那么这个时候我们就可以创建两个 sidecar 容器,分别将这两个日志输出到 stdout 和 stderr 中,这个 sidecar 的 YAML 文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
    - name: count
      image: busybox
      args:
        - /bin/sh
        - -c
        - >
          i=0;
          while true;
          do
            echo "$i: $(date)" >> /var/log/1.log;
            echo "$(date) INFO $i" >> /var/log/2.log;
            i=$((i+1));
            sleep 1;
          done
      volumeMounts:
        - name: varlog
          mountPath: /var/log
    - name: count-log-1
      image: busybox
      args: [/bin/sh, -c, "tail -n+1 -f /var/log/1.log"]
      volumeMounts:
        - name: varlog
          mountPath: /var/log
    - name: count-log-2
      image: busybox
      args: [/bin/sh, -c, "tail -n+1 -f /var/log/2.log"]
      volumeMounts:
        - name: varlog
          mountPath: /var/log
  volumes:
    - name: varlog
      emptyDir: {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

这时候分别通过 kubectl logs 查看这两个 sidecar 容器,就可以看到相应的日志内容了。

由于 sidecar 跟主容器是共享 volume 的,所以这里的 sidecar 方案其实并不会占用太多的资源。但是这种办法实际上是会存在两份文件,一份是系统自己写的文件,第二份是通过 sidecar 输出到 stdout 和 stderr 中所对应的 JSON 文件,多以对磁盘来说是一个大的开销。

# 三、以 sidecar 运行 logging-agent

这种方案就是直接在 sidecar 中运行 logging-agent,直接将日志转发到后端存储,也就是相当于在方案一中将 logging-agent 放到一个 Pod 中了,其架构如下:

abb27939b8ed33276ba2a31385065cfb MD5

在这个方案中,应用可以直接把日志输出到一个文件中,我们的 logging-agent 可以使用 fluentd 收集日志转发到后端 ElasticSearch 中,不过这里的输入源变成了日志文件。

一般来说,我们会把 fluentd 的输入源配置保存在 ConfigMap 中,如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluentd.conf: |
    <source>
      type tail
      format none
      path /var/log/1.log
      pos_file /var/log/1.log.pos
      tag count.format1
    </source>

    <source>
      type tail
      format none
      path /var/log/2.log
      pos_file /var/log/2.log.pos
      tag count.format2
    </source>

    <match **>
      type google_cloud
    </match>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

然后我们在 Pod 的定义里,就可以声明一个 Fluentd 的 sidecar,专门负责将日志转发到后端 ElasticSearch 中去。

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
    - name: count
      image: busybox
      args:
        - /bin/sh
        - -c
        - >
          i=0;
          while true;
          do
            echo "$i: $(date)" >> /var/log/1.log;
            echo "$(date) INFO $i" >> /var/log/2.log;
            i=$((i+1));
            sleep 1;
          done
      volumeMounts:
        - name: varlog
          mountPath: /var/log
    - name: count-agent
      image: k8s.gcr.io/fluentd-gcp:1.30
      env:
        - name: FLUENTD_ARGS
          value: -c /etc/fluentd-config/fluentd.conf
      volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: config-volume
          mountPath: /etc/fluentd-config
  volumes:
    - name: varlog
      emptyDir: {}
    - name: config-volume
      configMap:
        name: fluentd-config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

这样虽然更加灵活,但是在 sidecar 容器中运行日志采集代理程序会导致大量资源消耗,因为你有多少个要采集的 Pod,就需要运行多少个采集代理程序,另外还无法使用 kubectl logs 命令来访问这些日志,因为它们不受 kubelet 控制。

上次更新: 2025/07/20, 11:26:22
Kubernetes 性能指标
日志系统搭建

← Kubernetes 性能指标 日志系统搭建→

最近更新
01
elastic 账户认证 401 问题
07-20
02
使用 helm 安装 es 和 kibana
07-20
03
elastic stack 搭建
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 乔克 | MIT License | 渝ICP备20002153号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式