dnat centos(centos7.0下载)

这篇文章给大家聊聊关于dnat centos,以及centos7.0下载对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

Docker网络与Iptables浅析

了解 Docker网络模式,Docker如何操作 iptables以实现网络端口映射,使用 iptables控制主机网络流量规则。

当 Docker进程启动时,会在主机上创建一个名为 docker0的虚拟网桥,此主机上启动的 Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从 docker0子网中分配一个 IP给容器使用,并设置 docker0的 IP地址为容器的默认网关。在主机上创建一对虚拟网卡 veth pair设备,Docker将 veth pair设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中,以 vethxxx这样类似的名字命名,并将这个网络设备加入到 docker0网桥中。 bridge模式是 docker的默认网络模式,不写–net参数,就是 bridge模式。使用 docker run-p时,docker实际是在 iptables做了 DNAT规则,实现端口转发功能。可以使用 iptables-vnL查看。

如果启动容器的时候使用 host模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP等,而是使用宿主机的 IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo网卡设备通信。

使用 none模式,Docker容器拥有自己的 Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个 Docker容器没有网卡、IP、路由等信息。需要我们自己为 Docker容器添加网卡、配置 IP等。

iptables通过3个 chain(INPUT,FORWARD,OUTPUT)即可完成对网络流量的控制,其屏蔽了底层操作 netfilter的细节,常用案例:

使用 iptables-L可以查看已设置的规则, iptables-D可以删除规则,iptables命令执行完是即时生效的,但是如果主机重启,已设置的规则就会丢失,这里可以使用 iptables-save和 iptables-restore。

iptables-save将现有规则保存成文件,iptables-restore从文件中恢复规则。

该命令执行后,docker会在 iptables自定义链 DOCKER中定义转发规则,如果此时系统的 net.ipv4.ip_forward为0,该命令执行完会提示:WARNING: IPv4 forwarding is disabled. Networking will not work,只需打开该配置就行了,无需重启容器。

此时查看 DOCKER链可以看到添加了一条允许所有来源转发到6379端口的流量,用 redis-cli也可以顺利连上,如果我们手动执行:

发现现在 redis-cli连不上了~将命令中的-I换成-D删除即可。

开发中,经常会遇到容器里面放问宿主机的情况,除了使用 host.docker.internal之外,还可以配置 extra_hosts解决,因为 docker0与宿主机是相通的,直接用 ifconfig查看宿主机 en0网卡的ip地址,配置到 extra_hosts即可,如:

iptables在 centos系列正在逐渐被 firewalld替换,firewalld底层也是操作的 iptables,在同时操作这两个工具的时候就容易出现互相覆盖影响的情况,建议两个不要同时使用,使用其一即可。

单host下Docker的默认网络配置

本文用到的环境如下:

host: centos7

docker:通过 yum install-y docker安装,版本号为1.10.3

docker镜像:

# Version: 0.0.1 FROM ubuntu:latest MAINTAINER paul liu"pollux.liu@msn.com" RUN apt-get update RUN apt-get install-y net-tools RUN apt-get install-y iputils-ping CMD/bin/bash

场景图:

我的host主机接有无线路由器,通过ADSL拨号上网,网卡eth0固定IP为192.168.0.200,网关为路由器的IP 192.168.0.1。

在host上安装docker,并运行容器。

通过以下命令安装docker,

yum install-y docker

启用docker,

systemctl start docker

然后在host主机运行 ifconfig或 ip a命令,可以看到除去host原有的网卡eth0和回环lo外,多了个docker0。

docker0 IP为172.17.0.1,所在的网段默认为B类私网地址172.17.0.0/16。可以将docker0看做是host主机的一块虚拟网卡。这样host主机就等同于配置了双网卡,两块网卡之间可以通信,但前提是启用ip_forward。

这是docker0的第一个身份。

运行两个容器docker1,docker2,然后在host主机上运行 brctl show查看,

这里可以看出docker0的第二个身份,一个虚拟交换机。每运行一个容器,就会产生一对veth,其中一端连接到docker0上,另一端连接到容器的eth0上。这样,所有连接到docker0的容器组成了一个局域网。如下图:

在host主机上运行 ifconfig,也会发现多了两个veth这样的网络接口。

