使用golang sdk为docker api的ContainerCreate函数设置端口绑定配置。

12

基本上我需要像这样的东西

docker run -p something:something --name xxxx imagename

在 Golang SDK(即此处链接 https://docs.docker.com/engine/api/sdks/)中使用 Docker API 的当前代码如下:

exposedPorts, portBindings, _ := nat.ParsePortSpecs([]string{
    "127.0.0.1:8080:2368",
})
// Running the ghost container
createdBody, err := dockerClient.ContainerCreate(context.Background(),
    &container.Config{
        Image:        "ghost:latest",
        ExposedPorts: exposedPorts,// it supposed to be nat.PortSet
    },
    &container.HostConfig{
        PortBindings: portBindings,// it supposed to be nat.PortMap
    },
    &network.NetworkingConfig{},
    containerName)

我正在使用这个https://github.com/docker/go-connections/blob/master/nat/nat.go#L126中的ParsePortSpecs函数,它返回(map[Port]struct{},map[Port][]PortBinding,error),但是因为container.Config.ExposedPorts是nat.PortSet(实际上是map[Port]struct{}),而containter.HostConfig.PortBindings是nat.PortMap,所以失败了。

我不确定是否要使用这个客户端https://github.com/fsouza/go-dockerclient,因为我的当前版本的Docker API是1.25,不支持1.23以上的API版本。

2个回答

29

自 1 月以来,Docker Client Go SDK 可能已经有所改变,但我刚刚使其工作,因此我将在此记录我的操作。

如果您需要暴露一个端口,它看起来像在 docker ps 中的 4140/tcp,那么您可以执行以下操作:

config := &container.Config{
    Image: "nginx",
    ExposedPorts: nat.PortSet{
        "4140/tcp": struct{}{},
    },
}

hostConfig := &container.HostConfig{}

ctx := context.Background()
containerResp, err := Docker.ContainerCreate(ctx, config, hostConfig, nil, "")
if err != nil {
    panic(err)
}

if err := Docker.ContainerStart(ctx, containerResp.ID, types.ContainerStartOptions{}); err != nil {
    panic(err)
}

如果您想将该端口绑定到主机的0.0.0.0上,它看起来像是在docker ps的PORTS下 0.0.0.0:4140->4140/tcp,您需要将端口绑定添加到hostConfig中:

config := &container.Config{
    Image: "nginx",
    ExposedPorts: nat.PortSet{
        "4140/tcp": struct{}{},
    },
}

hostConfig := &container.HostConfig{
    PortBindings: nat.PortMap{
        "4140/tcp": []nat.PortBinding{
            {
                HostIP: "0.0.0.0",
                HostPort: "4140",
            },
        },
    },
}

ctx := context.Background()
containerResp, err := Docker.ContainerCreate(ctx, config, hostConfig, nil, "")
if err != nil {
    panic(err)
}

if err := Docker.ContainerStart(ctx, containerResp.ID, types.ContainerStartOptions{}); err != nil {
    panic(err)
}

希望这能节省某人的时间 :)


我在尝试使用nat.PortSet构建config对象时遇到了错误。这段代码config:=&container.Config { Image:“nginx”, ExposedPorts:nat.PortSet { nat.Port(“80:tcp”):struct {} {}, }, }会抛出错误cannot use (nat.PortSet literal) (value of type nat.PortSet) as nat.PortSet value in struct literal - ZacSketches

5
containerCfg := &container.Config {
    Image: haproxyImage,
    Tty: true,
    OpenStdin: true,
    AttachStdout: true,
    AttachStderr: true,
    ExposedPorts: nat.PortSet{
        nat.Port("443/tcp"): {},
        nat.Port("10001/tcp"): {},
    },
}

hostConfig := &container.HostConfig{
    Binds: []string{
        "/var/run/docker.sock:/var/run/docker.sock",
    },
    PortBindings: nat.PortMap{
        nat.Port("443/tcp"): []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: "443"}},
        nat.Port("10001/tcp"): []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: "10001"}},
    },
}

2
提示:如果您仍然喜欢/需要Docker随机分配的“HostPort”功能,只需省略“HostPort”键,Docker将随机分配一个数字。 - Michael Galaxy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接