java - 在主机模式下运行容器后的空 IP 地址
问题描述
我想使用 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
?为什么这不是自动发生的?
解决方案
当您有主机模式时,端口绑定将被忽略,因为您的代码负责选择端口并绑定到它。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
推荐阅读
- java - Java .forEach(list::add) 与 .collect(Collectors.toList())
- swift - 如何过滤 combineLatest 仅在一项更改时触发?
- c++ - 如何通过按下第三个窗口中的按钮将 QString 从一个窗口获取到另一个窗口
- docker - Docker-compose 返回一个非零代码:100
- java - 使用扫描仪读取文件数据,如何检查字段是否为空
- python-3.x - Python - 52 张扑克牌速记符号。我哪里做错了?
- c - 关于 x86_64 Linux 上的堆栈增长的困惑
- c++ - 正弦级数方程计算不正确
- arrays - TS:自定义对象数组的定义
- python - 根据另一列中的值创建新列