Kubernetes EFK 實(shí)戰(zhàn) - Flunt-Bit & Fluentd篇

準(zhǔn)備

環(huán)境規(guī)劃

有了上篇文章中的ElasticSearch集群,我們接下來(lái)就可以準(zhǔn)備日志數(shù)據(jù)采集的工作澎剥。業(yè)界推薦的最流行的有兩種:LogStash锡溯,F(xiàn)luentd。此文中哑姚,我們采用Kubernetes官方采用的Fluent體系中的組件:Fluent Bit 和 Fluentd.
所有的組件有:

組件 用途
Fluent Bit 拉起在每臺(tái)宿主機(jī)上采集宿主機(jī)上的容器日志祭饭。(Fluent Bit 比較新一些,但是資源消耗比較低蜻懦,性能比Fluentd好一些甜癞,但穩(wěn)定性有待于進(jìn)一步提升)
Fluentd 兩個(gè)用途:1 以日志收集中轉(zhuǎn)中心角色拉起,Deployment部署模式宛乃;2 在部分Fluent Bit無(wú)法正常運(yùn)行的主機(jī)上悠咱,以Daemon Set模式運(yùn)行采集宿主機(jī)上的日志,并發(fā)送給日志收集中轉(zhuǎn)中心
ElasticSearch 用來(lái)接收日志收集中轉(zhuǎn)中心發(fā)送過來(lái)的日志征炼,并通過Kibana分析展示出來(lái)析既,鑒于硬件資源有限,僅保留一周左右的數(shù)據(jù)谆奥。
Amazon S3 用來(lái)接收日志收集中轉(zhuǎn)中心發(fā)送過來(lái)的日志,對(duì)日志進(jìn)行壓縮歸檔酸些,也可后續(xù)使用Spark進(jìn)行進(jìn)一步大數(shù)據(jù)分析宰译。

部署架構(gòu)

image.png

此圖中,僅作描述Flunt-Bit 和Fluentd的采集集成魄懂,ES集群的部署架構(gòu)沿侈,和Kubernetes微服務(wù)整體的集群架構(gòu),不在此圖詳述市栗,有興趣缀拭,可參考本人的其它文章。

日志集中中轉(zhuǎn)代理中心

當(dāng)服務(wù)節(jié)點(diǎn)比較多的時(shí)候填帽,推薦使用集中中轉(zhuǎn)代理中心進(jìn)行初步的匯集轉(zhuǎn)送蛛淋,如果節(jié)點(diǎn)數(shù)沒那么多,可以直接由Node發(fā)送到ES或者S3篡腌。

Docker鏡像準(zhǔn)備

由于我們的日志集中中轉(zhuǎn)代理中心需要將日志采集點(diǎn)采集過來(lái)的日志轉(zhuǎn)發(fā)到兩個(gè)地方:ElasticSearch和Amazon S3褐荷,所以需要對(duì)我們創(chuàng)建的Fluentd的鏡像進(jìn)行再次處理。
鑒于Kubernetes官網(wǎng)提供的有EFK的現(xiàn)成方案嘹悼,我們就在這個(gè)方案基礎(chǔ)上進(jìn)行調(diào)整诚卸,使其滿足我們自身的需求葵第。

獲取Kubernetes官網(wǎng)的Fluentd的配置信息

[centos@master1 efk]$ wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml
--2018-06-08 17:46:35--  https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.72.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.72.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2774 (2.7K) [text/plain]
Saving to: ‘fluentd-es-ds.yaml’

fluentd-es-ds.yaml   100%[===================>]   2.71K  --.-KB/s    in 0s

2018-06-08 17:46:36 (8.56 MB/s) - ‘fluentd-es-ds.yaml’ saved [2774/2774]

[centos@master1 efk]$

打開該文件fluentd-es-ds.yaml,獲得官方使用的Docker鏡像合溺。

......
      - name: fluentd-es
        image: k8s.gcr.io/fluentd-elasticsearch:v2.0.4
        env:
......

在本地將該鏡像pull下來(lái)卒密,tag到本地Repo,并推送到私有Repo棠赛,以便方便獲取哮奇。此處需要科學(xué)上網(wǎng),并將docker的代理加上睛约。

[centos@master1 efk]$ docker pull k8s.gcr.io/fluentd-elasticsearch:v2.0.4
Trying to pull repository k8s.gcr.io/fluentd-elasticsearch ... 
v2.0.4: Pulling from k8s.gcr.io/fluentd-elasticsearch
e7bb522d92ff: Pull complete 
92e6b816bc34: Pull complete 
ffb38dbddc64: Pull complete 
4900a3591877: Pull complete 
812a2bf6252f: Pull complete 
f8d5892f0b74: Pull complete 
e6736dda51ce: Pull complete 
Digest: sha256:b8c94527b489fb61d3d81ce5ad7f3ddbb7be71e9620a3a36e2bede2f2e487d73
Status: Downloaded newer image for k8s.gcr.io/fluentd-elasticsearch:v2.0.4
[centos@master1 efk]$ docker tag k8s.gcr.io/fluentd-elasticsearch:v2.0.4 hub.***.***/google_containers/fluentd-elasticsearch:v2.1.0
[centos@master1 efk]$ docker push hub.***.***/google_containers/fluentd-elasticsearch:v2.1.0

增加Amazon S3的支持

基于Kubernetes鏡像添加對(duì)S3的支持鼎俘,新建Dockerfile,內(nèi)容如下:

FROM hub.***.***/google_containers/fluentd-elasticsearch:v2.1.0
MAINTAINER X.J CHEN
RUN \
    apt-get update -y && apt-get install ruby-dev -y && \
    gem install fluent-plugin-s3 && \
    apt-get clean

編譯該鏡像辩涝,并上傳到我們私庫(kù)贸伐。

[centos@master1 efk] docker build -t hub.***.***/google_containers/fluentd-s3:v2.1.0 .
[centos@master1 efk] docker push hub.***.***/google_containers/fluentd-s3:v2.1.0

