Docker系统六:Docker网络管理

时间:2023-03-09 04:37:14
Docker系统六:Docker网络管理

Docker网络

I. Docer的通信方式

默认情况下,Docker使用网桥(brige)+ NAT的通信模型.

Docker启动时会自动创建网桥Docker0,并配置ip 172.17.0.1/16

ifconfig docker0
docker0 Link encap:Ethernet HWaddr 02:42:e0:31:ac:10
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1846 errors:0 dropped:0 overruns:0 frame:0
TX packets:5562 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:168242 (168.2 KB) TX bytes:23550976 (23.5 MB)

Docker容器内容及容器与宿主机通信方式(Brige方式)

当Docker启动容器时,会创建一对veth虚拟网络设备:

  • 一个附加到网桥上;
  • 一个加入容器的网张命名空间并被改名为eth0

Docker容器与外部网张通信(NAT方式)

1)容器访问外网

Docker通过创建如下MASQUERADE规则进行外部网络访问:

iptables -t nat -A POSTROUTING -s 172.17.0.0/16 !-o docker0 -j MASQUERADE

规则说明:奖所有从容器(172.17.0.0/16)发往外网的包的源地址都改为Host(宿主机)的IP。

2)外网访问容器

当容器提供的服务需要暴露给外部网络里,Docker启动容器里,会创建SNAT规则。eg,启动一个apache容器:

docker run -d -p 80:80 apache

在上述命令背后其实会创建如下SNAT规则:

iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A DOCKER !-i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80

II. Docker的网络配置

Docker中很多网络相关的参数主是有:

  • Docker进程本身的,影响所有docker容器;
  • Docker容器相关的,只影响当前容器;

1. 网络配置参数

1)Docker进程的网络配置

相关参数如下:

-b, --bridge="" ;//指定Docker使用的网络设备。默认下,Docker会创建docker0网桥设备,通过该参数可以指定Docker使用已存在的网桥设备
--bip="" ;//指定网桥设备的docker0的IP和掩码,使用标准的CIDR形式,如192.168.1.5/24
--dns=[] ;//强制docker使用指定的DNS servers
--dns-search=[] ;//强制docker使用指定的DNS search domains
--icc=true ;//打开inter-container沟通
--ip="0.0.0.0" ;//绑定容器端口时的默认IP
--ip-forward=true ;//打开 net.ipv4.ip_forward
--iptables=true; //打开docker的iptables rules增加
--mtu=0; //设置容器的网络MTU,如果没有设置任何值则默认route MTU ,当默认路由不存在时,使用1500

Note:

--dns/--dns-search: 配置容器的DNS,改参数可以在启动Docker进程时指定(成为所有容器的默认值),也可以在启动容器(docker run)时指定(覆盖默认值)。
2)容器的网络配置

下面是docker run时的一些网络配置参数:

--net="bridge" //用于指定容器使用的网络通信方式;

它有如下四个值:

  • bridge : Docker容器的默认通信方式;
  • none : 容器没有网络栈,此时容器无法与外界通信;
  • container:<name|id> : 使用其他容器(name或id)的网络栈。实际上,Docker会将该容器加到指定的容器network namespace, 这是一种非常有用的方式。
  • host : 表示容器使用Host的网络,没有自己独立的网络栈。实际上,在这种情况下,Docker不会给容器创建单独的网络名字空间(newwork namespace).由于容器可以完全访问Host的网络,所以此方式也是不安全的。

2. 配置DNS

一般来说每个容器的hostname和DNS配置信息是不同的,我们不可能为每个容器都构建一个镜像,并在镜像中指定这些信息。实际上,Docker在启动容器时,会使用bind mount动态挂载/etc/hostname,/etc/hosts,/etc/resolv.conf几个文件,覆盖镜像中原来的文件。通过如下命令我们可以在容器内看到这个信息:

docker exec -it {容器} /bin/bash
mount /dev/vda1 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/vda1 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/vda1 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)

所以,我们可以通过命令行参数在启动Doker时指定DNS

3. Docker网络相关的一些参考