• Go语言实现通过Docker SDK获取docker ps 命令信息&SDK 中docker ps源码解析


    在命令行中我们可以通过docker ps命令去获取当前正在执行的容器。那么怎么在程序中获取到这些信息呢?

    这里使用的是Docker GO语言的SDK,官网参考链接为:SDK 除了GO语言外,还支持Python语言和HTTP获取。

    一、首先需要获取到SDK的依赖包 主要是以下两个包,将其放到$GOPATH目录下

    	"github.com/docker/docker/api/types"
    	"github.com/docker/docker/client"
    

    二、获取docker ps 或者docker ps -a的信息代码如下

    package main
    
    import (
    	"context"
    	"fmt"
    
    	"github.com/docker/docker/api/types"
    	"github.com/docker/docker/client"
    )
    
    func main() {
    	//第一步:获取ctx
    	ctx := context.Background()
    	
    	//获取cli客户端对象
    	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
    	if err != nil {
    		panic(err)
    	}
    	//通过cli客户端对象去执行ContainerList(其实docker ps 不就是一个docker正在运行容器的一个list嘛)
    	containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})
    	
    	//下面这条命令可以获取到docker ps -a 也就是所有容器包括运行的和没有运行的
    	//containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
    	if err != nil {
    		panic(err)
    	}
    	
    	//将获取到的结果输出
    	fmt.Println("container.ID,							container.Names,    container.Created,   container.Status,    container.Ports")
    	for _, container := range containers {
    		fmt.Println(container.ID,container.Names,container.Created,container.Status,container.Ports)
    	}
    }
    

    运行结果如下:

    三、查看源码

    首先来看看containers这里面到底有些啥 源码和注释如下:

    type Container struct {
    	ID         string   `json:"Id"` //容器id
    	Names      []string //容器名称
    	Image      string   //镜像名称
    	ImageID    string   //镜像id
    	Command    string   //命令
    	Created    int64    //创建时间,时间戳,单位秒
    	Ports      []Port   //端口信息
    	SizeRw     int64    `json:",omitempty"`
    	SizeRootFs int64    `json:",omitempty"`
    	Labels     map[string]string
    	State      string
    	Status     string //状态,运行或者结束Exited (0)
    	HostConfig struct {
    		NetworkMode string `json:",omitempty"`
    	}
    	NetworkSettings *SummaryNetworkSettings
    	Mounts          []MountPoint
    }
    

    信息还是很全面的。

    来看看它是怎么获取到的,首先是ContainerList这个函数,关于ctx这个对象待会儿再说,里面其实就是解析了一下我们传入的参数,例如我上面的All : true 其实就是docker ps 对应的一些参数而已。然后通过cli的get命令获取的

    // ContainerList returns the list of containers in the docker host.
    func (cli *Client) ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) {
    	query := url.Values{}
    
    	if options.All {
    		query.Set("all", "1")
    	}
    
    	if options.Limit != -1 {
    		query.Set("limit", strconv.Itoa(options.Limit))
    	}
    
    	if options.Since != "" {
    		query.Set("since", options.Since)
    	}
    
    	if options.Before != "" {
    		query.Set("before", options.Before)
    	}
    
    	if options.Size {
    		query.Set("size", "1")
    	}
    
    	if options.Filters.Len() > 0 {
    		//nolint:staticcheck // ignore SA1019 for old code
    		filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
    
    		if err != nil {
    			return nil, err
    		}
    
    		query.Set("filters", filterJSON)
    	}
    	//这里就是他的数据来源,用了cli客户端的get方法,基本上所有的命令都是这种方式获取的,感觉还是使用的HTTP API
    	resp, err := cli.get(ctx, "/containers/json", query, nil)
    	defer ensureReaderClosed(resp)
    	if err != nil {
    		return nil, err
    	}
    
    	var containers []types.Container
    	err = json.NewDecoder(resp.body).Decode(&containers)
    	return containers, err
    }
    

    既然他的数据来自于cli.get(),那我们来看看这个方法是个啥

    // get sends an http request to the docker API using the method GET with a specific Go context.
    func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
    	return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers)
    }
    

    和我说的一样,真的就是访问的HTTP API 看到这里基本上就能知道数据来源了。

    总结

    Docker的go语言的SDK基本上全是使用的HTTP API ,所以用起来他的用法基本类似,其他的也很容易看懂。

  • 相关阅读:
    RESTful Web服务的操作
    Nginx学习之如何搭建文件防盗链服务
    PostgreSQL10.5安装详细步骤(Win10)
    前端安全系列(一):如何防止XSS攻击?
    【原码笔记】-- protobuf.js 与 Long.js
    【微信开发】-- 发送模板消息
    能编程与会编程
    vue2入坑随记(二) -- 自定义动态组件
    微信上传图片
    vue2入坑随记(一)-- 初始全家桶
  • 原文地址:https://www.cnblogs.com/xwxz/p/13634394.html
Copyright © 2020-2023  润新知