Fluentd is an open source data collector and a great option because of its flexibility. This implementation uses a Fluentd DaemonSet to collect Kubernetes logs and send them to Logz.io. The Kubernetes DaemonSet ensures that some or all nodes run a copy of a pod.
The image used in this integration comes pre-configured for Fluentd to gather all logs from the Kubernetes node environment and append the proper metadata to the logs. If you prefer to customize your Fluentd configuration, you can edit it before it’s deployed.
The latest version pulls the image from logzio/logzio-fluentd
. Previous versions pulled the image from logzio/logzio-k8s
.
Fluentd will fetch all existing logs, as it is not able to ignore older logs.
For troubleshooting this solution, see our user guide.
Sending logs from nodes with taints
If you want to ship logs from any of the nodes that have a taint, make sure that the taint key values are listed in your in your daemonset/deployment configuration as follows:
tolerations:
- key:
operator:
value:
effect:
To determine if a node uses taints as well as to display the taint keys, run:
kubectl get nodes -o json | jq ".items[]|{name:.metadata.name, taints:.spec.taints}"
You need to use Helm
client with version v3.9.0
or above.
K8S version compatibility
Your Kubernetes version may affect your options, as follows:
-
K8S 1.19.3+ - If you’re running on K8S 1.19.3+ or later, be sure to use the DaemonSet that supports a containerd at runtime. It can be downloaded and customized from
logzio-daemonset-containerd.yaml
. -
K8S 1.16 or earlier - If you’re running K8S 1.16 or earlier, you may need to manually change the API version in your DaemonSet to
apiVersion: rbac.authorization.k8s.io/v1beta1
.The API versions of
ClusterRole
andClusterRoleBinding
are found inlogzio-daemonset-rbac.yaml
andlogzio-daemonset-containerd.yaml
.If you are running K8S 1.17 or later, the DaemonSet is set to use
apiVersion: rbac.authorization.k8s.io/v1
by default. No change is needed.
Multiline logs
Fluentd’s basic configuration may cause longer, multiline logs to split into multiple logs - 1 log per line. You can use the Fluentd multiline parser plugin to control this behavior.
See the next tab for details about using the Fluentd multiline parser plugin.
Deploy logzio-k8s with default configuration
For most environments, we recommend using the default configuration. However, you can deploy a custom configuration if your environment needs it.
Deploy Fluentd as a DaemonSet on Kubernetes
Create a monitoring namespace
Your DaemonSet will be deployed under the namespace monitoring
.
kubectl create namespace monitoring
Store your Logz.io credentials
Save your Logz.io shipping credentials as a Kubernetes secret.
kubectl create secret generic logzio-logs-secret \
--from-literal=logzio-log-shipping-token='<<LOG-SHIPPING-TOKEN>>' \
--from-literal=logzio-log-listener='https://<<LISTENER-HOST>>:8071' \
-n monitoring
Replace the placeholders to match your specifics. (They are indicated by the double angle brackets << >>
):
-
Replace
<<LOG-SHIPPING-TOKEN>>
with the token of the account you want to ship to. -
Replace
<<LISTENER-HOST>>
with the host for your region. For example,listener.logz.io
if your account is hosted on AWS US East, orlistener-nl.logz.io
if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071.
Deploy the DaemonSet
For an RBAC cluster:
kubectl apply -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/logzio-daemonset-rbac.yaml -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/configmap.yaml
For a non-RBAC cluster:
kubectl apply -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/logzio-daemonset.yaml -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/configmap.yaml
For container runtime Containerd:
kubectl apply -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/logzio-daemonset-containerd.yaml -f https://raw.githubusercontent.com/logzio/logzio-k8s/master/configmap.yaml
Check Logz.io for your logs
Give your logs some time to get from your system to ours, and then open Open Search Dashboards.
If you still don’t see your logs, see Kubernetes log shipping troubleshooting.
Deploy logzio-k8s with custom configuration
You can customize the configuration of your Fluentd container by editing either your DaemonSet or your Configmap.
Create a monitoring namespace
Your DaemonSet will be deployed under the namespace monitoring
.
kubectl create namespace monitoring
Store your Logz.io credentials
Save your Logz.io shipping credentials as a Kubernetes secret.
kubectl create secret generic logzio-logs-secret \
--from-literal=logzio-log-shipping-token='<<LOG-SHIPPING-TOKEN>>' \
--from-literal=logzio-log-listener='https://<<LISTENER-HOST>>:8071' \
-n monitoring
Replace the placeholders to match your specifics. (They are indicated by the double angle brackets << >>
):
-
Replace
<<LOG-SHIPPING-TOKEN>>
with the token of the account you want to ship to. -
Replace
<<LISTENER-HOST>>
with the host for your region. For example,listener.logz.io
if your account is hosted on AWS US East, orlistener-nl.logz.io
if hosted on Azure West Europe. The required port depends whether HTTP or HTTPS is used: HTTP = 8070, HTTPS = 8071.
Configure Fluentd
There are 3 DaemonSet options: RBAC DaemonSet, non-RBAC DaemonSet, Containerd. Download the relevant DaemonSet and open it in your text editor to edit it.
If you wish to make advanced changes in your Fluentd configuration, you can download and edit the configmap yaml file.
Environment variables
The following environment variables can be edited directly from the DaemonSet without editing the Configmap.
Parameter | Description | Default |
---|---|---|
output_include_time | To append a timestamp to your logs when they’re processed, true . Otherwise, false . |
true |
buffer_type | Specifies which plugin to use as the backend | file |
buffer_path | Path of the buffer | /var/log/Fluentd-buffers/stackdriver.buffer |
buffer_queue_full_action | Controls the behavior when the queue becomes full | block |
buffer_chunk_limit | Maximum size of a chunk allowed. | 2M |
buffer_queue_limit | Maximum length of the output queue. | 6 |
flush_interval | Interval, in seconds, to wait before invoking the next buffer flush. | 5s |
max_retry_wait | Maximum interval, in seconds, to wait between retries. | 30s |
num_threads | Number of threads to flush the buffer. | 2 |
INCLUDE_NAMESPACE | Sends logs from all namespaces by default. To send logs from specific k8s namespaces, specify them in the following format, space delimited: kubernetes.var.log.containers.**_<<NAMESPACE-TO-INCLUDE>>_** kubernetes.var.log.containers.**_<<ANOTHER-NAMESPACE>>_** . |
"" |
KUBERNETES_VERIFY_SSL | Enable to validate SSL certificates. | true |
FLUENT_FILTER_KUBERNETES_URL | URL to the API server. This parameter isn’t part of the default Daemonset. You can set it to retrieve additional Kubernetes metadata for logs from the Kubernetes API server. | null |
AUDIT_LOG_FORMAT | The format of your audit logs. If your audit logs are in json format, set to audit-json . |
audit |
CRI | The CRI of the cluster. In logzio-daemonset & logzio-daemonset-rbac is set to docker , and in logzio-daemonset-containerd is set to containerd . The configmap uses this var to determin which includes it needs to make for the fluent.conf file, when configuration needs to be adjusted by the CRI. |
Good to know
-
If
FLUENT_FILTER_KUBERNETES_URL
is not specified, the environment variablesKUBERNETES_SERVICE_HOST
andKUBERNETES_SERVICE_PORT
will be used, as long as both of them are present. Typically, they are present when running Fluentd in a pod. -
Note that
FLUENT_FILTER_KUBERNETES_URL
does not appear in the default environment variable list in the DaemonSet. If you wish to use this variable, you’ll have to add it manually to the DaemonSet’s environment variables.
Deploy the DaemonSet
For the RBAC DaemonSet:
kubectl apply -f /path/to/logzio-daemonset-rbac.yaml -f /path/to/configmap.yaml
For the non-RBAC DaemonSet:
kubectl apply -f /path/to/logzio-daemonset.yaml -f /path/to/configmap.yaml
For container runtime Containerd:
kubectl apply -f /path/to/logzio-daemonset-containerd.yaml -f /path/to/configmap.yaml
Check Logz.io for your logs
Give your logs some time to get from your system to ours, and then open Open Search Dashboards.
If you still don’t see your logs, see Kubernetes log shipping troubleshooting.
Disabling systemd input
To suppress Fluentd system messages, set the FLUENTD_SYSTEMD_CONF
environment variable to disable
in your Kubernetes environment.
Exclude logs from certain namespaces
If you wish to exclude logs from certain namespaces, add the following to your Fluentd configuration:
<match kubernetes.var.log.containers.**_NAMESPACE_**>
@type null
</match>
Replace NAMESPACE
with the name of the namespace you need to exclude logs from.
If you need to specify multiple namespaces, add another kubernetes.var.log.containers.**_NAMESPACE_**
line to the above function as follows:
<match kubernetes.var.log.containers.**_NAMESPACE1_** kubernetes.var.log.containers.**_NAMESPACE2_**>
@type null
</match>
Configuring Fluentd to concatenate multiline logs using a plugin
Fluentd splits multiline logs by default. If your original logs span multiple lines, you may find that they arrive in your Logz.io account split into several partial logs.
The Logz.io Docker image comes with a pre-built Fluentd filter plug-in that can be used to concatenate multiline logs. The plug-in is named fluent-plugin-concat
and you can view the full list of configuration options in the GitHub project.
Example
The following is an example of a multiline log sent from a deployment on a k8s cluster:
2021-02-08 09:37:51,031 - errorLogger - ERROR - Traceback (most recent call last):
File "./code.py", line 25, in my_func
1/0
ZeroDivisionError: division by zero
Fluentd’s default configuration will split the above log into 4 logs, 1 for each line of the original log. In other words, each line break (\n
) causes a split.
To avoid this, you can use the fluent-plugin-concat
and customize the configuration to meet your needs. The additional configuration is added to the values.yml
file.
For the above example, we could use the following regex expressions to demarcate the start and end of our example log:
<filter **>
@type concat
key message # The key for part of multiline log
multiline_start_regexp /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ # This regex expression identifies line starts.
</filter>