How can i get the info of container created by kubernetes as types.StatsJSON from docker golang client?

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

How can i get the info of container created by kubernetes as types.StatsJSON from docker golang client?

问题

在Docker Go客户端库中,要获取容器的types.StatsJSON,可以使用client.ContainerStats方法。但是,根据你提供的代码和示例输出,这种方法无法获取由Kubernetes创建的容器的网络信息。

要获取由Kubernetes创建的容器的网络信息,可以尝试使用Kubernetes客户端库来获取容器的详细信息,包括网络信息。你可以使用clientset.CoreV1().Pods(namespace).Get(podName, metav1.GetOptions{})方法来获取Pod的详细信息,其中namespace是Pod所在的命名空间,podName是Pod的名称。

在获取到Pod的详细信息后,你可以从中提取出容器的网络信息。具体的代码实现可能会有所不同,但以下是一个示例代码,用于获取由Kubernetes创建的容器的网络信息:

  1. import (
  2. "fmt"
  3. "k8s.io/client-go/kubernetes"
  4. "k8s.io/client-go/tools/clientcmd"
  5. "k8s.io/client-go/util/homedir"
  6. "path/filepath"
  7. )
  8. func main() {
  9. // 读取kubeconfig文件
  10. home := homedir.HomeDir()
  11. kubeconfig := filepath.Join(home, ".kube", "config")
  12. config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
  13. if err != nil {
  14. panic(err)
  15. }
  16. // 创建Kubernetes客户端
  17. clientset, err := kubernetes.NewForConfig(config)
  18. if err != nil {
  19. panic(err)
  20. }
  21. // 获取Pod的详细信息
  22. podName := "your-pod-name"
  23. namespace := "your-namespace"
  24. pod, err := clientset.CoreV1().Pods(namespace).Get(podName, metav1.GetOptions{})
  25. if err != nil {
  26. panic(err)
  27. }
  28. // 提取容器的网络信息
  29. for _, container := range pod.Spec.Containers {
  30. networkStats := container.Resources.Networks
  31. fmt.Println(networkStats)
  32. }
  33. }

请注意,上述代码中的your-pod-nameyour-namespace需要替换为你实际使用的Pod的名称和命名空间。

希望这可以帮助到你获取由Kubernetes创建的容器的网络信息。如果有任何进一步的问题,请随时提问。

英文:

Code in the file github.com/docker/docker/client/container_stats.go shows 2 ways to get container info, client.ContainerStats and client.ContainerStatsOneShot.
But the results both are types.ContainerStats, which doesn't include network info.
How can i get the types.StatsJSON of a container with the Docker Go client library?

  1. type StatsJSON struct {
  2. Stats
  3. Name string `json:"name,omitempty"`
  4. ID string `json:"id,omitempty"`
  5. // Networks request version >=1.21
  6. Networks map[string]NetworkStats `json:"networks,omitempty"`
  7. }
  1. func main() {
  2. cli, err := client.NewClientWithOpts(client.FromEnv)
  3. if err != nil {
  4. panic(err)
  5. }
  6. containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
  7. if err != nil {
  8. panic(err)
  9. }
  10. for _, container := range containers {
  11. containerStats, err := cli.ContainerStats(context.Background(), container.ID, false)
  12. if err != nil {
  13. panic(err)
  14. }
  15. fmt.Println(containerStats)
  16. fmt.Println(containerStats.Body)
  17. buf := new(bytes.Buffer)
  18. buf.ReadFrom(containerStats.Body)
  19. newStr := buf.String()
  20. fmt.Printf(newStr)
  21. }

}

my code is shown above.

