简体   繁体   English

暂时禁用 docker 容器网络接口

[英]Disable temporally the docker container network interface

I am building a library to simulate some faults in a system.我正在构建一个库来模拟系统中的一些故障。 One of the faults, is to simulate a network failure, which would forbid any connection.故障之一是模拟网络故障,这将禁止任何连接。 Currently, I am using this Kotlin code to disable the container network interface:目前,我正在使用此 Kotlin 代码来禁用容器网络接口:

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

When the interface is re-enabled, I am not able to restore connections with the container.重新启用接口后,我无法恢复与容器的连接。 I tried it on the command line, and the effect is the same:我在命令行试了一下,效果是一样的:

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

Does anybody have any idea why it occurs inside a docker container?有人知道为什么它会发生在 docker 容器内吗?

Docker sets up lots of things to make networking forward to the host, including iptables, bridge networks, ipvs, and routing. Docker 设置了很多东西来使网络转发到主机,包括 iptables、桥接网络、ipvs 和路由。 I suspect that dropping the eth0 interface has broken the configuration on at least one of these components.我怀疑删除 eth0 接口已经破坏了这些组件中至少一个的配置。 To recover, you'll likely need to restart the docker engine ( systemctl restart docker ).要恢复,您可能需要重新启动 docker 引擎 ( systemctl restart docker )。

Instead of dropping the interface, I'd recommend using tc to drop all packets.我建议使用tc来丢弃所有数据包,而不是丢弃接口。 There's even a project that can do this by labels on the individual containers, or controlled by an API, that you can find at lukaszlach/docker-tc .甚至有一个项目可以通过单个容器上的标签或由 API 控制来完成此操作,您可以在lukaszlach/docker-tc找到

The problem was that Docker was losing the default gateway address.问题是 Docker 丢失了默认网关地址。 I just added another command to reset the gateway address after restarting the interface and everything worked again:我刚刚添加了另一个命令来重新启动界面后重置网关地址,一切又恢复正常:

route add default gw ${this.defaultGatewayAddress}

At the end, I got this working Kotlin code:最后,我得到了这个有效的 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())
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM