文档章节

Docker网络与防火墙

无心灬快语
 无心灬快语
发布于 2017/07/07 09:43
字数 1463
阅读 1841
收藏 2

docker需不需要防火墙软件?

其实这个问题之前一直困扰着我,在请教技术大牛以及自己探讨以后,得到了一个答案,那就是docker不需要防火墙软件(注意这里指的是firewalld,iptables等防火墙软件而不是iptables服务)。

防火墙软件是否对docker有影响?

docker引擎启动的时候会修改iptables规则,如果使用了防火墙软件,只要重启防火墙软件,则docker的规则就全部丢失,影响容器访问。

如果必须使用防火墙需要注意什么?

增删开放端口都必须通过动态命令添加,并且不应该重启防火墙。

如果使用防火墙,部署业务映射了宿主机的端口,是否应该开放该端口?

没有必要,因为不管你开不开放端口,都可以访问到服务。具体看下面的解释。

Docker网络模式

Docker有多中网络模式,包括host,none,bridge ,overlay等。下面以Docker默认的bridge网络---Docker0来探讨Docker网络与iptables的关系。

Docker0网络是Docker搭建的一个虚拟桥接网络,默认网关地址是172.17.0.1。Docker默认的网络是Docker0网络,也就意味着Docker中所有没有指定网络的容器都会加入到这个桥接网络中,网络中的容器可以互相通信。

# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:c0ff:febb:bb1e  

容器对外请求数据

如果Docker0中的容器请求外部的数据,那么他的数据包将会发送到网关172.17.0.1处。当数据包到达网关后,将会查询主机的路由表,确定数据包将从那个网卡发出。iptables负责对数据包进行snat转换,将原地址转为对应网卡的地址,因此容器对外是不可见的。

外部对容器请求数据

外部想要访问容器内的数据,首先需要将容器的端口映射到宿主机上。这时候docker会在iptables添加转发规则,把接收到的数据转发给容器。

Docker数据在iptables中传递

下图是数据包在iptable的传递流程

image

创建一个端口映射的容器

接下来我们查看一下容器数据包在iptable中怎么传递的 创建一个redis容器,将映射容器6379端口到宿主机36379端口。

# docker run --name redistest -d -p 36379:6379 172.16.1.129/redis/3.0.7:v1.1
b4c3fc06cdaccc2080f9e4845ebb2d2b789632ddaecb6e7b2e3bdf863c416014

查看iptables的nat表

# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL    

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere            !loopback/8           ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
CATTLE_NAT_POSTROUTING  all  --  anywhere             anywhere            
MASQUERADE  all  --  172.17.0.0/16        anywhere            
MASQUERADE  all  --  172.18.0.0/16        anywhere            
MASQUERADE  tcp  --  172.17.0.3           172.17.0.3           tcp dpt:6379

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            
DNAT       tcp  --  anywhere             anywhere             tcp dpt:36379 to:172.17.0.3:6379

可以看到iptables的nat表中有一条Docker子链 里面有一条数据

DNAT       tcp  --  anywhere             anywhere             tcp dpt:36379 to:172.17.0.3:6379

这条数据就是负责宿主机tcp36379端口映射到172.17.0.3:6379上。

Docker子链被PREROUTING和OUTPUT链引用

  • PREROUTING:数据包到达防火墙时改变包的目的地址

  • OUTPUT:过滤所有本机产生的数据包(对源地址得数据包的过滤)

也就是说外部对宿主机36379访问的数据包在nat这里被进行snat和pnat转换,目的地址转为172.17.0.3:6379。

容器对外部访问的数据包也在这里进行dnat和pnat,将172.17.0.3:6379转为宿主机的36379端口

查看iptables的filter表

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER-ISOLATION  all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere            

DROP       all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         


Chain DOCKER (2 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.17.0.3           tcp dpt:6379

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

里面同样有一个 DOCKER子链,被FORWARD链引用

  • FORWARD链:过滤所有路过本机的数据包(源地址和目标地址都不是本机的数据包)

也就是说经过nat切换地址以后,测试容器的数据包将会转发到172.17.0.3,而不是宿主机,过滤规则是Accept,也就是通过。

通过上面的分析,可以知道数据到达宿主机的防火墙,直接就forward到容器了,没有执行到input流程,所以容器映射的宿主机端口不需要开放。

docker与防火墙软件同时使用注意事项

docker的部分网络功能是通过iptables转发来完成的,转发规则是docker进程启动后动态添加的,也就意味着如果你重启iptables,将会丢失docker的转发规则。

有两种解决办法:

  1. 动态添加iptables规则,然后保存到防火墙软件配置文件中

动态添加iptables规则可以使规则立即生效(重启失效)

sudo iptables -I INPUT 1 -p tcp --dport 46379 -j ACCEPT

这条命令会将规则添加到input规则的第一位 ,-I参数指定插入位置。不要使用-A参数,该参数会将规则添加到input的最后一条,一般原来的最后一条都是reject规则,所以新插入的规则无法生效。

sudo service iptables save
  1. 重启iptable后重新启动docker

影响:重启docker会导致全部容器重启,有可能造成短时间的业务故障。

此方法不建议使用,如果已经重启防火墙,导致docker业务故障,使用下面命令重启dcoker。

systemctl restart docker

© 著作权归作者所有

无心灬快语
粉丝 0
博文 11
码字总数 10418
作品 0
深圳
程序员
私信 提问
docker 容器无法连接外网

Q:docker run -itd --name=NAME --net host IMAGE bash 启动容器后,容器中无法连接外网 A:进入容器 docker exec -ti [NAMES] /bin/bash 设置防火墙 使用命令iptables -n -L 可以查看当前防...

Jack088
01/31
294
0
阿里云VPC和企业网络互通配置

Step1. 注册账号 注册地址:https://user.accesshub.cn/#/signUp Step2. 登陆管理控制台 登陆方式一:在 https://user.accesshub.cn/#/loginTo 输入管理平台域名跳转到登陆页面 登陆方式二:...

xuanliang
2018/07/23
0
0
青云QingCloud推出SDN网络直通服务 Docker网络能力大幅提升

企业级基础云服务商青云QingCloud日前宣布推出SDN网络直通服务,由IaaS平台网卡管理和Hostnic插件两部分组成。该服务能够使运行在虚拟机上的容器直接使用IaaS平台的SDN能力,从而极大地提升了...

玄学酱
2018/04/20
0
0
Weave在Docker虚拟网络中的应用

Weave 创建一个虚拟网络并连接到部署在多个主机上的 Docker 容器。 Weave Virtual Network 应用程序使用该网络就好像它们是插在同一个网络交换机上,无需任何配置和端口映射。容器内的服务可...

linuxprobe16
2018/11/18
8
0
Docker Swarm集群部署实践

本文为转载,原文:Docker Swarm集群部署实践 1. 介绍 Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命...

ChainZhang
2018/05/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

3_数组

3_数组

行者终成事
今天
7
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部