英文:
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创建的容器的网络信息:
import (
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
func main() {
// 读取kubeconfig文件
home := homedir.HomeDir()
kubeconfig := filepath.Join(home, ".kube", "config")
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err)
}
// 创建Kubernetes客户端
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
// 获取Pod的详细信息
podName := "your-pod-name"
namespace := "your-namespace"
pod, err := clientset.CoreV1().Pods(namespace).Get(podName, metav1.GetOptions{})
if err != nil {
panic(err)
}
// 提取容器的网络信息
for _, container := range pod.Spec.Containers {
networkStats := container.Resources.Networks
fmt.Println(networkStats)
}
}
请注意,上述代码中的your-pod-name
和your-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?
type StatsJSON struct {
Stats
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
// Networks request version >=1.21
Networks map[string]NetworkStats `json:"networks,omitempty"`
}
func main() {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
if err != nil {
panic(err)
}
for _, container := range containers {
containerStats, err := cli.ContainerStats(context.Background(), container.ID, false)
if err != nil {
panic(err)
}
fmt.Println(containerStats)
fmt.Println(containerStats.Body)
buf := new(bytes.Buffer)
buf.ReadFrom(containerStats.Body)
newStr := buf.String()
fmt.Printf(newStr)
}
}
my code is shown above.
I found that if the container is created by kubernetes, the code can't get the network info.
{"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.
{"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。
type ContainerStats struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}
下面的代码按预期工作。我可以将主体中的数据解码为StatsJSON
结构,并访问Networks
字段。
// 创建一个客户端
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
// 获取一些容器统计信息
cs, err := cli.ContainerStats(context.TODO(), "<container id>", false)
if err != nil {
panic(err)
}
// 不要忘记关闭主体
defer cs.Body.Close()
// 将主体解码为StatsJSON结构
data := types.StatsJSON{}
err = json.NewDecoder(cs.Body).Decode(&data)
if err != nil {
panic(err)
}
// 访问Networks字段
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.
type ContainerStats struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}
The below code works as expected. I can decode the data from the body into a StatsJSON
struct and access the Networks
fields.
// create a client
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
// get some container stats
cs, err := cli.ContainerStats(context.TODO(), "<container id>", false)
if err != nil {
panic(err)
}
// dont forget to close the body
defer cs.Body.Close()
// decode the body into a StatsJSON struct
data := types.StatsJSON{}
err = json.NewDecoder(cs.Body).Decode(&data)
if err != nil {
panic(err)
}
// access the Networks field
fmt.Println(data.Networks)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论