至此,我們的鏡像已準(zhǔn)備完畢怔揩。

Server Yaml文件準(zhǔn)備

參考上小節(jié)獲取的fluentd-es-ds.yaml捉邢,創(chuàng)建我們的Fluentd Server Yaml文件fluentd-server-s3.yaml,具體內(nèi)容如:
調(diào)整內(nèi)容主要有:

  • 更改ServiceAccount及相關(guān)的Rule商膊。
  • 更改鏡像為我們新Build的鏡像伏伐。
  • 刪除var log等讀取本地日志參數(shù)的路徑。
  • Replicas設(shè)置為5晕拆,這個(gè)主要是由于我們的環(huán)境生成日志量太大藐翎,該值可以依據(jù)自身的實(shí)際情況來(lái)決定Pod的個(gè)數(shù),推薦最少2個(gè)实幕。
  • 增加Fluent Server的Service吝镣,以供Kubernetes集群內(nèi)日志采集節(jié)點(diǎn)訪問上傳自己的日志。
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd-server
  namespace: kube-system
  labels:
    k8s-app: fluentd-server
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd-server
  labels:
    k8s-app: fluentd-server
    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-server
  labels:
    k8s-app: fluentd-server
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
subjects:
- kind: ServiceAccount
  name: fluentd-server
  namespace: kube-system
  apiGroup: ""
roleRef:
  kind: ClusterRole
  name: fluentd-server
  apiGroup: ""

---
apiVersion: v1
kind: Service
metadata:
  name: fluentd-server
  namespace: kube-system
  labels:
    k8s-app: fluentd-server
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "Flunetd"
spec:
  ports:
  - port: 24224
    protocol: TCP
    targetPort: server
  selector:
    k8s-app: fluentd-server
    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fluentd-server-v2.0.4
  namespace: kube-system
  labels:
    k8s-app: fluentd-server
    version: v2.0.4
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-server
      version: v2.0.4
  replicas: 5
  template:
    metadata:
      labels:
        k8s-app: fluentd-server
        kubernetes.io/cluster-service: "true"
        version: v2.0.4
    spec:
      serviceAccountName: fluentd-server
      containers:
      - name: fluentd-server
        #image: k8s.gcr.io/fluentd-elasticsearch:v2.0.4
        image: hub.***.***/google_containers/fluentd-s3:v2.1.0
        imagePullPolicy: Always
        env:
        - name: FLUENTD_ARGS
          value: --no-supervisor -q
        resources:
          limits:
            memory: 1024Mi
          requests:
            cpu: 1000m
            memory: 200Mi
        volumeMounts:
        - name: config-volume
          mountPath: /etc/fluent/config.d
        ports:
        - containerPort: 24224
          name: server
          protocol: TCP
      terminationGracePeriodSeconds: 160
      volumes:
      - name: config-volume
        configMap:
          name: fluentd-server-config-v0.1.4
      imagePullSecrets:
      - name: kube-sec

從Kubernetes官方獲取Fluentd的配置文件昆庇。

[centos@master1 efk]  wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-configmap.yaml

并在此基礎(chǔ)上末贾,創(chuàng)建我們自己的配置文件fluentd-server-s3-configmap.yaml,具體內(nèi)容如下:
主要調(diào)整內(nèi)容:

  • 刪除日志采集部分片段凰锡。
  • 增加Forward Input片段,增加Server的Host和監(jiān)聽信息圈暗。
  • 調(diào)整Output片段掂为。
  • 請(qǐng)注意,ES和S3兩個(gè)Output我們均有采用Buffer员串,均為文件Buffer勇哗。由于我們的Deployment中移除了Host 的Var log,此處Buffer緩存將會(huì)存在Docker 容器中寸齐,容器掛掉后欲诺,緩存的數(shù)據(jù)將丟失抄谐,請(qǐng)依據(jù)自身的實(shí)際情況調(diào)整(如果對(duì)數(shù)據(jù)特別敏感,甚至可以用StatetefulSet來(lái)創(chuàng)建PV)扰法。
kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-server-config-v0.1.4
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
data:
  system.conf: |-
    <system>
      root_dir /tmp/fluentd-buffers/
    </system>

  system.input.conf: |-
    # Listen to incoming data over SSL
    <source>
      @type forward
      port 24224
      bind 0.0.0.0
    </source>

  output.conf: |-
    # Enriches records with Kubernetes metadata
    <filter kubernetes.**>
      @type kubernetes_metadata
    </filter>
    # Store Data in Elasticsearch and S3
    <match *.**>
      @type copy
      <store>
        @id elasticsearch
        @type elasticsearch
        @log_level info
        host elasticsearch
        port 9200
        #include_tag_key true
        #tag_key @log_name
        logstash_format true
        request_timeout    30s
        slow_flush_log_threshold 30s
        <buffer>
          @type file
          path /var/log/fluentd-buffers/server.buffer
          flush_mode interval
          #retry_type exponential_backoff
          flush_thread_count 12 # 可以根據(jù)實(shí)際需要也需兼顧下ES的處理能力進(jìn)行調(diào)整
          flush_interval 8s  # 可以根據(jù)實(shí)際需要進(jìn)行調(diào)整
          retry_max_interval 30
          chunk_limit_size 32M # 可以根據(jù)ES實(shí)際處理能力進(jìn)行調(diào)整蛹含,務(wù)必<100MB 
          #queue_limit_length 64 #8
          total_limit_size 20G
          retry_wait 10s
        </buffer>
      </store>
      <store>
        @id s3
        @type s3
        @log_level info
        #include_tag_key true
        aws_key_id *********  # 請(qǐng)?zhí)顚懽陨淼膋ey id和sec key
        aws_sec_key **********
        s3_bucket ******** #請(qǐng)?zhí)顚懽陨淼腂ucket
        s3_region cn-north-1
        s3_object_key_format "%{path}dt=%{time_slice}_%{index}.%{file_extension}"
        #store_as json
        path hive/    
        time_slice_format %Y%m%d/%Y%m%d%H
        <buffer>
          @type file
          path /var/log/fluentd-buffers/s3.buffer
          timekey 3600 # 1 hour partition
          timekey_wait 10m
          timekey_use_utc true # use utc
          chunk_limit_size 256m
        </buffer>
      </store>
    </match>

