暂时禁用Docker容器网络接口

时间:2019-12-30 22:03:42

标签: docker networking containers

我正在建立一个库来模拟系统中的某些故障。故障之一是模拟网络故障,它将禁止任何连接。当前,我正在使用以下Kotlin代码禁用容器网络接口:

Runtime.getRuntime().exec("ifconfig eth0 down")
// wait some time
Runtime.getRuntime().exec("ifconfig eth0 up")

重新启用接口后,我无法恢复与容器的连接。我在命令行上尝试过,效果是一样的:

docker run --privileged -it alpine:latest sh
/ # apk add curl
...
OK: 7 MiB in 18 packages
/ # curl google.com

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

/ # ifconfig eth0 down
/ # ifconfig eth0 up
/ # curl google.com
curl: (6) Could not resolve host: google.com

有人知道为什么它会在docker容器内发生吗?

2 个答案:

答案 0 :(得分:0)

Docker设置了很多东西来使网络转发到主机,包括iptables,桥接网络,ipvs和路由。我怀疑删除eth0接口会破坏这些组件中至少一个组件上的配置。要恢复,您可能需要重新启动Docker引擎(systemctl restart docker)。

建议不要使用tc来丢弃所有数据包,而不是丢弃接口。甚至有一个项目可以通过单个容器上的标签或受API控制来执行此操作,您可以在lukaszlach/docker-tc中找到该项目。

答案 1 :(得分:0)

问题是Docker丢失了默认网关地址。我刚刚添加了另一个命令,以在重启接口后重置网关地址,然后一切再次正常运行:

route add default gw ${this.defaultGatewayAddress}

最后,我得到了这个有效的Kotlin代码:

data class NetworkInterface(val name: String) {

    private var defaultGatewayAddress: String

    init {
        this.defaultGatewayAddress = getDefaultGatewayIpAddress().address
    }

    fun disable() {
        Environment.runCLICommand("ifconfig $name down")
    }

    fun enable() {
        Environment.runCLICommand("ifconfig $name down")
        Environment.runCLICommand("route add default gw ${this.defaultGatewayAddress}")
    }

    fun getDefaultGatewayIpAddress(): IpAddress {
        val command = "netstat -nr | awk '{print $2}' | head -n3 | tail -n1"
        return IpAddress(Environment.runCLICommand(command).trim())
    }
}