Docker的单主机容器网络
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处: https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
本篇文章主要探索Docker的单机容器网络,了解一下单个Docker主机上网络的各种模式,从而为后续理解跨主机容器网络打下基础。
Docker默认容器网络的建立和控制是一种结合了network namespace,iptables,Linux网桥及route table等多种技术的综合解决方案,本篇主要针对于如何使用单主机网络的各种模式,对于实现细节不做过多的探索(这篇文章 http://tonybai.com/2016/01/15/understanding-container-networking-on-single-host/ 对于docker单主机网络的实现机制做了详细的探索)。
Docker的网络模式
Docker支持的网络模式主要有如下几种:
None
启动容器时,使用了参数 --network="none"
。在此种模式下,容器和外部网络没有连接。在容器中只有loopback的网络接口,但它没有对外的任何路由。
Bridge
启动容器时,使用了参数 --network="bridge"
或者未指定此参数。这是docker默认的网络模式。它允许此主机上的容器彼此进行通信,也允许容器访问主机的外部网络。下图显示了Docker bridge网络的示意图:
在主机上,docker创建了一个通常名为docker0的网桥,这里它的ip设置为172.17.0.1.在创建每个容器时,同时创建了一对veth网络接口。接口的一端连接到docker0的网桥上,另一端连接到容器的内部。从容器发起的到外部网络的连接是通过IP forwarding和设置了NAT规则的iptables rules实现的(图中的绿色箭头)。从外部网络到容器内部的连接使用了一条完全不同的路径。如果容器将自身的端口映射到主机上,则docker会启动一个docker-proxy进程来进行监听,通过此proxy将数据转发到容器中(图中的红色箭头)。
默认情况下,同一台docker主机上的容器彼此之间可以通过他们的IP地址进行通信。如果需要通过容器的主机名进行通信,容器之间必须设置了link。
Host
启动容器时,使用了参数 --network="host"
。在这种模式下,容器共享主机的networking namespace,所以主机上的网络接口对容器都可用,同时在bridge模式下docker所做的各种网络设置都被略过,这意味着容器的网络性能和普通的主机网络性能 一样快 。在运行一些对网络性能要求较高的应用时,如负载均衡器或高性能web服务器时,应使用此模式。
但此模式给予容器对本地系统服务的完全访问权限,所以比其它模式的安全性要差。
Container
启动容器时,使用了参数 --network="container:<name|id>"
。这种模式下容器使用了另外一个容器的networking namespace,也就是说它与另外一个容器共享网络栈。
User-defined network
在这种模式下,用户可以使用Docker网络驱动或外部网络驱动plugin来创建自定义的网络。用户可以将多个容器连接到同一个网络上。一旦容器连接到用户自定义的网络后,容器可以使用另外一个容器的ip地址 或名称 来彼此通信。此功能需要Docker 1.10之后的版本。在较新版本的docker daemon中内置了一个DNS服务器,对于任意在创建时指定了name或net-alias或通过link提供了别名的容器,它可以提供内置的 服务发现功能 ,从而无需再使用第三方软件提供的DNS服务(无需再使用文章“ 使用resolvable通过DNS查找容器 ”中提供的方法)。
对于overlay网络或使用了支持多主机连接的插件的容器,连接到同一多主机网络但从不同主机上启动的容器也可以彼此之间以这种方式通信。
Docker的network命令
Docker的network命令既可以用于单主机网络的相关操作,也可以用于多主机overlay网络的操作,本篇主要使用其与单主机网络相关的命令。
创建网络
当在主机上安装docker后,docker引擎自动创建三个网络,可用如下命令列出默认的三个网络:
- [yangdong@centos7 ~]$ docker network ls
- NETWORK ID NAME DRIVER SCOPE
- 2a820cde1d0c bridge bridge local
- 54be0bc791bf host host local
- 8488a8a4ca59 none null local
除此之外,用户还可以创建自己的bridge或overlay的网络。如果运行 docker network create
命令并且指定一个网络名称,则此命令为用户创建一个bridge网络:
- [yangdong@centos7 ~]$ docker network create simple-network
- a88875cc258fb24bbf55db67efefd05976dc8d1a8e25a2166a1acbd1dc9e125a
- [yangdong@centos7 ~]$ docker network inspect simple-network
- [
- {
- "Name": "simple-network",
- "Id": "a88875cc258fb24bbf55db67efefd05976dc8d1a8e25a2166a1acbd1dc9e125a",
- "Scope": "local",
- "Driver": "bridge",
- "EnableIPv6": false,
- "IPAM": {
- "Driver": "default",
- "Options": {},
- "Config": [
- {
- "Subnet": "172.18.0.0/16",
- "Gateway": "172.18.0.1/16"
- }
- ]
- },
- "Internal": false,
- "Containers": {},
- "Options": {},
- "Labels": {}
- }
- ]
连接容器
可以将容器动态得连接到一个或多个网络上。一旦连接后,容器可以通过其它容器的ip地址或名称进行通信。下面看一下例子:
首先创建两个容器:
- [yangdong@centos7 ~]$ docker run -itd --name=container1 busybox
- bdaadbef1c5b3a53c1cf54ddda70e170e386fc578c815f07b09d21ca2fcd3b20
- [yangdong@centos7 ~]$ docker run -itd --name=container2 busybox
- 126cf3af1ddd033a0925ca879e8d744293cb95949d560877ca630a29b4630630
然后创建一个隔离的bridge的网络用于测试:
- [yangdong@centos7 ~]$ docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw
- 38159357c0979fdbc6ca0be29475867115e002ef27d8f79fee014b03ffd86b8d
这里通过命令行参数 --subnet
指定了容器使用的子网网段。下面将container2连接到刚才创建的网络上:
- [yangdong@centos7 ~]$ docker network connect isolated_nw container2
然后启动第三个容器,在启动的同时将其连接到isolated_nw网络上,同时手动指定该容器的ip:
- [yangdong@centos7 ~]$ docker run --network=isolated_nw --ip=172.25.3.3 -itd --name=container3 busybox
- d649491fd218c65fb0dc26aa79cb0d6f43dabac2bdc2f404c515f97042e60206
只要容器连接到一个由用户指定子网网段(通过 --subnet
)的网络上时,就可以为容器指定ip地址。
上述命令运行完毕后,整个主机上的网络状态如下图所示:
使用docker attach命令连接到运行的container2容器内部并查看其网络栈:
- [yangdong@centos7 ~]$ docker attach container2
- / # ifconfig
- eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:05
- inet addr:172.17.0.5 Bcast:0.0.0.0 Mask:255.255.0.0
- inet6 addr: fe80::42:acff:fe11:5/64 Scope:Link
- UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
- RX packets:9 errors:0 dropped:0 overruns:0 frame:0
- TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:718 (718.0 B) TX bytes:648 (648.0 B)
- eth1 Link encap:Ethernet HWaddr 02:42:AC:19:00:02
- inet addr:172.25.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
- inet6 addr: fe80::42:acff:fe19:2/64 Scope:Link
- UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
- RX packets:32 errors:0 dropped:0 overruns:0 frame:0
- TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:3282 (3.2 KiB) TX bytes:648 (648.0 B)
- lo Link encap:Local Loopback
- inet addr:127.0.0.1 Mask:255.0.0.0
- inet6 addr: ::1/128 Scope:Host
- UP LOOPBACK RUNNING MTU:65536 Metric:1
- RX packets:0 errors:0 dropped:0 overruns:0 frame:0
- TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
可见eth0连接到了默认的bridge网络,eth1连接到了用户创建的isolated_nw网络,此网络可以通过docker内置的DNS服务器进行其它容器的名称解析,所以在container2中可以通过名称ping通container3:
- / # ping -w 4 container3
- PING container3 (172.25.3.3): 56 data bytes
- 64 bytes from 172.25.3.3: seq=0 ttl=64 time=0.146 ms
- 64 bytes from 172.25.3.3: seq=1 ttl=64 time=0.113 ms
- 64 bytes from 172.25.3.3: seq=2 ttl=64 time=0.100 ms
- 64 bytes from 172.25.3.3: seq=3 ttl=64 time=0.112 ms
- --- container3 ping statistics ---
- 4 packets transmitted, 4 packets received, 0% packet loss
- round-trip min/avg/max = 0.100/0.117/0.146 ms
然而在默认的bridge网络中,并不是这样。在默认的bridge网络中,Docker并不支持自动的服务发现:
- / # ping -w 4 container1
- ping: bad address 'container1'
在默认的bridge网络中,可以使用传统的 docker run --link
命令来启用通过名称的解析。当然,在没有使用 --link
时,可以通过彼此的ip地址进行通信。
退出container2的终端,使用快捷键CTRL-p然后CTRL-q。
在这个示例当中,container2连接到了两个网络上,所以它可以与container1和container3通信。但container1和container3并不在一个网络当中所以它们之间并不能通信。下面连接到container3的控制台然后测试一下(container1的ip为172.17.0.4):
- [yangdong@centos7 ~]$ docker attach container3
- / # ping 172.17.0.4
- PING 172.17.0.2 (172.17.0.2): 56 data bytes
- ^C
- --- 172.17.0.2 ping statistics ---
- 4 packets transmitted, 0 packets received, 100% packet loss
断开容器连接
用户可以通过 docker network disconnect
命令断开容器到某个网络的连接,当断开此连接后,容器就不能通过此网络与其它容器通信了:
- [yangdong@centos7 ~]$ docker network disconnect isolated_nw container2
- [yangdong@centos7 ~]$ docker attach container2
- / # ifconfig
- eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:05
- inet addr:172.17.0.5 Bcast:0.0.0.0 Mask:255.255.0.0
- inet6 addr: fe80::42:acff:fe11:5/64 Scope:Link
- UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
- RX packets:17 errors:0 dropped:0 overruns:0 frame:0
- TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:1222 (1.1 KiB) TX bytes:1152 (1.1 KiB)
- lo Link encap:Local Loopback
- inet addr:127.0.0.1 Mask:255.0.0.0
- inet6 addr: ::1/128 Scope:Host
- UP LOOPBACK RUNNING MTU:65536 Metric:1
- RX packets:16 errors:0 dropped:0 overruns:0 frame:0
- TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:0
- RX bytes:922 (922.0 B) TX bytes:922 (922.0 B)
- / # ping container3
- ping: bad address 'container3'
移除一个网络
当一个网络中所有的容器都停止或断开连接后,可以移除该网络:
- [yangdong@centos7 ~]$ docker network disconnect isolated_nw container3
- [yangdong@centos7 ~]$ docker network rm isolated_nw
- isolated_nw
- [yangdong@centos7 ~]$ docker network ls
- NETWORK ID NAME DRIVER SCOPE
- 2a820cde1d0c bridge bridge local
- 54be0bc791bf host host local
- 8488a8a4ca59 none null local
- a88875cc258f simple-network bridge local
Docker的单主机容器网络的更多相关文章
- docker容器网络—单主机容器网络
当我们在单台物理机或虚拟机中运行多个docker容器应用时,这些容器之间是如何进行通信的呢,或者外界是如何访问这些容器的? 这里就涉及了单机容器网络相关的知识.docker 安装后默认 情况下会在宿主 ...
- docker1.12在cento7里的跨多主机容器网络
docker1.12在cento7里的跨多主机容器网络
- Docker入门篇(二)之docker的单主机网络
Docker 安装时会自动在host上创建三个网络,我们可用 docker network ls命令查看: [root@localhost ~]# docker network ls NETWORK ...
- Swarm基于多主机容器网络 - overlay networks 梳理
前面介绍了Docker管理工具-Swarm部署记录,下面重点说下Swarm基于多主机容器通信的覆盖网络 在Docker版本1.12之后swarm模式原生支持覆盖网络(overlay networks) ...
- Docker:跨主机容器间通信之overlay [十五]
一.配置overlay类型网络准备工作 1.在luoahong3主机上 docker run -d -p 8500:8500 -h consul --name consul progrium/cons ...
- 【转】理解Docker容器网络之Linux Network Namespace
原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...
- Kubernetes & Docker 容器网络终极之战(十四)
目录 一.单主机 Docker 网络通信 1.1.host 模式 1.2 Bridge 模式 1.3 Container 模式 1.4.None 模式 二.跨主机 Docker 网络通信分类 2.1 ...
- 理解Docker(6):若干企业生产环境中的容器网络方案
本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...
- Docker 0x07: Docke 容器网络
目录 Docke 容器网络 Container Network Model (CNM) 具体项目中代码对象有哪些 Implementations实现的网络(直接英文版) Libnetwork incl ...
随机推荐
- iOS 程序报错:reason: [NSArrayI addObject:]: unrecognized selector sent to instance
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI ad ...
- .NET破解之图片下载器
自去年五月加入吾爱后,学习了三个月,对逆向破解产生了深厚的兴趣,尤其是对.NET方面的分析:但由于这一年,项目比较忙,事情比较多,破解这方面又停滞了许久,不知道还要好久. 前些天,帮忙批量下载QQ相册 ...
- 对称密码-DES和3DES
最近在看信息安全的知识,就总结了一下自己所学到知识. 先说一下什么是对称密码算法,什么是对称密码算法呢?对称密码算法是指有了加密密钥就可以推算出解密密钥,有了解密密钥就可以推算出加密密钥的的算法. 那 ...
- bootstrap的一些资源
http://www.cnblogs.com/landeanfen/p/5461849.html 总结了时间,加载,自动增加图片选择,等bootstap控件 http://www.cnblogs.co ...
- 需要记住的几个ASCII码
--------- A--------- a---------
- 利用Dreamweaver配置PHP服务器的站点
配置的步骤: 1.打开Dreamweaver的站点------->新建站点-------->点击保存 2.点击服务器------>保存 3.配置完成之后就可以看到在Dreamweav ...
- RxJava 和 RxAndroid 四(RxBinding的使用)
对Rxjava不熟悉的同学可以先看我之前写的几篇文章 RxJava 和 RxAndroid 一 (基础) RxJava 和 RxAndroid 二(操作符的使用) RxJava 和 RxAndroid ...
- Android 手机卫士--自定义组合控件构件布局结构
由于设置中心条目中的布局都很类似,所以可以考虑使用自定义组合控件来简化实现 本文地址:http://www.cnblogs.com/wuyudong/p/5909043.html,转载请注明源地址. ...
- IOS开发 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
xcode自7后不再使用http,而是使用https请求,但目前很多网络请求还只是以http请求,我们可以这样解决 info.plist->添加@“App Transport Security ...
- 【原】ios的hitTest方法以及不规则区域内触摸事件处理方法
概述 在正常的使用场景中,我们处理了比较多的矩形区域内触摸事件,比如UIButton.UIControl.一般来说,这些控件的图形以及触摸区域都是矩形或者圆角矩形的.但是在一些特殊应用场景中我们有时不 ...