拉起Aggregation Server

創(chuàng)建Server的配置聂儒。

[centos@master1 efk]$ kubectl create -f fluentd-server-s3-configmap.yaml

創(chuàng)建Server的Deployment脏里。

[centos@master1 efk]$ kubectl create -f fluentd-server-s3.yaml 

檢查Server的啟動(dòng)狀態(tài):

[centos@master1 efk]$ kubectl get service -n kube-system -o wide | grep fluentd-server
fluentd-server            ClusterIP   10.104.52.1      <none>        24224/TCP        4d        k8s-app=fluentd-server
[centos@master1 efk]$ 
[centos@master1 efk]$ kubectl get pods -n kube-system -o wide | grep fluentd-server
fluentd-server-v2.0.4-855db7cfc5-4wn47   1/1       Running            0          2h        10.244.29.20     minion6
fluentd-server-v2.0.4-855db7cfc5-pfmvd   1/1       Running            0          2h        10.244.3.211     minion17
fluentd-server-v2.0.4-855db7cfc5-rjqxl   1/1       Running            0          2h        10.244.13.47     minion19
fluentd-server-v2.0.4-855db7cfc5-shjfm   1/1       Running            0          2h        10.244.23.141    minion12
fluentd-server-v2.0.4-855db7cfc5-w7m5f   1/1       Running            0          2h        10.244.30.233    minion5
[centos@master1 efk]$ 

也可以查看下日志:


image.png

日志Agent

日志的Agent,我們使用的是Fluent Bit制妄,原因還是那句:性能相較Fluentd稍好祠锣,消耗資源要少一些酷窥。但是鑒于Fluent Bit 的穩(wěn)定性,有部分節(jié)點(diǎn)無(wú)法正常運(yùn)行(有些是日志無(wú)法解析造成的伴网,也有其它原因蓬推,由于太久沒接觸過C和C++,有時(shí)只能等待官方補(bǔ)对杼凇)沸伏,也有部分節(jié)點(diǎn)可能會(huì)運(yùn)行一段時(shí)間崩潰的情況。所以對(duì)于日志要求比較高的場(chǎng)景蛋铆,還是推薦使用Fluentd馋评。
常見的Fluent Bit的異常,該異常是由于日志文件Json解析異常直接導(dǎo)致Fluent Bit崩潰刺啦,號(hào)稱在0.13.3版本中解決,問題依舊:

[centos@master1 fluent-bit]$ 
[centos@master1 fluent-bit]$ kubectl logs -f fluent-bit-5kvpl -n kube-system
[2018/06/11 03:11:49] [ info] [engine] started (pid=1)
[2018/06/11 03:11:49] [ info] [filter_kube] https=1 host=kubernetes.default.svc.cluster.local port=443
[2018/06/11 03:11:49] [ info] [filter_kube] local POD info OK
[2018/06/11 03:11:49] [ info] [filter_kube] testing connectivity with API server...
[2018/06/11 03:11:49] [ info] [filter_kube] API server connectivity OK
[2018/06/11 03:11:49] [ info] [http_server] listen iface=0.0.0.0 tcp_port=2020
[engine] caught signal (SIGSEGV)
Fluent-Bit v0.13.2
Copyright (C) Treasure Data

#0  0x7fcc07f6eff1      in  ???() at ???:0
#1  0x55b0b655dede      in  msgpack_sbuffer_write() at lib/msgpack-2.1.3/include/msgpack/sbuffer.h:84
#2  0x55b0b6771ca5      in  msgpack_pack_ext_body() at lib/msgpack-2.1.3/include/msgpack/pack_template.h:890
#3  0x55b0b6771ca5      in  msgpack_pack_object() at lib/msgpack-2.1.3/src/objectc.c:72
#4  0x55b0b655e8c0      in  pack_map_content() at plugins/filter_kubernetes/kubernetes.c:321
#5  0x55b0b655f129      in  cb_kube_filter() at plugins/filter_kubernetes/kubernetes.c:493
#6  0x55b0b64feaea      in  flb_filter_do() at src/flb_filter.c:86
#7  0x55b0b64fc53c      in  flb_input_dbuf_write_end() at include/fluent-bit/flb_input.h:642
#8  0x55b0b64fe09c      in  flb_input_dyntag_append_raw() at src/flb_input.c:894
#9  0x55b0b6522b1d      in  process_content() at plugins/in_tail/tail_file.c:290
#10 0x55b0b6523968      in  flb_tail_file_chunk() at plugins/in_tail/tail_file.c:651
#11 0x55b0b6521357      in  in_tail_collect_static() at plugins/in_tail/tail.c:129
#12 0x55b0b64fe5db      in  flb_input_collector_fd() at src/flb_input.c:995
#13 0x55b0b6505370      in  flb_engine_handle_event() at src/flb_engine.c:296
#14 0x55b0b6505370      in  flb_engine_start() at src/flb_engine.c:515
#15 0x55b0b64a5606      in  main() at src/fluent-bit.c:824
#16 0x7fcc07e662e0      in  ???() at ???:0
#17 0x55b0b64a3a89      in  ???() at ???:0
#18 0xffffffffffffffff  in  ???() at ???:0
[centos@master1 fluent-bit]$ 

我們下面對(duì)于Fluent Bit和Fluentd的使用都將描述玛瘸,以供大家參考蜕青。

Fluent Bit

準(zhǔn)備Fluent Bit Yaml文件

我們參考https://github.com/fluent/fluent-bit-kubernetes-logging來(lái)整理我們自己的Fluent Bit相關(guān)Yaml文件。

