Невозможно перенаправить порт с синтаксисом диапазона портов в Docker SDK - PullRequest
2 голосов
/ 03 августа 2020

Я пытаюсь запустить контейнер Docker с помощью Go SDK. С терминала я могу без проблем выполнить следующую команду:

docker run -d --memory 1024M --name "cdb1" -p 2001-2006:8091-8096 -p 11210-11211:11210-11211 couchbase

Я хочу добиться того же, используя Docker SDK для 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.

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

nat.PortSet - это карта с типом ключа 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, используйте служебную функцию nat.ParsePortSpec(). Вот как вы можете собрать свой 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,
    },
},
1 голос
/ 03 августа 2020

Попробуйте добавить каждый порт отдельно вместо диапазона портов:

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",
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...