Docker入门之六Docker网络

一、理解docker0
Docker启动的时候会在主机上自动创建一个docker0网桥,实际上是一个Linux网桥,网桥可以理解为一个软件交换机,负责挂载其上的接口之间进行包转发。所有容器的启动如果在docker run的时候没有指定网络模式的情况下都会挂载到docker0网桥上。这样容器就可以和主机甚至是其他容器之间通讯了。
docker0是docker默认的网卡。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。
–bip=CIDR IP 地址加掩码格式,例如 192.168.0.1/24
–mtu=BYTES 覆盖默认的 Docker mtu 配置

当你安装Docker时,它会自动创建三个网络。你可以使用以下docker network ls命令列出这些网络:
在这里插入图片描述

查看宿主机的IP信息,可以看出docker0网络

ip addr

docker0网卡
Docker内置这三个网络,运行容器时,你可以使用该–network标志来指定容器应连接到哪些网络。

该bridge网络代表docker0所有Docker安装中存在的网络。除非你使用该docker run --network=选项指定,否则Docker守护程序默认将容器连接到此网络。

二、Docker网络模式
bridge:桥接 docker(默认)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少!)

在使用docker run创建Docker容器时,可以用 --net 选项指定容器的网络模式
host模式:使用 --net=host 指定
none模式:使用 --net=none 指定
bridge模式:使用 --net=bridge 指定,默认设置
container模式:使用 --net=container:NAME_or_ID 指定

2.1、host 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。

例如,我们在 10.10.101.105/24 的机器上用 host 模式启动一个含有 web 应用的 Docker 容器,监听 tcp 80 端口。当我们在容器中执行任何类似 ifconfig 命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用 10.10.101.105:80 即可,不用任何 NAT 转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

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

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

2.4、bridge模式
bridge 模式是 Docker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置 IP 等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配 IP 了,Docker 会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主机不同的IP地址和子网分配给 docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的 IP 使用。如一般 Docker 会使用 172.17.0.0/16 这个网段,并将 172.17.0.1/16 分配给 docker0 网桥(在主机上使用 ifconfig 命令是可以看到 docker0 的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)

三、Bridge模式详解
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
桥模式拓扑
Docker完成以上网络配置的过程大致是这样的:

(1)当创建一个Docker 容器的时候, 同时会创建了一对veth pair互联接口。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。

(2)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth****这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。注:brctl 命令在 Debian、Ubuntu 中可以使用 sudo apt-get install bridge-utils 来安装。

(3)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。查看容器网络桥模式docker network inspect bridge
bridge模式
四、自定义网桥
除了默认的docker0 网桥,用户也可以指定其他网桥来连接各个容器。在启动Docker 服务的时候,可使用-b BRIDGE 或–bridge=BRIDGE 来指定使用的网桥。
如果服务已经运行,就需要先停止服务,并删除旧的网桥:

$ sudo service docker stop
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0

然后创建一个网桥bridge0:

$ sudo brctl addbr bridge0
$ sudo ip addr add 192.168.5.1/24 dev bridge0
$ sudo ip link set dev bridge0 up

查看确认网桥创建并启动:

$ ip addr show bridge0
4: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default
link/ether 66:38:dO:Od:76:18 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
valid_lft forever preferred_lft forever

配置Docker 服务,默认桥接到创建的网桥上:

$ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
$ sudo service docker start

在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。

{
  "bridge": "bridge0",
}

启动Docker 服务:
新建一个容器,可以看到它已经桥接到了bridge0上。
可以继续用brctl show 命令查看桥接的信息。另外,在容器中可以使用ip addr 和ip route 命令来查看IP 地址配置和路由信息。

五、网络相关参数
下面是与Docker 网络相关的命令参数。其中部分命令选项只有在Docker 服务启动的时候才能配置, 修改后重启生效, 包括:
-b BRIDGE or --bridge=BRIDGE: 指定容器挂载的网桥;
–bip=CIDR: 定制docker0 的掩码;
-H SOCKET… or --host=SOCKET… :Docker 服务端接收命令的通道;
–icc=true | false : 是否支持容器之间进行通信;
–ip-forward=true | false : 启用net.ipv4.ip forward, 即打开转发功能;
–iptables=true I false : 禁止Docker 添加 iptables 规则;
–mtu=BYTES: 容器网络中的MTU。

下面的命令选项既可以在启动服务时指定, 也可以Docker 容器启动(使用docker [container]run 命令)时候指定。在Docker 服务启动的时候指定则会成为默认值, 后续执行该命令时可以覆盖设置的默认值:

