Docker网络学习笔记_第1页
Docker网络学习笔记_第2页
Docker网络学习笔记_第3页
Docker网络学习笔记_第4页
Docker网络学习笔记_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Docker 网络学习笔记Docker 网络学习笔记简介Docker 在网络方面并没有特别出彩的地方。 没有复杂的网络 设置,如果需要支持复杂应用的网络需求,光靠 Docker 的 设置参数也是不够的,还需要借助 linux 本身的一些网络设 置工具。本文只总结 Docker 本身的网络能力,对于更复杂的网络设 置,不属于 Docker 网络详解这个题目的范畴了,文章还是 要短小精悍比较好读,当然我也好写。下面会按照以下思路来总结下 Docker 的网络:1. Docker daemon 启动时对网络干了什么?2. Container 默认的启动方法有哪些网络能力?3. Container 如

2、何对外暴露网络服务?4. Container 之间的相互通信注:本文基于 Docker v1.0.1 代码分析)网络初始化我们先来看看,在不加任何参数的情况下,Docker daemon初始化对网络干了什么。运行 docker -d & 后,会有 如下打印(省略了无关联部分) : html view plaincopy/var/lib/docker|116d5cd4 +job init_networkdriver() /var/lib/docker|116d5cd4.init_networkdriver() creating new bridge for docker0 /var/li

3、b/docker|116d5cd4.init_networkdriver() getting iface addr/var/lib/docker|116d5cd4 -job init_networkdriver() = OK (0) 看样子只是简单的创建了 bridge docker0 ,分配 ip 地址。其 实内部还是有比较复杂的操作,图示如下: Init bridge这里有两个相关的启动参数: html view plaincopy-b, -bridge=: Attach containers to a pre-existing network bridge; use none to di

4、sable container networking -bip=: Use this CIDR notation address for the network bridges IP, not compatible with -b第一个是指定 bridge 接 口,第二个指定 bridge IP ,两个参数不能共存。这就是说, 指定 bridge IP 只能针对默认的 docker0 。第一个参数如果不 指定,那么默认是用 docker0 , 第二个参数不指定, 默认用 docker 内部定好的 IP ,一般没冲突的话,就会是第一个 。这里做了什么?查看指定(或者默认)

5、的 bridge 口是否存在。如果不存在, 则创建默认 bridge0 口(不指定 -b 参数)。逻辑上非常简单,这里就不再深入展开了,细节可以去看代 码。插一句嘴, 实际创建 bridge0 口的操作是通过 golang 的 syscall 库进行的: html viewplaincopyif _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr); err != 0 return err Init iptables这里直接看看启

6、动完后, iptalbes 里面有什么变化,就了解 Docker 干了什么了: html view plaincopy$ sudo iptables -L -verboseprot opt in out sourceChain INPUT (policy ACCEPT 168 packets, 11814 bytes)pkts bytes target destinationChain FORWARD (policy ACCEPT 0 packets, 0 bytes)pkts bytes targetprot opt inoutsourcedestination00 ACCEPTall -a

7、nydocker0anywhereanywherectstateRELATED,ESTABLISHED00 ACCEPTall -docker0 !docker0anywhereanywhere00 ACCEPTall -docker0 docker0anywhereanywhereChain OUTPUT (policy ACCEPT 128 packets, 16744 bytes)prot opt in out sourcepkts bytes target destination$ sudo iptables -L -t nat -verboseChain PREROUTING (po

8、licy ACCEPT 0 packets, 0 bytes)pkts bytes target destinationprot opt inoutsource0 0 DOCKER all - any any anywhere anywhere ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes targetprot opt in out sourcedestinationChain OUTPUT (policy ACCEPT 11 packets, 1014 bytes)

9、 pkts bytes target prot opt in out source destination0 0 DOCKER all - any any anywhere !/8ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT 11 packets, 1014 bytes)pkts bytes targetprot opt in out sourcedestination0 MASQUERADE allanyanyChain DOCKER (2 references)pkts bytes target

10、 prot opt in out source destination 先来看 filter 表, docker 启动后在 FORWARD chain 里面增加了三条规则。1. 第一条规则表示从其他接口发往 docker0 (就是发往 container )的报文,只有 RELATED 和 ESTABLISHED 状 态能通过。(比如 ftp 的关联链接, container 主动建链的 TCP 链接。外部是不能主动跟 container 内部的服务建链的。 )2. 第二条和第三条表示从 docker0 发往其他端口的报文都 能通过。再来看看 nat 表,这里比较重要。1. PREROUTIN

11、G chain 中和 OUTPUT chain 增加了都一条 规则,表示在收发两端,查找 route 之前,如果报文地址类 型是 local ,就会送到 DOCKER chain 处理。初始化时 DOCKER chain 是空的, 后面再详细介绍这两条规则的作用。 (在 route 之前怎么知道目的地址是 local ?这里需要再研究 下。)2. 在 POSTROUTING chain 中加了一条规则: 表示从container 往 host 外发(不是 container 之间) 的报文, 都会 将报文原地址改为外发接口地址发出去。这样在 container 访问 host 外部网络时,外部

12、看到的其实只是 host 地址,看 不到 container 的私有地址。 Init IP forward这个比较简单,就是将 proc 设置打开:/proc/sys/net/ipv4/ip_forward host 上的各个接口之间转发。打开了之后,报文就能够在Register functionDocker 内部的各种功能是以Job 形式存在,这里注册的就是 network 相关的几个 Job ,在后面 container 的启动中会 用到这些 Job 。 html view plaincopyallocate_interface: Allocate,release_interface: R

13、elease,allocate_port:AllocatePort,link:LinkContainers, 到这里, Docker的网络初始化就介绍完了。 Container 默认网络默认网络,指的是在启动 container 时不加其他网络相关的 参数,比如直接用 $docker run -i -t image command运行启动的 container 。这个 container 默认将使用 bridge 模式的网络,链接到 docker0内部流程主要分为两个部分, docker engine 部分和 execdriver 部分, 即配置部分和实际执行部分。 这里先介绍 bridge

14、模式,其他模式会在后面的参数介绍中简单介绍。Bridge 网络模式初始化主要分为两部分:1. allocate_interface前面 docker daemon 初始化最后, register function 操 作中注册了 “ allocate_interface ” Job ,这里主要就是调用这 个方法。这个方法比较简单,主要就是分配IP (在 bridge0 的网络地址范围中递增分配, 不会重用已释放的IP。、配置掩码、 网关等,保存到 container.NetworkSettings 结构。这里还没 实际的创建接口。逻辑简单,更细节的东西可以去看看代码2. create_inte

15、rface这里是真正的创建网络接口,所以与所使用的 execdriver 强相关( lxc 或 libcontainer )。 这里先介绍 lxc 的实现,因为简单。Lxc 的网络怎么配?可以用 man 查看帮助: $man lxc.conf , 里面专门有一节讲解怎么配 container 的网络 html view plaincopyNETWORKThe network section defines how the network is virtualized in the container. The networkvirtualizationactsat layer two. In

16、order to use the network virtualization, parameters must be specified to define the networkinterfaces of the container. Several virtual interfaces can be assigned and used in a container even if thesystem has only one physical network interface.work.typespecify what kind of network virtualization to

17、 be used for the container. Each time a work.type field is found a new round of network configuration begins. In this way, several network virtualizationtypes can be specified for the same container, as well as assigning several network interfaces for onecontainer. The different virtualization types

18、 can be:empty: will create only the loopback interface.Docker 在这里也是用 lxc 的配置, 不过配置文件是动态生成 的。可以参看 lxc_template.go 里面的配置文件: html view plaincopyconst LxcTemplate = if .Network.Interface# network configurationwork.type = vethwork.link = .Network.Interface.B = eth0work.mtu = .Network.Mtuels

19、e if .Network.HostNetworkingwork.type = noneelse# network is disabled (-n=false)work.type = empty work.flags = up work.mtu = .Network.Mtu end 有了配置文件,通过 lxc-start 就能启动一个带网络 的 container 了, container 里面的接口链接到 bridge0 。注:这里涉及到 network namespace 和 bridge 的知识,这 里不扩展介绍了,不然写不完了。 Container 端口映射 如果 host 外部客户想

20、访问 container 里面的服务,怎么办? 从前面介绍的 docker daemon 网络初始化看到, docker 添 加了一条 iptables 规则,外部发往 container 的报文,只有 在状态是 RELATED 和 ESTABLISHED 链接中,才能通过。 那么外部客户主动向 container 服务发起的建链,是会被拒 绝的。Docker 官网推荐的方式是使用端口映射, 对外暴露的是 host IP:port ,由 host 做 NAT 转换为 container 内部的 IP 和端口。 具体是怎么实现的呢?我们来看一下。如果我们这样创建一个 container : $d

21、ocker run -i -t -p 6000 image command ,然后看看 iptables 发生了什么变化(省 略了一些没影响的 Chain ): html view plaincopy<span style=color:#444444;>$ sudo iptables -L -verboseChain FORWARD (policy ACCEPT 0 packets, 0 bytes)pkts bytes targetprot opt in out sourcedestination</span><span style=color:#ff0000;

22、>00 ACCEPTtcp!docker0 docker0 anywheretcp dpt:x11</span><spanstyle=color:#444444;>0 ACCEPTallanydocker0anywhereanywherectstateRELATED,ESTABLISHED0 ACCEPTalldocker0 !docker0anywhereanywhere0 ACCEPTalldocker0 docker0anywhereanywhere$ sudo iptables -L -t nat -verboseChain POSTR

23、OUTING (policy ACCEPT 18 packets, 1486 bytes)pkts bytes targetprot opt inoutsourcedestination0 0 MASQUERADE all - anyany/16!/16Chain DOCKER (2 references)pkts bytes targetprot opt inoutsourcedestination</span><span style=color:#ff0000;>00 DNAT tcp - !docker0 anyanywhe

24、reanywhere tcp dpt:49153 to::6000</span> 这里就很明显了,里面主 要添加了两条规则:1. 在 filter 表 FORWARD 链中添加一条规则,让从 host 外 部过来的报文能够进入 container (这里 是新建 的 container 的 IP , x11 其实就是端口 6000 ,这是个知名端 口)。2. 在 nat 表 DOCKER 链中添加一条规则, host 外部过来的 访问 49153 端口的报文,会做 DNAT 将目的 IP 和端口转换 为 :6000 。有

25、了这两条规则,外部进来的报文就能正常访问 container 内部 6000 端口的服务了。 Container 之间通信同一个 host 上的 container ,默认是可以相互通信的,原理 就是 linux 的 bridge 原理。这里要介绍的其实是禁止 container 之间相互通信。 html viewplaincopy-icc=trueEnable inter-container communication 上面这个参数是启 动 docker daemon 时可选的参数, 默认是 true ,如果设置为 false ,那么这个 host 上的 container 就不能相互通信了,这 其实也是通过 iptables 来实现的。 html view plaincopy<span style=color:#444444;>$ sudo iptables -L -verboseChain INPUT (policy ACCEPT 94 packets, 6424 bytes)pkts bytes targetprot opt inout sourcedestinationChain FORWARD (poli

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论