Container auto-discovery for on-host integrations

Our container auto-discovery feature allows you to configure an integration to automatically monitor services that run in multiple containers. In an integration's configuration file, you can set containers' matching criteria, and the agent executes the integration for each local container matching the criteria.

An integration will be executed as many times as it finds discovery elements. If discovery doesn't find any containers, the integration won't be executed.

Currently, the infrastructure agent can discover local Docker containers.

Add placeholders to your configuration

In your integration configuration, you must create ${discovery.<property>} placeholders. These will then be automatically replaced by specific container information.

These examples (for Docker-only environments and for Kubernetes) show how to configure an NGINX integration to monitor all local containers that have an image name containing nginx, and that are labeled as env=production. Each service will be available through different IPs and ports, so they must be variables.

Docker example (non-orchestrated)

This config applies to non-orchestrated scenarios, where Docker is used without Kubernetes or other orchestration environments.

discovery:
  docker:
    match:
      image: /nginx/
      label.env: production
integrations:
  - name: nginx-server-metrics
    command: metrics
    env:
      STATUS_URL: http://${discovery.ip}:${discovery.port}/status
      STATUS_MODULE: discover
      REMOTE_MONITORING: true
    labels:
      env: ${discovery.label.env}
      role: ${discovery.label.role}
Kubernetes example

If you use Kubernetes and our Kubernetes integration, this is how the ConfigMap for the integration would look like. Notice that nri-discovery-kubernetes accepts several optional arguments:

  • --namespaces: Comma separated list of namespaces
  • --tls: Use secure (TLS) connection
  • --port: The port used to connect to the kubelet. Default is 10255
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nri-integration-cfg
  namespace: default
data:
  nginx-config.yaml: |
    ---
    discovery:
      command:
        # Run discovery for Kubernetes. Use the following optional arguments:
        # --namespaces: Comma separated list of namespaces to discover pods on
        # --tls: Use secure (TLS) connection
        # --port: Port used to connect to the kubelet. Default is 10255
        exec: /var/db/newrelic-infra/nri-discovery-kubernetes --port PORT --tls
        match:
          image: /nginx/
          label.env: production
    integrations:
      - name: nri-nginx
        env:
          # Use the discovered IP as the host address
          STATUS_URL: http://${discovery.ip}/server-status?auto
          METRICS: 1

Add discovery properties

To configure discovery, set up a discovery entry in your integration configuration YAML using the following properties. A container will be matched when all the properties match the defined values.

Properties values will be matched with an exact string, unless the value to match is set between /.../. The contents within the slashes will be matched as regular expressions.

Discovery key name Description

ttl

Type: String

Time-To-Live of the cached discovery results, used to minimize the number of discovery processes. Define as a number followed by a time unit (s, m or h).

Examples: 30s, 10m, 1h, 0

Default: 1m

docker

Type: YAML properties

Docker containers matching definition. This consists of a match property containing a map where:

  • Each key is any of the following properties.
  • The value is the expected value of the given property for the returned containers.
  • A container matches if all the properties match (AND operation).

Available YAML keys include:

  • ip: Container external IP address, if any
  • private.ip: Container private IP address
  • port: Container external port number
  • private.port: Container private port number
  • image: Image name
  • name: Container name
  • label.<label name>: Any container label, accessible by its name

Discovery example

The following example matches all Docker containers whose image starts with httpd: (provided as a regular expression) and are labeled as scrapable=yes. The results are cached with a Time-To-Live of 5 minutes.

discovery:
  ttl: 5m
  docker:
    match:
      image: /^httpd:/
      label.scrapable: yes

Available container information

Our discovery feature currently emits the following variables, which can be used to configure your integrations. The infrastructure agent replaces them with the corresponding values of the discovered containers.

Be sure to add the discovery. prefix.

Variable Description
${discovery.ip} Container public IP address, if any
${discovery.private.ip} Container private IP address
${discovery.port} Container public port number
${discovery.private.port} Container private port number
${discovery.image} Image name
${discovery.name} Container name
${discovery.label.<label name>} Any container label, accessible by its name

Mapping multiple ports

When a container exposes many private or public ports, they can be accessed via discovery.private.ports. or discovery.ports. followed by an index starting in 0. The ports are indexed from the lower to higher private port value.

For example, a container that exposes the 80 and 443 private ports via the public ports 2345 and 1111, respectively, would provide the following variables with their respective values:

Variable Value
${discovery.private.ports.0} 80 (the lowest private port)
${discovery.private.ports.1} 443 (the highest private port)
${discovery.ports.0} 2345 (the public port mapping to private port 0)
${discovery.ports.1} 1111 (the public port mapping to private port 1)
${discovery.private.port} 80 (same as ${discovery.private.ports.0})
${discovery.port} 2345 (same as ${discovery.ports.0})

Notice that the port word is singular in the non-indexed variables and plural in the indexed variables.

Mapping ports by protocol name

In addition to the indexing from the previous section, ports can be also referred by its protocol name (e.g. tcp, udp, ...). For example, ${discovery.ports.tcp} , ${discovery.ports.udp}, etc...

If multiple ports match to the same protocol, they can also be indexed by the rules in the previous section: ${discovery.ports.tcp.0}, ${discovery.ports.tcp.1}, and so on.

For more help

If you need more help, check out these support and learning resources: