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

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

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

问题

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

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

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

测试代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "strings"
  6. )
  7. func main() {
  8. res, _ := ExecCommand("systemctl", "status", "kubelet")
  9. fmt.Println(res)
  10. }
  11. func ExecCommand(command string, args ...string) (string, error) {
  12. cmd := exec.Command(command, args...)
  13. out, err := cmd.Output()
  14. if err != nil {
  15. return "", err
  16. }
  17. return strings.TrimSuffix(string(out), "\n"), nil
  18. }

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

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

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: cluster-monitor
  5. namespace: cluster-monitor
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: cluster-monitor
  10. template:
  11. metadata:
  12. labels:
  13. app: cluster-monitor
  14. spec:
  15. containers:
  16. - name: cluster-monitor
  17. image: monitor:v6
  18. imagePullPolicy: IfNotPresent
  19. securityContext:
  20. runAsUser: 0
  21. privileged: true
  22. hostIPC: true
  23. hostNetwork: true
  24. hostPID: true

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

  1. #!/bin/sh
  2. ## set host namespace
  3. nsenter -t 1 -m -u -i -n /bin/sh
  4. ## run the program
  5. /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:

  1. package main
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "strings"
  6. )
  7. func main() {
  8. res,_:=ExecCommand("systemctl","status","kubelet")
  9. fmt.Println(res)
  10. }
  11. func ExecCommand(command string, args ...string) (string, error) {
  12. cmd := exec.Command(command, args...)
  13. out, err := cmd.Output()
  14. if err != nil {
  15. return "", err
  16. }
  17. return strings.TrimSuffix(string(out), "\n"), nil
  18. }

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:

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: cluster-monitor
  5. namespace: cluster-monitor
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: cluster-monitor
  10. template:
  11. metadata:
  12. labels:
  13. app: cluster-monitor
  14. spec:
  15. containers:
  16. - name: cluster-monitor
  17. image: monitor:v6
  18. imagePullPolicy: IfNotPresent
  19. securityContext:
  20. runAsUser: 0
  21. privileged: true
  22. hostIPC: true
  23. hostNetwork: true
  24. hostPID: true

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

  1. #!/bin/sh
  2. ## set host namespace
  3. nsenter -t 1 -m -u -i -n /bin/sh
  4. ## run the program
  5. /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映射到容器中。

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: test-pd
  5. spec:
  6. containers:
  7. - image: k8s.gcr.io/test-webserver
  8. name: test-container
  9. volumeMounts:
  10. - mountPath: /var/run/docker.sock
  11. name: docker-socket
  12. volumes:
  13. - name: docker-socket
  14. hostPath:
  15. path: /var/run/docker.sock
  16. 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.

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: test-pd
  5. spec:
  6. containers:
  7. - image: k8s.gcr.io/test-webserver
  8. name: test-container
  9. volumeMounts:
  10. - mountPath: /var/run/docker.sock
  11. name: docker-socket
  12. volumes:
  13. - name: docker-socket
  14. hostPath:
  15. path: /var/run/docker.sock
  16. 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:

确定