[centos@master1 kube-log]$ git clone https://github.com/fluent/fluent-bit-kubernetes-logging.git

Fluent Bit 配置文件

我們還將繼續(xù)使用fluent-bit-configmap.yaml來(lái)作為我們的Fluent Bit的配置文件糊渊,不過要增加Forward組件右核,以使得Fluent Bit能夠正常的將日志轉(zhuǎn)發(fā)至日志集中中轉(zhuǎn)代理中心。

  • 增加output-fluentd.conf 片段渺绒,輸出到Fluent Server贺喝。
  • 去掉輸出到ES的配置片段。
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: kube-system
  labels:
    k8s-app: fluent-bit
data:
  # Configuration files: server, input, filters and output
  # ======================================================
  fluent-bit.conf: |
    [SERVICE]
        Flush         1
        Log_Level     info
        Daemon        off
        Parsers_File  parsers.conf
        HTTP_Server   On
        HTTP_Listen   0.0.0.0
        HTTP_Port     2020

    @INCLUDE input-kubernetes.conf
    @INCLUDE filter-kubernetes.conf
    @INCLUDE output-fluentd.conf
    # @INCLUDE output-elasticsearch.conf

  input-kubernetes.conf: |
    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            docker
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  5

  filter-kubernetes.conf: |
    [FILTER]
        Name                kubernetes
        Match               kube.*
        Kube_URL            https://kubernetes.default.svc.cluster.local:443
        Merge_Log           On
        K8S-Logging.Parser  On

  output-elasticsearch.conf: |
    [OUTPUT]
        Name            es
        Match           *
        Host            ${FLUENT_ELASTICSEARCH_HOST}
        Port            ${FLUENT_ELASTICSEARCH_PORT}
        Logstash_Format On
        Retry_Limit     False

  output-fluentd.conf: |
    [OUTPUT]
        Name          forward
        Match         *
        Host          ${FLUENTD_SERVER_HOST}
        Port          ${FLUENTD_SERVER_PORT}
        
  parsers.conf: |
    [PARSER]
        Name   apache
        Format regex
        Regex  ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
        Time_Key time
        Time_Format %d/%b/%Y:%H:%M:%S %z

    [PARSER]
        Name   apache2
        Format regex
        Regex  ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
        Time_Key time
        Time_Format %d/%b/%Y:%H:%M:%S %z

    [PARSER]
        Name   apache_error
        Format regex
        Regex  ^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])?( \[client (?<client>[^\]]*)\])? (?<message>.*)$

    [PARSER]
        Name   nginx
        Format regex
        Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
        Time_Key time
        Time_Format %d/%b/%Y:%H:%M:%S %z

    [PARSER]
        Name   json
        Format json
        Time_Key time
        Time_Format %d/%b/%Y:%H:%M:%S %z

    [PARSER]
        Name        docker
        Format      json
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L
        Time_Keep   On
        # Command      |  Decoder | Field | Optional Action
        # =============|==================|=================
        Decode_Field_As   escaped    log

    [PARSER]
        Name        syslog
        Format      regex
        Regex       ^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$
        Time_Key    time
        Time_Format %b %d %H:%M:%S

Fluent Bit Pod配置

我們將官方的相關(guān)Pod的各種配置(fluent-bit-service-account.yaml宗兼,fluent-bit-role.yaml躏鱼,fluent-bit-role-binding.yaml)整合到一個(gè)文件中(fluent-bit-ds.yaml)以便方便維護(hù)。

  • 更改Docker鏡像的Repo到我們的私庫(kù)殷绍。我們將原有的鏡像pull下來(lái)染苛,不做任何更改,tag并push到私庫(kù)主到。
  • 增加Fluentd Server的環(huán)境變量茶行。
  • 請(qǐng)注意nodeSelector片段躯概,需要將具備日志搜集的節(jié)點(diǎn)加上該標(biāo)簽。推薦一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)加(一兩個(gè)節(jié)點(diǎn)相隔幾分鐘畔师,也可以用腳本來(lái)實(shí)現(xiàn)娶靡,當(dāng)日志量比較大的時(shí)候,強(qiáng)烈推薦這么做茉唉,血淋淋的教訓(xùn))固蛾,批量加可能會(huì)造成數(shù)據(jù)風(fēng)暴,導(dǎo)致中轉(zhuǎn)中心處理不過來(lái)度陆,也會(huì)導(dǎo)致ES處理不過來(lái)而拒掉Fluentd的鏈接艾凯。
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluent-bit
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: fluent-bit-read
rules:
- apiGroups: [""]
  resources:
  - namespaces
  - pods
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fluent-bit-read
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluent-bit-read
subjects:
- kind: ServiceAccount
  name: fluent-bit
  namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: kube-system
  labels:
    k8s-app: fluent-bit-logging
    version: v1
    kubernetes.io/cluster-service: "true"
spec:
  template:
    metadata:
      labels:
        k8s-app: fluent-bit-logging
        version: v1
        kubernetes.io/cluster-service: "true"
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "2020"
        prometheus.io/path: /api/v1/metrics/prometheus
    spec:
      nodeSelector:
        beta.kubernetes.io/fluentd-ds-ready: "true"
      containers:
      - name: fluent-bit
        image: hub.***.***/google_containers/fluent-bit:0.13.2
        imagePullPolicy: Always
        ports:
          - containerPort: 2020
        env:
        - name: FLUENTD_SERVER_HOST
          value: "fluentd-server"
        - name: FLUENTD_SERVER_PORT
          value: "24224"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: fluent-bit-config
          mountPath: /fluent-bit/etc/
      terminationGracePeriodSeconds: 10
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: fluent-bit-config
        configMap:
          name: fluent-bit-config
      serviceAccountName: fluent-bit
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      imagePullSecrets:
      - name: kube-sec

拉起Fluent Bit DaemonSet

