怎么做网站的寄生,网站建设就问山东聚搜网络f,国内十大网站建设品牌,wordpress 录音自从Docker容器出现以来#xff0c;容器网络通信就一直是被关注的焦点#xff0c;也是生产环境的迫切需求。容器网络通信又分为两大方面#xff1a;单主机容器上的相互通信#xff0c;和跨主机的容器相互通信。
一、Docker单主机容器通信 基于对net namespace的控制#…自从Docker容器出现以来容器网络通信就一直是被关注的焦点也是生产环境的迫切需求。容器网络通信又分为两大方面单主机容器上的相互通信和跨主机的容器相互通信。
一、Docker单主机容器通信 基于对net namespace的控制docker可以为在容器创建隔离的网络环境在隔离的网络环境下容器具有完全独立的网络栈与宿主机隔离也可以使容器共享主机或者其他容器的网络命名空间基本可以满足开发者在各种场景下的需要。
按docker官方的说法docker容器的网络有五种模式bridge模式--netbridge(默认) 这是dokcer网络的默认设置为容器创建独立的网络命名空间容器具有独立的网卡等所有单独的网络栈是最常用的使用方式。在docker run启动容器的时候如果不加--net参数就默认采用这种网络模式。安装完docker系统会自动添加一个供docker使用的网桥docker0我们创建一个新的容器时容器通过DHCP获取一个与docker0同网段的IP地址并默认连接到docker0网桥以此实现容器与宿主机的网络互通。
host模式--nethost 这个模式下创建出来的容器直接使用容器宿主机的网络命名空间。将不拥有自己独立的Network Namespace即没有独立的网络环境。它使用宿主机的ip和端口。
none模式--netnone 为容器创建独立网络命名空间但不为它做任何网络配置容器中只有lo用户可以在此基础上对容器网络做任意定制。这个模式下dokcer不为容器进行任何网络配置。需要我们自己为容器添加网卡配置IP。因此若想使用pipework配置docker容器的ip地址必须要在none模式下才可以。
其他容器模式即container模式join模式--netcontainer:NAME_or_ID 与host模式类似只是容器将与指定的容器共享网络命名空间。这个模式就是指定一个已有的容器共享该容器的IP和端口。除了网络方面两个容器共享其他的如文件系统进程等还是隔离开的。
用户自定义docker 1.9版本以后新增的特性允许容器使用第三方的网络实现或者创建单独的bridge网络提供网络隔离能力。
这些网络模式在相互网络通信方面的对比如下所示 南北向通信指容器与宿主机外界的访问机制东西向流量指同一宿主机上与其他容器相互访问的机制。
1host模式 由于容器和宿主机共享同一个网络命名空间换言之容器的IP地址即为宿主机的IP地址。所以容器可以和宿主机一样使用宿主机的任意网卡实现和外界的通信。其网络模型可以参照下图 采用host模式的容器可以直接使用宿主机的IP地址与外界进行通信若宿主机具有公有IP那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口无需额外进行NAT转换而且由于容器通信时不再需要通过linuxbridge等方式转发或数据包的拆封性能上有很大优势。当然这种模式有优势也就有劣势主要包括以下几个方面 1最明显的就是容器不再拥有隔离、独立的网络栈。容器会与宿主机竞争网络栈的使用并且容器的崩溃就可能导致宿主机崩溃在生产环境中这种问题可能是不被允许的。 2容器内部将不再拥有所有的端口资源因为一些端口已经被宿主机服务、bridge模式的容器端口绑定等其他服务占用掉了。
2bridge模式 bridge模式是docker默认的也是开发者最常使用的网络模式。在这种模式下docker为容器创建独立的网络栈保证容器内的进程使用独立的网络环境实现容器之间、容器与宿主机之间的网络栈隔离。同时通过宿主机上的docker0网桥容器可以与宿主机乃至外界进行网络通信。其网络模型可以参考下图 从上面的网络模型可以看出容器从原理上是可以与宿主机乃至外界的其他机器通信的。同一宿主机上容器之间都是连接掉docker0这个网桥上的它可以作为虚拟交换机使容器可以相互通信。然而由于宿主机的IP地址与容器veth pair的 IP地址均不在同一个网段故仅仅依靠veth pair和namespace的技术还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以方位容器中的进程docker采用了端口绑定的方式也就是通过iptables的NAT将宿主机上的端口端口流量转发到容器内的端口上。举一个简单的例子使用下面的命令创建容器并将宿主机的3306端口绑定到容器的3306端口 1 # docker run -tid --name db -p 3306:3306 MySQL
在宿主机上可以通过iptables -t nat -L -n查到一条DNAT规则 1 # DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306
上面的172.17.0.5即为bridge模式下创建的容器IP。
很明显bridge模式的容器与外界通信时必定会占用宿主机上的端口从而与宿主机竞争端口资源对宿主机端口的管理会是一个比较大的问题。同时由于容器与外界通信是基于三层上iptables NAT性能和效率上的损耗是可以预见的。
3none模式 在这种模式下容器有独立的网络栈但不包含任何网络配置只具有lo这个loopback网卡用于进程通信。也就是说none模式为容器做了最少的网络设置但是俗话说得好“少即是多”在没有网络配置的情况下通过第三方工具或者手工的方式开发这任意定制容器的网络提供了最高的灵活性。
4其他容器container模式 其他网络模式是docker中一种较为特别的网络的模式。在这个模式下的容器会使用其他容器的网络命名空间其网络隔离性会处于bridge桥接模式与host模式之间。当容器共享其他容器的网络命名空间则在这两个容器之间不存在网络隔离而她们又与宿主机以及除此之外其他的容器存在网络隔离。其网络模型可以参考下图 在这种模式下的容器可以通过localhost来同一网络命名空间下的其他容器传输效率较高。而且这种模式还节约了一定数量的网络资源但它并没有改变容器与外界通信的方式。在一些特殊的场景中非常有用例如kubernetes的podkubernetes为pod创建一个基础设施容器同一pod下的其他容器都以其他容器模式共享这个基础设施容器的网络命名空间相互之间以localhost访问构成一个统一的整体。
5用户定义网络模式 在用户定义网络模式下开发者可以使用任何docker支持的第三方网络driver来定制容器的网络。并且docker 1.9以上的版本默认自带了bridge和overlay两种类型的自定义网络driver。可以用于集成calico、weave、openvswitch等第三方厂商的网络实现。 除了docker自带的bridge driver其他的几种driver都可以实现容器的跨主机通信。而基于bdrige driver的网络docker会自动为其创建iptables规则保证与其他网络之间、与docker0之间的网络隔离。 例如使用下面的命令创建一个基于bridge driver的自定义网络 1 # docker network create bri1
则docker会自动生成如下的iptables规则保证不同网络上的容器无法互相通信。 1 2 # -A DOCKER-ISOLATION -i br-8dba6df70456 -o docker0 -j DROP # -A DOCKER-ISOLATION -i docker0 -o br-8dba6df70456 -j DROP
除此之外bridge driver的所有行为都和默认的bridge模式完全一致。而overlay及其他driver则可以实现容器的跨主机通信。
二、Docker跨主机容器通信
早期大家的跨主机通信方案主要有以下几种 1容器使用host模式容器直接使用宿主机的网络这样天生就可以支持跨主机通信。虽然可以解决跨主机通信问题但这种方式应用场景很有限容易出现端口冲突也无法做到隔离网络环境一个容器崩溃很可能引起整个宿主机的崩溃。
2端口绑定通过绑定容器端口到宿主机端口跨主机通信时使用主机IP端口的方式访问容器中的服务。显而易见这种方式仅能支持网络栈的四层及以上的应用并且容器与宿主机紧耦合很难灵活的处理可扩展性不佳。
3docker外定制容器网络在容器通过docker创建完成后然后再通过修改容器的网络命名空间来定义容器网络。典型的就是很久以前的pipework容器以none模式创建pipework通过进入容器的网络命名空间为容器重新配置网络这样容器网络可以是静态IP、vxlan网络等各种方式非常灵活容器启动的一段时间内会没有IP明显无法在大规模场景下使用只能在实验室中测试使用。
4第三方SDN定义容器网络使用Open vSwitch或Flannel等第三方SDN工具为容器构建可以跨主机通信的网络环境。这些方案一般要求各个主机上的docker0网桥的cidr不同以避免出现IP冲突的问题限制了容器在宿主机上的可获取IP范围。并且在容器需要对集群外提供服务时需要比较复杂的配置对部署实施人员的网络技能要求比较高。
上面这些方案有各种各样的缺陷同时也因为跨主机通信的迫切需求docker 1.9版本时官方提出了基于vxlan的overlay网络实现原生支持容器的跨主机通信。同时还支持通过libnetwork的plugin机制扩展各种第三方实现从而以不同的方式实现跨主机通信。就目前社区比较流行的方案来说跨主机通信的基本实现方案有以下几种
1基于隧道的overlay网络按隧道类型来说不同的公司或者组织有不同的实现方案。docker原生的overlay网络就是基于vxlan隧道实现的。ovn则需要通过geneve或者stt隧道来实现的。flannel最新版本也开始默认基于vxlan实现overlay网络。2基于包封装的overlay网络基于UDP封装等数据包包装方式在docker集群上实现跨主机网络。典型实现方案有Weave、Flannel的早期版本。3基于三层实现SDN网络基于三层协议和路由直接在三层上实现跨主机网络并且通过iptables实现网络的安全隔离。典型的方案为 Calico。同时对不支持三层路由的环境Calico还提供了基于IPIP封装的跨主机网络实现
Dokcer通过使用Linux桥接提供容器之间的通信docker0桥接接口的目的就是方便Docker管理。当Docker daemon启动时需要做以下操作 - 如果docker0不存在则创建 - 搜索一个与当前路由不冲突的ip段 - 在确定的范围中选择 ip - 绑定ip到 docker0
列出当前主机网桥 1 2 3 [rootlocalhost ~]# brctl show bridge name bridgeid STP enabled interfaces docker0 8000.02426f15541e no vethe833b02
查看当前 docker0 ip 1 2 3 4 5 6 7 8 9 10 [rootlocalhost ~]# ifconfig docker0: flags4163UP,BROADCAST,RUNNING,MULTICAST mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:6fff:fe15:541e prefixlen 64 scopeid 0x20link ether 02:42:6f:15:54:1e txqueuelen 0 (Ethernet) RX packets 120315 bytes 828868638 (790.4 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 132565 bytes 100884398 (96.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ................
在容器运行时每个容器都会分配一个特定的虚拟机口并桥接到docker0。每个容器都会配置同docker0 ip相同网段的专用ip 地址docker0的IP地址被用于所有容器的默认网关。 一般启动的容器中ip默认是172.17.0.1/24网段的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [rootlinux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 67591570dd29 3 months ago 191.8 MB [rootlinux-node2 ~]# docker run -t -i --name my-test centos /bin/bash [rootc5217f7bd44c /]# [rootlinux-node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5217f7bd44c centos /bin/bash 10 seconds ago Up 10 seconds my-test [rootlinux-node2 ~]# docker inspect c5217f7bd44c|grep IPAddress SecondaryIPAddresses: null, IPAddress:172.17.0.2, IPAddress:172.17.0.2,
那么能不能在创建容器的时候指定特定的ip呢这是当然可以实现的
注意宿主机的ip路由转发功能一定要打开否则所创建的容器无法联网 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [rootlocalhost ~]# cat /proc/sys/net/ipv4/ip_forward 1 [rootlocalhost ~]# [rootlocalhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e64eade06d1 docker.io/centos /bin/bash 10 seconds ago Up 9 seconds my-centos [rootlocalhost ~]# docker run -itd --netnone --namecontainer1 docker.io/centos 5e5bdbc4d9977e6bcfa40e0a9c3be10806323c9bf5a60569775903d345869b09 [rootlocalhost ~]# docker attach container1 [root5e5bdbc4d997 /]# ping www.baidu.com PING www.a.shifen.com (61.135.169.121) 56(84) bytes of data. 64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq1 ttl53time2.09 ms 64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq2 ttl53time2.09 ms 关闭ip路由转发功能容器即不能联网 [rootlocalhost ~]# echo 0 /proc/sys/net/ipv4/ip_forward [rootlocalhost ~]# cat /proc/sys/net/ipv4/ip_forward 0 [root5e5bdbc4d997 /]# ping www.baidu.com //ping不通~
2.1、创建容器使用特定范围的IP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 Docker 会尝试寻找没有被主机使用的ip段尽管它适用于大多数情况下但是它不是万能的有时候我们还是需要对ip进一步规划。 Docker允许你管理docker0桥接或者通过-b选项自定义桥接网卡需要安装bridge-utils软件包。操作流程如下 a确保docker的进程是停止的 b创建自定义网桥 c给网桥分配特定的ip d以-b的方式指定网桥 具体操作过程如下比如创建容器的时候指定ip为192.168.5.1/24网段的 [rootlocalhost ~]# service docker stop [rootlocalhost ~]# ip link set dev docker0 down [rootlocalhost ~]# brctl delbr docker0 [rootlocalhost ~]# brctl addbr bridge0 [rootlocalhost ~]# ip addr add 192.168.5.1/24 dev bridge0 //注意这个192.168.5.1就是所建容器的网关地址。通过docker inspect container_id能查看到 [rootlocalhost ~]# ip link set dev bridge0 up [rootlocalhost ~]# ip addr show bridge0 [rootlocalhost ~]# vim /etc/sysconfig/docker //即将虚拟的桥接口由默认的docker0改为bridge0 将 OPTIONS--selinux-enabled --log-driverjournald 改为 OPTIONS--selinux-enabled --log-driverjournald -bbridge0 //即添加-bbridge0 [rootlocalhost ~]# service docker restart -------------------------------------------------------------------------------------- 上面是centos7下的操作步骤,下面提供下ubuntu下的操作步骤 $sudo service docker stop $sudo ip linkset dev docker0 down $sudo brctl delbr docker0 $sudo brctl addbr bridge0 $sudo ip addr add 192.168.5.1/24 dev bridge0 $sudo ip linkset dev bridge0 up $ ip addr show bridge0 $echo DOCKER_OPTS-bbridge0 /etc/default/docker $sudo service docker start -------------------------------------------------------------------------------------- 然后创建容器查看下容器ip是否为设定的192.168.5.1/24网段的 [rootlocalhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/ubuntu latest 0ef2e08ed3fa 2 weeks ago 130 MB centos7 7.3.1611 d5ebea14da54 3 weeks ago 311 MB [rootlocalhost ~]# docker run -t -i --name test2 centos7:7.3.1611 /bin/bash [root224facf8e054 /]# [rootlocalhost ~]# docker run -t -i --name test1 docker.io/ubuntu /bin/bash rootf5b1bfc2811a:/# [rootlocalhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 224facf8e054 centos7:7.3.1611 /bin/bash 46 minutes ago Up 46 minutes test2 f5b1bfc2811a docker.io/ubuntu /bin/bash 47 minutes ago Up 5 minutes test1 [rootlocalhost ~]# docker inspect --format{{.NetworkSettings.IPAddress}} f5b1bfc2811a 192.168.5.2 [rootlocalhost ~]# docker inspect --format{{.NetworkSettings.IPAddress}} 224facf8e054 192.168.5.3 [rootlocalhost ~]# brctl show bridge name bridgeid STP enabled interfaces bridge0 8000.ba141fa20c91 no vethe7e227b vethf382771
使用pipework给容器设置一个固定的ip 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 可以利用pipework为容器指定一个固定的ip操作方法非常简单如下 [rootnode1 ~]# brctl addbr br0 [rootnode1 ~]# ip link set dev br0 up [rootnode1 ~]# ip addr add 192.168.114.1/24 dev br0 //这个ip相当于br0网桥的网关ip可以随意设定。 [rootnode1 ~]# docker run -ti -d --netnone --namemy-test1 docker.io/nginx /bin/bash [rootnode1 ~]# pipework br0 -i eth0 my-test1 192.168.114.100/24192.168.114.1 [rootnode1 ~]# docker exec -ti my-test1 /bin/bash rootcf370a090f63:/# ip addr 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 57: eth0if58: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether b2:c1:8d:92:33:e2 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.114.100/24 brd 192.168.114.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::b0c1:8dff:fe92:33e2/64 scope link valid_lft forever preferred_lft forever 再启动一个容器 [rootnode1 ~]# docker run -ti -d --netnone --namemy-test2 docker.io/nginx /bin/bash [rootnode1 ~]# pipework br0 -i eth0 my-test12 192.168.114.200/24192.168.114.1 [rootnode1 ~]# pipework br0 -i eth0 my-test2 192.168.114.200/24192.168.114.1 这样my-test1容器和my-test2容器在同一个宿主机上所以它们固定后的ip是可以相互ping通的如果是在不同的宿主机上则就无法ping通 所以说 这样使用pipework指定固定ip的容器在同一个宿主机下的容器间的ip是可以相互ping通的但是跨主机的容器通过这种方式固定ip后就不能ping通了。 跨主机的容器间的通信可以看下面的介绍。
2.2、不同主机间的容器通信pipework config docker container ip 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 我的centos7测试机上的docker是yum安装的默认自带pipework工具所以就不用在另行安装它了。 ----------------------------------------------------------------------------------------------- 如果没有pipework工具可以安装下面步骤进行安装 # git clone https://github.com/jpetazzo/pipework.git # sudo cp -rp pipework/pipework /usr/local/bin/ 安装相应依赖软件(网桥) #sudo apt-get install iputils-arping bridge-utils -y ----------------------------------------------------------------------------------------------- 查看Docker宿主机上的桥接网络 [rootlinux-node2 ~]# brctl show bridge name bridgeid STP enabled interfaces docker0 8000.02426f15541e no veth92d132f 有两种方式做法 1可以选择删除docker0直接把docker的桥接指定为br0 2也可以选择保留使用默认docker0的配置这样单主机容器之间的通信可以通过docker0 跨主机不同容器之间通过pipework将容器的网卡桥接到br0上这样跨主机容器之间就可以通信了。 如果保留了docker0则容器启动时不加--netnone参数那么本机容器启动后就是默认的docker0自动分配的ip默认是172.17.1.0/24网段它们之间是可以通信的 跨宿主机的容器创建时要加--netnone参数待容器启动后通过pipework给容器指定ip这样跨宿主机的容器ip是在同一网段内的同网段地址因此可以通信。 一般来说最好在创建容器的时候加上--netnone防止自动分配的IP在局域网中有冲突。若是容器创建后自动获取ip下次容器启动会ip有变化可能会和物理网段中的ip冲突 --------------------------------------------------------------------------------------------------- 实例说明如下 宿主机信息 ip192.168.1.23 网卡设备为eth0 gateway192.168.1.1 netmask255.255.255.0 1删除虚拟桥接卡docker0的配置 [rootlocalhost ~]# service docker stop [rootlocalhost ~]# ip link set dev docker0 down [rootlocalhost ~]# brctl delbr docker0 [rootlocalhost ~]# brctl addbr br0 [rootlocalhost ~]# ip link set dev br0 up [rootlocalhost ~]# ip addr del 192.168.1.23/24 dev eth0 //删除宿主机网卡的IP如果是使用这个地址进行的远程连接这一步操作后就会断掉如果是使用外网地址连接的话就不会断开 [rootlocalhost ~]# ip addr add 192.168.1.23/24 dev br0 //将宿主主机的ip设置到br0 [rootlocalhost ~]# brctl addif br0 eth0 //将宿主机网卡挂到br0上 [rootlocalhost ~]# ip route del default //删除默认的原路由其实就是eth0上使用的原路由192.168.1.1这步小心注意删除后要保证机器能远程连接上最好是通过外网ip远程连的。别删除路由后远程连接不上中断了 [rootlocalhost ~]# ip route add default via 192.168.1.1 dev br0 //为br0设置路由 [rootlocalhost ~]# vim /etc/sysconfig/docker //即将虚拟的桥接口由默认的docker0改为bridge0 将 OPTIONS--selinux-enabled --log-driverjournald 改为 OPTIONS--selinux-enabled --log-driverjournald -bbr0 //即添加-bbr0 [rootlocalhost ~]# service docker start 启动一个手动设置网络的容器 [rootlocalhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e64eade06d1 docker.io/centos /bin/bash 10 seconds ago Up 9 seconds my-centos [rootlocalhost ~]# docker run -itd --netnone --namemy-test1 docker.io/centos 为my-test1容器设置一个与桥接物理网络同地址段的ip如下ipgateway 默认不指定网卡设备名则默认添加为eth0。可以通过-i参数添加网卡设备名 [rootlocalhost ~]# pipework br0 -i eth0 my-test1 192.168.1.190/24192.168.1.1 同理在其他机器上启动容器并类似上面用pipework设置一个同网段类的ip这样跨主机的容器就可以相互ping通了 -------------------------------------------------------------------------------------------------- 2保留默认虚拟桥接卡docker0的配置 [rootlocalhost ~]# cd /etc/sysconfig/network-scripts/ [rootlocalhost network-scripts]# cp ifcfg-eth0 ifcfg-eth0.bak [rootlocalhost network-scripts]# cp ifcfg-eth0 ifcfg-br0 [rootlocalhost network-scripts]# vim ifcfg-eth0 //增加BRIDGEbr0删除IPADDR,NETMASK,GATEWAY,DNS的设置 ...... BRIDGEbr0 [rootlocalhost network-scripts]# vim ifcfg-br0 //修改DEVICE为br0,Type为Bridge,把eth0的网络设置设置到这里来里面应该有ip网关子网掩码或DNS设置 ...... TYPEBridge DEVICEbr0 [rootlocalhost network-scripts]# service network restart [rootlocalhost network-scripts]# service docker restart 开启一个容器并指定网络模式为none这样创建的容器就不会通过docker0自动分配ip了而是根据pipework工具自定ip指定 [rootlocalhost network-scripts]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 67591570dd29 3 months ago 191.8 MB [rootlocalhost network-scripts]# docker run -itd --netnone --namemy-centos docker.io/centos /bin/bash 6e64eade06d1eb20be3bd22ece2f79174cd033b59182933f7bbbb502bef9cb0f 接着给容器配置网络 [rootlocalhost network-scripts]# pipework br0 -i eth0 my-centos 192.168.1.150/24192.168.1.1 [rootlocalhost network-scripts]# docker attach 6e64eade06d1 [root6e64eade06d1 /]# ifconfig eth0 //若没有ifconfig命令可以yum安装net-tools工具 eth0 Link encap:Ethernet HWaddr 86:b6:6b:e8:2e:4d inet addr:192.168.1.150 Bcast:0.0.0.0 Mask:255.255.255.0 inet6 addr: fe80::84b6:6bff:fee8:2e4d/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:9 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:648 (648.0 B) TX bytes:690 (690.0 B) [root6e64eade06d1 /]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 192.168.115.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 另外pipework不能添加静态路由如果有需求则可以在run的时候加上--privilegedtrue 权限在容器中手动添加但这种方法安全性有缺陷。 除此之外可以通过ip netns--help参考帮助添加静态路由以避免创建容器使用--privilegedtrue选项造成一些不必要的安全问题 如下获取指定容器的pid [rootlocalhost network-scripts]# docker inspect --format{{ .State.Pid }} 6e64eade06d1 7852 [rootlocalhost network-scripts]# ln -s /proc/7852/ns/net /var/run/netns/7852 [rootlocalhost network-scripts]# ip netns exec 7852 ip route add 192.168.0.0/16 dev eth0 via 192.168.1.1 [rootlocalhost network-scripts]# ip netns exec 7852 ip route //添加成功 192.168.0.0/16 via 192.168.1.1 dev eth0 同理在其它宿主机进行相应的配置新建容器并使用pipework添加虚拟网卡桥接到br0如此创建的容器间就可以相互通信了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1重启网卡报错如下 # systemctl restart network ...... Nov 23 22:09:08 hdcoe02 systemd[1]: network.service: control process exited, codeexited status1 Nov 23 22:09:08 hdcoe02 systemd[1]: Failed to start LSB: Bring up/down networking. Nov 23 22:09:08 hdcoe02 systemd[1]: Unit network.service entered failed state./span 解决办法 # systemctl enable NetworkManager-wait-online.service # systemctl stop NetworkManager # systemctl restart network.service 2创建容器出现下面告警 WARNING: IPv4 forwarding is disabled. Networking will not work. 解决办法 #vim /usr/lib/sysctl.d/00-system.conf 添加如下代码 net.ipv4.ip_forward1 重启network服务 # systemctl restart network 其实除了上面使用的pipework工具还还可以使用虚拟交换机(Open vSwitch)进行docker容器间的网络通信废话不多说下面说下Open vSwitch的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 一、在Server1和Server2上分别安装open vswitch [rootSlave1 ~]# # yum -y install wget openssl-devel kernel-devel [rootSlave1 ~]# yum groupinstall Development Tools [rootSlave1 ~]# adduser ovswitch [rootSlave1 ~]# su - ovswitch [ovswitchSlave1 ~]$ wget http://openvswitch.org/releases/openvswitch-2.3.0.tar.gz [ovswitchSlave1 ~]$tar -zxvpf openvswitch-2.3.0.tar.gz [ovswitchSlave1 ~]$mkdir -p ~/rpmbuild/SOURCES [ovswitchSlave1 ~]$sed s/openvswitch-kmod, //g openvswitch-2.3.0/rhel/openvswitch.spec openvswitch-2.3.0/rhel/openvswitch_no_kmod.spec [ovswitchSlave1 ~]$cp openvswitch-2.3.0.tar.gz rpmbuild/SOURCES/ [ovswitchSlave1 ~]$ rpmbuild -bb --without check ~/openvswitch-2.3.0/rhel/openvswitch_no_kmod.spec [rootSlave1 ~]$exit [rootSlave1 ~]# yum localinstall /home/ovswitch/rpmbuild/RPMS/x86_64/openvswitch-2.3.0-1.x86_64.rpm [rootSlave1 ~]# mkdir /etc/openvswitch [rootSlave1 ~]# setenforce 0 [rootSlave1 ~]# systemctl start openvswitch.service [rootSlave1 ~]# systemctl status openvswitch.service -l 二、在Slave1和Slave2上建立OVS Bridge并配置路由 1在Slave1宿主机上设置docker容器内网ip网段172.17.1.0/24 [rootSlave1 ~]# vim /proc/sys/net/ipv4/ip_forward 1 [rootSlave1 ~]# ovs-vsctl add-br obr0 [rootSlave1 ~]# ovs-vsctl add-port obr0 gre0 -- set Interface gre0 typegre options:remote_ip192.168.115.5 [rootSlave1 ~]# brctl addbr kbr0 [rootSlave1 ~]# brctl addif kbr0 obr0 [rootSlave1 ~]# ip link set dev docker0 down [rootSlave1 ~]# ip link del dev docker0 [rootSlave1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-kbr0 ONBOOTyes BOOTPROTOstatic IPADDR172.17.1.1 NETMASK255.255.255.0 GATEWAY172.17.1.0 USERCTLno TYPEBridge IPV6INITno [rootSlave1 ~]# vim /etc/sysconfig/network-scripts/route-ens32 172.17.2.0/24 via 192.168.115.6 dev ens32 [rootSlave1 ~]# systemctl restart network.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2在Slave2宿主机上设置docker容器内网ip网段172.17.2.0/24 [rootSlave2 ~]# vim /proc/sys/net/ipv4/ip_forward 1 [rootSlave2 ~]# ovs-vsctl add-br obr0 [rootSlave2 ~]# ovs-vsctl add-port obr0 gre0 -- set Interface gre0 typegre options:remote_ip192.168.115.6 [rootSlave2 ~]# brctl addbr kbr0 [rootSlave2 ~]# brctl addif kbr0 obr0 [rootSlave2 ~]# ip link set dev docker0 down [rootSlave2 ~]# ip link del dev docker0 [rootSlave2 ~] vim/etc/sysconfig/network-scripts/ifcfg-kbr0 ONBOOTyes BOOTPROTOstatic IPADDR172.17.2.1 NETMASK255.255.255.0 GATEWAY172.17.2.0 USERCTLno TYPEBridge IPV6INITno [rootSlave2 ~]# vim /etc/sysconfig/network-scripts/route-ens32 172.17.1.0/24 via 192.168.115.5 dev ens32 [rootSlave2 ~]# systemctl restart network.service 三、启动容器测试 Server1和Server2上修改docker启动的虚拟网卡绑定为kbr0重启docker进程 1在Server1宿主机上启动容器,然后登陆容器内查看ip就会发现ip是上面设定额172.17.1.0/24网段的 1 [rootSlave1 ~]# docker run -idt --name my-server1 daocloud.io/library/centos/bin/bash
2在Server2宿主机上启动容器然后登陆容器内查看ip就会发现ip是上面设定额172.17.2.0/24网段的 1 [rootSlave2 ~]#docker run -idt --name my-server1 daocloud.io/library/centos /bin/bash
然后在上面启动的容内互ping对方容器发现是可以ping通的