• 基于golang操作Docker


    官方库

    github.com/docker/docker

    • github.com/docker/docker/api/types
    • github.com/docker/docker/client
    • github.com/docker/docker/api/types/container
    • github.com/docker/docker/pkg/stdcopy

    官方文档

    https://docs.docker.com/engine/api/sdk

    实例: https://docs.docker.com/engine/api/sdk/examples/

    docker 开启远程访问

    vim /usr/lib/systemd/system/docker.service
    
    • 1

    在[Service]部分,修改ExecStart参数,在最后增加-H tcp://0.0.0.0:2375

    ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
    
    • 1
    systemctl daemon-reload && systemctl restart docker
    
    • 1
    1. 查看是否成功 curl http://localhost:2375/version

    如果不能访问,可能是因为防火墙的原因,所以开放防火墙2357端口

    firewall-cmd --zone=public --add-port=2375/tcp --permanent
    firewall-cmd --r
    
    • 1
    • 2

    Docker开启远程安全访问 请参考 https://blog.csdn.net/yuntiank/article/details/116520114

    Docker 开启远程安全访问(脚本生成配置) 请参考 https://blog.csdn.net/cszzboy/article/details/123552589

    实例

    package main
    
    import (
    	"context"
    	"encoding/base64"
    	"encoding/json"
    	"io"
    	"log"
    	"os"
    
    	"github.com/docker/docker/api/types"
    	"github.com/docker/docker/api/types/container"
    	"github.com/docker/docker/client"
    	"github.com/docker/docker/pkg/stdcopy"
    )
    
    func main(){
    	case1()
    
    	case2()
    
    	case3()
    
    	case4()
    
    	case5()
    }
    
    // docker 客户端
    func Client() *client.Client {
    	// 获取docker镜像列表
    	//cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) // 连接本地的docker
    
    	// 连接 开启了远程访问的docker
    	cli, err := client.NewClientWithOpts(client.WithHost("tcp://192.168.0.9:2375"), client.WithAPIVersionNegotiation())
    
    	// 连接 开启了远程访问的docker, 旧方法,已经弃用
    	//cli, err := client.NewClient("tcp://127.0.0.1:2375", "1.40", nil, nil)
    	if err != nil {
    		log.Println(err)
    		os.Exit(0)
    	}
    	return cli
    }
    
    // docker image ls
    func case1(){
    	cli := Client()
    	images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
    	if err != nil {
    		log.Println(err)
    		os.Exit(0)
    	}
    	var imagesLib []string
    	for _, image := range images {
    		log.Println("image = ", image)
    		log.Println("_______________\n\n")
    		imagesLib = append(imagesLib, image.RepoTags[0])
    	}
    	log.Println(imagesLib)
    }
    
    // docker ps
    func case2(){
    	cli := Client()
    	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
    	if err != nil {
    		panic(err)
    	}
    
    	for _, container := range containers {
    		log.Print("container = ", container)
    		log.Println("_______________\n\n")
    		// 停止所有容器
    		//if err := cli.ContainerStop(context.Background(), container.ID, nil); err != nil {
    		//	panic(err)
    		//}
    	}
    }
    
    // 运行一个容器
    // docker run
    func case3(){
    	cli := Client()
    	// 拉镜像
    	reader, err := cli.ImagePull(context.Background(), "docker.io/library/alpine", types.ImagePullOptions{})
    	if err != nil {
    		panic(err)
    	}
    
    	defer reader.Close()
    	io.Copy(os.Stdout, reader)
    
    
    	/*
    	container.Config:
    		Hostname        string              // 主机名
    		Domainname      string              // 域名
    		User            string              // 将在容器内运行命令的用户,还支持User:group
    		AttachStdin     bool                // 附加标准输入,实现用户交互
    		AttachStdout    bool                // 附加标准输出
    		AttachStderr    bool                // 附加标准误差
    		ExposedPorts    nat.PortSet         `json:",omitempty"` //暴露端口列表
    		Tty             bool                // 将标准流附加到Tty,如果Tty未关闭,则包括stdin。
    		OpenStdin       bool                // Open stdin
    		StdinOnce       bool                // 如果为true,请在连接的1个客户端断开连接后关闭stdin。
    		Env             []string            // 要在容器中设置的环境变量列表
    		Cmd             strslice.StrSlice   // 启动容器时要运行的命令
    		Healthcheck     *HealthConfig       `json:",omitempty"` // Healthcheck描述了如何检查容器是否健康
    		ArgsEscaped     bool                `json:",omitempty"` // True,如果命令已转义(意味着将其视为命令行)(特定于Windows)。
    		Image           string              // 操作传递的镜像的名称(例如,可以是符号)
    		Volumes         map[string]struct{} // 用于容器的卷(装载)列表
    		WorkingDir      string              // 将启动命令中的当前目录(PWD)
    		Entrypoint      strslice.StrSlice   // 启动容器时要运行的入口点
    		NetworkDisabled bool                `json:",omitempty"` // 已禁用网络
    		MacAddress      string              `json:",omitempty"` // 容器的Mac地址
    		OnBuild         []string            // image Dockerfile上定义的OnBuild元数据
    		Labels          map[string]string   // 设置到此容器的标签列表
    		StopSignal      string              `json:",omitempty"` // 停止容器的信号
    		StopTimeout     *int                `json:",omitempty"` // 停止容器的超时(秒)
    		Shell           strslice.StrSlice   `json:",omitempty"` // Shell表示RUN的Shell形式,CMD,ENTRYPOINT
    	 */
    
    	/*
    	container.HostConfig:
    		Binds           []string      // 此容器的卷绑定列表
    		ContainerIDFile string        // 写入containerId的文件(路径)
    		LogConfig       LogConfig     // 此容器的日志配置
    		NetworkMode     NetworkMode   // 用于容器的网络模式
    		PortBindings    nat.PortMap   // 暴露端口(容器)和主机之间的端口映射
    		RestartPolicy   RestartPolicy // 用于容器的重新启动策略
    		AutoRemove      bool          // 退出时自动删除容器
    		VolumeDriver    string        // 用于装载卷的卷驱动程序的名称
    		VolumesFrom     []string      // 从其他容器获取的卷列表
    
    		// Applicable to UNIX platforms
    		CapAdd          strslice.StrSlice // 要添加到容器的内核功能列表
    		CapDrop         strslice.StrSlice // 要从容器中删除的内核功能列表
    		CgroupnsMode    CgroupnsMode      // 用于容器的Cgroup命名空间模式
    		DNS             []string          `json:"Dns"`        // 要查找的DNS服务器列表
    		DNSOptions      []string          `json:"DnsOptions"` // 要查找的DNS选项列表
    		DNSSearch       []string          `json:"DnsSearch"`  // 要查找的DNS搜索列表
    		ExtraHosts      []string          // 额外主机列表
    		GroupAdd        []string          // 容器进程将作为其运行的其他组的列表
    		IpcMode         IpcMode           // 用于容器的IPC命名空间
    		Cgroup          CgroupSpec        // 用于容器的Cgroup
    		Links           []string          // 链接列表(名称:alias form)
    		OomScoreAdj     int               // OOM-killing的容器偏好
    		PidMode         PidMode           // 用于容器的PID命名空间
    		Privileged      bool              // 容器是否处于特权模式
    		PublishAllPorts bool              // docker是否应该发布容器的所有暴露端口
    		ReadonlyRootfs  bool              // 容器根文件系统是只读的吗
    		SecurityOpt     []string          // 用于自定义MLS系统(如SELinux)标签的字符串值列表。
    		StorageOpt      map[string]string `json:",omitempty"` // 每个容器的存储驱动程序选项。
    		Tmpfs           map[string]string `json:",omitempty"` // 用于集装箱的tmpfs(支架)列表
    		UTSMode         UTSMode           // 用于容器的UTS命名空间
    		UsernsMode      UsernsMode        // 用于容器的用户命名空间
    		ShmSize         int64             // shm内存使用总量
    		Sysctls         map[string]string `json:",omitempty"` // 用于容器的命名空间sysctl列表
    		Runtime         string            `json:",omitempty"` // 与此容器一起使用的运行时
    
    		// Applicable to Windows
    		ConsoleSize [2]uint   // 初始控制台尺寸(高度、宽度)
    		Isolation   Isolation // 容器的隔离技术(例如默认、hyperv)
    
    		// 包含容器的资源(cgroup、ulimit)
    		Resources
    
    		// 安装容器使用的规格
    		Mounts []mount.Mount `json:",omitempty"`
    
    		// MaskedPaths是容器内要屏蔽的路径列表(这将覆盖默认路径集)
    		MaskedPaths []string
    
    		// ReadonlyPaths是要在容器内设置为只读的路径列表(这将覆盖默认路径集)
    		ReadonlyPaths []string
    
    		// 在容器内运行自定义init,如果为null,则使用守护进程的配置设置
    		Init *bool `json:",omitempty"`
    	 */
    
    	/*
    	network.NetworkingConfig:
    		EndpointsConfig map[string]*EndpointSettings // 为每个连接网络配置端点
    	 */
    
    	/*
    	specs.Platform:
    		// 架构字段指定CPU架构,例如
    		// `amd64` or `ppc64`.
    		Architecture string `json:"architecture"`
    
    		// 操作系统指定操作系统,例如“linux”或“windows”。
    		OS string `json:"os"`
    
    		// OSVersion是一个可选字段,用于指定操作系统
    		// 版本,例如在Windows“10.0.14393.1066”上。
    		OSVersion string `json:"os.version,omitempty"`
    
    		// OSFeatures是一个可选字段,用于指定字符串数组,
    		// 每个都列出了所需的操作系统功能(例如在Windows“win32k”上).
    		OSFeatures []string `json:"os.features,omitempty"`
    
    		// 变量是一个可选字段,用于指定CPU的变量
    		// 示例“v7”用于在体系结构为“arm”时指定ARMv7。
    		Variant string `json:"variant,omitempty"`
    	 */
    
    	// 创建容器
    	resp, err := cli.ContainerCreate(context.Background(), &container.Config{
    		Image: "alpine",
    		Cmd:   []string{"echo", "hello world"},
    		Tty:   false,
    	}, nil, nil, nil, "")
    	if err != nil {
    		panic(err)
    	}
    
    	// 启动容器
    	if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
    		panic(err)
    	}
    
    	// 监听容器状态
    	statusCh, errCh := cli.ContainerWait(context.Background(), resp.ID, container.WaitConditionNotRunning)
    	select {
    	case err := <-errCh:
    		if err != nil {
    			panic(err)
    		}
    	case <-statusCh:
    	}
    
    	// 获取容器日志
    	out, err := cli.ContainerLogs(context.Background(), resp.ID, types.ContainerLogsOptions{ShowStdout: true})
    	if err != nil {
    		panic(err)
    	}
    
    	stdcopy.StdCopy(os.Stdout, os.Stderr, out)
    }
    
    // docker pull
    // 通过身份验证拉取图像
    func case4(){
    	cli := Client()
    	authConfig := types.AuthConfig{
    		Username: "username",
    		Password: "password",
    	}
    	encodedJSON, err := json.Marshal(authConfig)
    	if err != nil {
    		panic(err)
    	}
    	authStr := base64.URLEncoding.EncodeToString(encodedJSON)
    
    	out, err := cli.ImagePull(context.Background(), "alpine", types.ImagePullOptions{RegistryAuth: authStr})
    	if err != nil {
    		panic(err)
    	}
    
    	defer out.Close()
    	io.Copy(os.Stdout, out)
    }
    
    // docker push
    func case5(){
    	cli := Client()
    	createResp, err := cli.ContainerCreate(context.Background(), &container.Config{
    		Image: "alpine",
    		Cmd:   []string{"touch", "/helloworld"},
    	}, nil, nil, nil, "")
    	if err != nil {
    		panic(err)
    	}
    
    	if err := cli.ContainerStart(context.Background(), createResp.ID, types.ContainerStartOptions{}); err != nil {
    		panic(err)
    	}
    
    	statusCh, errCh := cli.ContainerWait(context.Background(), createResp.ID, container.WaitConditionNotRunning)
    	select {
    	case err := <-errCh:
    		if err != nil {
    			panic(err)
    		}
    	case <-statusCh:
    	}
    
    	commitResp, err := cli.ContainerCommit(context.Background(), createResp.ID, types.ContainerCommitOptions{Reference: "helloworld"})
    	if err != nil {
    		panic(err)
    	}
    
    	log.Println(commitResp.ID)
    }
    
    // 远程 ssh连接
    // 如果有报错 exec /usr/lib/ssh/ssh-askpass : No such file or directory error.
    // 安装 ssh-askpass
    //		sudo apt-get autoremove openssh-client
    //		sudo apt-get install openssh-client openssh-sftp-server openssh-server ssh
    //		sudo apt-get install ssh-askpass
    func case6(){
    	helper, err := connhelper.GetConnectionHelper("ssh://root@192.168.0.192:22")
    	if err != nil {
    		log.Println(err)
    		return
    	}
    	httpClient := &http.Client{
    		Transport: &http.Transport{
    			DialContext: helper.Dialer,
    		},
    	}
    	cl, err := client.NewClientWithOpts(
    		client.WithHTTPClient(httpClient),
    		client.WithHost(helper.Host),
    		client.WithDialContext(helper.Dialer),
    	)
    	if err != nil {
    		log.Println("Unable to create docker client")
    		panic(err)
    	}
    
    	log.Println(cl.ImageList(context.Background(), types.ImageListOptions{}))
    }
    
    
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
  • 相关阅读:
    东极岛 需要提早买门票
    网络流中反向边作用
    【Python程序设计】Python 中的环境变量【05/8】
    手把手教你CSP系列之script-src
    Java安全 CC链6分析
    849. Dijkstra求最短路 I
    优化用户体验:直播带货系统源码的界面设计与互动功能
    【等保小知识】等级保护单项测评包括哪些项目?
    线性插值方法介绍及图像缩放
    数据可视化之大数据平台可视化
  • 原文地址:https://blog.csdn.net/Man_ge/article/details/128204150