include::{libbeat-dir}/shared-docker.asciidoc[]

[float]
[[monitoring-host]]
==== Monitor the host machine
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.

["source","sh",subs="attributes"]
----
docker run \
  --mount type=bind,source=/proc,target=/hostfs/proc,readonly \ <1>
  --mount type=bind,source=/sys/fs/cgroup,target=/hostfs/sys/fs/cgroup,readonly \ <2>
  --mount type=bind,source=/,target=/hostfs,readonly \ <3>
  --net=host \ <4>
  {dockerimage} -e -system.hostfs=/hostfs
----

<1> Metricbeat's <<metricbeat-module-system,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.
<2> By default, cgroup reporting is enabled for the
<<metricbeat-metricset-system-process,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.
<3> If you want to be able to monitor filesystems from the host by using the
<<metricbeat-metricset-system-filesystem,system filesystem metricset>>, then those filesystems need to be mounted inside
of the container. They can be mounted at any location.
<4> The <<metricbeat-metricset-system-network,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.

NOTE: 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.


If the <<metricbeat-metricset-system-socket,system socket metricset>>
is being used on Linux, more privileges will need to be granted to Metricbeat.
This metricset reads files from `/proc` that are an interface to internal
objects owned by other users. The capabilities needed to read all these files
(`sys_ptrace` and `dac_read_search`) are disabled by default on Docker. To
grant these permissions these flags are needed too:

["source","sh",subs="attributes"]
----
--user root --cap-add sys_ptrace --cap-add dac_read_search
----
[float]

[[monitoring-service]]
==== Monitor a service in another container

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

["source","sh",subs="attributes"]
----
docker run \
  --network=mysqlnet \ <1>
  -e MYSQL_PASSWORD=secret \ <2>
  {dockerimage}
----

<1> 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.
<2> 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-line-options>>).

The mysql module configuration would look like this:

[source,yaml]
----
metricbeat.modules:
- module: mysql
  metricsets: ["status"]
  hosts: ["tcp(mysql:3306)/"] <1>
  username: root
  password: ${MYSQL_PASSWORD} <2>
----

<1> The `mysql` hostname will resolve to the address of a container
named `mysql` on the `mysqlnet` Docker network.
<2> The `MYSQL_PASSWORD` variable will be evaluated at startup. If the variable
is not set, this will lead to an error at startup.
