您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 工作范文 > Docker网络配置
Docker网络配置摘要当docker启动时,它会在宿主机器上创建一个名为docker0的虚拟网络接口。它会从RFC1918定义的私有地址中随机选择一个主机不用的地址和子网掩码,并将它分配给docker0。例如当我启动docker几分钟后它选择了172.17.42.1/16-一个16位的子网掩码为主机和它的容器提供了65,534个ip地址。但docker0并不是正常的网络接口。它只是一个在绑定到这上面的其他网卡间自动转发数据包的虚拟以太网桥。它可以使容器与主机相互通信。每次Docker创建一个容器,它就会创建一对对等接口(peerinterface),类似于一个管子的两端--在这边可以收到另一边发送的数据包。Docker会将对等接口中的一个做为eth0接口连接到容器上,并使用类似于vethAQI2QT这样的惟一名称来持有另一个,该名称取决于主机的命名空间。通过将所有veth*接口绑定到docker0桥接网卡上,Docker在主机和所有Docker容器间创建一个共享的虚拟子网。本文其他部分将会讲解使用Docker选项的所有方式,并且-在高级模式下-使用纯linux网线配置命令来调整,补充,或完全替代Docker的默认网络配置。Docker选项快速指南这里有一份关于Docker网络配置的命令行选项列表,省去您查找相关资料的麻烦。一些网络配置的命令行选项只能在服务器启动时提供给Docker服务器。并且一旦启动起来就无法改变。一些网络配置命令选项只能在启动时提供给Docker服务器,并且在运行中不能改变:-bBRIDGE或--bridge=BRIDGE建立自己的网桥--bip=CIDR定制docker0-HSOCKET...或--host=SOCKET...它看起来像是在设置容器的网络,但实际却恰恰相反:它告诉Docker服务器要接收命令的通道,例如“runcontainer和stopcontainer。--icc=true|false容器间通信--ip=IP_ADDRESS绑定容器端口--ip-forward=true|false容器间通信--iptables=true|false容器间通信--mtu=BYTES—see定制docker0有两个网络配置选项可以在启动时或调用dockerrun时设置。当在启动时设置它会成为dockerrun的默认值:--dns=IP_ADDRESS...配置DNS--dns-search=DOMAIN...配置DNS最后,一些网络配置选项只能在调用dockerrun时指出,因为它们要为每个容器做特定的配置:-hHOSTNAME或--hostname=HOSTNAME配置DNS和Docker与容器连接原理--link=CONTAINER_NAME:ALIAS配置DNS和容器间通信--net=bridge|none|container:NAME_or_ID|hostDocker与容器连接原理-pSPEC或--publish=SPEC绑定容器端口-P或--publish-all=true|false绑定容器端口接下来的部分会对以上话题从易到难做出逐一解答。配置DNS(为每一个容器进行主机名和DNS配置)怎样为Docker提供的每一个容器进行主机名和DNS配置,而不必建立自定义镜像并将主机名写到里面?它的诀窍是覆盖三个至关重要的在/etc下的容器内的虚拟文件,那几个文件可以写入新的信息。你可以在容器内部运行mount看到这个:#mount/dev/disk/by-uuid/1fec...ebdfon/etc/hostnametypeext4/dev/disk/by-uuid/1fec...ebdfon/etc/hoststypeext4tmpfson/etc/resolv.conftypetmpfs在容器内部运行(查看容器的主机名配置和DNS配置):#cat/etc/resolv.conf#cat/etc/hosts#cat/etc/hostname这样的配置允许Docker去做聪明的事情,类似于当主机接收到新的DHCP配置之后,保持resolv.conf的数据到所有的容器中。Docker怎样维护在容器内的这些文件从Docker的一个版本到下一个版本的具体细节,你应该抛开这些单独的文件本身并且使用下面的Docker选项代替。有四种不同的选项会影响容器守护进程的服务名称(容器的主机名称)。1、-hHOSTNAME或者--hostname=HOSTNAME设置容器的主机名,仅本机可见(应该用途不大,因为容器内通讯可以通过localhost访问)。这种方式是写到/etc/hostname,以及/etc/hosts文件中,作为容器主机IP的别名,并且将显示在容器的bash中(格式如:[root@a1d1291ffd08/]#)。不过这种方式设置的主机名将不容易被容器之外可见。这将不会出现在dockerps或者其他的容器的/etc/hosts文件中。2、--link=CONTAINER_NAME:ALIAS(通过这种方式,让两个容器之间可以通讯。其中CONTAINER_NAME标识已经启动的容器的名字,在本容器中,需要通过其别名访问该已经启动的容器)使用这个选项去run一个容器将在此容器的/etc/hosts文件中增加一个主机名ALIAS(别名),这个主机名是名为CONTAINER_NAME的容器的IP地址的别名。这使得新容器的内部进程可以访问主机名为ALIAS的容器而不用知道它的IP。--link=关于这个选项的详细讨论请看:Communicationbetweencontainers.例子:1、启动DB服务器#dockerrun--name=mysql_server-d-Pkongxx/mysql_server2、启动应用服务器1#dockerrun--name=mysql_client1--link=mysql_server:db-t-ikongxx/mysql_client\/usr/bin/mysql-hdb-uroot–pletmein3:启动应用服务器2#dockerrun--name=mysql_client2--link=mysql_server:db-t-i\kongxx/mysql_client/usr/bin/mysql-hdb-uroot–pletmein3、--dns=IP_ADDRESS设置DNS服务器的IP地址,写入到容器的/etc/resolv.conf文件中。当容器中的进程尝试访问不在/etc/hosts文件中的主机A时,容器将以53端口(DNS缺省端口)连接到IP_ADDRESS这个DNS服务器去搜寻主机A的IP地址。问题探讨(需要实验):a)通过--link,可以实现同一个宿主机上的所有容器(除了上例中的DB服务器无法添加link参数,因为她启动时,其它容器还未启动)之间的通讯;b)当用--dns参数方式,当前容器可以访问dns来定位其它宿主机上的docker容器;延伸阅读(DNS和docker小技巧)在容器迁移的时候,Docker在每次开始时会有一个不同的IP,数据成功迁移后,你重新启动你的容器的时候,你需要更新你下你的信息,例如让你的应用容器知道你的数据库更换了ip地址。当然你可以使用etcd等来同步配置,但是还是有点时间成本的。让我告诉你一个懒人的办法。设置一个DNS,使用最简单的dnsmasq,它同时也为Docker提供DHCP服务。dnsmasq配置文件$cat/etc/dnsmasq.conflisten-address=0.0.0.0interface=lointerface=eth0interface=docker0resolv-file=/etc/resolv.dnsmasq.confconf-dir=/opt/docker/dnsmasq.d#dockerrun-d-dns172.17.42.1-namedb-hdbdb_image#dockerrun-d-dns172.17.42.1-nameapp-happapp_image当我们更换了容器,我们只需要更新一些主机配置和DNS服务$container='db'$new_ip=$(dockerinspect$container|grepIPAddress|cut-f4-d'')$echohost-record=$container,$new_ip/opt/docker/dnsmasq.d/0host_$container$servicednsmasqrestart好了,现在我们可以在配置中简单的使用db作为主机,同理,可以把app都加载到dns中,在其它宿主机上运行容器时,可以通过主机名,让dnsServer解析后,获得实际的IP地址。注意:要实现该功能,需要先安装DNS服务(或安装dnsmasq服务)。4、--dns-search=DOMAIN(自动补齐域名搜索)设置DNS服务器的搜索域,以防容器尝试访问不完整的主机名时从中检索相应的IP。这是写入到容器的/etc/resolv.conf文件中的。当容器尝试访问主机host,而DNS搜索域被设置为example.com,那么DNS将不仅去查寻host主机的IP,还去查询host.example.com的IP。在docker中,如果启动容器时缺少以上最后两种选项设置时,将使得容器的/etc/resolv.conf文件看起来和宿主主机的/etc/resolv.conf文件一致。这些选项将修改默认的设置。容器间通信在操作系统层面上,决定两个容器间的通信能否得到控制,有以下三个因素。1、网络拓扑逻辑是否连接上了容器的网络接口。默认情况下Docker将把所有容器绑定到一个singledocker0bridge,并为两个容器间的包传输提供路径。参见本文档后续部分---其他可能的拓扑逻辑2、主机是否要发送IP包?这由ip_forward系统参数控制。如果这个参数设为1,那么数据包只能在容器间传输。通常情况下,让Docker服务器使用它的默认设置--ip-forward=true,Docker在启动的时候会把ip_forwardsh。要检查设置或手动设置参数,可以这样做:#Usuallynotnecessary:turningonforwarding,#onthehostwhereyourDockerserverisrunning$cat/proc/sys/net/ipv4/ip_forward0$echo1/proc/sys/net/ipv4/ip_forward$cat/proc/sys/net/ipv4/ip_forward13、iptables是否允许特殊连接?如果你把设置--iptables=false,当守护进程启动时,Docker不会改变你的系统iptables规则。另外,如果你保留默认设置--icc=true,Docker服务器或向FORWARD链添加一个带有全局ACCEPT策略的默认规则。如果不保留默认设置,系统会把策略设为DROP。几乎所有人使用docker都希望ip_forward是打开的,至少使容器间的通讯成为可能。但是否同意--icc=true或者更改为--icc=false使得iptables可以保护容器以及宿主主机不被任意地端口扫描、避免被已经被渗透的容器所访问,这是一个策略问题。(在ubuntu,是编辑/etc/default/docker文件中的DOCKER_OPTS参数,然后重启docker服务),如果你选择最安全的设置--icc=false,那么当你想让它们彼此提供服务的时候如何让它们相互通讯?答案是:使用前文提到的--link=CONTAINER_NAME:ALIAS选项。如果docker守护进程正在以--icc=false和--iptables=true参数运行,当以选项--link=执行dockerrun命令时,docker服务将插入一部分iptablesACCEPT规则使得新容器可以连接其他容器所
本文标题:Docker网络配置
链接地址:https://www.777doc.com/doc-2910193 .html