Skip to content

Commit

Permalink
strip rootfs prefix for run in docker
Browse files Browse the repository at this point in the history
- relates to prometheus#66

Signed-off-by: Ivan Mikheykin <ivan.mikheykin@flant.com>
  • Loading branch information
diafour authored and cofyc committed Sep 3, 2018
1 parent 05e55bd commit 88115b6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,23 @@ The node\_exporter is designed to monitor the host system. It's not recommended
to deploy it as Docker container because it requires access to the host system.
Be aware that any non-root mount points you want to monitor will need bind-mounted
into the container.
If you start container for host monitoring, specify `path.rootfs` argument.
This argument must match path in bind-mount of host root. The node\_exporter will use
`path.rootfs` as prefix to filter entries in ${path.procfs}/mounts and to
cleanup it from `mountpoint` label. You also need bind-mount host proc and host sys
with `path.procfs` and `path.sysfs` arguments.
Also you need to use `bind-propagation=rslave` option for bind-mount host rootfs to
propagate host mounts changes to container (option available since 17.05.0).

```bash
docker run -d \
--net="host" \
--pid="host" \
quay.io/prometheus/node-exporter
-v "/proc:/host/proc:ro" -v "/sys:/host/sys:ro" \
--mount "type=bind,source=/,target=/rootfs,readonly,bind-propagation=rslave" \
quay.io/prometheus/node-exporter \
--path.procfs /host/proc --path.sysfs /host/sys \
--path.rootfs /rootfs
```

On some systems, the `timex` collector requires an additional Docker flag,
Expand Down
10 changes: 7 additions & 3 deletions collector/filesystem_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
go stuckMountWatcher(labels.mountPoint, success)

buf := new(syscall.Statfs_t)
err = syscall.Statfs(labels.mountPoint, buf)
err = syscall.Statfs(rootfsFilePath(labels.mountPoint), buf)

stuckMountsMtx.Lock()
close(success)
Expand All @@ -86,7 +86,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
labels: labels,
deviceError: 1,
})
log.Debugf("Error on statfs() system call for %q: %s", labels.mountPoint, err)
log.Debugf("Error on statfs() system call for %q: %s", rootfsFilePath(labels.mountPoint), err)
continue
}

Expand Down Expand Up @@ -143,6 +143,10 @@ func mountPointDetails() ([]filesystemLabels, error) {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
parts := strings.Fields(scanner.Text())
// skip non rootfs paths if rootfsPath defined
if !rootfsPathDetect(parts[1]) {
continue
}

// Ensure we handle the translation of \040 and \011
// as per fstab(5).
Expand All @@ -151,7 +155,7 @@ func mountPointDetails() ([]filesystemLabels, error) {

filesystems = append(filesystems, filesystemLabels{
device: parts[0],
mountPoint: parts[1],
mountPoint: rootfsStripPrefix(parts[1]),
fsType: parts[2],
options: parts[3],
})
Expand Down
33 changes: 31 additions & 2 deletions collector/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ package collector

import (
"path"
"strings"

"github.com/prometheus/procfs"
"gopkg.in/alecthomas/kingpin.v2"
)

var (
// The path of the proc filesystem.
procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String()
sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String()
procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String()
sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String()
rootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("").String()
)

func procFilePath(name string) string {
Expand All @@ -33,3 +35,30 @@ func procFilePath(name string) string {
func sysFilePath(name string) string {
return path.Join(*sysPath, name)
}

func rootfsFilePath(name string) string {
if name == "/" {
return *rootfsPath
}
return path.Join(*rootfsPath, name)
}

func rootfsStripPrefix(path string) string {
if path == *rootfsPath {
return "/"
}
if strings.HasPrefix(path, *rootfsPath) {
return strings.TrimPrefix(path, *rootfsPath)
}
return path
}

func rootfsPathDetect(path string) bool {
if *rootfsPath == "" {
return true
}
if strings.HasPrefix(path, *rootfsPath) {
return true
}
return false
}

0 comments on commit 88115b6

Please sign in to comment.