gokubernetesdaemonset

how to run host command in DaemonSet in kubernetes with golang?


Now,I want to monitor the status of the node(such as docker,kubelet,cri...) in cluster. So I wrote a golang program and deployed it as DaemonSet in kubernetes. But as you know, when the golang program runs the commands in the DaemonSet to get the correct result of host, it does't works. How to run "systemctl status kubelet/docker" in DaemonSet, but get the result of the host?

the test code likes:

package main

import (
    "fmt"
    "os/exec"
    "strings"
)

func main() {
    res,_:=ExecCommand("systemctl","status","kubelet")
    fmt.Println(res)
}

func ExecCommand(command string, args ...string) (string, error) {

    cmd := exec.Command(command, args...)
    out, err := cmd.Output()
    if err != nil {
        return "", err
    }

    return strings.TrimSuffix(string(out), "\n"), nil
}

I just want to run the command in DaemonSet to get the result of "systemctl status kubelet/docker" of host, not the container.But I don't know hot to get it.

I also try to deploy it as a privileged container:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: cluster-monitor
  namespace: cluster-monitor
spec:
  selector:
    matchLabels:
      app: cluster-monitor
  template:
    metadata:
      labels:
        app: cluster-monitor
    spec:
      containers:
        - name: cluster-monitor
          image: monitor:v6
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsUser: 0
            privileged: true
      hostIPC: true
      hostNetwork: true
      hostPID: true

What'more, I also try to set namespace of container using "nsenter" command in entrypoint.sh:

#!/bin/sh

## set host namespace
nsenter -t 1 -m -u -i -n /bin/sh

## run the program
/monitor -conf /config.toml

But no matter what I do, I can't get the status of the host in the container with using my monitor parogram as DaemonSet in kubernetes.

So what should I do to get the results of some commands of the host in a golang program as DaemonSet. Your answer is very important for me, thanks so much!


Solution

  • You need to use the hostPath attribute of volumes as shown here: https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

    This will allow you to map the files/directories from the host into your container, you will need to map the /var/run/docker.sock from the host into your container.

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: k8s.gcr.io/test-webserver
        name: test-container
        volumeMounts:
        - mountPath:  /var/run/docker.sock
          name: docker-socket
      volumes:
      - name: docker-socket
        hostPath:
          path: /var/run/docker.sock
          type: File
    

    Your image will also need to have docker installed on it