創(chuàng)建Fluent Bit所需的配置。

[centos@master1 fluent-bit]$ ls -al
total 28
drwxrwxr-x 2 centos centos 4096 Jun  7 02:32 .
drwxrwxr-x 7 centos centos 4096 Jun 11 03:03 ..
-rw-rw-r-- 1 centos centos 3562 Jun  7 02:32 fluent-bit-configmap.yaml
-rw-rw-r-- 1 centos centos 2248 Jun  6 12:51 fluent-bit-ds.yaml
-rw-rw-r-- 1 centos centos  273 May 31 13:35 fluent-bit-role-binding.yaml
-rw-rw-r-- 1 centos centos  194 May 31 13:33 fluent-bit-role.yaml
-rw-rw-r-- 1 centos centos   90 May 31 13:35 fluent-bit-service-account.yaml
[centos@master1 fluent-bit]$ 
[centos@master1 fluent-bit]$ kubectl create -f fluent-bit-configmap.yaml

拉起Fluent Bit的Daemon Set懂傀。

[centos@master1 fluent-bit]$ kubectl create -f fluent-bit-ds.yaml

檢查Pod趾诗,此時(shí)會(huì)發(fā)現(xiàn)

[centos@master1 fluent-bit]$ kubectl get pods -n kube-system -o wide | grep fluent-bit
[centos@master1 fluent-bit]$

不要緊張,我們接下來(lái)就要對(duì)Node打label蹬蚁,這樣就會(huì)拉起來(lái)了恃泪,中間注意間隔點(diǎn)時(shí)間。

[centos@master1 fluent-bit]$ kubectl label node minion1 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 fluent-bit]$ kubectl label node minion2 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 fluent-bit]$ kubectl label node minion3 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 fluent-bit]$ kubectl label node minion4 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 fluent-bit]$ kubectl label node minion5 beta.kubernetes.io/fluentd-ds-ready=true
.....

我們?cè)贆z查節(jié)點(diǎn)被拉起狀態(tài):

[centos@master1 fluent-bit]$ kubectl get pods -n kube-system -o wide | grep flu
fluent-bit-2sd9k                         1/1       Running   0          4d        10.244.30.213    minion5
fluent-bit-5jd4w                         1/1       Running   0          4d        10.244.32.12     minion3
fluent-bit-952fn                         1/1       Running   0          4d        10.244.15.14     minion13
fluent-bit-cz2xq                         1/1       Running   0          4d        10.244.29.250    minion6
fluent-bit-fx22k                         1/1       Running   0          4d        10.244.25.235    minion10
fluent-bit-g4fmw                         1/1       Running   0          4d        10.244.23.99     minion12
fluent-bit-gnfxg                         1/1       Running   0          4d        10.244.28.207    minion7
fluent-bit-h9t9l                         1/1       Running   0          4d        10.244.11.91     minion22
fluent-bit-ld9fx                         1/1       Running   0          4d        10.244.3.191     minion17
fluent-bit-pgc2f                         1/1       Running   0          4d        10.244.14.48     minion20
fluent-bit-st2qq                         1/1       Running   0          3d        10.244.16.3      minion11
fluent-bit-tm5hl                         1/1       Running   0          4d        10.244.12.46     minion18
fluent-bit-tt44q                         1/1       Running   0          4d        10.244.21.24     minion14
fluent-bit-vgptk                         1/1       Running   0          4d        10.244.31.9      minion4
fluent-bit-vptft                         1/1       Running   0          4d        10.244.34.93     minion1
fluent-bit-wpwl4                         1/1       Running   0          4d        10.244.13.35     minion19
fluent-bit-xdvbz                         1/1       Running   0          4d        10.244.9.99      minion2
fluent-bit-zrmsj                         1/1       Running   0          4d        10.244.20.33     minion15

我們查看Kibana來(lái)確定下日志傳輸情況:


image.png

我們發(fā)現(xiàn)日志已傳輸?shù)紼S犀斋,我們接下來(lái)對(duì)Kibana稍微調(diào)整下顯示的Fields贝乎,更能滿足我們查看日志的需要。

  • 增加Host到顯示列表叽粹。
  • 增加Pod Name到顯示列表览效。
  • 增加Log到顯示列表。
image.png

我們接下來(lái)挨個(gè)主機(jī)查看下日志情況:

  • 增加輸入條件虫几,查詢節(jié)點(diǎn)的日志锤灿。
image.png

我們會(huì)發(fā)現(xiàn)每個(gè)主機(jī)的日志已正常的傳遞到ES,那我們接下來(lái)再檢查下S3辆脸。
我們會(huì)發(fā)現(xiàn)但校,日志已按照我們既定的目錄規(guī)則創(chuàng)建出來(lái)。


image.png

點(diǎn)開某一個(gè)目錄啡氢,則可以發(fā)現(xiàn)文件已存在状囱,亦可以下載到本地,進(jìn)行再次查看倘是,不問不再做論述亭枷。

image.png

至此,F(xiàn)luent Bit部署已完成辨绊,在拉起Fluent Bit的過程中奶栖,會(huì)有部分節(jié)點(diǎn)Crash匹表,無(wú)法正常拉起门坷。接下來(lái)這些節(jié)點(diǎn)宣鄙,我們將采用Fluentd來(lái)進(jìn)行日志的采集。

Fluentd

我們參考Fluentd Server章節(jié)中的描述默蚌,來(lái)準(zhǔn)備Fluentd的拉起冻晤。Fluentd的Docker文件可以和Server章節(jié)中使用的一致。

準(zhǔn)備Fluentd Yaml文件

Fluentd 配置文件

我們新建一文件fluentd-standalone-configmap.yaml绸吸,用來(lái)Fluentd的獨(dú)立運(yùn)行鼻弧。

  • 調(diào)整output.conf。
  • 移除ES片段锦茁。
  • 添加forward片段攘轩。
kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-sa-config-v0.1.4
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
data:
  system.conf: |-
    <system>
      root_dir /tmp/fluentd-buffers/
    </system>

  containers.input.conf: |-
    # This configuration file for Fluentd / td-agent is used
    # to watch changes to Docker log files. The kubelet creates symlinks that
    # capture the pod name, namespace, container name & Docker container ID
    # to the docker logs for pods in the /var/log/containers directory on the host.
    # If running this fluentd configuration in a Docker container, the /var/log
    # directory should be mounted in the container.
    #
    # These logs are then submitted to Elasticsearch which assumes the
    # installation of the fluent-plugin-elasticsearch & the
    # fluent-plugin-kubernetes_metadata_filter plugins.
    # See https://github.com/uken/fluent-plugin-elasticsearch &
    # https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter for
    # more information about the plugins.
    #
    # Example
    # =======
    # A line in the Docker log file might look like this JSON:
    #
    # {"log":"2014/09/25 21:15:03 Got request with path wombat\n",
    #  "stream":"stderr",
    #   "time":"2014-09-25T21:15:03.499185026Z"}
    #
    # The time_format specification below makes sure we properly
    # parse the time format produced by Docker. This will be
    # submitted to Elasticsearch and should appear like:
    # $ curl 'http://elasticsearch-logging:9200/_search?pretty'
    # ...
    # {
    #      "_index" : "logstash-2014.09.25",
    #      "_type" : "fluentd",
    #      "_id" : "VBrbor2QTuGpsQyTCdfzqA",
    #      "_score" : 1.0,
    #      "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n",
    #                 "stream":"stderr","tag":"docker.container.all",
    #                 "@timestamp":"2014-09-25T22:45:50+00:00"}
    #    },
    # ...
    #
    # The Kubernetes fluentd plugin is used to write the Kubernetes metadata to the log
    # record & add labels to the log record if properly configured. This enables users
    # to filter & search logs on any metadata.
    # For example a Docker container's logs might be in the directory:
    #
    #  /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b
    #
    # and in the file:
    #
    #  997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
    #
    # where 997599971ee6... is the Docker ID of the running container.
    # The Kubernetes kubelet makes a symbolic link to this file on the host machine
    # in the /var/log/containers directory which includes the pod name and the Kubernetes
    # container name:
    #
    #    synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
    #    ->
    #    /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
    #
    # The /var/log directory on the host is mapped to the /var/log directory in the container
    # running this instance of Fluentd and we end up collecting the file:
    #
    #   /var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
    #
    # This results in the tag:
    #
    #  var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
    #
    # The Kubernetes fluentd plugin is used to extract the namespace, pod name & container name
    # which are added to the log message as a kubernetes field object & the Docker container ID
    # is also added under the docker field object.
    # The final tag is:
    #
    #   kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
    #
    # And the final log record look like:
    #
    # {
    #   "log":"2014/09/25 21:15:03 Got request with path wombat\n",
    #   "stream":"stderr",
    #   "time":"2014-09-25T21:15:03.499185026Z",
    #   "kubernetes": {
    #     "namespace": "default",
    #     "pod_name": "synthetic-logger-0.25lps-pod",
    #     "container_name": "synth-lgr"
    #   },
    #   "docker": {
    #     "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b"
    #   }
    # }
    #
    # This makes it easier for users to search for logs by pod name or by
    # the name of the Kubernetes container regardless of how many times the
    # Kubernetes pod has been restarted (resulting in a several Docker container IDs).

    # Json Log Example:
    # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
    # CRI Log Example:
    # 2016-02-17T00:04:05.931087621Z stdout F [info:2016-02-16T16:04:05.930-08:00] Some log text here
    <source>
      @id fluentd-containers.log
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/es-containers.log.pos
      time_format %Y-%m-%dT%H:%M:%S.%NZ
      tag raw.kubernetes.*
      read_from_head true
      <parse>
        @type multi_format
        <pattern>
          format 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>

    # Detect exceptions in the log output and forward them as one log entry.
    <match raw.kubernetes.**>
      @id raw.kubernetes
      @type detect_exceptions
      remove_tag_prefix raw
      message log
      stream stream
      multiline_flush_interval 5
      max_bytes 500000
      max_lines 1000
    </match>

  system.input.conf: |-
    # Example:
    # 2015-12-21 23:17:22,066 [salt.state       ][INFO    ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081
    <source>
      @id minion
      @type tail
      format /^(?<time>[^ ]* [^ ,]*)[^\[]*\[[^\]]*\]\[(?<severity>[^ \]]*) *\] (?<message>.*)$/
      time_format %Y-%m-%d %H:%M:%S
      path /var/log/salt/minion
      pos_file /var/log/salt.pos
      tag salt
    </source>

    # Example:
    # Dec 21 23:17:22 gke-foo-1-1-4b5cbd14-node-4eoj startupscript: Finished running startup script /var/run/google.startup.script
    <source>
      @id startupscript.log
      @type tail
      format syslog
      path /var/log/startupscript.log
      pos_file /var/log/es-startupscript.log.pos
      tag startupscript
    </source>

    # Examples:
    # time="2016-02-04T06:51:03.053580605Z" level=info msg="GET /containers/json"
    # time="2016-02-04T07:53:57.505612354Z" level=error msg="HTTP Error" err="No such image: -f" statusCode=404
    # TODO(random-liu): Remove this after cri container runtime rolls out.
    <source>
      @id docker.log
      @type tail
      format /^time="(?<time>[^)]*)" level=(?<severity>[^ ]*) msg="(?<message>[^"]*)"( err="(?<error>[^"]*)")?( statusCode=($<status_code>\d+))?/
      path /var/log/docker.log
      pos_file /var/log/es-docker.log.pos
      tag docker
    </source>

    # Example:
    # 2016/02/04 06:52:38 filePurge: successfully removed file /var/etcd/data/member/wal/00000000000006d0-00000000010a23d1.wal
    <source>
      @id etcd.log
      @type tail
      # Not parsing this, because it doesn't have anything particularly useful to
      # parse out of it (like severities).
      format none
      path /var/log/etcd.log
      pos_file /var/log/es-etcd.log.pos
      tag etcd
    </source>

    # Multi-line parsing is required for all the kube logs because very large log
    # statements, such as those that include entire object bodies, get split into
    # multiple lines by glog.

    # Example:
    # I0204 07:32:30.020537    3368 server.go:1048] POST /stats/container/: (13.972191ms) 200 [[Go-http-client/1.1] 10.244.1.3:40537]
    <source>
      @id kubelet.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/kubelet.log
      pos_file /var/log/es-kubelet.log.pos
      tag kubelet
    </source>

    # Example:
    # I1118 21:26:53.975789       6 proxier.go:1096] Port "nodePort for kube-system/default-http-backend:http" (:31429/tcp) was open before and is still needed
    <source>
      @id kube-proxy.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/kube-proxy.log
      pos_file /var/log/es-kube-proxy.log.pos
      tag kube-proxy
    </source>

    # Example:
    # I0204 07:00:19.604280       5 handlers.go:131] GET /api/v1/nodes: (1.624207ms) 200 [[kube-controller-manager/v1.1.3 (linux/amd64) kubernetes/6a81b50] 127.0.0.1:38266]
    <source>
      @id kube-apiserver.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/kube-apiserver.log
      pos_file /var/log/es-kube-apiserver.log.pos
      tag kube-apiserver
    </source>

    # Example:
    # I0204 06:55:31.872680       5 servicecontroller.go:277] LB already exists and doesn't need update for service kube-system/kube-ui
    <source>
      @id kube-controller-manager.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/kube-controller-manager.log
      pos_file /var/log/es-kube-controller-manager.log.pos
      tag kube-controller-manager
    </source>

    # Example:
    # W0204 06:49:18.239674       7 reflector.go:245] pkg/scheduler/factory/factory.go:193: watch of *api.Service ended with: 401: The event in requested index is outdated and cleared (the requested history has been cleared [2578313/2577886]) [2579312]
    <source>
      @id kube-scheduler.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/kube-scheduler.log
      pos_file /var/log/es-kube-scheduler.log.pos
      tag kube-scheduler
    </source>

    # Example:
    # I1104 10:36:20.242766       5 rescheduler.go:73] Running Rescheduler
    <source>
      @id rescheduler.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/rescheduler.log
      pos_file /var/log/es-rescheduler.log.pos
      tag rescheduler
    </source>

    # Example:
    # I0603 15:31:05.793605       6 cluster_manager.go:230] Reading config from path /etc/gce.conf
    <source>
      @id glbc.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/glbc.log
      pos_file /var/log/es-glbc.log.pos
      tag glbc
    </source>

    # Example:
    # I0603 15:31:05.793605       6 cluster_manager.go:230] Reading config from path /etc/gce.conf
    <source>
      @id cluster-autoscaler.log
      @type tail
      format multiline
      multiline_flush_interval 5s
      format_firstline /^\w\d{4}/
      format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
      time_format %m%d %H:%M:%S.%N
      path /var/log/cluster-autoscaler.log
      pos_file /var/log/es-cluster-autoscaler.log.pos
      tag cluster-autoscaler
    </source>

    # Logs from systemd-journal for interesting services.
    # TODO(random-liu): Remove this after cri container runtime rolls out.
    <source>
      @id journald-docker
      @type systemd
      filters [{ "_SYSTEMD_UNIT": "docker.service" }]
      <storage>
        @type local
        persistent true
      </storage>
      read_from_head true
      tag docker
    </source>

    <source>
      @id journald-container-runtime
      @type systemd
      filters [{ "_SYSTEMD_UNIT": "{{ container_runtime }}.service" }]
      <storage>
        @type local
        persistent true
      </storage>
      read_from_head true
      tag container-runtime
    </source>

    <source>
      @id journald-kubelet
      @type systemd
      filters [{ "_SYSTEMD_UNIT": "kubelet.service" }]
      <storage>
        @type local
        persistent true
      </storage>
      read_from_head true
      tag kubelet
    </source>

    <source>
      @id journald-node-problem-detector
      @type systemd
      filters [{ "_SYSTEMD_UNIT": "node-problem-detector.service" }]
      <storage>
        @type local
        persistent true
      </storage>
      read_from_head true
      tag node-problem-detector
    </source>
    
    <source>
      @id kernel
      @type systemd
      filters [{ "_TRANSPORT": "kernel" }]
      <storage>
        @type local
        persistent true
      </storage>
      <entry>
        fields_strip_underscores true
        fields_lowercase true
      </entry>
      read_from_head true
      tag kernel
    </source>

  forward.input.conf: |-
    # Takes the messages sent over TCP
    <source>
      @type forward
    </source>

  monitoring.conf: |-
    # Prometheus Exporter Plugin
    # input plugin that exports metrics
    <source>
      @type prometheus
    </source>

    <source>
      @type monitor_agent
    </source>

    # input plugin that collects metrics from MonitorAgent
    <source>
      @type prometheus_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>

    # input plugin that collects metrics for output plugin
    <source>
      @type prometheus_output_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>

    # input plugin that collects metrics for in_tail plugin
    <source>
      @type prometheus_tail_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>

  output.conf: |-
    # Enriches records with Kubernetes metadata
    <filter kubernetes.**>
      @type kubernetes_metadata
    </filter>

    <match **>
      @type forward
      require_ack_response true
      ack_response_timeout 30
      recover_wait 10s
      heartbeat_interval 1s
      phi_threshold 16
      send_timeout 10s
      hard_timeout 10s
      expire_dns_cache 15
      heartbeat_type tcp
      buffer_chunk_limit 2M
      buffer_queue_limit 64
      flush_interval 5s
      max_retry_wait 15
      disable_retry_limit
      num_threads 8
      
      <server>
        name fluentd-server
        host fluentd-server
        port 24224
        weight 100
        </server>
    </match>

Fluentd Pod Yaml

我們亦將新建fluentd-standalone.yaml,用來(lái)控制Fluentd Pod的啟動(dòng)码俩。
請(qǐng)注意此Yaml中度帮,我們亦使用了NodeSelector,和Fluent Bit不同的是稿存,我們使用的
beta.kubernetes.io/fluentd-ds-ready = "fluentd"笨篷。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd-es
  namespace: kube-system
  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: kube-system
  apiGroup: ""
roleRef:
  kind: ClusterRole
  name: fluentd-es
  apiGroup: ""
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-es-v2.0.4
  namespace: kube-system
  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
      # This annotation ensures that fluentd does not get evicted if the node
      # supports critical pod annotation based priority scheme.
      # Note that this does not guarantee admission on the nodes (#40573).
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      priorityClassName: system-node-critical
      serviceAccountName: fluentd-es
      containers:
      - name: fluentd-es
        #image: k8s.gcr.io/fluentd-elasticsearch:v2.0.4
        image: hub.***.***/google_containers/fluentd-s3:v2.1.0
        imagePullPolicy: Always
        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: "fluentd"
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: config-volume
        configMap:
          name: fluentd-sa-config-v0.1.4
      imagePullSecrets:
      - name: kube-sec

拉起Fluentd DaemonSet

創(chuàng)建Fluentd所需的配置。

[centos@master1 efk]$ kubectl create -f fluentd-standalone-configmap.yaml 

拉起Fluentd的DaemonSet瓣履。

[centos@master1 efk]$ kubectl create -f fluentd-standalone.yaml 

和Fluent Bit 拉起時(shí)一樣率翅,此時(shí)我們檢查Pod,除了Fluentd Server的5個(gè)Pod外袖迎,此時(shí)亦發(fā)現(xiàn)沒有Pod被拉起冕臭。

[centos@master1 efk]$ kubectl get pods -n kube-system -o wide | grep fluentd
fluentd-server-v2.0.4-855db7cfc5-4wn47   1/1       Running   0          6h        10.244.29.20     minion6
fluentd-server-v2.0.4-855db7cfc5-pfmvd   1/1       Running   0          6h        10.244.3.211     minion17
fluentd-server-v2.0.4-855db7cfc5-rjqxl   1/1       Running   0          6h        10.244.13.47     minion19
fluentd-server-v2.0.4-855db7cfc5-shjfm   1/1       Running   0          6h        10.244.23.141    minion12
fluentd-server-v2.0.4-855db7cfc5-w7m5f   1/1       Running   0          6h        10.244.30.233    minion5
[centos@master1 efk]$ 

我們接下來(lái)就要對(duì)Node打label,這樣就會(huì)拉起來(lái)了瓢棒,中間注意間隔點(diǎn)時(shí)間浴韭。

[centos@master1 efk]$ kubectl label node minion8 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 efk]$ kubectl label node minion21 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 efk]$ kubectl label node minion9 beta.kubernetes.io/fluentd-ds-ready=true
[centos@master1 efk]$ kubectl label node minion16 beta.kubernetes.io/fluentd-ds-ready=true