I found that if the container is created by kubernetes, the code can't get the network info.

  1. {"read":"2022-04-16T13:19:35.763484238Z","preread":"2022-04-16T13:19:34.758939054Z","pids_stats":{"current":2},"blkio_stats":{"io_service_bytes_recursive":[],"io_serviced_recursive":[],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]},"num_procs":0,"storage_stats":{},"cpu_stats":{"cpu_usage":{"total_usage":81301483,"percpu_usage":[0,381774,697871,3974768,0,49920,599904,622885,6274012,858410,0,570611,52635,11229798,100631,0,99914,0,479666,698862,51132727,902108,1941742,633245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"usage_in_kernelmode":40000000,"usage_in_usermode":20000000},"system_cpu_usage":82393060580000000,"online_cpus":24,"throttling_data":{"periods":12,"throttled_periods":8,"throttled_time":811771919}},"precpu_stats":{"cpu_usage":{"total_usage":81301483,"percpu_usage":[0,381774,697871,3974768,0,49920,599904,622885,6274012,858410,0,570611,52635,11229798,100631,0,99914,0,479666,698862,51132727,902108,1941742,633245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"usage_in_kernelmode":40000000,"usage_in_usermode":20000000},"system_cpu_usage":82393036780000000,"online_cpus":24,"throttling_data":{"periods":12,"throttled_periods":8,"throttled_time":811771919}},"memory_stats":{"usage":1515520,"max_usage":7999488,"stats":{"active_anon":196608,"active_file":0,"cache":0,"dirty":0,"hierarchical_memory_limit":419430400,"hierarchical_memsw_limit":0,"inactive_anon":0,"inactive_file":0,"mapped_file":0,"pgfault":2077,"pgmajfault":0,"pgpgin":1658,"pgpgout":1610,"rss":196608,"rss_huge":0,"total_active_anon":196608,"total_active_file":0,"total_cache":0,"total_dirty":0,"total_inactive_anon":0,"total_inactive_file":0,"total_mapped_file":0,"total_pgfault":2077,"total_pgmajfault":0,"total_pgpgin":1658,"total_pgpgout":1610,"total_rss":196608,"total_rss_huge":0,"total_unevictable":0,"total_writeback":0,"unevictable":0,"writeback":0},"limit":419430400},"name":"/k8s_centos_ltstatefulset-b-0_default_19f13fc1-b971-47c0-9519-619b64c01b68_195","id":"b15626bfc4665c457c7fb319f17e162d611262d193e38ec9e7878ca8b3e8b02b"}

if not, the code works.

  1. {"read":"2022-04-16T14:35:12.97263525Z","preread":"2022-04-16T14:35:11.937969083Z","pids_stats":{"current":25},"blkio_stats":{"io_service_bytes_recursive":[{"major":8,"minor":0,"op":"Read","value":11210752},{"major":8,"minor":0,"op":"Write","value":8192},{"major":8,"minor":0,"op":"Sync","value":4096},{"major":8,"minor":0,"op":"Async","value":11214848},{"major":8,"minor":0,"op":"Total","value":11218944}],"io_serviced_recursive":[{"major":8,"minor":0,"op":"Read","value":527},{"major":8,"minor":0,"op":"Write","value":2},{"major":8,"minor":0,"op":"Sync","value":1},{"major":8,"minor":0,"op":"Async","value":528},{"major":8,"minor":0,"op":"Total","value":529}],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]},"num_procs":0,"storage_stats":{},"cpu_stats":{"cpu_usage":{"total_usage":349863146,"percpu_usage":[10474676,1510192,454233,1388678,254249,80111,3389261,101473612,416604,8936772,5378206,4940434,0,347495,891133,85645,0,0,168781006,13378842,9622376,4594553,9938770,3526298],"usage_in_kernelmode":80000000,"usage_in_usermode":260000000},"system_cpu_usage":109879214590000000,"online_cpus":24,"throttling_data":{"periods":0,"throttled_periods":0,"throttled_time":0}},"precpu_stats":{"cpu_usage":{"total_usage":349863146,"percpu_usage":[10474676,1510192,454233,1388678,254249,80111,3389261,101473612,416604,8936772,5378206,4940434,0,347495,891133,85645,0,0,168781006,13378842,9622376,4594553,9938770,3526298],"usage_in_kernelmode":80000000,"usage_in_usermode":260000000},"system_cpu_usage":109879190530000000,"online_cpus":24,"throttling_data":{"periods":0,"throttled_periods":0,"throttled_time":0}},"memory_stats":{"usage":33136640,"max_usage":34250752,"stats":{"active_anon":15036416,"active_file":4644864,"cache":11415552,"dirty":0,"hierarchical_memory_limit":9223372036854771712,"hierarchical_memsw_limit":0,"inactive_anon":4096,"inactive_file":6766592,"mapped_file":5271552,"pgfault":9844,"pgmajfault":77,"pgpgin":9350,"pgpgout":2892,"rss":15036416,"rss_huge":0,"total_active_anon":15036416,"total_active_file":4644864,"total_cache":11415552,"total_dirty":0,"total_inactive_anon":4096,"total_inactive_file":6766592,"total_mapped_file":5271552,"total_pgfault":9844,"total_pgmajfault":77,"total_pgpgin":9350,"total_pgpgout":2892,"total_rss":15036416,"total_rss_huge":0,"total_unevictable":0,"total_writeback":0,"unevictable":0,"writeback":0},"limit":50609074176},"name":"/mynginx","id":"4af194a6885917eed220a0c45a235e749b566bd5aa0ab18ae5aaf5c6295fc527","networks":{"eth0":{"rx_bytes":3385,"rx_packets":47,"rx_errors":0,"rx_dropped":1,"tx_bytes":0,"tx_packets":0,"tx_errors":0,"tx_dropped":0}}}

