文章目录
- 1 获取容器列表
- 2 查看指定容器信息
- 3. 查看容器日志
- 4 创建容器
- 4.1 简单使用
- 4.1.1 语法
- 4.1.2 完整示例
- 4.2 端口映射
- 4.2.1 语法
- 4.2.2 完整示例
- 4.3 挂载本机目录/文件
- 4.3.1 语法
- 4.3.2 完整代码
- 5. 启动容器
- 6 停止容器
- 7 删除(已停止的)容器
- 8 进入容器执行命令
- 8.1 语法
- 8.2 完整示例
1 获取容器列表
- 语法
func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptions) ([]Container, error)
- 语法示例
containers, err := Cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
- 完整示例
package mainimport ("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 -acontainers, 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 {*ContainerJSONBaseMounts []MountPointConfig *ConfigNetworkSettings *NetworkSettings
}
*ContainerJSONBase
的内容
type ContainerJSONBase struct {ID string `json:"Id"`Created stringPath stringArgs []stringState *ContainerStateImage stringResolvConfPath stringHostnamePath stringHostsPath stringLogPath stringNode *ContainerNode `json:",omitempty"`Name stringRestartCount intDriver stringPlatform stringMountLabel stringProcessLabel stringAppArmorProfile stringExecIDs []stringHostConfig *HostConfigGraphDriver GraphDriverDataSizeRw *int64 `json:",omitempty"`SizeRootFs *int64 `json:",omitempty"`
}
- 完整示例
package mainimport ("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, Follow: true})
- 参数
- ShowStdout:标准输出
- Follow:
- true:实时日志
- false:当前日志
- 完整示例
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 stringDomainname stringUser stringAttachStdin boolAttachStdout boolAttachStderr boolExposedPorts PortSet `json:",omitempty"`Tty boolOpenStdin boolStdinOnce boolEnv []stringCmd StrSliceHealthcheck *HealthConfig `json:",omitempty"`ArgsEscaped bool `json:",omitempty"`Image stringVolumes map[string]struct{}WorkingDir stringEntrypoint StrSliceNetworkDisabled bool `json:",omitempty"`MacAddress string `json:",omitempty"`OnBuild []stringLabels map[string]stringStopSignal string `json:",omitempty"`StopTimeout *int `json:",omitempty"`Shell StrSlice `json:",omitempty"`
}
- 结构体
**container.HostConfig
宿主机相关配置,在这个结构体中。
type HostConfig struct {Binds []stringContainerIDFile stringLogConfig LogConfigNetworkMode NetworkModePortBindings PortMapRestartPolicy RestartPolicyAutoRemove boolVolumeDriver stringVolumesFrom []stringConsoleSize [2]uintCapAdd StrSliceCapDrop StrSliceCgroupnsMode CgroupnsModeDNS []string `json:"Dns"`DNSOptions []string `json:"DnsOptions"`DNSSearch []string `json:"DnsSearch"`ExtraHosts []stringGroupAdd []stringIpcMode IpcModeCgroup CgroupSpecLinks []stringOomScoreAdj intPidMode PidModePrivileged boolPublishAllPorts boolReadonlyRootfs boolSecurityOpt []stringStorageOpt map[string]string `json:",omitempty"`Tmpfs map[string]string `json:",omitempty"`UTSMode UTSModeUsernsMode UsernsModeShmSize int64Sysctls map[string]string `json:",omitempty"`Runtime string `json:",omitempty"`Isolation IsolationResourcesMounts []Mount `json:",omitempty"`MaskedPaths []stringReadonlyPaths []stringInit *bool `json:",omitempty"`
}
*network.NetworkingConfig
type NetworkingConfig struct {EndpointsConfig map[string]*EndpointSettings
}
4.1.2 完整示例
package mainimport ("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 mainimport ("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 mainimport ("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 mainimport ("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 mainimport ("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