8.7 KiB
assignees | title | ||
---|---|---|---|
|
Logging Overview |
Application and systems logs can help you understand what is happening inside your cluster. The logs are particularly useful for debugging problems and monitoring cluster activity. Most modern applications have some kind of logging mechanism; as such, most container engines are likewise designed to support some kind of logging. The easiest and most embraced logging method for containerized applications is to write to the standard output and standard error streams.
However, the native functionality provided by a container engine or runtime is usually not enough for a complete logging solution. For example, if a container crashes, a pod is evicted, or a node dies, you'll usually still want to access your application's logs. As such, logs should have a separate storage and lifecycle independent of nodes, pods, or containers; this concept is called cluster-level-logging. Cluster-level logging requires a separate back-end to store, analyze, and query logs. Kubernetes provides no native storage solution for logs data, but you can integrate many existing logging solutions into your Kubernetes cluster.
In this document, you can find:
- A basic demonstration of logging in Kubernetes using the standard output stream
- A detailed description of the node logging architecture in Kubernetes
- Guidance for implementing cluster-level logging in Kubernetes
The guidance for cluster-level logging assumes that a logging back-end is present inside or outside of your cluster. If you're not interested in having cluster-level logging, you might still find the description how logs are stored and handled on the node to be useful.
Basic logging in Kubernetes
In this section, you can see an example of basic logging in Kubernetes that outputs data to the standard output stream. This demonstration uses a pod specification with a container that writes some text to standard output once per second.
{% include code.html language="yaml" file="counter-pod.yaml" %}
To run this pod, use the following command:
$ kubectl create -f counter-pod.yaml
pod "counter" created
To fetch the logs, use the kubectl logs
command, as follows
$ kubectl logs counter
0: Tue Jun 2 21:37:31 UTC 2015
1: Tue Jun 2 21:37:32 UTC 2015
2: Tue Jun 2 21:37:33 UTC 2015
3: Tue Jun 2 21:37:34 UTC 2015
4: Tue Jun 2 21:37:35 UTC 2015
5: Tue Jun 2 21:37:36 UTC 2015
...
You can use kubectl logs
to retrieve logs from a previous instantiation of a container with --previous
flag, in case the container has crashed. If your pod has multiple containers, you should specify which container's logs you want to access by appending a container name to the command. See the kubectl logs
documentation for more details.
Logging at the node level
Everything a containerized application writes to stdout
and stderr
is handled and redirected somewhere by a container engine. For example, Docker container engine redirects those two streams to a logging driver, which is configured in Kubernetes to write to a file in json format.
Note: The Docker json logging driver treats each line as a separate message. When using the Docker logging driver, there is no direct support for multi-line messages. To do so, you'll need to handle these at the logging agent level or higher.
By default, if a container restarts, kubelet keeps one terminated container with its logs. If a pod is evicted from the node, all corresponding containers are also evicted, along with their logs.
An important consideration in node-level logging is implementing log rotation, so that logs don't consume all available storage on the node. Kubernetes uses the logrotate
tool to implement log rotation.
Kubernetes performs log rotation daily, or if the log file grows beyond 10MB in size. Each rotation belongs to a single container; if the container repeatedly fails or the pod is evicted, all previous rotations for the container are lost. By default, Kubernetes keeps up to five logging rotations per container.
The Kubernetes logging configuration differs depending on the node type. For example, you can find detailed information for GCI in the corresponding configure helper.
When you run kubectl logs
, as in the basic logging example, the kubelet on the node handles the request and reads directly from the log file, returning the contents in the response. Note that kubectl logs
only returns the last rotation; you must manually extract prior rotations, if desired.
System components logs
Kubernetes system components use a different logging mechanism than the application containers in pods. Components such as kube-proxy
(among others) use the glog logging library. You can find the conventions for logging severity for those components in the development docs on logging.
System components write directly to log files in the /var/log
directory in the node's host filesystem. Like container logs, system component logs are rotated daily and based on size. However, system component logs have a higher size retention: by default, they store 100MB.
Cluster-level logging architectures
While Kubernetes does not provide a native solution for cluster-level logging, there are several common approaches you can consider:
- You can use a node-level logging agent that runs on every node.
- You can include a dedicated sidecar container for logging in an application pod.
- You can push logs directly to a back-end from within an application.
Using a node logging agent
You can implement cluster-level logging by including a node-level logging agent on each node. The logging agent is a dedicated tool that exposes logs or pushes logs to a back-end. Commonly, the logging agent is a container that has access to a directory with log files from all of the application containers on that node.
Because the logging agent must run on every node, it's common to implement it as either a DaemonSet replica, a manifest pod, or a dedicated native process on the node. However the latter two approaches are deprecated and highly discouraged.
Using a node-level logging agent is the most common and encouraged approach for a Kubernetes cluster, since it creates only one agent per node and it doesn't require any changes to the applications running on the node. However, node-level logging only works for applications' standard output and standard error.
Kubernetes doesn't specify a logging agent, but two optional logging agents are packaged with the Kubernetes release: Stackdriver Logging for use with Google Cloud Platform, and Elasticsearch. You can find more information and instructions in the dedicated documents. Both use fluentd with custom configuration as an agent on the node.
Using a sidecar container with the logging agent
You can implement cluster-level logging by including a dedicated logging agent for each application on your cluster. You can include this logging agent as a "sidecar" container in the pod spec for each application; the sidecar container should contain only the logging agent.
The concrete implementation of the logging agent, the interface between agent and the application, and the interface between the logging agent and the logs back-end are completely up to a you. For an example implementation, see the fluentd sidecar container for the Stackdriver logging backend.
Note: Using a sidecar container for logging may lead to significant resource consumption.
Exposing logs directly from the application
You can implement cluster-level logging by exposing or pushing logs directly from every application itself; however, the implementation for such a logging mechanism is outside the scope of Kubernetes.