再次檢查節(jié)點(diǎn)被拉起的狀態(tài):

[centos@master1 efk]$ kubectl get pods -n kube-system -o wide | grep fluentd
fluentd-es-v2.0.4-75gdf                  1/1       Running   1          4d        10.244.27.245    minion8
fluentd-es-v2.0.4-kx5pz                  1/1       Running   0          2h        10.244.10.96     minion21
fluentd-es-v2.0.4-n89xj                  1/1       Running   6          4d        10.244.26.92     minion9
fluentd-es-v2.0.4-zsrln                  1/1       Running   0          6h        10.244.19.67     minion16
fluentd-server-v2.0.4-855db7cfc5-4wn47   1/1       Running   0          6h        10.244.29.20     minion6
fluentd-server-v2.0.4-855db7cfc5-pfmvd   1/1       Running   0          6h        10.244.3.211     minion17
fluentd-server-v2.0.4-855db7cfc5-rjqxl   1/1       Running   0          6h        10.244.13.47     minion19
fluentd-server-v2.0.4-855db7cfc5-shjfm   1/1       Running   0          6h        10.244.23.141    minion12
fluentd-server-v2.0.4-855db7cfc5-w7m5f   1/1       Running   0          6h        10.244.30.233    minion5
[centos@master1 efk]$ 

