无法使用 Docker SDK 中的端口范围语法进行端口转发
Unable to port forward with the port range syntax in Docker SDK
我正在尝试使用 Go SDK 运行 一个 Docker 容器。从终端,我可以 运行 以下命令没有问题:
docker run -d --memory 1024M --name "cdb1" -p 2001-2006:8091-8096 -p 11210-11211:11210-11211 couchbase
我想使用 Docker SDK for Go 实现相同的目的,但找不到如何重现 -p 2001-2006:8091-8096
部分。这是我的 ContainerCreate 调用:
cont, err := cli.ContainerCreate(
context.Background(),
&container.Config{
Image: "couchbase",
ExposedPorts: nat.PortSet{
"2001-2006": struct{}{},
"11210-11211": struct{}{},
},
},
&container.HostConfig{
PortBindings: nat.PortMap{
"8091-8096": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2001-2006",
},
},
"11210-11211": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11210-11211",
},
},
},
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},
nil,
"cdb1",
)
但是运行宁这总是抛出同样的错误:
Error response from daemon: invalid port specification: "8091-8096"
再做一些测试,错误似乎专门来自 PortBindings
部分(如果我删除这个并保留暴露的端口,它工作正常)。
我在 Docker 文档中找不到任何相关信息。
尝试单独添加每个端口而不是端口范围:
cont, err := cli.ContainerCreate(
context.Background(),
&container.Config{
Image: "couchbase",
ExposedPorts: nat.PortSet{
"2001": struct{}{},
"2002": struct{}{},
"2003": struct{}{},
"2004": struct{}{},
"2005": struct{}{},
"2006": struct{}{},
"11210": struct{}{},
"11211": struct{}{}
},
},
&container.HostConfig{
PortBindings: nat.PortMap{
"8091": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2001",
},
},
"8092": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2002",
},
},
"8093": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2003",
},
},
"8094": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2004",
},
},
"8095": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2005",
},
},
"8096": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2006",
},
},
"11210": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11210",
},
},
"11211": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11211",
},
}
},
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},
nil,
"cdb1",
)
nat.PortSet
is a map with nat.Port
是它的键类型:
type PortSet map[Port]struct{}
"2001-2006"
的“端口”规范在语法上有效,因为它是一个无类型的字符串常量,可以转换为 nat.Port
,它的基础类型是 string
,但是这个字符串文字缺少协议规范(例如 tcp
或 udp
)。
改为使用 nat.NewPort()
函数创建密钥:
ports1, err := nat.NewPort("tcp", "2001-2006") // check err
ports2, err := nat.NewPort("tcp", "11210-11211") // check err
ExposedPorts: nat.PortSet{
ports1: struct{}{},
ports2: struct{}{},
},
请注意,预期的“原始”字符串格式是 "2001-2006/tcp"
,这也可以接受,但最好将此内部细节留给 nat.NewPort()
。
并构造一个nat.PortMap
, use the nat.ParsePortSpec()
效用函数。这就是您 assemble 您的 PortBindings
:
portBindings := nat.PortMap{}
for _, rawMapping := range []string{
"0.0.0.0:2001-2006:8091-8096",
"0.0.0.0:11210-11211:11210-11211",
} {
mappings, err := nat.ParsePortSpec(rawMapping)
if err != nil {
panic(err)
}
for _, pm := range mappings {
portBindings[pm.Port] = []nat.PortBinding{pm.Binding}
}
}
然后你可以使用上面的portBindings
用于HostConfig.PortBindings
字段:
&container.HostConfig{
PortBindings: portBindings ,
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},
我正在尝试使用 Go SDK 运行 一个 Docker 容器。从终端,我可以 运行 以下命令没有问题:
docker run -d --memory 1024M --name "cdb1" -p 2001-2006:8091-8096 -p 11210-11211:11210-11211 couchbase
我想使用 Docker SDK for Go 实现相同的目的,但找不到如何重现 -p 2001-2006:8091-8096
部分。这是我的 ContainerCreate 调用:
cont, err := cli.ContainerCreate(
context.Background(),
&container.Config{
Image: "couchbase",
ExposedPorts: nat.PortSet{
"2001-2006": struct{}{},
"11210-11211": struct{}{},
},
},
&container.HostConfig{
PortBindings: nat.PortMap{
"8091-8096": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2001-2006",
},
},
"11210-11211": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11210-11211",
},
},
},
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},
nil,
"cdb1",
)
但是运行宁这总是抛出同样的错误:
Error response from daemon: invalid port specification: "8091-8096"
再做一些测试,错误似乎专门来自 PortBindings
部分(如果我删除这个并保留暴露的端口,它工作正常)。
我在 Docker 文档中找不到任何相关信息。
尝试单独添加每个端口而不是端口范围:
cont, err := cli.ContainerCreate(
context.Background(),
&container.Config{
Image: "couchbase",
ExposedPorts: nat.PortSet{
"2001": struct{}{},
"2002": struct{}{},
"2003": struct{}{},
"2004": struct{}{},
"2005": struct{}{},
"2006": struct{}{},
"11210": struct{}{},
"11211": struct{}{}
},
},
&container.HostConfig{
PortBindings: nat.PortMap{
"8091": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2001",
},
},
"8092": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2002",
},
},
"8093": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2003",
},
},
"8094": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2004",
},
},
"8095": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2005",
},
},
"8096": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "2006",
},
},
"11210": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11210",
},
},
"11211": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "11211",
},
}
},
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},
nil,
"cdb1",
)
nat.PortSet
is a map with nat.Port
是它的键类型:
type PortSet map[Port]struct{}
"2001-2006"
的“端口”规范在语法上有效,因为它是一个无类型的字符串常量,可以转换为 nat.Port
,它的基础类型是 string
,但是这个字符串文字缺少协议规范(例如 tcp
或 udp
)。
改为使用 nat.NewPort()
函数创建密钥:
ports1, err := nat.NewPort("tcp", "2001-2006") // check err
ports2, err := nat.NewPort("tcp", "11210-11211") // check err
ExposedPorts: nat.PortSet{
ports1: struct{}{},
ports2: struct{}{},
},
请注意,预期的“原始”字符串格式是 "2001-2006/tcp"
,这也可以接受,但最好将此内部细节留给 nat.NewPort()
。
并构造一个nat.PortMap
, use the nat.ParsePortSpec()
效用函数。这就是您 assemble 您的 PortBindings
:
portBindings := nat.PortMap{}
for _, rawMapping := range []string{
"0.0.0.0:2001-2006:8091-8096",
"0.0.0.0:11210-11211:11210-11211",
} {
mappings, err := nat.ParsePortSpec(rawMapping)
if err != nil {
panic(err)
}
for _, pm := range mappings {
portBindings[pm.Port] = []nat.PortBinding{pm.Binding}
}
}
然后你可以使用上面的portBindings
用于HostConfig.PortBindings
字段:
&container.HostConfig{
PortBindings: portBindings ,
Resources: container.Resources{
Memory: 1024 * 1000000,
},
},