k8s-容器日志收集方法

168 阅读2分钟

cluster-level-logging

Kubernetes 里面对容器日志的处理方式,都叫作 cluster-level-logging, 即:这个日志处理系统,与容器、Pod 以及 Node 的生命周期都是完全无关的。

这种设计当然是为了保证,无论是容器挂了、Pod 被删除,甚至节点宕机的时候,应用的日志依然可以被正常获取到

当应用把日志输出到 stdout 和 stderr 之后,容器项目在默认情况下就会把这些日志输出到宿主机上的一个 JSON 文件里

如何去宿主机上查找pod日志?

方案一 在宿主机上采集pod日志

在 Node 上部署 logging agent,在宿主机上采集pod的日志 然后将日志文件转发到es/kafka

image.png

优点:

  • 在于一个节点只需要部署一个 agent
  • 并且不会对应用和 Pod 有任何侵入性

缺点

要求应用输出的日志,都必须是直接输出到容器的 stdout 和 stderr 里

方案二

容器输出的日志 是写到了文件中

通过sidecar 边车容器 读取 应用中的日志 然后输出到stdout 和 stderr 让宿主机上的log agent能够采集到

image.png

要求边车容器 和 应用容器 共享存储

边车容器可以读取到 应用容器中的日志文件

举例

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: {}

缺点:

  • sidecar容器会占用一些cpu 内存资源
  • 日志文件冗余了
    • 宿主机上存了一份
    • 应用容器中存了一份

方案三 直接通过sidecar 将日志发送到后端存储

image.png

声明一个 Fluentd 容器作为 sideca

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

把 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>