fluentd收集k8s集群pod日志
方案:
使用fluentd部署在每个node节点上,通过配置node节点的标签可选择daemonset-fluentd部署在选定的node节点上
通过在每个pod打上logging:true标签,结合fluentd的containers.input.conf可以有选择的匹配想要过滤的pod日志,从而可以过滤proxy,flannel容器的日志
参考:
https://blog.51cto.com/xiaorenwutest/2500036
fluentd的comfigmap:
kind: ConfigMap apiVersion: v1 metadata: name: fluentd-config namespace: logging data: system.conf: |- <system> root_dir /tmp/fluentd-buffers/ </system> containers.input.conf: |- # 日志源配置 <source> @id fluentd-containers.log # 日志源唯一标识符,后面可以使用该标识符进一步处理 @type tail # Fluentd 内置的输入方式,其原理是不停地从源文件中获取新的日志。 path /var/log/containers/*.log # 挂载的服务器Docker容器日志地址 pos_file /var/log/es-containers.log.pos # 检查点 Fluentd重启后会从该文件中的位置恢复日志采集 tag raw.kubernetes.* # 设置日志标签 read_from_head true <parse> # 多行格式化成JSON @type multi_format # 使用 multi-format-parser 解析器插件 <pattern> format json # JSON解析器 time_key time # 指定事件时间的时间字段 time_format %Y-%m-%dT%H:%M:%S.%NZ # 时间格式 </pattern> <pattern> format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/ time_format %Y-%m-%dT%H:%M:%S.%N%:z </pattern> </parse> </source> <match raw.kubernetes.**> # 匹配tag为raw.kubernetes.**日志信息 @id raw.kubernetes @type detect_exceptions # 使用detect-exceptions插件处理异常栈信息 remove_tag_prefix raw # 移除 raw 前缀 message log stream stream multiline_flush_interval 5 max_bytes 500000 max_lines 1000 </match> <filter kubernetes.**> # 添加 Kubernetes metadata 数据 @id filter_kubernetes_metadata @type kubernetes_metadata </filter> <filter kubernetes.**> # 修复ES中的JSON字段 @id filter_parser @type parser # multi-format-parser多格式解析器插件 key_name log # 在要解析的记录中指定字段名称。 reserve_data true # 在解析结果中保留原始键值对。 remove_key_name_field true # key_name 解析成功后删除字段。 <parse> @type multi_format <pattern> format json </pattern> <pattern> format none </pattern> </parse> </filter> <filter kubernetes.**> # 删除一些多余的属性 @type record_transformer remove_keys $.docker.container_id,$.kubernetes.container_image_id,$.kubernetes.pod_id,$.kubernetes.namespace_id,$.kubernetes.master_url,$.kubernetes.labels.pod-template-hash </filter> <filter kubernetes.**> # 只采集具有logging=true标签的Pod日志 @id filter_log @type grep <regexp> key $.kubernetes.labels.logging pattern ^true$ </regexp> </filter> forward.input.conf: |- # 监听配置,一般用于日志聚合用 <source> @id forward @type forward </source> output.conf: |- # 路由配置,将处理后的日志数据发送到ES <match **> # 标识一个目标标签,后面是一个匹配日志源的正则表达式,我们这里想要捕获所有的日志并将它们发送给 Elasticsearch,所以需要配置成** @id elasticsearch # 目标的一个唯一标识符 @type elasticsearch # 支持的输出插件标识符,输出到 Elasticsearch @log_level info # 指定要捕获的日志级别,我们这里配置成 info,表示任何该级别或者该级别以上(INFO、WARNING、ERROR)的日志都将被路由到 Elsasticsearch。 include_tag_key true host elasticsearch # 定义 Elasticsearch 的地址 port 9200 logstash_format true # Fluentd 将会以 logstash 格式来转发结构化的日志数据 logstash_prefix k8s # 设置 index 前缀为 k8s request_timeout 30s <buffer> # Fluentd 允许在目标不可用时进行缓存 @type file path /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever retry_max_interval 30 chunk_limit_size 2M queue_limit_length 8 overflow_action block </buffer> </match>
fluentd的dameonset
apiVersion: v1 kind: ServiceAccount metadata: name: fluentd-es namespace: logging labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile rules: - apiGroups: - "" resources: - "namespaces" - "pods" verbs: - "get" - "watch" - "list" --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile subjects: - kind: ServiceAccount name: fluentd-es namespace: logging apiGroup: "" roleRef: kind: ClusterRole name: fluentd-es apiGroup: "" --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-es namespace: logging labels: k8s-app: fluentd-es version: v2.0.4 kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: k8s-app: fluentd-es version: v2.0.4 template: metadata: labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" version: v2.0.4 annotations: scheduler.alpha.kubernetes.io/critical-pod: '' spec: serviceAccountName: fluentd-es containers: - name: fluentd-es image: cnych/fluentd-elasticsearch:v2.0.4 env: - name: FLUENTD_ARGS value: --no-supervisor -q resources: limits: memory: 500Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: config-volume mountPath: /etc/fluent/config.d nodeSelector: #节点选择 beta.kubernetes.io/fluentd-ds-ready: "true" #节点需有这个标签才会部署收集 tolerations: #添加容忍 - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: config-volume configMap: name: fluentd-config