方案:
使用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
