# Docker 与 IPtables

### Docker 与 IPtables

#### docker行为

> 默认情况下，Docker deamon会在启动container的时候向iptables中添加转发的规则。它会创建一个filter chain - DOCKER。

```python
Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
...

Chain DOCKER (1 references)
target     prot opt source               destination
```

* 同时，docke利用这个规则r向外暴露container的端口。但是，很不幸，这条规则将这个端口暴露给了全世界。
* 所以，如果你是在宿主机直接运行docker，同时这个宿主机已经拥有了关于防火墙的一些配置（利用iptables）。
* 那么，可以考虑在创建或者运行container的时候使用 --iptables=false。

#### docker对iptables的操作？

首先，我们确定场景：

* 主机服务器可访问网络
  * 在主机内使用docker构建container
  * 主机拥有iptables，并用其进行防火墙的配置
  * 之后，我们需要让docker取消对我们系统iptables的操作和修改。我们就在启动daemon的时候使用如下的配置：

```python
--iptables=false    # 已安装 docker ，直接在 docker.service 服务配置文件内后面加上
```

对于使用sysvinit和upstart的系统，我们可以修改 /etc/default/docker，docker的配置文件。对于systemd：

```python
mkdir /etc/systemd/system/docker.service.d
cat << EOF > /etc/systemd/system/docker.service.d/noiptables.conf
[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --iptables=false
EOF
systemctl daemon-reload
```

然后，重启我们的防火墙，同时重启docker daemon。然后我们就能够看到DOCKER这个chain以及和其相关的FORWARDchain的配置已经没有了。

为docker配置iptables， 例如以太网卡 ech0, docker默认网卡名称： 'docker0'。

我们可以通过以下设置配置FORWARD的rules：

```python
-A FORWARD -i docker0 -o eth0 -j ACCEPT
-A FORWARD -i eth0 -o docker0 -j ACCEPT
```

同时，如果你想要暴露一个正在运行的container的TCP端口10000，，这个container需要将这port暴露给任何IP：

```python
docker run --name some-nginx -d -p 10000:80 nginx

netstat -an | grep 10000
tcp6       0      0 :::10000                :::*                    LISTEN
```

同时，我们可以将这个规则加入到iptables中，让外来访问可以通过防火墙访问container：

```python
-A INPUT -p tcp -m tcp --dport 10000 -s 0.0.0.0/0 -j ACCEPT
```