How can i get the network info of the container created by k8s?

答案1

得分: 2

你需要读取ContainerStats的主体,因为它返回的数据在一个名为body的字段中,该字段是一个io.ReadCloser

  1. type ContainerStats struct {
  2. Body io.ReadCloser `json:"body"`
  3. OSType string `json:"ostype"`
  4. }

下面的代码按预期工作。我可以将主体中的数据解码为StatsJSON结构,并访问Networks字段。

  1. // 创建一个客户端
  2. cli, err := client.NewClientWithOpts(client.FromEnv)
  3. if err != nil {
  4. panic(err)
  5. }
  6. // 获取一些容器统计信息
  7. cs, err := cli.ContainerStats(context.TODO(), "<container id>", false)
  8. if err != nil {
  9. panic(err)
  10. }
  11. // 不要忘记关闭主体
  12. defer cs.Body.Close()
  13. // 将主体解码为StatsJSON结构
  14. data := types.StatsJSON{}
  15. err = json.NewDecoder(cs.Body).Decode(&data)
  16. if err != nil {
  17. panic(err)
  18. }
  19. // 访问Networks字段
  20. fmt.Println(data.Networks)
英文:

You need to read the body since ContainerStats returns the data in a field named body which is an io.ReadCloser.

  1. type ContainerStats struct {
  2. Body io.ReadCloser `json:&quot;body&quot;`
  3. OSType string `json:&quot;ostype&quot;`
  4. }

The below code works as expected. I can decode the data from the body into a StatsJSON struct and access the Networks fields.

  1. // create a client
  2. cli, err := client.NewClientWithOpts(client.FromEnv)
  3. if err != nil {
  4. panic(err)
  5. }
  6. // get some container stats
  7. cs, err := cli.ContainerStats(context.TODO(), &quot;&lt;container id&gt;&quot;, false)
  8. if err != nil {
  9. panic(err)
  10. }
  11. // dont forget to close the body
  12. defer cs.Body.Close()
  13. // decode the body into a StatsJSON struct
  14. data := types.StatsJSON{}
  15. err = json.NewDecoder(cs.Body).Decode(&amp;data)
  16. if err != nil {
  17. panic(err)
  18. }
  19. // access the Networks field
  20. fmt.Println(data.Networks)

huangapple
  • 本文由 发表于 2022年4月16日 20:52:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/71894035.html
匿名

发表评论

匿名网友

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

确定