├── .DS_Store
├── Image
├── .DS_Store
├── Dockerfile
├── Gemfile
├── clean-apt
├── clean-install
├── fluent.conf
└── run.sh
├── README.MD
└── yaml
├── .DS_Store
├── fluentd-es-configmap.yaml
└── fluentd-es-ds.yaml
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengdidi/k8s-fluentd-elasticsearch/95ad9c10fbff27e1086ed4889412cc506d085a71/.DS_Store
--------------------------------------------------------------------------------
/Image/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengdidi/k8s-fluentd-elasticsearch/95ad9c10fbff27e1086ed4889412cc506d085a71/Image/.DS_Store
--------------------------------------------------------------------------------
/Image/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2017 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # This Dockerfile will build an image that is configured
16 | # to run Fluentd with an Elasticsearch plug-in and the
17 | # provided configuration file.
18 | # The image acts as an executable for the binary /usr/sbin/td-agent.
19 | # Note that fluentd is run with root permssion to allow access to
20 | # log files with root only access under /var/log/containers/*
21 |
22 | FROM debian:stretch-slim
23 |
24 | ARG DEBIAN_FRONTEND=noninteractive
25 |
26 | COPY clean-apt /usr/bin
27 | COPY clean-install /usr/bin
28 | COPY Gemfile /Gemfile
29 |
30 | # 1. Install & configure dependencies.
31 | # 2. Install fluentd via ruby.
32 | # 3. Remove build dependencies.
33 | # 4. Cleanup leftover caches & files.
34 | RUN BUILD_DEPS="make gcc g++ libc6-dev ruby-dev libffi-dev" \
35 | #authorize the scripts, modify by fengdidi@gmail.com
36 | && chmod +x /usr/bin/clean-install \
37 | && chmod +x /usr/bin/clean-apt \
38 | && clean-install $BUILD_DEPS \
39 | ca-certificates \
40 | libjemalloc1 \
41 | ruby \
42 | && echo 'gem: --no-document' >> /etc/gemrc \
43 | && gem install --file Gemfile \
44 | && apt-get purge -y --auto-remove \
45 | -o APT::AutoRemove::RecommendsImportant=false \
46 | $BUILD_DEPS \
47 | && clean-apt \
48 | # Ensure fluent has enough file descriptors
49 | && ulimit -n 65536
50 |
51 | # Copy the Fluentd configuration file for logging Docker container logs.
52 | COPY fluent.conf /etc/fluent/fluent.conf
53 | COPY run.sh /run.sh
54 |
55 | #authorize the scripts, modify by fengdidi@gmail.com
56 | RUN chmod +x /run.sh
57 |
58 | # Expose prometheus metrics.
59 | EXPOSE 80
60 |
61 | ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.1
62 |
63 | # Start Fluentd to pick up our config that watches Docker container logs.
64 | CMD /run.sh $FLUENTD_ARGS
--------------------------------------------------------------------------------
/Image/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'fluentd', '<=1.1.0'
4 | gem 'activesupport', '~>5.1.4'
5 | gem 'fluent-plugin-kubernetes_metadata_filter', '~>1.0.0'
6 | gem 'fluent-plugin-elasticsearch', '~>2.4.1'
7 | gem 'fluent-plugin-systemd', '~>0.3.1'
8 | gem 'fluent-plugin-detect-exceptions', '~>0.0.9'
9 | gem 'fluent-plugin-prometheus', '~>0.3.0'
10 | gem 'fluent-plugin-multi-format-parser', '~>1.0.0'
11 | gem 'oj', '~>3.3.1.0'
--------------------------------------------------------------------------------
/Image/clean-apt:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright 2017 The Kubernetes Authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # A script encapsulating a common Dockerimage pattern for installing packages
18 | # and then cleaning up the unnecessary install artifacts.
19 | # e.g. clean-install iptables ebtables conntrack
20 |
21 | set -o errexit
22 |
23 | apt-get clean -y
24 | rm -rf \
25 | /var/cache/debconf/* \
26 | /var/lib/apt/lists/* \
27 | /var/log/* \
28 | /tmp/* \
29 | /var/tmp/*
--------------------------------------------------------------------------------
/Image/clean-install:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright 2017 The Kubernetes Authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # A script encapsulating a common Dockerimage pattern for installing packages
18 | # and then cleaning up the unnecessary install artifacts.
19 | # e.g. clean-install iptables ebtables conntrack
20 |
21 | set -o errexit
22 |
23 | if [ $# = 0 ]; then
24 | echo >&2 "No packages specified"
25 | exit 1
26 | fi
27 |
28 | apt-get update
29 | apt-get install -y --no-install-recommends $@
30 | clean-apt
--------------------------------------------------------------------------------
/Image/fluent.conf:
--------------------------------------------------------------------------------
1 | # This is the root config file, which only includes components of the actual configuration
2 |
3 | # Do not collect fluentd's own logs to avoid infinite loops.
4 |
5 | @type null
6 |
7 |
8 | @include /etc/fluent/config.d/*.conf
--------------------------------------------------------------------------------
/Image/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright 2017 The Kubernetes Authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # These steps must be executed once the host /var and /lib volumes have
18 | # been mounted, and therefore cannot be done in the docker build stage.
19 |
20 | # For systems without journald
21 | mkdir -p /var/log/journal
22 |
23 | /usr/local/bin/fluentd $@
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | ## K8s-fluentd-elasticsearch
2 |
3 | For Chinese documentation, please visit [Here](https://www.jianshu.com/p/92a4c11e77ba)
4 |
5 | This is a custom fluentd image with elasticsearch plugin based on Kubernetes's official implementation.
6 |
7 | Fluentd is deployed as a DaemonSet which spawns a pod on each node that reads logs, generated by kubelet, container runtime and containers and sends them to Elasticsearch.
8 |
9 | Note: in order for Fluentd to work, every Kubernetes node must be labeled with beta.kubernetes.io/fluentd-ds-ready=true, as otherwise the Fluentd DaemonSet will ignore them.
10 |
11 | Differences between my custom fluentd-elasticseach image and the official one:
12 | * The Elasticseach address and port are injected into the container by using environment variables.
13 | * Modify Dockerfile to solve some permission problems.
14 | * The offical implementation also deploys the elasticseach on the kubernetes cluster. But in my company, we deploy elasticsearch cluster outside of kubernetes. We think this is a better idea because Elasticseach is a database that is stateful. Since our company uses kubernetes as a micro serice platform, we don't want to deploy anything stateful on kubernetes cluster.
15 |
16 | logs are collected by this image:
17 | * containers log: /var/log/containers/*.log
18 | * docker log: /var/log/docker.log
19 | * kubelet log: /var/log/kubelet.log
20 | * kube-proxy log: /var/log/kube-proxy.log
21 | * kube-apiserver log: /var/log/kube-apiserver.log
22 | * kube-controller-manager log: /var/log/kube-controller-manager.log
23 | * kube-scheduler log: /var/log/kube-scheduler.log
24 | For more details, please check yaml/fluentd-es-configmap.yaml
25 |
26 | ## How to use
27 | Before you deploy this log collector on your Kubernetes node, you have to label your node by this command:
28 | ```
29 | kubectl label nodes nodename beta.kubernetes.io/fluentd-ds-ready=true
30 | ```
31 | Then, you need to build the image by yourself. Simply go into the Image directory, and run:
32 | ```
33 | docker build -t dockerhub.fengdidi:5000/fengdidi/fluentd-elasticsearch:1801 .
34 | docker push dockerhub.fengdidi:5000/fengdidi/fluentd-elasticsearch:1801
35 | ```
36 | dockerhub.fengdidi:5000/fengdidi/fluentd-elasticsearch:1801 is the image name and tag, use your own name and tag when you build by yourself.
37 | After you build the image, go to the yaml directory, create the config map on your kubernetes cluster.
38 | ```
39 | kubectl create -f fluentd-es-configmap.yaml
40 | ```
41 | Then modify fluentd-es-ds.yaml, change the image name to the one you built before. Assign the Elasticseach address and port.
42 | The Elasticseach address and port are injected into the container by using environment variables. After finishing your configuration, you can run the fluentd DaemonSet by using the command below:
43 | ```
44 | kubectl create -f fluentd-es-ds.yaml
45 | ```
--------------------------------------------------------------------------------
/yaml/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengdidi/k8s-fluentd-elasticsearch/95ad9c10fbff27e1086ed4889412cc506d085a71/yaml/.DS_Store
--------------------------------------------------------------------------------
/yaml/fluentd-es-configmap.yaml:
--------------------------------------------------------------------------------
1 | kind: ConfigMap
2 | apiVersion: v1
3 | metadata:
4 | name: fluentd-es-config-v0.1.4
5 | namespace: kube-system
6 | labels:
7 | addonmanager.kubernetes.io/mode: Reconcile
8 | data:
9 | system.conf: |-
10 |
11 | root_dir /tmp/fluentd-buffers/
12 |
13 | containers.input.conf: |-
14 | # This configuration file for Fluentd / td-agent is used
15 | # to watch changes to Docker log files. The kubelet creates symlinks that
16 | # capture the pod name, namespace, container name & Docker container ID
17 | # to the docker logs for pods in the /var/log/containers directory on the host.
18 | # If running this fluentd configuration in a Docker container, the /var/log
19 | # directory should be mounted in the container.
20 | #
21 | # These logs are then submitted to Elasticsearch which assumes the
22 | # installation of the fluent-plugin-elasticsearch & the
23 | # fluent-plugin-kubernetes_metadata_filter plugins.
24 | # See https://github.com/uken/fluent-plugin-elasticsearch &
25 | # https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter for
26 | # more information about the plugins.
27 | #
28 | # Example
29 | # =======
30 | # A line in the Docker log file might look like this JSON:
31 | #
32 | # {"log":"2014/09/25 21:15:03 Got request with path wombat\n",
33 | # "stream":"stderr",
34 | # "time":"2014-09-25T21:15:03.499185026Z"}
35 | #
36 | # The time_format specification below makes sure we properly
37 | # parse the time format produced by Docker. This will be
38 | # submitted to Elasticsearch and should appear like:
39 | # $ curl 'http://elasticsearch-logging:9200/_search?pretty'
40 | # ...
41 | # {
42 | # "_index" : "logstash-2014.09.25",
43 | # "_type" : "fluentd",
44 | # "_id" : "VBrbor2QTuGpsQyTCdfzqA",
45 | # "_score" : 1.0,
46 | # "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n",
47 | # "stream":"stderr","tag":"docker.container.all",
48 | # "@timestamp":"2014-09-25T22:45:50+00:00"}
49 | # },
50 | # ...
51 | #
52 | # The Kubernetes fluentd plugin is used to write the Kubernetes metadata to the log
53 | # record & add labels to the log record if properly configured. This enables users
54 | # to filter & search logs on any metadata.
55 | # For example a Docker container's logs might be in the directory:
56 | #
57 | # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b
58 | #
59 | # and in the file:
60 | #
61 | # 997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
62 | #
63 | # where 997599971ee6... is the Docker ID of the running container.
64 | # The Kubernetes kubelet makes a symbolic link to this file on the host machine
65 | # in the /var/log/containers directory which includes the pod name and the Kubernetes
66 | # container name:
67 | #
68 | # synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
69 | # ->
70 | # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
71 | #
72 | # The /var/log directory on the host is mapped to the /var/log directory in the container
73 | # running this instance of Fluentd and we end up collecting the file:
74 | #
75 | # /var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
76 | #
77 | # This results in the tag:
78 | #
79 | # var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
80 | #
81 | # The Kubernetes fluentd plugin is used to extract the namespace, pod name & container name
82 | # which are added to the log message as a kubernetes field object & the Docker container ID
83 | # is also added under the docker field object.
84 | # The final tag is:
85 | #
86 | # kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
87 | #
88 | # And the final log record look like:
89 | #
90 | # {
91 | # "log":"2014/09/25 21:15:03 Got request with path wombat\n",
92 | # "stream":"stderr",
93 | # "time":"2014-09-25T21:15:03.499185026Z",
94 | # "kubernetes": {
95 | # "namespace": "default",
96 | # "pod_name": "synthetic-logger-0.25lps-pod",
97 | # "container_name": "synth-lgr"
98 | # },
99 | # "docker": {
100 | # "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b"
101 | # }
102 | # }
103 | #
104 | # This makes it easier for users to search for logs by pod name or by
105 | # the name of the Kubernetes container regardless of how many times the
106 | # Kubernetes pod has been restarted (resulting in a several Docker container IDs).
107 | # Json Log Example:
108 | # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
109 | # CRI Log Example:
110 | # 2016-02-17T00:04:05.931087621Z stdout F [info:2016-02-16T16:04:05.930-08:00] Some log text here
111 |
112 | @id fluentd-containers.log
113 | @type tail
114 | path /var/log/containers/*.log
115 | pos_file /var/log/es-containers.log.pos
116 | time_format %Y-%m-%dT%H:%M:%S.%NZ
117 | tag raw.kubernetes.*
118 | read_from_head true
119 |
120 | @type multi_format
121 |
122 | format json
123 | time_key time
124 | time_format %Y-%m-%dT%H:%M:%S.%NZ
125 |
126 |
127 | format /^(?
130 |
131 |
132 | # Detect exceptions in the log output and forward them as one log entry.
133 |
134 | @id raw.kubernetes
135 | @type detect_exceptions
136 | remove_tag_prefix raw
137 | message log
138 | stream stream
139 | multiline_flush_interval 5
140 | max_bytes 500000
141 | max_lines 1000
142 |
143 | system.input.conf: |-
144 | # Example:
145 | # 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081
146 |
147 | @id minion
148 | @type tail
149 | format /^(?
155 | # Example:
156 | # Dec 21 23:17:22 gke-foo-1-1-4b5cbd14-node-4eoj startupscript: Finished running startup script /var/run/google.startup.script
157 |
158 | @id startupscript.log
159 | @type tail
160 | format syslog
161 | path /var/log/startupscript.log
162 | pos_file /var/log/es-startupscript.log.pos
163 | tag startupscript
164 |
165 | # Examples:
166 | # time="2016-02-04T06:51:03.053580605Z" level=info msg="GET /containers/json"
167 | # time="2016-02-04T07:53:57.505612354Z" level=error msg="HTTP Error" err="No such image: -f" statusCode=404
168 | # TODO(random-liu): Remove this after cri container runtime rolls out.
169 |
170 | @id docker.log
171 | @type tail
172 | format /^time="(?
177 | # Example:
178 | # 2016/02/04 06:52:38 filePurge: successfully removed file /var/etcd/data/member/wal/00000000000006d0-00000000010a23d1.wal
179 |
180 | @id etcd.log
181 | @type tail
182 | # Not parsing this, because it doesn't have anything particularly useful to
183 | # parse out of it (like severities).
184 | format none
185 | path /var/log/etcd.log
186 | pos_file /var/log/es-etcd.log.pos
187 | tag etcd
188 |
189 | # Multi-line parsing is required for all the kube logs because very large log
190 | # statements, such as those that include entire object bodies, get split into
191 | # multiple lines by glog.
192 | # Example:
193 | # 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]
194 |
195 | @id kubelet.log
196 | @type tail
197 | format multiline
198 | multiline_flush_interval 5s
199 | format_firstline /^\w\d{4}/
200 | format1 /^(?\w)(?