如何使用testcontainers
创建docker网络
- 允许网络中的所有容器相互通信
- 允许容器将端口映射到主机
- 但不允许容器访问互联网
我曾尝试使用internal
网络:
private Network generateInternalNetwork() {
// Consumer which operates on the final CreateNetworkCmd which will be run to
// make sure the 'internal' flag is set.
Consumer<CreateNetworkCmd> cmdModifier = (createNetworkCmd) -> {
createNetworkCmd.withInternal(true);
};
return Network.builder()
.createNetworkCmdModifier(cmdModifier)
.build();
}
但是,当我运行这个时,我无法映射我的端口。引发异常:
Caused by: java.lang.IllegalArgumentException: Requested port (8024) is not mapped
如果我在没有withInternal(true)
的情况下运行它,它可以正常工作,但容器当然可以访问互联网。
我认为您可以通过(a(创建正常网络,然后(b(向DOCKER-USER
防火墙链添加DROP
规则来获得您想要的:
iptables -I DOCKER-USER -j DROP
在我刚才的快速实验中,这让我可以从容器映射端口,但阻止了容器访问互联网(因为这个链是从FORWARD
链调用的,它阻止了容器通过主机将流量转发到外部互联网(。
花了几天时间尝试不同的东西后,我想出了一个可行的解决方案:
/**
* Set an invalid DNS for the given container.
* This is done as a workaround so that the container cannot access
* the internet.
*/
void setInvalidDns() {
GenericContainer<?> container = getContainer();
Consumer<CreateContainerCmd> modifier = (cmd) -> {
// Amend the config with the garbage DNS.
String invalidDns = "255.255.255.255";
HostConfig hostConfig = cmd.getHostConfig();
hostConfig.withDns(invalidDns);
cmd.withHostConfig(hostConfig);
};
container.withCreateContainerCmdModifier(modifier);
}
这将容器的DNS设置为无效IP,然后当您尝试在容器中发出HTTP请求时,它将抛出java.net.ConnectException
。