和Fluent Bit一樣,需要去Kibana那邊再次檢查下節(jié)點(diǎn)的日志是否有正常傳遞到ES和S3脯宿,在此就不再累述念颈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市连霉,隨后出現(xiàn)的幾起案子榴芳,更是在濱河造成了極大的恐慌,老刑警劉巖跺撼,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窟感,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡歉井,警方通過查閱死者的電腦和手機(jī)柿祈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人躏嚎,你說(shuō)我怎么就攤上這事蜜自。” “怎么了卢佣?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵重荠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我虚茶,道長(zhǎng)戈鲁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任嘹叫,我火速辦了婚禮婆殿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罩扇。我一直安慰自己鸣皂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布暮蹂。 她就那樣靜靜地躺著寞缝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仰泻。 梳的紋絲不亂的頭發(fā)上荆陆,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音集侯,去河邊找鬼被啼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛棠枉,可吹牛的內(nèi)容都是我干的浓体。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辈讶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼命浴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起贱除,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤生闲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后月幌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碍讯,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年扯躺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捉兴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝎困。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖倍啥,靈堂內(nèi)的尸體忽然破棺而出难衰,到底是詐尸還是另有隱情,我是刑警寧澤逗栽,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站失暂,受9級(jí)特大地震影響彼宠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弟塞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一凭峡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧决记,春花似錦摧冀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扩借,卻和暖如春椒惨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潮罪。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工康谆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫉到。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓沃暗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親何恶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子孽锥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容