cluster-level-logging
Kubernetes 里面对容器日志的处理方式,都叫作 cluster-level-logging, 即:这个日志处理系统,与容器、Pod 以及 Node 的生命周期都是完全无关的。
这种设计当然是为了保证,无论是容器挂了、Pod 被删除,甚至节点宕机的时候,应用的日志依然可以被正常获取到
当应用把日志输出到 stdout 和 stderr 之后,容器项目在默认情况下就会把这些日志输出到宿主机上的一个 JSON 文件里
如何去宿主机上查找pod日志?
方案一 在宿主机上采集pod日志
在 Node 上部署 logging agent,在宿主机上采集pod的日志 然后将日志文件转发到es/kafka
优点:
- 在于一个节点只需要部署一个 agent
- 并且不会对应用和 Pod 有任何侵入性
缺点
要求应用输出的日志,都必须是直接输出到容器的 stdout 和 stderr 里
方案二
容器输出的日志 是写到了文件中
通过sidecar 边车容器 读取 应用中的日志 然后输出到stdout 和 stderr 让宿主机上的log agent能够采集到
要求边车容器 和 应用容器 共享存储
边车容器可以读取到 应用容器中的日志文件
举例
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 将日志发送到后端存储
声明一个 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>