dockerSDK-Go语言实现
前情提要
本文基于开发一个在线代码运行平台的项目需求上,所以需要挂载目录以达到获得执行文件的目的。
步骤1
首先在docker-compose 文件中,当前容器一定要跟宿主机的套接字进行挂载
version: '3.8'
services:
code-runner-api:
build:
context: .
dockerfile: builds/api/Dockerfile
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- APP_ENV=production
- DOCKER_HOST=unix:///var/run/docker.sock
ports:
- ""
步骤二
创建docker客户端
type dockerContainerClient struct {
ctx context.Context
cli *client.Client
}
// NewDockerClient
func NewDockerClient(ctx context.Context) (*dockerContainerClient, error) {
cli, err := client.NewClientWithOpts(
client.WithHost("unix:///var/run/docker.sock"),
client.WithAPIVersionNegotiation(), // 自动协商API版本
)
if err != nil {
log.Println("domain.client.entity.NewDockerClient() NewClientWithOpts err=", err)
return nil, fmt.Errorf("创建Docker客户端失败: %v", err)
}
return &dockerContainerClient{ctx: ctx, cli: cli}, nil
}
创建容器示例
// CreateContainer 创建指定容器
func (client *dockerContainerClient) createContainer(image string, language string) (container.CreateResponse, error) {
config := &container.Config{
Image: image,
User: "root",
WorkingDir: "/app",
Cmd: []string{"sleep", "infinity"}, // 修改启动命令为 sleep 无限循环
Env: []string{
"GO111MODULE=on",
"GOPROXY=https://goproxy.cn,direct",
},
}
hostConfig := &container.HostConfig{
ReadonlyRootfs: false,
CapDrop: []string{"ALL"},
NetworkMode: "none", // 关闭容器网络连接
Resources: container.Resources{
Memory: 512 * 1024 * 1024,
MemorySwap: 512 * 1024 * 1024,
CPUQuota: 100000,
CPUPeriod: 100000,
CPUCount: 1,
},
Binds: []string{fmt.Sprintf("/tmp/%s:/app", language)}, // 挂载到容器的/app目录
}
fmt.Printf("创建容器配置:\n")
fmt.Printf("镜像:%s\n", image)
fmt.Printf("工作目录:%s\n", config.WorkingDir)
fmt.Printf("挂载路径:%s\n", hostConfig.Binds[0])
resp, err := client.cli.ContainerCreate(
client.ctx,
config,
hostConfig,
nil,
nil,
"",
)
if err != nil {
log.Println("domain.client.entity.createContainer() ContainerCreate err=", err)
return container.CreateResponse{}, fmt.Errorf("容器创建失败: %v", err)
}
return resp, nil
}