–dns=IP_ADDRESS: 使用指定的DNS 服务器;添加DNS 服务器到容器的/etc/resolv.conf 中,容器会用指定的服务器来解析所有不在/etc/hosts 中的主机名;
–dns-opt=" " :指定DNS 选项;
–dns-search=DOMAIN: 指定DNS 搜索域。设定容器的搜索域,当设定搜索域为.example.com 时,在搜索一个名为host 的主机时,DNS 不仅搜索host ,还会搜索host.example.com。

还有些选项只能在docker [container] run 命令执行时使用, 因为它针对容器的配置:

-h HOSTNAME or --hostname=HOSTNAME: 配置容器主机名;容器主机名会被写到容器内的/etc/hostname和/etc/hosts 。但这个主机名只有容器内能中看到,在容器外部则看不到,既不会在docker ps 中显示,也不会在其他容器的/etc/hosts 中看到;
-ip=" ": 指定容器内接口的IP 地址;
–link=CONTAINER_NAME:ALIAS: 添加到另一个容器的连接;在创建容器的时候,添加一个所连接容器的主机名到容器内/etc/hosts 文件中。这样,新建容器可以直接使用主机名与所连接容器通信;
–net=bridge|none|container:NAME_or_ID|host|user_defined_network: 配置容器的桥接模式;
–netwark-alias: 容器在网络中的别名;
-p SPEC or --publish=SPEC: 映射容器端口到宿主主机;
-P or --publish-all=true|false: 映射容器所有端口到宿主主机。其中, --net 选项支持以下五种模式:
–net=bridge : 默认配置。为容器创建独立的网络命名空间,分配网卡、IP 地址等网络配置, 并通过veth 接口对将容器挂载到一个虚拟网桥(默认为docker0) 上;
–net=none: 为容器创建独立的网络命名空间, 但不进行网络配置, 即容器内没有创建网卡、IP 地址等;
–net=container:NAME_or_ID : 新创建的容器共享指定的已存在容器的网络命名空间, 两个容器内的网络配置共享, 但其他资源(如进程空间、文件系统等)还是相互隔离的;
—net=host:不为容器创建独立的网络命名空间, 容器内看到的网络配置(网卡信息、路由表、Iptables 规则等)均与主机上的保持一致。注意其他资源还是与主机隔离的;
–net=user_ defined_network :用户自行用network 相关命令创建一个网络,同一个网络内的容器彼此可见,可以采用更多类型的网络插件。

六、配置容器DNS 和主机名
Docker 服务启动后会默认启用一个内嵌的DNS 服务,来自动解析同一个网络中的容器主机名和地址,如果无法解析,则通过容器内的DNS 相关配置进行解析。用户可以通过命令选项自定义容器的主机名和DNS 配置, 下面分别介绍。

6.1、相关配置文件
容器中主机名和DNS 配置信息可以通过三个系统配置文件来管理: /etc/resolv.conf、/etc/hostname 和/etc/hosts 。
启动一个容器,在容器中使用mount 命令可以看到这三个文件挂载信息:

$ docker run -it ubuntu
root@75dbd6685305:/# mount
/dev/sda on /etc/resolv. conf type ext4 (rw, noatime,errors=remount-ro , data=ordered)
/dev/sda on /etc/hostname type ext4 (rw , noatime , errors=remount ro , data=ordered)
/dev/sda on /etc/hosts type ext4 (rw,noatime,errors=remount-ro,data=ordered)

Docker 启动容器时,会从宿主机上复制/etc/resolv.conf 文件,并删除掉其中无法连接到
的DNS 服务器:

root@75dbd6685305: /# cat /etc/resolv.conf
nameserver 8.8.8.8
search my-docker-cloud.com

/etc/hosts 文件中默认只记录了容器自身的地址和名称:

root@75dbd6685305:/# cat /etc/hosts
172.17.0.2 75dbd6685305
: :1 localhost ip6-localhost ip6-loopback
127.0 0.1 localhost

/etc/hostname 文件则记录了容器的主机名:

root@75dbd6685305:/# cat /etc/hostname
75dbd6685305

6.2、容器内修改配置文件
容器运行时,可以在运行中的容器里直接编辑/etc/hosts 、/etc/hostname 和/etc/resolve.conf 文件。但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被docker commit 提交。
6.3、 通过参数指定
如果用户想要自定义容器的配置,可以在创建或启动容器时利用下面的参数指定,注意一般不推荐与-net=host 一起使用,会破坏宿主机上的配置信息。
-h HOSTNAME 或者-hostname=HOSTNAME
–link=CONTAINER_NAME:ALIAS
–dns=IP_ADDRESS
–dns-option list
–dns-search=DOMAIN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值