问题

不知道大家在自己的服务器上运行Docker时,一般是将防火墙关闭呢还是将防火墙打开同时允许端口访问的模式;笔者之前都是一刀切,关闭防火墙,轻松省事。但是要想在生产环境这样部署,怕是要挨批评了,所以开始了解在开启防火墙的同时,也能让Docker的服务正常被外部所访问。

步骤

1、检查 iptables

接下来会清除 iptables 现有规则,如果你一直使用的是 Firewalld 来管理你的防火墙,就没必要查看现有的 iptbales 规则了。

1
iptables -L

2、关闭 Firewalld 和 docker 服务

1
systemctl stop Firewalld docker

3、清除现有防火墙规则

由于 docker 启动容器时会在 iptables中添加规则,我们先放行规则,非常重要!
否则 22 端口也就是你的 SSH 服务可能再也连不上了。

1
iptables -P INPUT ACCEPT

清除所有规则

1
iptables -F 

4、开启端口转发

1、开启内核 IP 地址转发功能

首先查看内核是否开启 IP 地址转发功能

1
cat /proc/sys/net/ipv4/ip_forward

返回为 1 已开启,返回 0 则需要手动开一下。

方法一:

1
2
[root@centos7 ~]# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

复制到终端上,以 root 用户身份执行即可。

方法二:

1
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf 

使更改立即生效

1
sysctl -p 
2、防火墙放行 IP 地址转发

现在将 Firewalld 服务启动:

1
systemctl start Firewalld

默认情况下 Firewalld 会禁止转发流量,可以执行 firewall-cmd --query-masquerade 查看状态,应该是 no,请执行下面的命令开启转发。
永久开启 IP 地址转发:

1
firewall-cmd --add-masquerade --permanent 

5、启动 Docker 服务

现在可以启动 docker 服务检查容器网络是否正常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@centos7 ~]# systemctl start docker
[root@centos7 ~]# docker run -it --rm centos:latest ping baidu.com
Unable to find image 'centos:latest' locally
Trying to pull repository docker.io/library/centos ...
sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700: Pulling from docker.io/library/centos
8a29a15cefae: Pull complete
Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
Status: Downloaded newer image for docker.io/centos:latest
PING baidu.com (39.156.69.79) 56(84) bytes of data.
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=47 time=48.5 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=47 time=47.8 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=47 time=46.8 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=47 time=47.10 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=5 ttl=47 time=46.9 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=6 ttl=47 time=47.6 ms
^C
--- baidu.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 12ms
rtt min/avg/max/mdev = 46.810/47.608/48.513/0.651 ms

额外要注意的一点是,如果你防火墙屏蔽了 icmp 的 echo-request 请求,也就是我们说的禁止 Ping。那么在容器中 Ping 别人及其的时候也会被主机防火墙拦截下来,Ping 不通的哦。如果 Ping 不通可以使用 curl www.baidu.com看看能不能访问得到百度页面,这样检测。

6、开放容器对应端口

这里仅举例80端口,如果采用HTTPS访问,则对应的将80改为443再执行该命令即可:

1
firewall-cmd --zone=public --add-port=80/tcp --permanent

重新载入以生效防火墙规则:

1
firewall-cmd --reload

查看所有开放端口:

1
firewall-cmd --zone=public --list-ports

此时访问ip+容器服务端口号,你会发现Docker服务能正常被访问,Firewalld防火墙也正常开启了。