如何在Kubernetes中使用Golang在DaemonSet中运行主机命令?

huangapple go评论89阅读模式
英文:

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

问题

现在,我想要监控集群中节点(如docker、kubelet、cri等)的状态。所以我编写了一个用golang编写的程序,并将其部署为Kubernetes中的DaemonSet。

但是,正如你所知道的,当golang程序在DaemonSet中运行命令以获取主机的正确结果时,它不起作用。

如何在DaemonSet中运行"systemctl status kubelet/docker"命令,但获取主机的结果呢?

测试代码如下:

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
}

我只想在DaemonSet中运行命令以获取主机的"systemctl status kubelet/docker"结果,而不是容器的结果。但我不知道如何做到。

我还尝试将其部署为特权容器:

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

此外,我还尝试在entrypoint.sh中使用"nsenter"命令设置容器的命名空间:

#!/bin/sh

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

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

但无论我做什么,我都无法在作为DaemonSet在Kubernetes中使用我的监控程序的容器中获取主机的状态。

那么,我应该如何在一个golang程序作为DaemonSet时获取主机的一些命令结果呢?

你的答案对我非常重要,非常感谢!

英文:

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!

答案1

得分: 0

你需要使用卷的hostPath属性,如此处所示:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

这将允许你将主机上的文件/目录映射到容器中,你需要将主机上的/var/run/docker.sock映射到容器中。

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

你的镜像还需要安装Docker。

英文:

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

huangapple
  • 本文由 发表于 2022年6月2日 17:00:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/72473504.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定