我想使用Java库
以主机模式创建docker容器https://github.com/spotify/docker-client
我的容器中存在我的应用程序,该应用程序在运行后应打开容器中的端口20202
至下一次使用。所以我要做的代码是
Map<String, List<PortBinding>> portBindings = Maps.newHashMap();
portBindings.put("20202", Lists.newArrayList(PortBinding.of("localhost", "20202")));
HostConfig hostConfig = HostConfig.builder()
.networkMode("host")
.portBindings(portBindings)
.build();
ContainerConfig config = ContainerConfig.builder()
.hostConfig(hostConfig)
.image("myImage")
.exposedPorts("20202")
.cmd("myProg", "arg1", "arg2"))
.build();
DefaultDockerClient.fromEnv().build();
client.pull(config.image());
ContainerCreation creation = client.createContainer(config);
client.startContainer(creation.id());
ContainerInfo info = client.inspectContainer(creation.id());
我在日志中看到了如何从本地注册表中提取图像,但是当我的主程序尝试在创建的容器中运行命令时,我得到了异常
org.apache.http.client.ClientProtocolException:URI没有指定有效的主机名:http://:20202
程序运行该容器后,我在命令行上从手册中检查了该容器是否存在,并且端口是否在127.0.0.1:20202
上本地打开并且没问题,
docker ps
之后看到它们)netstat -altp
检查---> tcp 0 0 127.0.0.1:20202 0.0.0.0:* LISTEN 23839/myProg
127.0.0.1:20202
我看到问题在于,在我的主程序中尝试使用以下方法从ContainerInfo
获取有关主机的信息
ContainerInfo info = client.inspectContainer(creation.id());
String host = info.networkSettings().ipAddress(); // host is empty
问题是,当我在ContainerInfo
中设置主机模式时,如何将localhost
或127.0.0.1
的信息放在HostConfig
上?
为什么这不是自动发生的?
答案 0 :(得分:1)
在具有主机模式时,端口绑定将被忽略,因为您的代码负责选择端口并对其进行绑定。 Docker只是将您的主机修补到主机网络。因此,无论您是否通过端口映射,它都不会在主机模式下使用
此外,当您运行的容器是NetworkMode时,没有这样分配IP到容器。您需要使用主机IP
$ docker run -d --network host alpine sleep 900
804006d7f917637ee615d877558da7fae5b01a03af713c773098d0ef563d06c2
$ docker inspect 804006d7f917637ee615d877558da7fae5b01a03af713c773098d0ef563d06c2 | grep IPA
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "",
从上面可以看到,那么容器在主机模式下永远不会获得ip