1 获取容器列表
| func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]Container, error) |
| containers, err := Cli.ContainerList(context.Background(), types.ContainerListOptions{All: true}) |
| package main |
| |
| import ( |
| "bufio" |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/client" |
| "io" |
| "log" |
| "os" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| err = GetContainers(cli) |
| if err != nil { |
| fmt.Println(err) |
| } |
| } |
| |
| |
| |
| func ConnectDocker() (cli *client.Client, err error) { |
| cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375")) |
| if err != nil { |
| fmt.Println(err) |
| return nil, err |
| } |
| |
| return cli, nil |
| } |
| |
| |
| |
| func GetContainers(cli *client.Client) error { |
| |
| containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| |
| for _, container := range containers { |
| fmt.Printf("%s %s\n", container.ID[:10], container.Image) |
| } |
| return nil |
| } |
| docker 链接成功 |
| 08d317f408 harbocto.boe.com.cn/public/redis:4 |
| c91fc7eeb1 harbocto.boe.com.cn/public/mysql:5.7 |
| 48bcf68112 harbocto.boe.com.cn/crow/crow-qin |
| 381f5b2790 harbocto.boe.com.cn/magicube/ibex:0.3 |
2 查看指定容器信息
| func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (ContainerJSON, error) |
语法示例
| ctx := context.Background() |
| containerJson, err := cli.ContainerInspect(ctx, containerId) |
| type ContainerJSON struct { |
| *ContainerJSONBase |
| Mounts []MountPoint |
| Config *Config |
| NetworkSettings *NetworkSettings |
| } |
| type ContainerJSONBase struct { |
| ID string `json:"Id"` |
| Created string |
| Path string |
| Args []string |
| State *ContainerState |
| Image string |
| ResolvConfPath string |
| HostnamePath string |
| HostsPath string |
| LogPath string |
| Node *ContainerNode `json:",omitempty"` |
| Name string |
| RestartCount int |
| Driver string |
| Platform string |
| MountLabel string |
| ProcessLabel string |
| AppArmorProfile string |
| ExecIDs []string |
| HostConfig *HostConfig |
| GraphDriver GraphDriverData |
| SizeRw *int64 `json:",omitempty"` |
| SizeRootFs *int64 `json:",omitempty"` |
| } |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/client" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| containerId := "48bcf6811212" |
| containerJson, err := GetContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Printf("=======容器信息======\nID:%+v\name:%+v\n", containerJson.ID[:10], containerJson.Name) |
| } |
| |
| func GetContainer(cli *client.Client, containerId string) (containerInfo types.ContainerJSON, err error) { |
| ctx := context.Background() |
| containerJson, err := cli.ContainerInspect(ctx, containerId) |
| if err != nil { |
| fmt.Println(err) |
| return containerJson, err |
| } |
| return containerJson, nil |
| } |
| docker 链接成功 |
| =======容器信息====== |
| ID:48bcf68112 |
| ame:/crow-qin_crow_qin_1 |
3. 查看容器日志
| func (cli *Client) ContainerLogs(ctx context.Context, container string, options ContainerLogsOptions) (io.ReadCloser, error) |
| ctx := context.Background() |
| logs, err := Cli.ContainerLogs(ctx, containerId, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "200"}) |
- 参数
- ShowStdout:标准输出
- ShowStderr:错误输出
- Follow:
- Tail:看结尾多少行,string类型,默认"all"
- 完整示例
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| err = containerLogs(cli, "48bcf68112") |
| if err != nil { |
| fmt.Println(err) |
| } |
| } |
| |
| |
| |
| func ConnectDocker() (cli *client.Client, err error) { |
| cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375")) |
| if err != nil { |
| fmt.Println(err) |
| return nil, err |
| } |
| |
| return cli, nil |
| } |
| |
| |
| |
| func containerLogs(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| logs, err := cli.ContainerLogs(ctx, containerId, types.ContainerLogsOptions{ShowStdout: true, Follow: true, ShowStderr: true}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| _, err = io.Copy(os.Stdout, logs) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
4 创建容器
4.1 简单使用
4.1.1 语法
| func (cli *Client) ContainerCreate(ctx context.Context, config *Config, hostConfig *HostConfig, networkingConfig *NetworkingConfig, platform *Platform, containerName string) (CreateResponse, error) |
关于container的设置在此结构体
| type Config struct { |
| Hostname string |
| Domainname string |
| User string |
| AttachStdin bool |
| AttachStdout bool |
| AttachStderr bool |
| ExposedPorts PortSet `json:",omitempty"` |
| Tty bool |
| OpenStdin bool |
| StdinOnce bool |
| Env []string |
| Cmd StrSlice |
| Healthcheck *HealthConfig `json:",omitempty"` |
| ArgsEscaped bool `json:",omitempty"` |
| Image string |
| Volumes map[string]struct{} |
| WorkingDir string |
| Entrypoint StrSlice |
| NetworkDisabled bool `json:",omitempty"` |
| MacAddress string `json:",omitempty"` |
| OnBuild []string |
| Labels map[string]string |
| StopSignal string `json:",omitempty"` |
| StopTimeout *int `json:",omitempty"` |
| Shell StrSlice `json:",omitempty"` |
| } |
- 结构体
**container.HostConfig
宿主机相关配置,在这个结构体中。
| type HostConfig struct { |
| Binds []string |
| ContainerIDFile string |
| LogConfig LogConfig |
| NetworkMode NetworkMode |
| PortBindings PortMap |
| RestartPolicy RestartPolicy |
| AutoRemove bool |
| VolumeDriver string |
| VolumesFrom []string |
| ConsoleSize [2]uint |
| CapAdd StrSlice |
| CapDrop StrSlice |
| CgroupnsMode CgroupnsMode |
| DNS []string `json:"Dns"` |
| DNSOptions []string `json:"DnsOptions"` |
| DNSSearch []string `json:"DnsSearch"` |
| ExtraHosts []string |
| GroupAdd []string |
| IpcMode IpcMode |
| Cgroup CgroupSpec |
| Links []string |
| OomScoreAdj int |
| PidMode PidMode |
| Privileged bool |
| PublishAllPorts bool |
| ReadonlyRootfs bool |
| SecurityOpt []string |
| StorageOpt map[string]string `json:",omitempty"` |
| Tmpfs map[string]string `json:",omitempty"` |
| UTSMode UTSMode |
| UsernsMode UsernsMode |
| ShmSize int64 |
| Sysctls map[string]string `json:",omitempty"` |
| Runtime string `json:",omitempty"` |
| Isolation Isolation |
| Resources |
| Mounts []Mount `json:",omitempty"` |
| MaskedPaths []string |
| ReadonlyPaths []string |
| Init *bool `json:",omitempty"` |
| } |
*network.NetworkingConfig
| type NetworkingConfig struct { |
| EndpointsConfig map[string]*EndpointSettings |
| } |
4.1.2 完整示例
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types/container" |
| "github.com/docker/docker/api/types/network" |
| "github.com/docker/docker/client" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| config := &container.Config{ |
| Image: "harbocto.boe.com.cn/crow/crow-qin", |
| Tty: true, |
| } |
| |
| |
| containerId, err := CreateContainer(cli, config, nil, nil, "crow-test") |
| if err != nil { |
| fmt.Println(err) |
| } |
| |
| containerInfo, err := GetContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Printf("成功创建容器%q,状态为:%q", containerInfo.ID[:10], containerInfo.State.Status) |
| } |
| |
| |
| |
| func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) { |
| ctx := context.Background() |
| |
| |
| resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName) |
| if err != nil { |
| fmt.Println(err.Error()) |
| } |
| return resp.ID, nil |
| } |
| docker 链接成功 |
| 成功创建容器"c13a3deefb",状态为:"created" |
4.2 端口映射
4.2.1 语法
- 容器内端口
container.Config.ExposedPorts
- 上文已经知道
container.Config
是容器的配置,它的成员 ExposedPorts
即是容器内部监听的端口。 ExposedPorts
的类型是nat.PortSet
nat.PortSet
的类型如下 | type PortSet map[Port]struct{} |
- 语法示例
| config := &container.Config{ |
| Image: "harbocto.boe.com.cn/crow/crow-qin", |
| Tty: true, |
| ExposedPorts: nat.PortSet{ |
| "1840": struct{}{}, |
| }, |
| } |
- 绑定容器外端口
container.HostConfig.PortBindings
| type PortBinding struct { |
| HostIP string `json:"HostIp"` |
| HostPort string |
| } |
| hostConfig := &container.HostConfig{ |
| PortBindings: nat.PortMap{ |
| "1840": []nat.PortBinding{ |
| { |
| HostIP: "0.0.0.0", |
| HostPort: "1841", |
| }, |
| }, |
| }, |
| } |
4.2.2 完整示例
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| |
| |
| config := &container.Config{ |
| Image: "harbocto.boe.com.cn/crow/crow-qin", |
| Tty: true, |
| ExposedPorts: nat.PortSet{ |
| "1840": struct{}{}, |
| }, |
| } |
| hostConfig := &container.HostConfig{ |
| PortBindings: nat.PortMap{ |
| "1840": []nat.PortBinding{ |
| { |
| HostIP: "0.0.0.0", |
| HostPort: "1841", |
| }, |
| }, |
| }, |
| } |
| containerId, err := CreateContainer(cli, config, hostConfig, nil, "crow-qin-test") |
| |
| err = StartContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Println(containerId) |
| |
| } |
| |
| |
| |
| func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) { |
| ctx := context.Background() |
| |
| resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName) |
| if err != nil { |
| fmt.Println(err.Error()) |
| } |
| return resp.ID, nil |
| |
| } |
| |
| |
| |
| func StartContainer(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
4.3 挂载本机目录/文件
4.3.1 语法
- 指明容器内目录
container.Config.Volumes
- 类型:
| Volumes map[string]struct{} |
- 语法示例
| config := &container.Config{ |
| Image: "harbocto.boe.com.cn/crow/crow-qin", |
| Tty: true, |
| Volumes: map[string]struct{}{ |
| "/test01": {}, |
| }, |
| } |
- 容器内外路径网绑定
container.HostConfig.Binds
- 注意
- 如果只有
container.Config.ExposedPorts
,容器内目录将挂载到docker的默认位置(docker目录的 /volumes
下) - 如果写了
container.HostConfig.PortBindings
,则 container.Config.ExposedPorts
实际可以不写
4.3.2 完整代码
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| |
| |
| |
| config := &container.Config{ |
| Image: "harbocto.boe.com.cn/crow/crow-qin", |
| Tty: true, |
| Volumes: map[string]struct{}{ |
| "/test01": {}, |
| }, |
| } |
| hostConfig := &container.HostConfig{ |
| Binds: []string{"/tmp/test01:/test01"}, |
| } |
| containerId, err := CreateContainer(cli, config, hostConfig, nil, "crow-qin-test") |
| |
| err = StartContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Println(containerId) |
| } |
| |
| |
| func CreateContainer(cli *client.Client, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (containerId string, err error) { |
| ctx := context.Background() |
| |
| resp, err := cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, nil, containerName) |
| if err != nil { |
| fmt.Println(err.Error()) |
| } |
| return resp.ID, nil |
| |
| } |
| |
| |
| |
| func StartContainer(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
5. 启动容器
| func (cli *Client) ContainerStart(ctx context.Context, containerID string, options ContainerStartOptions) error |
| ctx := context.Background() |
| err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{}) |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/client" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| containerId := "c13a3deefb" |
| err = StartContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| |
| containerInfo, err := GetContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Printf("成功启动容器%q\n状态为:%q", containerInfo.ID[:10], containerInfo.State.Status) |
| } |
| |
| |
| |
| func StartContainer(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
| docker 链接成功 |
| 成功启动容器"c13a3deefb" |
| 状态为:"running" |
如上可见,我们刚才创建的容器状态从created
变为running
6 停止容器
| func (cli *Client) ContainerStart(ctx context.Context, containerID string, options ContainerStartOptions) error |
| ctx := context.Background() |
| err := cli.ContainerStart(ctx, containerId, types.ContainerStartOptions{}) |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types/container" |
| "github.com/docker/docker/client" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| containerId := "c13a3deefba9" |
| err = StopContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| |
| containerInfo, err := GetContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Printf("成功停止容器%q\n状态为:%q", containerInfo.ID[:10], containerInfo.State.Status) |
| } |
| |
| |
| |
| func StopContainer(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| err := cli.ContainerStop(ctx, containerId, container.StopOptions{}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
7 删除(已停止的)容器
| func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options ContainerRemoveOptions) error |
| ctx := context.Background() |
| err := cli.ContainerRemove(ctx, containerId, types.ContainerRemoveOptions{}) |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/client" |
| ) |
| |
| func main() { |
| cli, err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| containerId := "c13a3deefba9" |
| err = DeleteContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| |
| |
| b, err := CheckContainer(cli, containerId) |
| if err != nil { |
| fmt.Println(err) |
| } |
| if b == false { |
| fmt.Println("删除成功") |
| } else { |
| fmt.Println("删除失败") |
| } |
| } |
| |
| |
| |
| func DeleteContainer(cli *client.Client, containerId string) error { |
| ctx := context.Background() |
| err := cli.ContainerRemove(ctx, containerId, types.ContainerRemoveOptions{}) |
| if err != nil { |
| fmt.Println(err) |
| return err |
| } |
| return nil |
| } |
| |
| |
| func CheckContainer(cli *client.Client, containerId string) (result bool, err error) { |
| ctx := context.Background() |
| containerJson, err := cli.ContainerInspect(ctx, containerId) |
| if err != nil { |
| fmt.Println(err) |
| return false, err |
| } |
| if containerJson.ContainerJSONBase == nil { |
| return false,nil |
| } |
| fmt.Println(containerJson) |
| return true, nil |
| } |
8 进入容器执行命令
本文仅演示示例,实际应用参见本人文档《gin框架使用websocket实现进入容器内部执行命令》
8.1 语法
说明:创建一个新的exec配置来运行exec进程。
| func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config ExecConfig) (IDResponse, error) |
语法示例
| ir, err := dockerCli.ContainerExecCreate(ctx, containerId, types.ExecConfig{ |
| AttachStdin: true, |
| AttachStdout: true, |
| AttachStderr: true, |
| Cmd: []string{"/bin/sh"}, |
| Tty: true, |
| }) |
语法
| func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config ExecStartCheck) (HijackedResponse, error) |
语法示例
| hr, err := cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true}) |
| _, err = hr.Conn.Write([]byte("ls\r")) |
8.2 完整示例
| package main |
| |
| import ( |
| "bufio" |
| "context" |
| "fmt" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/client" |
| "io" |
| "log" |
| "os" |
| ) |
| |
| |
| func main() { |
| cli,err := ConnectDocker() |
| if err != nil { |
| fmt.Println(err) |
| } else { |
| fmt.Println("docker 链接成功") |
| } |
| |
| err = ExecContainer(cli,"48bcf68112") |
| if err != nil { |
| fmt.Println(err) |
| } |
| |
| } |
| |
| |
| |
| func ConnectDocker() (cli *client.Client,err error) { |
| cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375")) |
| if err != nil { |
| fmt.Println(err) |
| return nil,err |
| } |
| |
| return cli,nil |
| } |
| |
| |
| |
| func ExecContainer(cli *client.Client, containerId string) error { |
| |
| ctx := context.Background() |
| |
| ir, err := cli.ContainerExecCreate(ctx, containerId, types.ExecConfig{ |
| AttachStdin: true, |
| AttachStdout: true, |
| AttachStderr: true, |
| Cmd: []string{"/bin/sh"}, |
| Tty: true, |
| }) |
| if err != nil { |
| return err |
| } |
| |
| |
| hr, err := cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true}) |
| if err != nil { |
| return err |
| } |
| |
| defer hr.Close() |
| |
| |
| _, err = hr.Conn.Write([]byte("echo liuBei > xiShu.txt\r")) |
| if err != nil { |
| return err |
| } |
| |
| _, err = hr.Conn.Write([]byte("cat xiShu.txt\r")) |
| if err != nil { |
| return err |
| } |
| |
| |
| scanner := bufio.NewScanner(hr.Conn) |
| for scanner.Scan() { |
| fmt.Println(scanner.Text()) |
| if err != nil { |
| log.Println("写入错误", err) |
| continue |
| } |
| } |
| |
| return nil |
| } |
| |
| docker 链接成功 |
| / # echo liuBei > xiShu.txt |
| / # cat xiShu.txt |
| liuBei |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了