在host主机上运行 ip addr show veth6d9a691,可以查看到该veth具有mac地址,这也正说明了docker0的虚拟交换机的身份,交换机是通过mac地址通信的,连接到交换机的设备必须具有mac地址。

由于docker0自身也具有mac地址,这个与纯二层交换机是不同的,并且绑定了IP 172.17.0.1,容器默认把docker0作为了网关。也就是docker0还兼具路由的功能,因此可以把docker0看做是一个三层交换机,可以做二层数据包转发,也可以做三层路由转发。

在容器中运行 route-n查看路由如下:

在host主机上运行 route-n查看路由如下:

在host中,访问本网段192.168.0.0是通过eth0转发数据包的,访问172.17.0.0网段是通过docker0转发数据包的,而对于其他如公网是通过eth0将数据包转发给网关192.168.0.1,再由该网关进行数据包转发的,比如上网。

在容器中运行 ping sohu.com或 ping 192.168.0.200都可以ping通。

默认情况下,不需要再额外做任何配置,在一台host主机上,通过docker0,各容器之间可以互通,并且可以通过host的eth0连接外网。

通俗的讲,通过docker0组成了一个网段为172.17.0.0/16的以太网,docker容器发起请求时,如果是相同网段则经由docker0转发到目标机器,如果是不同网段,则经由docker0,转发到host的另一块网卡eth0上,由eth0负责下一步的数据包转发,比如公网地址。

下面进一步分析一下报文是怎么发送到外面的。

容器内部发送一条公网请求报文,通过eth0,在veth被接收。此时报文已经来到了主机上,通过查询主机的路由表( route-n),如果发现报文应该通过主机的eth0,从默认网关发送出去,那么报文就被从docker0转发给主机的eth0,但前提是首先启用ip_forward功能,才能在host主机的docker0和eth0两个网卡间传递数据包。

由于目标地址并不属于host主机所在网段,那么会匹配机器上的 iptables中的nat表POSTROUTING链中的规则。

在host主机运行命令 iptables-L-n-t nat--line-numbers,查看nat表,这里只看POSTROUTING链:

第一行中说明,对于源地址为172.17.0.0/16网段的数据包,发出去之前通过MQSQUERADE伪装。linux内核会修改数据包源地址为host主机eth0的地址(也就是192.168.0.200),然后把报文转发出去。对于外部来说,报文是从主机eth0发送出去的。

局域网内的机器由于都是私有IP,是无法直接访问互联网的(数据包可以发出去,但回不来。)如果要上网,除了可以通过硬件路由器,也可以通过软件路由,在iptables的nat表中的POSTROUTING链中添加SNAT规则。

测试一下,在host主机运行命令 iptables-t nat-D POSTROUTING 1将第一条规则删掉,那么在容器中就运行命令 ping sohu.com就ping不通了。但仍然可以ping通host主机。

在host主机运行命令以下命令恢复:

iptables-t nat-I POSTROUTING-s 172.17.0.0/16-o eth0-j SNAT--to-source 192.168.0.200

或者

iptables-t nat-I POSTROUTING-s 172.17.0.0/16-j MASQUERADE

关于SNAT和MASQUERADE,这篇文章已经有过描述,可以参考: Docker前传之linux iptables

新建一Dockerfile,用以运行nginx容器:

# Version: 0.0.1 FROM paulliu/ubuntu_ip RUN apt-get install-y nginx EXPOSE 80

在host主机运行构建命令构建镜像 docker build-t paulliu/nginx.

在host主机运行容器启动命令 docker run-d-p 80--name nginx1 paulliu/nginx nginx-g"daemon off;"

在host主机查看容器的端口映射 docker port nginx1 80

在host主机运行命令 iptables-nat-L-n可以看到在PREROUTING链中多了以下DNAT规则:

也就是在容器启动时通过-p 80将host主机192.168.0.200:32773映射为容器172.17.0.4:80。

注意:docker容器每次启动时获取的IP地址未必是一样的,而且-p 80是在host主机上随机选择一个端口号进行映射,每次启动的端口号也未必是一样的。但iptables中相关的规则是自动变更的。

在host主机运行 curl localhost:32773或者在其他主机运行 curl 192.168.0.200:32773结果如下:

阅读剩余
THE END