标签:启动 之间 hostname 相同 iptable 关于 参数 dns服务 主主
本章介绍docker的一些关于网络的高级知识,包括网络的启动和配置参数、DNS的使用配置、容器访问和端口映射的相关实现。
20.1 网络启动与配置参数
1. 基本过程
docker启动时会在主机上自动创建一个docker0虚拟网桥,实际上是一个Linux网桥,可以理解为一个软件交换机。它会在挂载其上的接口之间进行转发。
同时docker随机分配一个本地未占用的私有网段中的一个地址给docker0接口。此后启动的容器内的网口也会自动分配一个同一网段的地址。包括IP和掩码。
当创建一个docker容器的时候,同时会创建了一对veth pair接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即eth0;另一端在本地并被挂载到docker0网桥,名称以veth开头。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。这样一来,docker就创建了在主机和所有容器之间一个虚拟共享网络。
2, 网络相关参数
下面是跟docker网络相关的命令参数,其中有些命令选项只有在docker服务启动的时候才能配置,而且不能马上生效:
1)-b BRIDGE or --bridge=BRIDGE:指定容器挂载的网桥。
2)--bip=CIDR:定制docker0的掩码。
3)-H SOCKET... or --host=SOCKET...:docker服务端接收命令的通道。
4)--icc=true|false:是否支持容器之间进行通信。
5)--ip-forward=true|false:启用net.ipv4.ip forward,即打开转发功能。
6)--iptables=true|false:禁止docker添加iptables规则。
7)--mtu=BYTES:容器网络中的MTU。
下面两个命令选项既可以在启动服务时指定,也可以docker容器启动(docker run)时候指定。在docker服务启动的时候指定则会成为默认值,后续执行docker run时可以覆盖设置的默认值:
1)--dns=IP_ADDRESS...:使用指定的DNS服务器。
2)--dns-search=DOMAIN...:指定DNS搜索域。
最后这些选项只能在docker run执行时使用,因为它们是针对容器的特性内容:
1)-h HOSTNAME or --hostname=HOSTNAME:配置容器主机名。
2)--link=CONTAINER_NAME:ALIAS:添加到另一个容器的连接。
3)--net=bridge | none | container:NAME_or_ID | host:配置容器的桥接模式。
4)-p SPEC or --publish=SPEC:映射容器端口到宿主主机。
5)-P or --publish-all=true|false:映射容器所有端口到宿主主机。
20.2 哦欸之容器DNS和主机名
docker支持自定义容器的主机名和DNS配置。
1. 相关配置文件
容器中主机名和DNS配置信息都是通过三个系统配置文件来维护的:
/etc/resolv.conf、/etc/hostname和/etc/hosts。
其中,/etc/resolv.conf文件在创建容器时候,默认会与宿主机/etc/resolv.conf文件内容保持一致。
/etc/hosts文件中默认只记录了容器自身的一些地址和名称。
/etc/hostname文件则记录了容器的主机名。
2. 容器内修改配置文件
docker 1.2.0开始支持在运行中的容器里直接编辑/etc/hosts, /etc/hostname和/etc/resolv.conf文件。但是是临时性的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被docker commit提交。
3. 通过参数指定
如果用户想要自定义容器的配置,可以在创建或启动容器时利用下面的参数指定:
1)指定主机名 -h HOSTNAME or --hostname=HOSTNAME。设定容器的主机名,它会被写到容器内的/etc/hostname和/etc/hosts。但这个主机名只有容器内能看到,在容器外部看不到,既不会在docker ps中显示,也不会再其他容器的/etc/hosts看到。
2)记录其它容器主机名 --link=CONTAINER_NAME:ALIAS。选项会在创建容器的时候,添加一个所连接容器的主机名到容器内/etc/hosts文件值。这样,新创建容器可以直接使用主机名来与所连接容器通信。
3)指定DNS服务器--dns=IP_ADDRESS。添加DNS服务器到容器的/etc/resolv.conf中,容器会用指定的服务器来解析所有不在/etc/hosts中的主机名。
4)指定DNS搜索域--dns-search=DOMAIN。设定容器的搜索域,当设定搜索域为.example.com时,在搜索一个名为host的主机时,DNS不仅搜索host,还会搜索host.example.com。
20.3 容器访问控制
容器的访问控制,主要通过Linux上的iptables防火墙软件来进行管理和实现。iptables是Linux系统流行的防火墙软件,在大部分发行版中都自带。
1. 容器访问外部网络
容器默认指定了网关为docker0网桥上的docker0内部接口。docker0内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访问到宿主机本地的。
更进一步地,容器要想通过宿主机访问到外部网络,需要宿主机进行转发。
在启动docker服务的时候设定--ip-forward=true,docker服务会自动打开宿主机系统的转发服务。
2. 容器之间访问
容器之间相互访问需要以下两方面的支持。
1)网络拓朴是否已经连通。默认情况下,所有容器都会连接到docker0网桥上,这意味着默认情况下拓扑是互通的。
2)本地系统的防火墙软件iptables是否允许访问通过。这取决于防火墙的默认规则是允许还是禁止。
访问所有端口:
当启动docker服务时,默认会添加一条“允许”转发策略到iptables的FORWARD链上。通过配置--icc=true|false(默认值为true)参数可以控制默认的策略。
为了安全考虑,可以在/etc/default/docker文件中配置DOCKER_OPTS=--icc=false来默认禁止容器之间的相互访问。
同时,如果启动docker服务时手动指定--iptables=false参数则不会修改宿主机系统上的iptables规则。
访问指定端口:
在通过-icc=false禁止容器间相互访问后,仍可以通过--link=CONTAINER_NAME:ALIAS选项来允许访问指定容器的开放端口。
20.4 映射容器端口到宿主主机的实现
默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。
1. 容器访问外部实现
假设容器内部的网络地址为172.17.0.2,本地网络地址为10.0.2.2。容器要能访问外部网络,源地址不能为172.17.0.2,需要进行源地址映射(SourceNAT, SNAT),修改为本地系统的IP地址10.0.2.2,映射是通过iptables的源地址伪装操作实现的。
2. 外部访问容器实现
容器允许外部访问,可以在docker run时通过-p或-P参数来启用。
不管用哪种方法,都是在本地的iptables的nat表中添加相应的规则,将访问外部IP地址的网包进行目标地址DNAT,将目标地址修改为容器的IP地址。
1)IP映射0.0.0.0,意味着将接受主机来自所有网络接口上的流量。用户可以通过-p IP:host_port:container_port或-p IP::port来指定绑定的外部网络接口,以制定更严格的访问规则。
2)如果希望映射永久绑定到某个固定的IP地址,可以在docker配置文件/etc/default/docker中指定DOCKER_OPTS="--ip=IP_ADDRESS",之后重启docker服务即可生效。
20.5 配置docker0网桥
docker服务默认创建一个名称为docker0的Linux网桥(其上有一个docker0内部接口),它在内核层连通了其它的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了MTU(接口允许接收的最大传输单元),通常是1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。
1)--bip=CIDR:IP地址加掩码格式,例如 192.168.1.5/24
2)--mtu=BYTES:覆盖默认的docker run配置。
也可以在配置文件中配置DOCKER_OPTS,然后重启服务。由于目前docker网桥是Linux网桥,用户可以使用brctl show来查看网桥和端口连接信息。
每次创建一个新容器的时候,docker从可用的地址段中选择一个空闲的IP地址分配给容器的eth0端口,并且使用本地主机上docker0接口的IP作为容器的默认网关。
目前,docker不支持在启动容器时候指定IP地址。
20.6 自定义网桥
除了默认的docker0网桥,用户也可以指定网桥来连接各个容器。
在启动docker服务时,使用-b BRIDGE或--bridge=BRIDGE来指定使用的网桥。
20.7 创建一个点到点连接
默认情况下,docker会将所有容器连接到由docker0提供的虚拟子网中。
用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。
解决办法是:创建一对peer接口,分别放到两个容器中,配置成点到点链路类型即可。
标签:启动 之间 hostname 相同 iptable 关于 参数 dns服务 主主
原文地址:https://www.cnblogs.com/cjj-ggboy/p/12639877.html