本文永久链接: https://www.xtplayer.cn/rancher/rancher-logging-v2-collect-rke1-k8s-logs/

问题背景

rke1 创建的 k8s 集群,k8s 系统基础组件(比如 kubelet、etcd、kube-scheduler等)都是以 docker 容器方式部署。在使用 rancher v2.6+ 版本,建议升级 rancher logging 到 v2 版本。rancher logging 基于开源的 logging operator,对应的 git repo:https://github.com/kube-logging/logging-operator 和文档地址:https://kube-logging.dev/docs/

logging operator 默认只针对 k8s pod 日志和 k8s events,对于主机上 docker run 运行的容器日志不是很友好。因此针对这个问题,rancher 在原有的 logging operator 基础上增加了 rancher-logging-rke-aggregator DaemonSet 组件,用以搜集 rke1 k8s 系统基础组件容器日志。对应的 chart 配置 https://github.com/rancher/charts/tree/release-v2.8/charts/rancher-logging/103.1.2%2Bup4.4.0/templates/loggings/rke

但是在测试中发现, rancher-logging-rke-aggregator 搜集的日志只是 rke1 k8s 系统组件的原始日志,并没有 rke1 k8s 系统组件对应的标签等元数据,因此搜集到的日志无法进行区分是什么组件的日志。也因为没有标签等元数据,如果想把 rke1 k8s 发送到特有的 topic,那么在添加 ClusterFlows 或者 Flows 时将无法进行过滤。

解决方法

创建 HostTailer

针对以上日志无法区分的问题,可以考虑将 rke1 k8s 系统组件的原始日志文件挂载到某个容器中,然后再在容器中去打印这些日志,从而将这些日志转变为这个容器的标准输出日志。比如将 kubelet 容器日志挂载到名为 kubelet-log 的容器中,这样 logging operator 收集到 kubelet-log 这个容器的日志,也就表示搜集到 kubelet 的日志。

logging operator 支持 HostTailer 功能,配置好之后会自动创建一个 DaemonSet 服务,然后将预先配置的容器日志分别挂载到对应的容器中。可以参考以下配置,或者 https://kube-logging.dev/docs/configuration/extensions/kubernetes-host-tailer/

注意:

  1. /var/pos 目录为 fluent-bit 的索引 db 目录,默认是挂载到主机上用以持久化数据,以避免 pod 重启后重复打印日志,导致日志重复搜集。可以根据实际情况进行修改。
  2. /var/lib/docker docker root 目录,根据实际情况进行修改。
  3. 如果有节点打了污点,那么需要在 workloadOverrides 中添加 tolerations。
apiVersion: logging-extensions.banzaicloud.io/v1alpha1
kind: HostTailer
metadata:
name: rke1-k8s-system-component-logs
namespace: cattle-logging-system
spec:
fileTailers:
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
- mountPath: /var/pos
name: positions
name: etcd-log
path: /var/lib/rancher/rke/log/etcd_*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
- mountPath: /var/pos
name: positions
name: etcd-rolling-snapshots-log
path: /var/lib/rancher/rke/log/etcd-rolling-snapshots*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/pos
name: positions
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
name: kube-apiserver-log
path: /var/lib/rancher/rke/log/kube-apiserver*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/pos
name: positions
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
name: kube-controller-manager-log
path: /var/lib/rancher/rke/log/kube-controller-manager*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/pos
name: positions
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
name: kubelet-log
path: /var/lib/rancher/rke/log/kubelet*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/pos
name: positions
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
name: kube-proxy-log
path: /var/lib/rancher/rke/log/kube-proxy_*.log
- containerOverrides:
volumeMounts:
- mountPath: /var/lib/rancher
name: var-lib-rancher-rke-log
- mountPath: /var/pos
name: positions
- mountPath: /var/lib/docker
name: var-lib-docker-rke-log
name: kube-scheduler-log
path: /var/lib/rancher/rke/log/kube-scheduler_*.log
workloadOverrides:
# tolerations:
# - effect: string
# key: string
# operator: string
# tolerationSeconds: int
# value: string
volumes:
- hostPath:
path: /var/lib/rancher
name: var-lib-rancher-rke-log
- hostPath:
path: /var/lib/docker
name: var-lib-docker-rke-log
- hostPath:
path: /var/pos
name: positions

将以上配置导入 k8s 后,会在 cattle-logging-system 命名空间中创建 rke1-k8s-system-component-logs-host-tailer DaemonSet 。

为了避免日志重复发送,建议在 cluster tool 中编辑 rancher logging app,将 rke.enabled 设置为 false,这样将禁用 rancher-logging-rke-aggregator DaemonSet ,避免 rke1 系统组件日志被重复发送。

创建 ClusterOutputs 或者 Outputs

在 rancher ui 创建 ClusterOutputs 或者 Outputs,如果创建 Outputs,需要选择在 cattle-logging-system 命名空间。

创建 ClusterFlows 或者 Flows

在 rancher ui 创建 ClusterFlows 或者 Flows,如果创建 Flows,需要选择在 cattle-logging-system 命名空间。以 ClusterFlows 为例,如下图,在匹配中配置 仅限特定的容器名称,这样这个 ClusterFlows 或者 Flows 就只收集指定的容器日志。

结果

如果不经过以上方法处理,那么收集到 rke1 k8s 系统组件日志将如下图所示。没有组件对应的标签信息,无法判断对应什么组件。

经过处理之后,搜集到的 rke1 k8s 系统组件日志如下。其中的 “container name”:”kubelet-log” 则表示它对应 kubelet 的日志。