go调用docker远程API(二)-docker API 的容器操作

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)
}
}
// ConnectDocker
// 链接docker
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
}
// GetContainers
// 获取容器列表
func GetContainers(cli *client.Client) error {
//All-true相当于docker ps -a
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)
  • 返回结构体types.ContainerJSON
type ContainerJSON struct {
*ContainerJSONBase
Mounts []MountPoint
Config *Config
NetworkSettings *NetworkSettings
}
  • *ContainerJSONBase的内容
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:
      • true:实时日志
      • false:当前日志
    • 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)
}
}
// ConnectDocker
// 链接docker
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
}
//containerLogs
//获取容器日志
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 语法

  • ContainerCreate() 函数
func (cli *Client) ContainerCreate(ctx context.Context, config *Config, hostConfig *HostConfig, networkingConfig *NetworkingConfig, platform *Platform, containerName string) (CreateResponse, error)
  • 结构体 *container.Config

关于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)
}
// CreateContainer
// 创建容器
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
    • 上文已经知道 container.HostConfig是宿主机的配置
    • 它的成员 PortBindings绑定容器内外端口。
    • ExposedPorts的类型是nat.PortMap
    • nat.PortMap的类型如下
      type PortMap map[Port][]PortBinding
    • PortBinding的类型如下
    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 链接成功")
}
//创建容器
//protMap := nat.PortSet{}
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)
}
// CreateContainer
// 创建容器
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
}
// StartContainer
// 启动容器
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
    • 类型:[]string
    • 语法示例
      hostConfig := &container.HostConfig{
      Binds: []string{"/tmp/liuBei.txt:/liuBei.txt"},
      }
  • 注意
    • 如果只有 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 链接成功")
}
//创建容器
//protMap := nat.PortSet{}
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)
}
// CreateContainer
// 创建容器
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
}
// StartContainer
// 启动容器
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)
}
//StartContainer
// 启动容器
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)
}
// StopContainer
// 停止容器
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("删除失败")
}
}
// DeleteContainer
// 删除已停止容器
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
}
// CheckContainer
// 获取容器信息
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,
})
  • 将链接附加到exec进程

语法

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 链接成功")
}
//GetContainers()
err = ExecContainer(cli,"48bcf68112")
if err != nil {
fmt.Println(err)
}
}
// ConnectDocker
// 链接docker
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
}
// 将链接附加到exec进程
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

在这里插入图片描述

posted on   运维开发玄德公  阅读(799)  评论(0编辑  收藏  举报  

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示