├── .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 /^(?