创建一个允许容器之间通信但不能访问互联网的网络

Creating a network which allows communication between containers but no internet access

如何使用 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) 将 DROP 规则添加到您的 DOCKER-USER 防火墙链来获得您想要的:

iptables -I DOCKER-USER -j DROP

在我刚才的快速实验中,这让我从容器映射端口,但阻止了容器访问互联网(因为这个链是从 FORWARD 链调用的,它阻止了容器转发流量通过主机到外部互联网)。

在花了几天时间尝试不同的事情后,我想出了一个 kind-of 有效的解决方案:

    /**
     * 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.