Monitoring and Logging
Introduction
Here we describe how you can setup your logging and monitoring for kubernetes keeping in mind dashboard design also.
Logging
Logging mainly divide into three parts
Logs collector
fluentd
Elasticsearch Beats (like filebeat for logs)
fluent bit (light version of fluentd written in C for performance and low resource utilization)
Telegraf (part of influxdb project)
Logs storage
Elasticsearch (best for text based searching)
filesystem (if you won't interested in text based search)
InfluxDB (influxDB also able to store logs, but I am not so much aware)
Logs dashboard
Kibana (Kibana is well known ELK stack project and well works with elasticsearch database, but the problem is it uses lots of RAM, you can use logtrail plugin for showing logs in tail form based on some filters)
Here we are going to use Elasticsearch, fluent bit, and Kibana for logging solution for kubernetes.
Fluent bit/Fluentd
For collecting all logs you need to run fluent bit/fluentd as a DaemonSet and collect all files from folder /var/log/containers. You can also use helm chart for the deployment of this.
Here we can also create new index of each namespace of kubernetes, this easily the filtering little bit on logtrail plugin screen
output.conf: |
# Enriches records with Kubernetes metadata
<filter kubernetes.**>
@type kubernetes_metadata
annotation_match [ ".+"] # Get annotations
</filter>
<filter kubernetes.**>
@type record_modifier
remove_keys _dummy_
<record>
_dummy_ ${ record['stag']= tag; if record["kubernetes"].has_key?("annotations"); if record["kubernetes"]["annotations"].has_key?('fluentbit_io/parser'); record['stag'] = record["kubernetes"]["annotations"]['fluentbit_io/parser'] + "." + tag ; end ; end; nil}
# _dummy_ ${ record["before"] = "before" ; nil }
</record>
</filter>
match kubernetes.**>
@type rewrite_tag_filter
capitalize_regex_backreference yes
@log_level info
<rule>
key stag
pattern ^(.+)$
tag modified.$1
</rule>
</match>
<filter modified.**>
@type record_modifier
remove_keys stag
</filter>
<match **>
@id elasticsearch
@type elasticsearch_dynamic
@log_level info
include_tag_key true
host "#{ENV['OUTPUT_HOST']}"
port "#{ENV['OUTPUT_PORT']}"
logstash_format true
logstash_prefix namespace-${record['kubernetes']['namespace_name']}
<buffer>
@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 "#{ENV['OUTPUT_BUFFER_CHUNK_LIMIT']}"
queue_limit_length "#{ENV['OUTPUT_BUFFER_QUEUE_LIMIT']}"
overflow_action block
</buffer>
</match>
output.conf: |-
<match **>
type elasticsearch_dynamic
log_level info
include_tag_key true
host elasticsearch-logging
port 9200
logstash_format true
logstash_prefix namespace-${record['kubernetes']['namespace_name']}
# Set the chunk limits.
buffer_chunk_limit 2M
buffer_queue_limit 8
flush_interval 5s
# Never wait longer than 5 minutes between retries.
max_retry_wait 30
# Disable the limit on the number of retries (retry forever).
disable_retry_limit
# Use multiple threads for processing.
num_threads 2
</match>
In above you can see that I am using logstash_prefix
which is used generate dynamic index in elasticsearch, you can also use your own pattern, this will help you filter in settings of logtrail plugin

Use any standard way to install fluent bit/fluentd on your kubernetes, for e.g., use below helm charts
Elasticsearch
Install elasticsearch on your own, either use helm chart (https://github.com/kubernetes/charts/tree/master/incubator/elasticsearch) and just use any VMs to install it, you can find many tutorial to configure and optimize it.
Kibana
You can install default kibana either on Kubernetes or on any machine from where it can access elasticsearch
Logging tail in Kibana
You can use logtail(https://github.com/sivasamyk/logtrail) plugin of kibana for that, and use below logtrail.json
{
"index_patterns" : [
{
"es": {
"default_index": "logstash-local-influxdb-*",
"allow_url_parameter": false
},
"tail_interval_in_seconds": 2,
"es_index_time_offset_in_seconds": 0,
"display_timezone": "local",
"display_timestamp_format": "MMM DD HH:mm:ss",
"max_buckets": 500,
"nested_objects" : true,
"default_time_range_in_days" : 0,
"fields" : {
"mapping" : {
"timestamp" : "@timestamp",
"display_timestamp" : "@timestamp",
"hostname" : "kubernetes.pod_name",
"program": "kubernetes.container_name",
"message": "log"
},
"message_format": "ENV|{{{kubernetes.labels.environment}}} APP|{{{kubernetes.labels.app}}} : {{{log}}}"
}
}
]
}
In above you can just use various filters according to index patterns made my fluentd/fluent bit and also define your own mapping
Last updated