Metricbeat kubernetes module can’t connect to kubelet

12/24/2018

We have a setup, where Metricbeat is deployed as a DaemonSet on a Kubernetes cluster (specifically -- AWS EKS).

All seems to be functioning properly, but the kubelet connection.

To clarify, the following module:

- module: kubernetes
  enabled: true
  metricsets:
    - state_pod
  period: 10s
  hosts: ["kube-state-metrics.system:8080"]

works properly (the events flow into logstash/elastic).

This module configuration, however, doesn't work in any variants of hosts value (localhost/kubernetes.default/whatever):

- module: kubernetes
  period: 10s
  metricsets:
    - pod
  hosts: ["localhost:10255"]
  enabled: true
  add_metadata: true
  in_cluster: true

NOTE: using cluster IP instead of localhost (so that it goes to control plane) also works (although doesn't retrieve the needed information, of course).

The configuration above was taken directly from the Metricbeat documentation and immediately struck me as odd -- how does localhost get translated (from within Metricbeat docker) to corresponding kubelet?

The error is, as one would expect, in light of the above:

error making http request: Get http://localhost:10255/stats/summary: 
dial tcp [::1]:10255: connect: cannot assign requested address

which indicates some sort of connectivity issue.

However, when SSH-ing to any node Metricbeat is deployed on, http://localhost:10255/stats/summary provides the correct output:

{
  "node": {
   "nodeName": "...",
   "systemContainers": [
    {
     "name": "pods",
     "startTime": "2018-12-06T11:22:07Z",
     "cpu": {
      "time": "2018-12-23T06:54:06Z",
      ...
     },
     "memory": {
      "time": "2018-12-23T06:54:06Z",
      "availableBytes": 17882275840,
      ....

I must be missing something very obvious. Any suggestion would do.

NOTE: I cross-posted (and got no response for a couple of days) the same on Elasticsearch Forums

-- ZenMaster
elastic-stack
kubernetes
metricbeat

1 Answer

12/29/2018

Inject the Pod's Node's IP via the valueFrom provider in the env: list:

env:
- name: HOST_IP
  valueFrom:
    fieldRef: status.hostIP

and then update the metricbeat config file to use the host's IP:

hosts: ["${HOST_IP}:10255"]

which metricbeat will resolve via its environment variable config injection

-- mdaniel
Source: StackOverflow