Running Metricbeat on Docker

edit

Docker images for Metricbeat are available from the Elastic Docker registry. The base image is centos:7.

A list of all published Docker images and tags is available at www.docker.elastic.co. The source code is in GitHub.

These images are free to use under the Elastic license. They contain open source and free commercial features and access to paid commercial features. Start a 30-day trial to try out all of the paid commercial features. See the Subscriptions page for information about Elastic license levels.

Pulling the image

edit

Obtaining Beats for Docker is as simple as issuing a docker pull command against the Elastic Docker registry.

docker pull docker.elastic.co/beats/metricbeat:6.4.3

Alternatively, you can download other Docker images that contain only features available under the Apache 2.0 license. To download the images, go to www.docker.elastic.co.

Configure Metricbeat on Docker

edit

The Docker image provides several methods for configuring Metricbeat. The conventional approach is to provide a configuration file via a bind mount, but it’s also possible to create a custom image with your configuration included.

Bind-mounted configuration
edit

One way to configure Metricbeat on Docker is to provide metricbeat.yml via a bind mount. With docker run, the bind mount can be specified like this:

docker run \
  --mount type=bind,source="$(pwd)"/metricbeat.yml,target=/usr/share/metricbeat/metricbeat.yml \
  docker.elastic.co/beats/metricbeat:6.4.3
Custom image configuration
edit

It’s possible to embed your Metricbeat configuration in a custom image. Here is an example Dockerfile to achieve this:

FROM docker.elastic.co/beats/metricbeat:6.4.3
COPY metricbeat.yml /usr/share/metricbeat/metricbeat.yml
USER root
RUN chown root:metricbeat /usr/share/metricbeat/metricbeat.yml
USER metricbeat

Monitor the host machine

edit

When executing Metricbeat in a container, there are some important things to be aware of if you want to monitor the host machine or other containers. Let’s walk-through some examples using Docker as our container orchestration tool.

This example highlights the changes required to make the system module work properly inside of a container. This enables Metricbeat to monitor the host machine from within the container.

docker run \
  --mount type=bind,source=/proc,target=/hostfs/proc,readonly \ 
  --mount type=bind,source=/sys/fs/cgroup,target=/hostfs/sys/fs/cgroup,readonly \ 
  --mount type=bind,source=/,target=/hostfs,readonly \ 
  --net=host 
  docker.elastic.co/beats/metricbeat:6.4.3 -system.hostfs=/hostfs

Metricbeat’s system module collects much of its data through the Linux proc filesystem, which is normally located at /proc. Because containers are isolated as much as possible from the host, the data inside of the container’s /proc is different than the host’s /proc. To account for this, you can mount the host’s /proc filesystem inside of the container and tell Metricbeat to look inside the /hostfs directory when looking for /proc by using the -system.hostfs=/hostfs CLI flag.

By default, cgroup reporting is enabled for the system process metricset, so you need to mount the host’s cgroup mountpoints within the container. They need to be mounted inside the directory specified by the -system.hostfs CLI flag.

If you want to be able to monitor filesystems from the host by using the system filesystem metricset, then those filesystems need to be mounted inside of the container. They can be mounted at any location.

The system network metricset uses data from /proc/net/dev, or /hostfs/proc/net/dev when using -system.hostfs=/hostfs. The only way to make this file contain the host’s network devices is to use the --net=host flag. This is due to Linux namespacing; simply bind mounting the host’s /proc to /hostfs/proc is not sufficient.

The special filesystems /proc and /sys are only available if the host system is running Linux. Attempts to bind-mount these filesystems will fail on Windows and MacOS.

Monitor a service in another container

edit

Next, let’s look at an example of monitoring a containerized service from a Metricbeat container.

docker run \
  --network=mysqlnet \ 
  -e MYSQL_PASSWORD=secret \ 
  docker.elastic.co/beats/metricbeat:6.4.3

Placing the Metricbeat and MySQL containers on the same Docker network allows Metricbeat access to the exposed ports of the MySQL container, and makes the hostname mysql resolvable to Metricbeat.

If you do not want to hardcode certain values into your Metricbeat configuration, then you can pass them into the container either as environment variables or as command line flags to Metricbeat (see the -E CLI flag in Command reference).

The mysql module configuration would look like this:

metricbeat.modules:
- module: mysql
  metricsets: ["status"]
  hosts: ["tcp(mysql:3306)/"] 
  username: root
  password: ${MYSQL_PASSWORD} 

The mysql hostname will resolve to the address of a container named mysql on the mysqlnet Docker network.

The MYSQL_PASSWORD variable will be evaluated at startup. If the variable is not set, this will lead to an error at startup.